00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qfile.h>
00022 #include <qtl.h>
00023 #include <math.h>
00024 #include <limits.h>
00025 #include <qdatastream.h>
00026 #include "qimpencombining.h"
00027
00028 static unsigned int combiningSymbols[] = { '\\', '/', '^', '~', '\"', 'o' };
00029 static unsigned int combiningChars[][7] = {
00030
00031 { 'A', 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5 },
00032 { 'O', 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0000 },
00033 { 'U', 0x00D9, 0x00DA, 0x00DB, 0x0000, 0x00DC, 0x0000 },
00034 { 'E', 0x00C8, 0x00C9, 0x00CA, 0x0000, 0x00CB, 0x0000 },
00035 { 'I', 0x00CC, 0x00CD, 0x00CE, 0x0000, 0x00CF, 0x0000 },
00036 { 'a', 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5 },
00037 { 'e', 0x00E8, 0x00E9, 0x00EA, 0x0000, 0x00EB, 0x0000 },
00038 { 'i', 0x00EC, 0x00ED, 0x00EE, 0x0000, 0x00EF, 0x0000 },
00039 { 'n', 0x0000, 0x0000, 0x0000, 0x00F1, 0x0000, 0x0000 },
00040 { 'o', 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0000 },
00041 { 'u', 0x00F9, 0x00FA, 0x00FB, 0x0000, 0x00FC, 0x0000 },
00042 { 'y', 0x0000, 0x00FD, 0x0000, 0x0000, 0x00FF, 0x0000 },
00043 { 0, 0, 0, 0, 0, 0, 0 }
00044 };
00045
00046
00047 QIMPenCombining::QIMPenCombining()
00048 {
00049 }
00050
00051 QIMPenCombining::QIMPenCombining( const QString &fn )
00052 : QIMPenCharSet( fn )
00053 {
00054 }
00055
00056 void QIMPenCombining::addCombined( QIMPenCharSet *cs )
00057 {
00058 unsigned int count = cs->count();
00059 QIMPenCharIterator it( cs->characters() );
00060 for ( ; it.current() && count; ++it, --count ) {
00061 QIMPenChar *pc = it.current();
00062 if ( pc->testFlag( QIMPenChar::Deleted ) )
00063 continue;
00064 int charIdx = findCombining( pc->character() );
00065 if ( charIdx < 0 )
00066 continue;
00067 for ( int i = 0; i < 6; i++ ) {
00068 if ( combiningChars[charIdx][i+1] ) {
00069 QIMPenCharIterator cit( chars );
00070 for ( ; cit.current(); ++cit ) {
00071 QIMPenChar *accentPc = cit.current();
00072 if ( accentPc->character() == combiningSymbols[i] ) {
00073 QIMPenChar *combined = combine( pc, accentPc );
00074 combined->setCharacter( combiningChars[charIdx][i+1] );
00075 combined->setFlag( QIMPenChar::Combined );
00076 cs->addChar( combined );
00077 }
00078 }
00079 }
00080 }
00081 }
00082 }
00083
00084 int QIMPenCombining::findCombining( unsigned int ch ) const
00085 {
00086 int i = 0;
00087 while ( combiningChars[i][0] ) {
00088 if ( combiningChars[i][0] == ch )
00089 return i;
00090 i++;
00091 }
00092
00093 return -1;
00094 }
00095
00096 QIMPenChar *QIMPenCombining::combine( QIMPenChar *base, QIMPenChar *accent )
00097 {
00098 QRect brect = base->boundingRect();
00099 QRect arect = accent->boundingRect();
00100 int offset;
00101 if ( accent->testFlag( QIMPenChar::CombineRight ) )
00102 offset = brect.left() - arect.left() + brect.width() + 2;
00103 else
00104 offset = brect.left() - arect.left() + (brect.width() - arect.width())/2;
00105 QIMPenChar *combined = 0;
00106 if ( base->character() == 'i' ) {
00107
00108 if ( base->penStrokes().count() > 1 ) {
00109 combined = new QIMPenChar;
00110 QIMPenStrokeIterator it( base->penStrokes() );
00111 for ( unsigned int i = 0; i < base->penStrokes().count()-1; ++it, i++ ) {
00112 QIMPenStroke *st = new QIMPenStroke( *(it.current()) );
00113 combined->addStroke( st );
00114 }
00115 combined->setFlag( QIMPenChar::System );
00116 }
00117 }
00118 if ( !combined )
00119 combined = new QIMPenChar( *base );
00120 QIMPenStrokeIterator it( accent->penStrokes() );
00121 for ( ; it.current(); ++it ) {
00122 QIMPenStroke *st = new QIMPenStroke( *(it.current()) );
00123 st->setStartingPoint( st->startingPoint() + QPoint(offset, 0 ));
00124 combined->addStroke( st );
00125 delete st;
00126 }
00127
00128 return combined;
00129 }
00130
00131 QIMPenChar *QIMPenCombining::penChar( int type )
00132 {
00133 QIMPenCharIterator it( chars );
00134 for ( ; it.current(); ++it ) {
00135 QIMPenChar *pc = it.current();
00136 if ( pc->character() == combiningSymbols[type] )
00137 return pc;
00138 }
00139
00140 return 0;
00141 }
00142