Diffstat (limited to 'inputmethods/handwriting/qimpenchar.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | inputmethods/handwriting/qimpenchar.cpp | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/inputmethods/handwriting/qimpenchar.cpp b/inputmethods/handwriting/qimpenchar.cpp index 929f370..db5d135 100644 --- a/inputmethods/handwriting/qimpenchar.cpp +++ b/inputmethods/handwriting/qimpenchar.cpp | |||
@@ -1,281 +1,282 @@ | |||
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 | ||
21 | #include <qfile.h> | 21 | #include <qfile.h> |
22 | #include <qtl.h> | 22 | #include <qtl.h> |
23 | #include <math.h> | 23 | #include <math.h> |
24 | #include <limits.h> | 24 | #include <limits.h> |
25 | #include <errno.h> | 25 | #include <errno.h> |
26 | #include <qdatastream.h> | 26 | #include <qdatastream.h> |
27 | #include "qimpencombining.h" | 27 | #include "qimpencombining.h" |
28 | #include "qimpenchar.h" | 28 | #include "qimpenchar.h" |
29 | #include "opie2/odebug.h" | ||
29 | 30 | ||
30 | #define QIMPEN_MATCH_THRESHOLD 200000 | 31 | #define QIMPEN_MATCH_THRESHOLD 200000 |
31 | 32 | ||
32 | const QIMPenSpecialKeys qimpen_specialKeys[] = { | 33 | const QIMPenSpecialKeys qimpen_specialKeys[] = { |
33 | { Qt::Key_Escape, "[Esc]" }, | 34 | { Qt::Key_Escape, "[Esc]" }, |
34 | { Qt::Key_Tab, "[Tab]" }, | 35 | { Qt::Key_Tab, "[Tab]" }, |
35 | { Qt::Key_Backspace,"[BackSpace]" }, | 36 | { Qt::Key_Backspace,"[BackSpace]" }, |
36 | { Qt::Key_Return, "[Return]" }, | 37 | { Qt::Key_Return, "[Return]" }, |
37 | { QIMPenChar::Caps, "[Uppercase]" }, | 38 | { QIMPenChar::Caps, "[Uppercase]" }, |
38 | { QIMPenChar::CapsLock,"[Caps Lock]" }, | 39 | { QIMPenChar::CapsLock,"[Caps Lock]" }, |
39 | { QIMPenChar::Shortcut,"[Shortcut]" }, | 40 | { QIMPenChar::Shortcut,"[Shortcut]" }, |
40 | { QIMPenChar::Punctuation, "[Punctuation]" }, | 41 | { QIMPenChar::Punctuation, "[Punctuation]" }, |
41 | { QIMPenChar::Symbol,"[Symbol]" }, | 42 | { QIMPenChar::Symbol,"[Symbol]" }, |
42 | { QIMPenChar::Extended,"[Extended]" }, | 43 | { QIMPenChar::Extended,"[Extended]" }, |
43 | { Qt::Key_unknown, 0 } }; | 44 | { Qt::Key_unknown, 0 } }; |
44 | 45 | ||
45 | 46 | ||
46 | /*! | 47 | /*! |
47 | \class QIMPenChar qimpenchar.h | 48 | \class QIMPenChar qimpenchar.h |
48 | 49 | ||
49 | Handles a single character. Can calculate closeness of match to | 50 | Handles a single character. Can calculate closeness of match to |
50 | another character. | 51 | another character. |
51 | */ | 52 | */ |
52 | 53 | ||
53 | QIMPenChar::QIMPenChar() | 54 | QIMPenChar::QIMPenChar() |
54 | { | 55 | { |
55 | flags = 0; | 56 | flags = 0; |
56 | strokes.setAutoDelete( TRUE ); | 57 | strokes.setAutoDelete( TRUE ); |
57 | } | 58 | } |
58 | 59 | ||
59 | QIMPenChar::QIMPenChar( const QIMPenChar &chr ) | 60 | QIMPenChar::QIMPenChar( const QIMPenChar &chr ) |
60 | { | 61 | { |
61 | strokes.setAutoDelete( TRUE ); | 62 | strokes.setAutoDelete( TRUE ); |
62 | ch = chr.ch; | 63 | ch = chr.ch; |
63 | flags = chr.flags; | 64 | flags = chr.flags; |
64 | d = chr.d; | 65 | d = chr.d; |
65 | QIMPenStrokeIterator it( chr.strokes ); | 66 | QIMPenStrokeIterator it( chr.strokes ); |
66 | while ( it.current() ) { | 67 | while ( it.current() ) { |
67 | strokes.append( new QIMPenStroke( *it.current() ) ); | 68 | strokes.append( new QIMPenStroke( *it.current() ) ); |
68 | ++it; | 69 | ++it; |
69 | } | 70 | } |
70 | } | 71 | } |
71 | 72 | ||
72 | QIMPenChar &QIMPenChar::operator=( const QIMPenChar &chr ) | 73 | QIMPenChar &QIMPenChar::operator=( const QIMPenChar &chr ) |
73 | { | 74 | { |
74 | strokes.clear(); | 75 | strokes.clear(); |
75 | ch = chr.ch; | 76 | ch = chr.ch; |
76 | flags = chr.flags; | 77 | flags = chr.flags; |
77 | d = chr.d; | 78 | d = chr.d; |
78 | QIMPenStrokeIterator it( chr.strokes ); | 79 | QIMPenStrokeIterator it( chr.strokes ); |
79 | while ( it.current() ) { | 80 | while ( it.current() ) { |
80 | strokes.append( new QIMPenStroke( *it.current() ) ); | 81 | strokes.append( new QIMPenStroke( *it.current() ) ); |
81 | ++it; | 82 | ++it; |
82 | } | 83 | } |
83 | 84 | ||
84 | return *this; | 85 | return *this; |
85 | } | 86 | } |
86 | 87 | ||
87 | QString QIMPenChar::name() const | 88 | QString QIMPenChar::name() const |
88 | { | 89 | { |
89 | QString n; | 90 | QString n; |
90 | 91 | ||
91 | if ( (ch & 0x0000FFFF) == 0 ) { | 92 | if ( (ch & 0x0000FFFF) == 0 ) { |
92 | int code = ch >> 16; | 93 | int code = ch >> 16; |
93 | for ( int i = 0; qimpen_specialKeys[i].code != Qt::Key_unknown; i++ ) { | 94 | for ( int i = 0; qimpen_specialKeys[i].code != Qt::Key_unknown; i++ ) { |
94 | if ( qimpen_specialKeys[i].code == code ) { | 95 | if ( qimpen_specialKeys[i].code == code ) { |
95 | n = qimpen_specialKeys[i].name; | 96 | n = qimpen_specialKeys[i].name; |
96 | break; | 97 | break; |
97 | } | 98 | } |
98 | } | 99 | } |
99 | } else { | 100 | } else { |
100 | n = QChar( ch & 0x0000FFFF ); | 101 | n = QChar( ch & 0x0000FFFF ); |
101 | } | 102 | } |
102 | 103 | ||
103 | return n; | 104 | return n; |
104 | } | 105 | } |
105 | 106 | ||
106 | void QIMPenChar::clear() | 107 | void QIMPenChar::clear() |
107 | { | 108 | { |
108 | ch = 0; | 109 | ch = 0; |
109 | flags = 0; | 110 | flags = 0; |
110 | d = QString::null; | 111 | d = QString::null; |
111 | strokes.clear(); | 112 | strokes.clear(); |
112 | } | 113 | } |
113 | 114 | ||
114 | unsigned int QIMPenChar::strokeLength( int s ) const | 115 | unsigned int QIMPenChar::strokeLength( int s ) const |
115 | { | 116 | { |
116 | QIMPenStrokeIterator it( strokes ); | 117 | QIMPenStrokeIterator it( strokes ); |
117 | while ( it.current() && s ) { | 118 | while ( it.current() && s ) { |
118 | ++it; | 119 | ++it; |
119 | --s; | 120 | --s; |
120 | } | 121 | } |
121 | 122 | ||
122 | if ( it.current() ) | 123 | if ( it.current() ) |
123 | return it.current()->length(); | 124 | return it.current()->length(); |
124 | 125 | ||
125 | return 0; | 126 | return 0; |
126 | } | 127 | } |
127 | 128 | ||
128 | /*! | 129 | /*! |
129 | Add a stroke to the character | 130 | Add a stroke to the character |
130 | */ | 131 | */ |
131 | void QIMPenChar::addStroke( QIMPenStroke *st ) | 132 | void QIMPenChar::addStroke( QIMPenStroke *st ) |
132 | { | 133 | { |
133 | QIMPenStroke *stroke = new QIMPenStroke( *st ); | 134 | QIMPenStroke *stroke = new QIMPenStroke( *st ); |
134 | strokes.append( stroke ); | 135 | strokes.append( stroke ); |
135 | } | 136 | } |
136 | 137 | ||
137 | /*! | 138 | /*! |
138 | Return an indicator of the closeness of this character to \a pen. | 139 | Return an indicator of the closeness of this character to \a pen. |
139 | Lower value is better. | 140 | Lower value is better. |
140 | */ | 141 | */ |
141 | int QIMPenChar::match( QIMPenChar *pen ) | 142 | int QIMPenChar::match( QIMPenChar *pen ) |
142 | { | 143 | { |
143 | /* | 144 | /* |
144 | if ( strokes.count() > pen->strokes.count() ) | 145 | if ( strokes.count() > pen->strokes.count() ) |
145 | return INT_MAX; | 146 | return INT_MAX; |
146 | */ | 147 | */ |
147 | int err = 0; | 148 | int err = 0; |
148 | int maxErr = 0; | 149 | int maxErr = 0; |
149 | int diff = 0; | 150 | int diff = 0; |
150 | QIMPenStrokeIterator it1( strokes ); | 151 | QIMPenStrokeIterator it1( strokes ); |
151 | QIMPenStrokeIterator it2( pen->strokes ); | 152 | QIMPenStrokeIterator it2( pen->strokes ); |
152 | err = it1.current()->match( it2.current() ); | 153 | err = it1.current()->match( it2.current() ); |
153 | if ( err > maxErr ) | 154 | if ( err > maxErr ) |
154 | maxErr = err; | 155 | maxErr = err; |
155 | ++it1; | 156 | ++it1; |
156 | ++it2; | 157 | ++it2; |
157 | while ( err < 400000 && it1.current() && it2.current() ) { | 158 | while ( err < 400000 && it1.current() && it2.current() ) { |
158 | QPoint p1 = it1.current()->boundingRect().center() - | 159 | QPoint p1 = it1.current()->boundingRect().center() - |
159 | strokes.getFirst()->boundingRect().center(); | 160 | strokes.getFirst()->boundingRect().center(); |
160 | QPoint p2 = it2.current()->boundingRect().center() - | 161 | QPoint p2 = it2.current()->boundingRect().center() - |
161 | pen->strokes.getFirst()->boundingRect().center(); | 162 | pen->strokes.getFirst()->boundingRect().center(); |
162 | int xdiff = QABS( p1.x() - p2.x() ) - 6; | 163 | int xdiff = QABS( p1.x() - p2.x() ) - 6; |
163 | int ydiff = QABS( p1.y() - p2.y() ) - 5; | 164 | int ydiff = QABS( p1.y() - p2.y() ) - 5; |
164 | if ( xdiff < 0 ) | 165 | if ( xdiff < 0 ) |
165 | xdiff = 0; | 166 | xdiff = 0; |
166 | if ( ydiff < 0 ) | 167 | if ( ydiff < 0 ) |
167 | ydiff = 0; | 168 | ydiff = 0; |
168 | if ( xdiff > 10 || ydiff > 10 ) { // not a chance | 169 | if ( xdiff > 10 || ydiff > 10 ) { // not a chance |
169 | #ifdef DEBUG_QIMPEN | 170 | #ifdef DEBUG_QIMPEN |
170 | qDebug( "char %c, stroke starting pt diff excessive", pen->ch ); | 171 | odebug << "char " << pen->ch <<", stroke starting pt diff excessive" << oendl; |
171 | #endif | 172 | #endif |
172 | return INT_MAX; | 173 | return INT_MAX; |
173 | } | 174 | } |
174 | diff += xdiff*xdiff + ydiff*ydiff; | 175 | diff += xdiff*xdiff + ydiff*ydiff; |
175 | err = it1.current()->match( it2.current() ); | 176 | err = it1.current()->match( it2.current() ); |
176 | if ( err > maxErr ) | 177 | if ( err > maxErr ) |
177 | maxErr = err; | 178 | maxErr = err; |
178 | ++it1; | 179 | ++it1; |
179 | ++it2; | 180 | ++it2; |
180 | } | 181 | } |
181 | 182 | ||
182 | maxErr += diff * diff * 6; // magic weighting :) | 183 | maxErr += diff * diff * 6; // magic weighting :) |
183 | 184 | ||
184 | #ifdef DEBUG_QIMPEN | 185 | #ifdef DEBUG_QIMPEN |
185 | qDebug( "char: %c, maxErr %d, diff %d, (%d)", pen->ch, maxErr, diff, strokes.count() ); | 186 | odebug << "char: " << pen->ch << ", maxErr " << maxErr << ", diff " << diff << ", " << strokes.count() << oendl; |
186 | #endif | 187 | #endif |
187 | return maxErr; | 188 | return maxErr; |
188 | } | 189 | } |
189 | 190 | ||
190 | /*! | 191 | /*! |
191 | Return the bounding rect of this character. It may have sides with | 192 | Return the bounding rect of this character. It may have sides with |
192 | negative coords since its origin is where the user started drawing | 193 | negative coords since its origin is where the user started drawing |
193 | the character. | 194 | the character. |
194 | */ | 195 | */ |
195 | QRect QIMPenChar::boundingRect() | 196 | QRect QIMPenChar::boundingRect() |
196 | { | 197 | { |
197 | QRect br; | 198 | QRect br; |
198 | QIMPenStroke *st = strokes.first(); | 199 | QIMPenStroke *st = strokes.first(); |
199 | while ( st ) { | 200 | while ( st ) { |
200 | br |= st->boundingRect(); | 201 | br |= st->boundingRect(); |
201 | st = strokes.next(); | 202 | st = strokes.next(); |
202 | } | 203 | } |
203 | 204 | ||
204 | return br; | 205 | return br; |
205 | } | 206 | } |
206 | 207 | ||
207 | 208 | ||
208 | /*! | 209 | /*! |
209 | Write the character's data to the stream. | 210 | Write the character's data to the stream. |
210 | */ | 211 | */ |
211 | QDataStream &operator<< (QDataStream &s, const QIMPenChar &ws) | 212 | QDataStream &operator<< (QDataStream &s, const QIMPenChar &ws) |
212 | { | 213 | { |
213 | s << ws.ch; | 214 | s << ws.ch; |
214 | s << ws.flags; | 215 | s << ws.flags; |
215 | if ( ws.flags & QIMPenChar::Data ) | 216 | if ( ws.flags & QIMPenChar::Data ) |
216 | s << ws.d; | 217 | s << ws.d; |
217 | s << ws.strokes.count(); | 218 | s << ws.strokes.count(); |
218 | QIMPenStrokeIterator it( ws.strokes ); | 219 | QIMPenStrokeIterator it( ws.strokes ); |
219 | while ( it.current() ) { | 220 | while ( it.current() ) { |
220 | s << *it.current(); | 221 | s << *it.current(); |
221 | ++it; | 222 | ++it; |
222 | } | 223 | } |
223 | 224 | ||
224 | return s; | 225 | return s; |
225 | } | 226 | } |
226 | 227 | ||
227 | /*! | 228 | /*! |
228 | Read the character's data from the stream. | 229 | Read the character's data from the stream. |
229 | */ | 230 | */ |
230 | QDataStream &operator>> (QDataStream &s, QIMPenChar &ws) | 231 | QDataStream &operator>> (QDataStream &s, QIMPenChar &ws) |
231 | { | 232 | { |
232 | s >> ws.ch; | 233 | s >> ws.ch; |
233 | s >> ws.flags; | 234 | s >> ws.flags; |
234 | if ( ws.flags & QIMPenChar::Data ) | 235 | if ( ws.flags & QIMPenChar::Data ) |
235 | s >> ws.d; | 236 | s >> ws.d; |
236 | unsigned size; | 237 | unsigned size; |
237 | s >> size; | 238 | s >> size; |
238 | for ( unsigned i = 0; i < size; i++ ) { | 239 | for ( unsigned i = 0; i < size; i++ ) { |
239 | QIMPenStroke *st = new QIMPenStroke(); | 240 | QIMPenStroke *st = new QIMPenStroke(); |
240 | s >> *st; | 241 | s >> *st; |
241 | ws.strokes.append( st ); | 242 | ws.strokes.append( st ); |
242 | } | 243 | } |
243 | 244 | ||
244 | return s; | 245 | return s; |
245 | } | 246 | } |
246 | 247 | ||
247 | //=========================================================================== | 248 | //=========================================================================== |
248 | 249 | ||
249 | bool QIMPenCharMatch::operator>( const QIMPenCharMatch &m ) | 250 | bool QIMPenCharMatch::operator>( const QIMPenCharMatch &m ) |
250 | { | 251 | { |
251 | return error > m.error; | 252 | return error > m.error; |
252 | } | 253 | } |
253 | 254 | ||
254 | bool QIMPenCharMatch::operator<( const QIMPenCharMatch &m ) | 255 | bool QIMPenCharMatch::operator<( const QIMPenCharMatch &m ) |
255 | { | 256 | { |
256 | return error < m.error; | 257 | return error < m.error; |
257 | } | 258 | } |
258 | 259 | ||
259 | bool QIMPenCharMatch::operator<=( const QIMPenCharMatch &m ) | 260 | bool QIMPenCharMatch::operator<=( const QIMPenCharMatch &m ) |
260 | { | 261 | { |
261 | return error <= m.error; | 262 | return error <= m.error; |
262 | } | 263 | } |
263 | 264 | ||
264 | //=========================================================================== | 265 | //=========================================================================== |
265 | 266 | ||
266 | /*! | 267 | /*! |
267 | \class QIMPenCharSet qimpenchar.h | 268 | \class QIMPenCharSet qimpenchar.h |
268 | 269 | ||
269 | Maintains a set of related characters. | 270 | Maintains a set of related characters. |
270 | */ | 271 | */ |
271 | 272 | ||
272 | QIMPenCharSet::QIMPenCharSet() | 273 | QIMPenCharSet::QIMPenCharSet() |
273 | { | 274 | { |
274 | chars.setAutoDelete( TRUE ); | 275 | chars.setAutoDelete( TRUE ); |
275 | desc = "Unnamed"; | 276 | desc = "Unnamed"; |
276 | csTitle = "abc"; | 277 | csTitle = "abc"; |
277 | csType = Unknown; | 278 | csType = Unknown; |
278 | maxStrokes = 0; | 279 | maxStrokes = 0; |
279 | } | 280 | } |
280 | 281 | ||
281 | /*! | 282 | /*! |
@@ -365,147 +366,147 @@ bool QIMPenCharSet::save( Domain d ) | |||
365 | 366 | ||
366 | QString fn = filename( d ); | 367 | QString fn = filename( d ); |
367 | QString tmpFn = fn + ".new"; | 368 | QString tmpFn = fn + ".new"; |
368 | QFile file( tmpFn ); | 369 | QFile file( tmpFn ); |
369 | if ( file.open( IO_WriteOnly|IO_Raw ) ) { | 370 | if ( file.open( IO_WriteOnly|IO_Raw ) ) { |
370 | QByteArray buf; | 371 | QByteArray buf; |
371 | QDataStream ds( buf, IO_WriteOnly ); | 372 | QDataStream ds( buf, IO_WriteOnly ); |
372 | ds << QString( "QPT 1.1" ); | 373 | ds << QString( "QPT 1.1" ); |
373 | ds << csTitle; | 374 | ds << csTitle; |
374 | ds << desc; | 375 | ds << desc; |
375 | ds << (Q_INT8)csType; | 376 | ds << (Q_INT8)csType; |
376 | QIMPenCharIterator ci( chars ); | 377 | QIMPenCharIterator ci( chars ); |
377 | for ( ; ci.current(); ++ci ) { | 378 | for ( ; ci.current(); ++ci ) { |
378 | QIMPenChar *pc = ci.current(); | 379 | QIMPenChar *pc = ci.current(); |
379 | if ( ( ( (d == System) && pc->testFlag( QIMPenChar::System ) ) || | 380 | if ( ( ( (d == System) && pc->testFlag( QIMPenChar::System ) ) || |
380 | ( (d == User) && !pc->testFlag( QIMPenChar::System ) ) ) && | 381 | ( (d == User) && !pc->testFlag( QIMPenChar::System ) ) ) && |
381 | ( !pc->testFlag (QIMPenChar::Combined ) ) ) { | 382 | ( !pc->testFlag (QIMPenChar::Combined ) ) ) { |
382 | ds << *pc; | 383 | ds << *pc; |
383 | } | 384 | } |
384 | } | 385 | } |
385 | 386 | ||
386 | file.writeBlock( buf ); | 387 | file.writeBlock( buf ); |
387 | file.close(); | 388 | file.close(); |
388 | if ( file.status() == IO_Ok ) | 389 | if ( file.status() == IO_Ok ) |
389 | ok = TRUE; | 390 | ok = TRUE; |
390 | } | 391 | } |
391 | 392 | ||
392 | if ( ok ) { | 393 | if ( ok ) { |
393 | if ( ::rename( tmpFn.latin1(), fn.latin1() ) < 0 ) { | 394 | if ( ::rename( tmpFn.latin1(), fn.latin1() ) < 0 ) { |
394 | qWarning( "problem renaming file %s to %s, errno: %d", | 395 | qWarning( "problem renaming file %s to %s, errno: %d", |
395 | tmpFn.latin1(), fn.latin1(), errno ); | 396 | tmpFn.latin1(), fn.latin1(), errno ); |
396 | // remove the tmp file, otherwise, it will just lay around... | 397 | // remove the tmp file, otherwise, it will just lay around... |
397 | QFile::remove( tmpFn.latin1() ); | 398 | QFile::remove( tmpFn.latin1() ); |
398 | ok = FALSE; | 399 | ok = FALSE; |
399 | } | 400 | } |
400 | } | 401 | } |
401 | 402 | ||
402 | return ok; | 403 | return ok; |
403 | } | 404 | } |
404 | 405 | ||
405 | QIMPenChar *QIMPenCharSet::at( int i ) | 406 | QIMPenChar *QIMPenCharSet::at( int i ) |
406 | { | 407 | { |
407 | return chars.at(i); | 408 | return chars.at(i); |
408 | } | 409 | } |
409 | 410 | ||
410 | void QIMPenCharSet::markDeleted( uint ch ) | 411 | void QIMPenCharSet::markDeleted( uint ch ) |
411 | { | 412 | { |
412 | QIMPenCharIterator ci( chars ); | 413 | QIMPenCharIterator ci( chars ); |
413 | for ( ; ci.current(); ++ci ) { | 414 | for ( ; ci.current(); ++ci ) { |
414 | QIMPenChar *pc = ci.current(); | 415 | QIMPenChar *pc = ci.current(); |
415 | if ( pc->character() == ch && pc->testFlag( QIMPenChar::System ) ) | 416 | if ( pc->character() == ch && pc->testFlag( QIMPenChar::System ) ) |
416 | pc->setFlag( QIMPenChar::Deleted ); | 417 | pc->setFlag( QIMPenChar::Deleted ); |
417 | } | 418 | } |
418 | } | 419 | } |
419 | 420 | ||
420 | /*! | 421 | /*! |
421 | Find the best matches for \a ch in this character set. | 422 | Find the best matches for \a ch in this character set. |
422 | */ | 423 | */ |
423 | QIMPenCharMatchList QIMPenCharSet::match( QIMPenChar *ch ) | 424 | QIMPenCharMatchList QIMPenCharSet::match( QIMPenChar *ch ) |
424 | { | 425 | { |
425 | QIMPenCharMatchList matches; | 426 | QIMPenCharMatchList matches; |
426 | 427 | ||
427 | QIMPenCharIterator ci( chars ); | 428 | QIMPenCharIterator ci( chars ); |
428 | for ( ; ci.current(); ++ci ) { | 429 | for ( ; ci.current(); ++ci ) { |
429 | QIMPenChar *tmplChar = ci.current(); | 430 | QIMPenChar *tmplChar = ci.current(); |
430 | if ( tmplChar->testFlag( QIMPenChar::Deleted ) ) { | 431 | if ( tmplChar->testFlag( QIMPenChar::Deleted ) ) { |
431 | continue; | 432 | continue; |
432 | } | 433 | } |
433 | int err; | 434 | int err; |
434 | if ( ch->penStrokes().count() <= tmplChar->penStrokes().count() ) { | 435 | if ( ch->penStrokes().count() <= tmplChar->penStrokes().count() ) { |
435 | err = ch->match( tmplChar ); | 436 | err = ch->match( tmplChar ); |
436 | if ( err <= QIMPEN_MATCH_THRESHOLD ) { | 437 | if ( err <= QIMPEN_MATCH_THRESHOLD ) { |
437 | if (tmplChar->penStrokes().count() != ch->penStrokes().count()) | 438 | if (tmplChar->penStrokes().count() != ch->penStrokes().count()) |
438 | err = QMIN(err*3, QIMPEN_MATCH_THRESHOLD); | 439 | err = QMIN(err*3, QIMPEN_MATCH_THRESHOLD); |
439 | QIMPenCharMatchList::Iterator it; | 440 | QIMPenCharMatchList::Iterator it; |
440 | for ( it = matches.begin(); it != matches.end(); ++it ) { | 441 | for ( it = matches.begin(); it != matches.end(); ++it ) { |
441 | if ( (*it).penChar->character() == tmplChar->character() && | 442 | if ( (*it).penChar->character() == tmplChar->character() && |
442 | (*it).penChar->penStrokes().count() == tmplChar->penStrokes().count() ) { | 443 | (*it).penChar->penStrokes().count() == tmplChar->penStrokes().count() ) { |
443 | if ( (*it).error > err ) | 444 | if ( (*it).error > err ) |
444 | (*it).error = err; | 445 | (*it).error = err; |
445 | break; | 446 | break; |
446 | } | 447 | } |
447 | } | 448 | } |
448 | if ( it == matches.end() ) { | 449 | if ( it == matches.end() ) { |
449 | QIMPenCharMatch m; | 450 | QIMPenCharMatch m; |
450 | m.error = err; | 451 | m.error = err; |
451 | m.penChar = tmplChar; | 452 | m.penChar = tmplChar; |
452 | matches.append( m ); | 453 | matches.append( m ); |
453 | } | 454 | } |
454 | } | 455 | } |
455 | } | 456 | } |
456 | } | 457 | } |
457 | qHeapSort( matches ); | 458 | qHeapSort( matches ); |
458 | /* | 459 | /* |
459 | QIMPenCharMatchList::Iterator it; | 460 | QIMPenCharMatchList::Iterator it; |
460 | for ( it = matches.begin(); it != matches.end(); ++it ) { | 461 | for ( it = matches.begin(); it != matches.end(); ++it ) { |
461 | qDebug( "Match: \'%c\', error %d, strokes %d", (*it).penChar->character(), | 462 | |
462 | (*it).error, (*it).penChar->penStrokes().count() ); | 463 | odebug << "Match: \'" << (*it).penChar->character() "\', error " << (*it).error ", strokes " <<(*it).penChar->penStrokes().count() << oendl; |
463 | } | 464 | } |
464 | */ | 465 | */ |
465 | return matches; | 466 | return matches; |
466 | } | 467 | } |
467 | 468 | ||
468 | /*! | 469 | /*! |
469 | Add a character \a ch to this set. | 470 | Add a character \a ch to this set. |
470 | QIMPenCharSet will delete this character when it is no longer needed. | 471 | QIMPenCharSet will delete this character when it is no longer needed. |
471 | */ | 472 | */ |
472 | void QIMPenCharSet::addChar( QIMPenChar *ch ) | 473 | void QIMPenCharSet::addChar( QIMPenChar *ch ) |
473 | { | 474 | { |
474 | if ( ch->penStrokes().count() > maxStrokes ) | 475 | if ( ch->penStrokes().count() > maxStrokes ) |
475 | maxStrokes = ch->penStrokes().count(); | 476 | maxStrokes = ch->penStrokes().count(); |
476 | chars.append( ch ); | 477 | chars.append( ch ); |
477 | } | 478 | } |
478 | 479 | ||
479 | /*! | 480 | /*! |
480 | Remove a character by reference \a ch from this set. | 481 | Remove a character by reference \a ch from this set. |
481 | QIMPenCharSet will delete this character. | 482 | QIMPenCharSet will delete this character. |
482 | */ | 483 | */ |
483 | void QIMPenCharSet::removeChar( QIMPenChar *ch ) | 484 | void QIMPenCharSet::removeChar( QIMPenChar *ch ) |
484 | { | 485 | { |
485 | chars.remove( ch ); | 486 | chars.remove( ch ); |
486 | } | 487 | } |
487 | 488 | ||
488 | /*! | 489 | /*! |
489 | Move the character up the list of characters. | 490 | Move the character up the list of characters. |
490 | */ | 491 | */ |
491 | void QIMPenCharSet::up( QIMPenChar *ch ) | 492 | void QIMPenCharSet::up( QIMPenChar *ch ) |
492 | { | 493 | { |
493 | int idx = chars.findRef( ch ); | 494 | int idx = chars.findRef( ch ); |
494 | if ( idx > 0 ) { | 495 | if ( idx > 0 ) { |
495 | chars.take(); | 496 | chars.take(); |
496 | chars.insert( idx - 1, ch ); | 497 | chars.insert( idx - 1, ch ); |
497 | } | 498 | } |
498 | } | 499 | } |
499 | 500 | ||
500 | /*! | 501 | /*! |
501 | Move the character down the list of characters. | 502 | Move the character down the list of characters. |
502 | */ | 503 | */ |
503 | void QIMPenCharSet::down( QIMPenChar *ch ) | 504 | void QIMPenCharSet::down( QIMPenChar *ch ) |
504 | { | 505 | { |
505 | int idx = chars.findRef( ch ); | 506 | int idx = chars.findRef( ch ); |
506 | if ( idx >= 0 && idx < (int)chars.count() - 1 ) { | 507 | if ( idx >= 0 && idx < (int)chars.count() - 1 ) { |
507 | chars.take(); | 508 | chars.take(); |
508 | chars.insert( idx + 1, ch ); | 509 | chars.insert( idx + 1, ch ); |
509 | } | 510 | } |
510 | } | 511 | } |
511 | 512 | ||