summaryrefslogtreecommitdiff
path: root/inputmethods/handwriting
Unidiff
Diffstat (limited to 'inputmethods/handwriting') (more/less context) (ignore whitespace changes)
-rw-r--r--inputmethods/handwriting/qimpenchar.cpp637
-rw-r--r--inputmethods/handwriting/qimpenchar.h2
-rw-r--r--inputmethods/handwriting/qimpencombining.cpp1
3 files changed, 322 insertions, 318 deletions
diff --git a/inputmethods/handwriting/qimpenchar.cpp b/inputmethods/handwriting/qimpenchar.cpp
index 152bfec..0c37e5c 100644
--- a/inputmethods/handwriting/qimpenchar.cpp
+++ b/inputmethods/handwriting/qimpenchar.cpp
@@ -1,20 +1,20 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2 ** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3 **
4** This file is part of Qtopia Environment. 4 ** This file is part of Qtopia Environment.
5** 5 **
6** This file may be distributed and/or modified under the terms of the 6 ** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7 ** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8 ** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9 ** packaging of this file.
10** 10 **
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13 **
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15 **
16** Contact info@trolltech.com if any conditions of this licensing are 16 ** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17 ** not clear to you.
18** 18 **
19**********************************************************************/ 19 **********************************************************************/
20 20
@@ -32,13 +32,13 @@
32const QIMPenSpecialKeys qimpen_specialKeys[] = { 32const QIMPenSpecialKeys qimpen_specialKeys[] = {
33 { Qt::Key_Escape, "[Esc]" }, 33 { Qt::Key_Escape, "[Esc]" },
34 { Qt::Key_Tab, "[Tab]" }, 34 { Qt::Key_Tab, "[Tab]" },
35 { Qt::Key_Backspace,"[BackSpace]" }, 35 { Qt::Key_Backspace,"[BackSpace]" },
36 { Qt::Key_Return, "[Return]" }, 36 { Qt::Key_Return, "[Return]" },
37 { QIMPenChar::Caps, "[Uppercase]" }, 37 { QIMPenChar::Caps, "[Uppercase]" },
38 { QIMPenChar::CapsLock,"[Caps Lock]" }, 38 { QIMPenChar::CapsLock,"[Caps Lock]" },
39 { QIMPenChar::Shortcut,"[Shortcut]" }, 39 { QIMPenChar::Shortcut,"[Shortcut]" },
40 { QIMPenChar::Punctuation, "[Punctuation]" }, 40 { QIMPenChar::Punctuation, "[Punctuation]" },
41 { QIMPenChar::Symbol,"[Symbol]" }, 41 { QIMPenChar::Symbol,"[Symbol]" },
42 { QIMPenChar::Extended,"[Extended]" }, 42 { QIMPenChar::Extended,"[Extended]" },
43 { Qt::Key_unknown, 0 } }; 43 { Qt::Key_unknown, 0 } };
44 44
@@ -50,3 +50,3 @@ const QIMPenSpecialKeys qimpen_specialKeys[] = {
50 another character. 50 another character.
51*/ 51 */
52 52
@@ -54,4 +54,4 @@ QIMPenChar::QIMPenChar()
54{ 54{
55 flags = 0; 55 flags = 0;
56 strokes.setAutoDelete( TRUE ); 56 strokes.setAutoDelete( TRUE );
57} 57}
@@ -60,11 +60,11 @@ QIMPenChar::QIMPenChar( const QIMPenChar &chr )
60{ 60{
61 strokes.setAutoDelete( TRUE ); 61 strokes.setAutoDelete( TRUE );
62 ch = chr.ch; 62 ch = chr.ch;
63 flags = chr.flags; 63 flags = chr.flags;
64 d = chr.d; 64 d = chr.d;
65 QIMPenStrokeIterator it( chr.strokes ); 65 QIMPenStrokeIterator it( chr.strokes );
66 while ( it.current() ) { 66 while ( it.current() ) {
67 strokes.append( new QIMPenStroke( *it.current() ) ); 67 strokes.append( new QIMPenStroke( *it.current() ) );
68 ++it; 68 ++it;
69 } 69 }
70} 70}
@@ -73,13 +73,13 @@ QIMPenChar &QIMPenChar::operator=( const QIMPenChar &chr )
73{ 73{
74 strokes.clear(); 74 strokes.clear();
75 ch = chr.ch; 75 ch = chr.ch;
76 flags = chr.flags; 76 flags = chr.flags;
77 d = chr.d; 77 d = chr.d;
78 QIMPenStrokeIterator it( chr.strokes ); 78 QIMPenStrokeIterator it( chr.strokes );
79 while ( it.current() ) { 79 while ( it.current() ) {
80 strokes.append( new QIMPenStroke( *it.current() ) ); 80 strokes.append( new QIMPenStroke( *it.current() ) );
81 ++it; 81 ++it;
82 } 82 }
83 83
84 return *this; 84 return *this;
85} 85}
@@ -88,17 +88,17 @@ QString QIMPenChar::name() const
88{ 88{
89 QString n; 89 QString n;
90 90
91 if ( (ch & 0x0000FFFF) == 0 ) { 91 if ( (ch & 0x0000FFFF) == 0 ) {
92 int code = ch >> 16; 92 int code = ch >> 16;
93 for ( int i = 0; qimpen_specialKeys[i].code != Qt::Key_unknown; i++ ) { 93 for ( int i = 0; qimpen_specialKeys[i].code != Qt::Key_unknown; i++ ) {
94 if ( qimpen_specialKeys[i].code == code ) { 94 if ( qimpen_specialKeys[i].code == code ) {
95 n = qimpen_specialKeys[i].name; 95 n = qimpen_specialKeys[i].name;
96 break; 96 break;
97 } 97 }
98 }
99 } else {
100 n = QChar( ch & 0x0000FFFF );
98 } 101 }
99 } else {
100 n = QChar( ch & 0x0000FFFF );
101 }
102 102
103 return n; 103 return n;
104} 104}
@@ -107,6 +107,6 @@ void QIMPenChar::clear()
107{ 107{
108 ch = 0; 108 ch = 0;
109 flags = 0; 109 flags = 0;
110 d = QString::null; 110 d = QString::null;
111 strokes.clear(); 111 strokes.clear();
112} 112}
@@ -115,12 +115,12 @@ unsigned int QIMPenChar::strokeLength( int s ) const
115{ 115{
116 QIMPenStrokeIterator it( strokes ); 116 QIMPenStrokeIterator it( strokes );
117 while ( it.current() && s ) { 117 while ( it.current() && s ) {
118 ++it; 118 ++it;
119 --s; 119 --s;
120 } 120 }
121 121
122 if ( it.current() ) 122 if ( it.current() )
123 return it.current()->length(); 123 return it.current()->length();
124 124
125 return 0; 125 return 0;
126} 126}
@@ -129,7 +129,7 @@ unsigned int QIMPenChar::strokeLength( int s ) const
129 Add a stroke to the character 129 Add a stroke to the character
130*/ 130 */
131void QIMPenChar::addStroke( QIMPenStroke *st ) 131void QIMPenChar::addStroke( QIMPenStroke *st )
132{ 132{
133 QIMPenStroke *stroke = new QIMPenStroke( *st ); 133 QIMPenStroke *stroke = new QIMPenStroke( *st );
134 strokes.append( stroke ); 134 strokes.append( stroke );
135} 135}
@@ -139,50 +139,50 @@ void QIMPenChar::addStroke( QIMPenStroke *st )
139 Lower value is better. 139 Lower value is better.
140*/ 140 */
141int QIMPenChar::match( QIMPenChar *pen ) 141int QIMPenChar::match( QIMPenChar *pen )
142{ 142{
143/* 143 /*
144 if ( strokes.count() > pen->strokes.count() ) 144 if ( strokes.count() > pen->strokes.count() )
145 return INT_MAX; 145 return INT_MAX;
146*/ 146 */
147 int err = 0; 147 int err = 0;
148 int maxErr = 0; 148 int maxErr = 0;
149 int diff = 0; 149 int diff = 0;
150 QIMPenStrokeIterator it1( strokes ); 150 QIMPenStrokeIterator it1( strokes );
151 QIMPenStrokeIterator it2( pen->strokes ); 151 QIMPenStrokeIterator it2( pen->strokes );
152 err = it1.current()->match( it2.current() ); 152 err = it1.current()->match( it2.current() );
153 if ( err > maxErr ) 153 if ( err > maxErr )
154 maxErr = err; 154 maxErr = err;
155 ++it1; 155 ++it1;
156 ++it2; 156 ++it2;
157 while ( err < 400000 && it1.current() && it2.current() ) { 157 while ( err < 400000 && it1.current() && it2.current() ) {
158 QPoint p1 = it1.current()->boundingRect().center() - 158 QPoint p1 = it1.current()->boundingRect().center() -
159 strokes.getFirst()->boundingRect().center(); 159 strokes.getFirst()->boundingRect().center();
160 QPoint p2 = it2.current()->boundingRect().center() - 160 QPoint p2 = it2.current()->boundingRect().center() -
161 pen->strokes.getFirst()->boundingRect().center(); 161 pen->strokes.getFirst()->boundingRect().center();
162 int xdiff = QABS( p1.x() - p2.x() ) - 6; 162 int xdiff = QABS( p1.x() - p2.x() ) - 6;
163 int ydiff = QABS( p1.y() - p2.y() ) - 5; 163 int ydiff = QABS( p1.y() - p2.y() ) - 5;
164 if ( xdiff < 0 ) 164 if ( xdiff < 0 )
165 xdiff = 0; 165 xdiff = 0;
166 if ( ydiff < 0 ) 166 if ( ydiff < 0 )
167 ydiff = 0; 167 ydiff = 0;
168 if ( xdiff > 10 || ydiff > 10 ) { // not a chance 168 if ( xdiff > 10 || ydiff > 10 ) { // not a chance
169#ifdef DEBUG_QIMPEN 169#ifdef DEBUG_QIMPEN
170 qDebug( "char %c, stroke starting pt diff excessive", pen->ch ); 170 qDebug( "char %c, stroke starting pt diff excessive", pen->ch );
171#endif 171#endif
172 return INT_MAX; 172 return INT_MAX;
173 }
174 diff += xdiff*xdiff + ydiff*ydiff;
175 err = it1.current()->match( it2.current() );
176 if ( err > maxErr )
177 maxErr = err;
178 ++it1;
179 ++it2;
173 } 180 }
174 diff += xdiff*xdiff + ydiff*ydiff;
175 err = it1.current()->match( it2.current() );
176 if ( err > maxErr )
177 maxErr = err;
178 ++it1;
179 ++it2;
180 }
181 181
182 maxErr += diff * diff * 6; // magic weighting :) 182 maxErr += diff * diff * 6; // magic weighting :)
183 183
184#ifdef DEBUG_QIMPEN 184#ifdef DEBUG_QIMPEN
185 qDebug( "char: %c, maxErr %d, diff %d, (%d)", pen->ch, maxErr, diff, strokes.count() ); 185 qDebug( "char: %c, maxErr %d, diff %d, (%d)", pen->ch, maxErr, diff, strokes.count() );
186#endif 186#endif
187 return maxErr; 187 return maxErr;
188} 188}
@@ -193,13 +193,13 @@ int QIMPenChar::match( QIMPenChar *pen )
193 the character. 193 the character.
194*/ 194 */
195QRect QIMPenChar::boundingRect() 195QRect QIMPenChar::boundingRect()
196{ 196{
197 QRect br; 197 QRect br;
198 QIMPenStroke *st = strokes.first(); 198 QIMPenStroke *st = strokes.first();
199 while ( st ) { 199 while ( st ) {
200 br |= st->boundingRect(); 200 br |= st->boundingRect();
201 st = strokes.next(); 201 st = strokes.next();
202 } 202 }
203 203
204 return br; 204 return br;
205} 205}
@@ -209,17 +209,17 @@ QRect QIMPenChar::boundingRect()
209 Write the character's data to the stream. 209 Write the character's data to the stream.
210*/ 210 */
211QDataStream &operator<< (QDataStream &s, const QIMPenChar &ws) 211QDataStream &operator<< (QDataStream &s, const QIMPenChar &ws)
212{ 212{
213 s << ws.ch; 213 s << ws.ch;
214 s << ws.flags; 214 s << ws.flags;
215 if ( ws.flags & QIMPenChar::Data ) 215 if ( ws.flags & QIMPenChar::Data )
216 s << ws.d; 216 s << ws.d;
217 s << ws.strokes.count(); 217 s << ws.strokes.count();
218 QIMPenStrokeIterator it( ws.strokes ); 218 QIMPenStrokeIterator it( ws.strokes );
219 while ( it.current() ) { 219 while ( it.current() ) {
220 s << *it.current(); 220 s << *it.current();
221 ++it; 221 ++it;
222 } 222 }
223 223
224 return s; 224 return s;
225} 225}
@@ -228,18 +228,18 @@ QDataStream &operator<< (QDataStream &s, const QIMPenChar &ws)
228 Read the character's data from the stream. 228 Read the character's data from the stream.
229*/ 229 */
230QDataStream &operator>> (QDataStream &s, QIMPenChar &ws) 230QDataStream &operator>> (QDataStream &s, QIMPenChar &ws)
231{ 231{
232 s >> ws.ch; 232 s >> ws.ch;
233 s >> ws.flags; 233 s >> ws.flags;
234 if ( ws.flags & QIMPenChar::Data ) 234 if ( ws.flags & QIMPenChar::Data )
235 s >> ws.d; 235 s >> ws.d;
236 unsigned size; 236 unsigned size;
237 s >> size; 237 s >> size;
238 for ( unsigned i = 0; i < size; i++ ) { 238 for ( unsigned i = 0; i < size; i++ ) {
239 QIMPenStroke *st = new QIMPenStroke(); 239 QIMPenStroke *st = new QIMPenStroke();
240 s >> *st; 240 s >> *st;
241 ws.strokes.append( st ); 241 ws.strokes.append( st );
242 } 242 }
243 243
244 return s; 244 return s;
245} 245}
@@ -250,3 +250,3 @@ bool QIMPenCharMatch::operator>( const QIMPenCharMatch &m )
250{ 250{
251 return error > m.error; 251 return error > m.error;
252} 252}
@@ -255,3 +255,3 @@ bool QIMPenCharMatch::operator<( const QIMPenCharMatch &m )
255{ 255{
256 return error < m.error; 256 return error < m.error;
257} 257}
@@ -260,3 +260,3 @@ bool QIMPenCharMatch::operator<=( const QIMPenCharMatch &m )
260{ 260{
261 return error <= m.error; 261 return error <= m.error;
262} 262}
@@ -269,3 +269,3 @@ bool QIMPenCharMatch::operator<=( const QIMPenCharMatch &m )
269 Maintains a set of related characters. 269 Maintains a set of related characters.
270*/ 270 */
271 271
@@ -273,7 +273,7 @@ QIMPenCharSet::QIMPenCharSet()
273{ 273{
274 chars.setAutoDelete( TRUE ); 274 chars.setAutoDelete( TRUE );
275 desc = "Unnamed"; 275 desc = "Unnamed";
276 csTitle = "abc"; 276 csTitle = "abc";
277 csType = Unknown; 277 csType = Unknown;
278 maxStrokes = 0; 278 maxStrokes = 0;
279} 279}
@@ -282,11 +282,11 @@ QIMPenCharSet::QIMPenCharSet()
282 Construct and load a characters set from file \a fn. 282 Construct and load a characters set from file \a fn.
283*/ 283 */
284QIMPenCharSet::QIMPenCharSet( const QString &fn ) 284QIMPenCharSet::QIMPenCharSet( const QString &fn )
285{ 285{
286 chars.setAutoDelete( TRUE ); 286 chars.setAutoDelete( TRUE );
287 desc = "Unnamed"; 287 desc = "Unnamed";
288 csTitle = "abc"; 288 csTitle = "abc";
289 csType = Unknown; 289 csType = Unknown;
290 maxStrokes = 0; 290 maxStrokes = 0;
291 load( fn, System ); 291 load( fn, System );
292} 292}
@@ -295,6 +295,6 @@ const QString &QIMPenCharSet::filename( Domain d ) const
295{ 295{
296 if ( d == System ) 296 if ( d == System )
297 return sysFilename; 297 return sysFilename;
298 else 298 else
299 return userFilename; 299 return userFilename;
300} 300}
@@ -303,6 +303,6 @@ void QIMPenCharSet::setFilename( const QString &fn, Domain d )
303{ 303{
304 if ( d == System ) 304 if ( d == System )
305 sysFilename = fn; 305 sysFilename = fn;
306 else if ( d == User ) 306 else if ( d == User )
307 userFilename = fn; 307 userFilename = fn;
308} 308}
@@ -311,41 +311,41 @@ void QIMPenCharSet::setFilename( const QString &fn, Domain d )
311 Load a character set from file \a fn. 311 Load a character set from file \a fn.
312*/ 312 */
313bool QIMPenCharSet::load( const QString &fn, Domain d ) 313bool QIMPenCharSet::load( const QString &fn, Domain d )
314{ 314{
315 setFilename( fn, d ); 315 setFilename( fn, d );
316 316
317 bool ok = FALSE; 317 bool ok = FALSE;
318 QFile file( fn ); 318 QFile file( fn );
319 if ( file.open( IO_ReadOnly ) ) { 319 if ( file.open( IO_ReadOnly ) ) {
320 QDataStream ds( &file ); 320 QDataStream ds( &file );
321 QString version; 321 QString version;
322 ds >> version; 322 ds >> version;
323 ds >> csTitle; 323 ds >> csTitle;
324 ds >> desc; 324 ds >> desc;
325 int major = version.mid( 4, 1 ).toInt(); 325 int major = version.mid( 4, 1 ).toInt();
326 int minor = version.mid( 6 ).toInt(); 326 int minor = version.mid( 6 ).toInt();
327 if ( major >= 1 && minor > 0 ) { 327 if ( major >= 1 && minor > 0 ) {
328 ds >> (Q_INT8 &)csType; 328 ds >> (Q_INT8 &)csType;
329 } else { 329 } else {
330 if ( csTitle == "abc" ) 330 if ( csTitle == "abc" )
331 csType = Lower; 331 csType = Lower;
332 else if ( csTitle == "ABC" ) 332 else if ( csTitle == "ABC" )
333 csType = Upper; 333 csType = Upper;
334 else if ( csTitle == "123" ) 334 else if ( csTitle == "123" )
335 csType = Numeric; 335 csType = Numeric;
336 else if ( fn == "Combining" ) 336 else if ( fn == "Combining" )
337 csType = Combining; 337 csType = Combining;
338 }
339 while ( !ds.atEnd() ) {
340 QIMPenChar *pc = new QIMPenChar;
341 ds >> *pc;
342 if ( d == User )
343 markDeleted( pc->character() ); // override system
344 addChar( pc );
345 }
346 if ( file.status() == IO_Ok )
347 ok = TRUE;
338 } 348 }
339 while ( !ds.atEnd() ) { 349
340 QIMPenChar *pc = new QIMPenChar; 350 return ok;
341 ds >> *pc;
342 if ( d == User )
343 markDeleted( pc->character() ); // override system
344 addChar( pc );
345 }
346 if ( file.status() == IO_Ok )
347 ok = TRUE;
348 }
349
350 return ok;
351} 351}
@@ -354,44 +354,47 @@ bool QIMPenCharSet::load( const QString &fn, Domain d )
354 Save this character set. 354 Save this character set.
355*/ 355 */
356bool QIMPenCharSet::save( Domain d ) 356bool QIMPenCharSet::save( Domain d )
357{ 357{
358 if ( filename( d ).isEmpty() ) 358 if ( filename( d ).isEmpty() )
359 return FALSE; 359 return FALSE;
360 360
361 bool ok = FALSE; 361 bool ok = FALSE;
362 362
363 QString fn = filename( d ); 363 QString fn = filename( d );
364 QString tmpFn = fn + ".new"; 364 QString tmpFn = fn + ".new";
365 QFile file( tmpFn ); 365 QFile file( tmpFn );
366 if ( file.open( IO_WriteOnly|IO_Raw ) ) { 366 if ( file.open( IO_WriteOnly|IO_Raw ) ) {
367 QDataStream ds( &file ); 367 QByteArray buf;
368 ds << QString( "QPT 1.1" ); 368 QDataStream ds( buf, IO_WriteOnly );
369 ds << csTitle; 369 ds << QString( "QPT 1.1" );
370 ds << desc; 370 ds << csTitle;
371 ds << (Q_INT8)csType; 371 ds << desc;
372 QIMPenCharIterator ci( chars ); 372 ds << (Q_INT8)csType;
373 for ( ; ci.current(); ++ci ) { 373 QIMPenCharIterator ci( chars );
374 QIMPenChar *pc = ci.current(); 374 for ( ; ci.current(); ++ci ) {
375 if ( ( (d == System) && pc->testFlag( QIMPenChar::System ) ) || 375 QIMPenChar *pc = ci.current();
376 ( (d == User) && !pc->testFlag( QIMPenChar::System ) ) ) { 376 if ( ( ( (d == System) && pc->testFlag( QIMPenChar::System ) ) ||
377 ds << *pc; 377 ( (d == User) && !pc->testFlag( QIMPenChar::System ) ) ) &&
378 } 378 ( !pc->testFlag (QIMPenChar::Combined ) ) ) {
379 if ( file.status() != IO_Ok ) 379 ds << *pc;
380 break; 380 }
381 } 381 }
382 if ( file.status() == IO_Ok ) 382
383 ok = TRUE; 383 file.writeBlock( buf );
384 } 384 file.close();
385 385 if ( file.status() == IO_Ok )
386 if ( ok ) { 386 ok = TRUE;
387 if ( ::rename( tmpFn.latin1(), fn.latin1() ) < 0 ) {
388 qWarning( "problem renaming file %s to %s, errno: %d",
389 tmpFn.latin1(), fn.latin1(), errno );
390 // remove the tmp file, otherwise, it will just lay around...
391 QFile::remove( tmpFn.latin1() );
392 ok = FALSE;
393 } 387 }
394 }
395 388
396 return ok; 389 if ( ok ) {
390 if ( ::rename( tmpFn.latin1(), fn.latin1() ) < 0 ) {
391 qWarning( "problem renaming file %s to %s, errno: %d",
392 tmpFn.latin1(), fn.latin1(), errno );
393 // remove the tmp file, otherwise, it will just lay around...
394 QFile::remove( tmpFn.latin1() );
395 ok = FALSE;
396 }
397 }
398
399 return ok;
397} 400}
@@ -400,3 +403,3 @@ QIMPenChar *QIMPenCharSet::at( int i )
400{ 403{
401 return chars.at(i); 404 return chars.at(i);
402} 405}
@@ -405,8 +408,8 @@ void QIMPenCharSet::markDeleted( uint ch )
405{ 408{
406 QIMPenCharIterator ci( chars ); 409 QIMPenCharIterator ci( chars );
407 for ( ; ci.current(); ++ci ) { 410 for ( ; ci.current(); ++ci ) {
408 QIMPenChar *pc = ci.current(); 411 QIMPenChar *pc = ci.current();
409 if ( pc->character() == ch && pc->testFlag( QIMPenChar::System ) ) 412 if ( pc->character() == ch && pc->testFlag( QIMPenChar::System ) )
410 pc->setFlag( QIMPenChar::Deleted ); 413 pc->setFlag( QIMPenChar::Deleted );
411 } 414 }
412} 415}
@@ -415,46 +418,46 @@ void QIMPenCharSet::markDeleted( uint ch )
415 Find the best matches for \a ch in this character set. 418 Find the best matches for \a ch in this character set.
416*/ 419 */
417QIMPenCharMatchList QIMPenCharSet::match( QIMPenChar *ch ) 420QIMPenCharMatchList QIMPenCharSet::match( QIMPenChar *ch )
418{ 421{
419 QIMPenCharMatchList matches; 422 QIMPenCharMatchList matches;
420 423
421 QIMPenCharIterator ci( chars ); 424 QIMPenCharIterator ci( chars );
422 for ( ; ci.current(); ++ci ) { 425 for ( ; ci.current(); ++ci ) {
423 QIMPenChar *tmplChar = ci.current(); 426 QIMPenChar *tmplChar = ci.current();
424 if ( tmplChar->testFlag( QIMPenChar::Deleted ) ) { 427 if ( tmplChar->testFlag( QIMPenChar::Deleted ) ) {
425 continue; 428 continue;
426 }
427 int err;
428 if ( ch->penStrokes().count() <= tmplChar->penStrokes().count() ) {
429 err = ch->match( tmplChar );
430 if ( err <= QIMPEN_MATCH_THRESHOLD ) {
431 if (tmplChar->penStrokes().count() != ch->penStrokes().count())
432 err = QMIN(err*3, QIMPEN_MATCH_THRESHOLD);
433 QIMPenCharMatchList::Iterator it;
434 for ( it = matches.begin(); it != matches.end(); ++it ) {
435 if ( (*it).penChar->character() == tmplChar->character() &&
436 (*it).penChar->penStrokes().count() == tmplChar->penStrokes().count() ) {
437 if ( (*it).error > err )
438 (*it).error = err;
439 break;
440 }
441 } 429 }
442 if ( it == matches.end() ) { 430 int err;
443 QIMPenCharMatch m; 431 if ( ch->penStrokes().count() <= tmplChar->penStrokes().count() ) {
444 m.error = err; 432 err = ch->match( tmplChar );
445 m.penChar = tmplChar; 433 if ( err <= QIMPEN_MATCH_THRESHOLD ) {
446 matches.append( m ); 434 if (tmplChar->penStrokes().count() != ch->penStrokes().count())
435 err = QMIN(err*3, QIMPEN_MATCH_THRESHOLD);
436 QIMPenCharMatchList::Iterator it;
437 for ( it = matches.begin(); it != matches.end(); ++it ) {
438 if ( (*it).penChar->character() == tmplChar->character() &&
439 (*it).penChar->penStrokes().count() == tmplChar->penStrokes().count() ) {
440 if ( (*it).error > err )
441 (*it).error = err;
442 break;
443 }
444 }
445 if ( it == matches.end() ) {
446 QIMPenCharMatch m;
447 m.error = err;
448 m.penChar = tmplChar;
449 matches.append( m );
450 }
451 }
447 } 452 }
448 }
449 } 453 }
450 } 454 qHeapSort( matches );
451 qHeapSort( matches ); 455 /*
452/* 456 QIMPenCharMatchList::Iterator it;
453 QIMPenCharMatchList::Iterator it; 457 for ( it = matches.begin(); it != matches.end(); ++it ) {
454 for ( it = matches.begin(); it != matches.end(); ++it ) { 458 qDebug( "Match: \'%c\', error %d, strokes %d", (*it).penChar->character(),
455 qDebug( "Match: \'%c\', error %d, strokes %d", (*it).penChar->character(), 459 (*it).error, (*it).penChar->penStrokes().count() );
456 (*it).error, (*it).penChar->penStrokes().count() ); 460 }
457 } 461 */
458*/ 462 return matches;
459 return matches;
460} 463}
@@ -464,8 +467,8 @@ QIMPenCharMatchList QIMPenCharSet::match( QIMPenChar *ch )
464 QIMPenCharSet will delete this character when it is no longer needed. 467 QIMPenCharSet will delete this character when it is no longer needed.
465*/ 468 */
466void QIMPenCharSet::addChar( QIMPenChar *ch ) 469void QIMPenCharSet::addChar( QIMPenChar *ch )
467{ 470{
468 if ( ch->penStrokes().count() > maxStrokes ) 471 if ( ch->penStrokes().count() > maxStrokes )
469 maxStrokes = ch->penStrokes().count(); 472 maxStrokes = ch->penStrokes().count();
470 chars.append( ch ); 473 chars.append( ch );
471} 474}
@@ -475,6 +478,6 @@ void QIMPenCharSet::addChar( QIMPenChar *ch )
475 QIMPenCharSet will delete this character. 478 QIMPenCharSet will delete this character.
476*/ 479 */
477void QIMPenCharSet::removeChar( QIMPenChar *ch ) 480void QIMPenCharSet::removeChar( QIMPenChar *ch )
478{ 481{
479 chars.remove( ch ); 482 chars.remove( ch );
480} 483}
@@ -483,10 +486,10 @@ void QIMPenCharSet::removeChar( QIMPenChar *ch )
483 Move the character up the list of characters. 486 Move the character up the list of characters.
484*/ 487 */
485void QIMPenCharSet::up( QIMPenChar *ch ) 488void QIMPenCharSet::up( QIMPenChar *ch )
486{ 489{
487 int idx = chars.findRef( ch ); 490 int idx = chars.findRef( ch );
488 if ( idx > 0 ) { 491 if ( idx > 0 ) {
489 chars.take(); 492 chars.take();
490 chars.insert( idx - 1, ch ); 493 chars.insert( idx - 1, ch );
491 } 494 }
492} 495}
@@ -495,10 +498,10 @@ void QIMPenCharSet::up( QIMPenChar *ch )
495 Move the character down the list of characters. 498 Move the character down the list of characters.
496*/ 499 */
497void QIMPenCharSet::down( QIMPenChar *ch ) 500void QIMPenCharSet::down( QIMPenChar *ch )
498{ 501{
499 int idx = chars.findRef( ch ); 502 int idx = chars.findRef( ch );
500 if ( idx >= 0 && idx < (int)chars.count() - 1 ) { 503 if ( idx >= 0 && idx < (int)chars.count() - 1 ) {
501 chars.take(); 504 chars.take();
502 chars.insert( idx + 1, ch ); 505 chars.insert( idx + 1, ch );
503 } 506 }
504} 507}
diff --git a/inputmethods/handwriting/qimpenchar.h b/inputmethods/handwriting/qimpenchar.h
index 9a5f687..efd6f16 100644
--- a/inputmethods/handwriting/qimpenchar.h
+++ b/inputmethods/handwriting/qimpenchar.h
@@ -62,3 +62,3 @@ public:
62 62
63 enum Flags { System=0x01, Deleted=0x02, CombineRight=0x04, Data=0x08 }; 63 enum Flags { System=0x01, Deleted=0x02, CombineRight=0x04, Data=0x08, Combined=0x10 };
64 // Correspond to codes in template files. Do not change values. 64 // Correspond to codes in template files. Do not change values.
diff --git a/inputmethods/handwriting/qimpencombining.cpp b/inputmethods/handwriting/qimpencombining.cpp
index 30459e7..2e01ac2 100644
--- a/inputmethods/handwriting/qimpencombining.cpp
+++ b/inputmethods/handwriting/qimpencombining.cpp
@@ -74,2 +74,3 @@ void QIMPenCombining::addCombined( QIMPenCharSet *cs )
74 combined->setCharacter( combiningChars[charIdx][i+1] ); 74 combined->setCharacter( combiningChars[charIdx][i+1] );
75 combined->setFlag( QIMPenChar::Combined );
75 cs->addChar( combined ); 76 cs->addChar( combined );