source: trunk/src/kernel/qtextengine_pm.cpp@ 63

Last change on this file since 63 was 20, checked in by dmik, 20 years ago

Fixed a bunch of compiler warnings

  • Property svn:keywords set to Id
File size: 20.8 KB
Line 
1/****************************************************************************
2** $Id: qtextengine_pm.cpp 20 2005-11-17 18:00:27Z dmik $
3**
4** ???
5**
6** Copyright (C) 2003 Trolltech AS. All rights reserved.
7** Copyright (C) 2004 Norman ASA. Initial OS/2 Port.
8** Copyright (C) 2005 netlabs.org. Further OS/2 Development.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#ifdef QT_THREAD_SUPPORT
39# include <private/qmutexpool_p.h>
40#endif // QT_THREAD_SUPPORT
41#include "qlibrary.h"
42
43
44/// @todo (dmik) remove?
45#if 0
46// these defines are from usp10.h
47typedef void *SCRIPT_CACHE;
48typedef struct tag_SCRIPT_CONTROL {
49 DWORD uDefaultLanguage :16;
50 DWORD fContextDigits :1;
51 DWORD fInvertPreBoundDir :1;
52 DWORD fInvertPostBoundDir :1;
53 DWORD fLinkStringBefore :1;
54 DWORD fLinkStringAfter :1;
55 DWORD fNeutralOverride :1;
56 DWORD fNumericOverride :1;
57 DWORD fLegacyBidiClass :1;
58 DWORD fReserved :8;
59} SCRIPT_CONTROL;
60
61typedef struct tag_SCRIPT_STATE {
62 WORD uBidiLevel :5;
63 WORD fOverrideDirection :1;
64 WORD fInhibitSymSwap :1;
65 WORD fCharShape :1;
66 WORD fDigitSubstitute :1;
67 WORD fInhibitLigate :1;
68 WORD fDisplayZWG :1;
69 WORD fArabicNumContext :1;
70 WORD fGcpClusters :1;
71 WORD fReserved :1;
72 WORD fEngineReserved :2;
73} SCRIPT_STATE;
74
75typedef struct tag_SCRIPT_ITEM {
76 int iCharPos;
77 QScriptAnalysis a;
78} SCRIPT_ITEM;
79
80typedef GlyphAttributes SCRIPT_VISATTR;
81typedef qoffset_t GOFFSET;
82
83#define USP_E_SCRIPT_NOT_IN_FONT \
84 MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,0x200) // Script doesn't exist in font
85
86typedef struct {
87 DWORD langid :16;
88 DWORD fNumeric :1;
89 DWORD fComplex :1;
90 DWORD fNeedsWordBreaking :1;
91 DWORD fNeedsCaretInfo :1;
92 DWORD bCharSet :8;
93 DWORD fControl :1;
94 DWORD fPrivateUseArea :1;
95 DWORD fNeedsCharacterJustify :1;
96 DWORD fInvalidGlyph :1;
97 DWORD fInvalidLogAttr :1;
98 DWORD fCDM :1;
99 DWORD fAmbiguousCharSet :1;
100 DWORD fClusterSizeVaries :1;
101 DWORD fRejectInvalid :1;
102} SCRIPT_PROPERTIES;
103
104#if defined(Q_OS_TEMP) && UNDER_CE < 400
105typedef struct _ABC {
106 int abcA;
107 UINT abcB;
108 int abcC;
109} ABC;
110#endif
111
112typedef HRESULT (WINAPI *fScriptFreeCache)( SCRIPT_CACHE *);
113typedef HRESULT (WINAPI *fScriptItemize)( const WCHAR *, int, int, const SCRIPT_CONTROL *,
114 const SCRIPT_STATE *, SCRIPT_ITEM *, int *);
115typedef HRESULT (WINAPI *fScriptShape)( HDC hdc, SCRIPT_CACHE *, const WCHAR *, int, int,
116 QScriptAnalysis *, WORD *, WORD *, SCRIPT_VISATTR *, int *);
117typedef HRESULT (WINAPI *fScriptPlace)( HDC, SCRIPT_CACHE *, const WORD *, int, const SCRIPT_VISATTR *, QScriptAnalysis *, int *,
118 GOFFSET *, ABC * );
119typedef HRESULT (WINAPI *fScriptTextOut)( const HDC, SCRIPT_CACHE *, int, int, UINT, const RECT *, const QScriptAnalysis *,
120 const WCHAR *, int, const WORD *, int, const int *, const int *, const GOFFSET *);
121typedef HRESULT (WINAPI *fScriptBreak)( const WCHAR *, int, const QScriptAnalysis *, QCharAttributes * );
122//typedef HRESULT (WINAPI *fScriptGetFontProperties)( HDC, SCRIPT_CACHE *, SCRIPT_FONTPROPERTIES * );
123typedef HRESULT (WINAPI *fScriptGetProperties)( const SCRIPT_PROPERTIES ***, int *);
124
125fScriptFreeCache ScriptFreeCache = 0;
126static fScriptItemize ScriptItemize = 0;
127static fScriptShape ScriptShape = 0;
128static fScriptPlace ScriptPlace = 0;
129fScriptTextOut ScriptTextOut = 0;
130static fScriptBreak ScriptBreak = 0;
131//static fScriptGetFontProperties ScriptGetFontProperties = 0;
132static fScriptGetProperties ScriptGetProperties = 0;
133
134static bool resolvedUsp10 = FALSE;
135bool hasUsp10 = FALSE;
136
137const SCRIPT_PROPERTIES **script_properties = 0;
138int num_scripts = 0;
139int usp_latin_script = 0;
140
141
142const QFont::Script japanese_tryScripts[] = {
143 QFont::Latin,
144 QFont::Han_Japanese,
145 QFont::Hangul,
146 QFont::Han_SimplifiedChinese,
147 QFont::Han_TraditionalChinese
148};
149
150const QFont::Script korean_tryScripts[] = {
151 QFont::Latin,
152 QFont::Hangul,
153 QFont::Han_Japanese,
154 QFont::Han_SimplifiedChinese,
155 QFont::Han_TraditionalChinese
156};
157
158const QFont::Script simplifiedChinese_tryScripts[] = {
159 QFont::Latin,
160 QFont::Han_SimplifiedChinese,
161 QFont::Han_TraditionalChinese,
162 QFont::Han_Japanese,
163 QFont::Hangul
164};
165
166const QFont::Script traditionalChinese_tryScripts[] = {
167 QFont::Latin,
168 QFont::Han_TraditionalChinese,
169 QFont::Han_SimplifiedChinese,
170 QFont::Han_Japanese,
171 QFont::Hangul
172};
173
174const QFont::Script *tryScripts = japanese_tryScripts;
175
176static void uspAppendItems(QTextEngine *engine, int &start, int &stop, BidiControl &control, QChar::Direction dir);
177
178static void resolveUsp10()
179{
180#ifndef QT_NO_COMPONENT
181 if ( !resolvedUsp10 ) {
182 // need to resolve the security info functions
183
184#ifdef QT_THREAD_SUPPORT
185 // protect initialization
186 QMutexLocker locker( qt_global_mutexpool ?
187 qt_global_mutexpool->get( (void*)&resolveUsp10 ) : 0 );
188 // check triedResolve again, since another thread may have already
189 // done the initialization
190 if ( resolvedUsp10 ) {
191 // another thread did initialize the security function pointers,
192 // so we shouldn't do it again.
193 return;
194 }
195#endif
196
197 resolvedUsp10 = TRUE;
198 QLibrary lib("usp10");
199 lib.setAutoUnload( FALSE );
200
201 ScriptFreeCache = (fScriptFreeCache) lib.resolve( "ScriptFreeCache" );
202 ScriptItemize = (fScriptItemize) lib.resolve( "ScriptItemize" );
203 ScriptShape = (fScriptShape) lib.resolve( "ScriptShape" );
204 ScriptPlace = (fScriptPlace) lib.resolve( "ScriptPlace" );
205 ScriptTextOut = (fScriptTextOut) lib.resolve( "ScriptTextOut" );
206 ScriptBreak = (fScriptBreak) lib.resolve( "ScriptBreak" );
207 ScriptGetProperties = (fScriptGetProperties) lib.resolve( "ScriptGetProperties" );
208
209 if ( !ScriptFreeCache )
210 return;
211
212 hasUsp10 = TRUE;
213 ScriptGetProperties( &script_properties, &num_scripts );
214
215 // get the usp script for western
216 for( int i = 0; i < num_scripts; i++ ) {
217 if (script_properties[i]->langid == LANG_ENGLISH &&
218 !script_properties[i]->fAmbiguousCharSet ) {
219 usp_latin_script = i;
220 break;
221 }
222 }
223
224 // initialize tryScripts according to locale
225 LANGID lid = GetUserDefaultLangID();
226 switch( lid&0xff ) {
227 case LANG_CHINESE: // Chinese (Taiwan)
228 if ( lid == 0x0804 ) // Taiwan
229 tryScripts = traditionalChinese_tryScripts;
230 else
231 tryScripts = simplifiedChinese_tryScripts;
232 break;
233 case LANG_JAPANESE:
234 // japanese is already the default
235 break;
236 case LANG_KOREAN:
237 tryScripts = korean_tryScripts;
238 break;
239 default:
240 break;
241 }
242
243 appendItems = uspAppendItems;
244 }
245#endif
246}
247
248static unsigned char script_for_win_language[ 0x80 ] = {
249 //0x00 LANG_NEUTRAL Neutral
250 QFont::Latin,
251 //0x01 LANG_ARABIC Arabic
252 QFont::Arabic,
253 //0x02 LANG_BULGARIAN Bulgarian
254 QFont::NScripts,
255 //0x03 LANG_CATALAN Catalan
256 QFont::NScripts,
257 //0x04 LANG_CHINESE Chinese
258 QFont::Han,
259 //0x05 LANG_CZECH Czech
260 QFont::NScripts,
261 //0x06 LANG_DANISH Danish
262 QFont::NScripts,
263 //0x07 LANG_GERMAN German
264 QFont::NScripts,
265 //0x08 LANG_GREEK Greek
266 QFont::Greek,
267 //0x09 LANG_ENGLISH English
268 QFont::Latin,
269 //0x0a LANG_SPANISH Spanish
270 QFont::NScripts,
271 //0x0b LANG_FINNISH Finnish
272 QFont::NScripts,
273 //0x0c LANG_FRENCH French
274 QFont::NScripts,
275 //0x0d LANG_HEBREW Hebrew
276 QFont::Hebrew,
277 //0x0e LANG_HUNGARIAN Hungarian
278 QFont::NScripts,
279 //0x0f LANG_ICELANDIC Icelandic
280 QFont::NScripts,
281
282 //0x10 LANG_ITALIAN Italian
283 QFont::NScripts,
284 //0x11 LANG_JAPANESE Japanese
285 QFont::Hiragana,
286 //0x12 LANG_KOREAN Korean
287 QFont::Hangul,
288 //0x13 LANG_DUTCH Dutch
289 QFont::NScripts,
290 //0x14 LANG_NORWEGIAN Norwegian
291 QFont::NScripts,
292 //0x15 LANG_POLISH Polish
293 QFont::NScripts,
294 //0x16 LANG_PORTUGUESE Portuguese
295 QFont::NScripts,
296 QFont::NScripts,
297 //0x18 LANG_ROMANIAN Romanian
298 QFont::NScripts,
299 //0x19 LANG_RUSSIAN Russian
300 QFont::Cyrillic,
301 //0x1a LANG_CROATIAN Croatian
302 //0x1a LANG_SERBIAN Serbian
303 QFont::NScripts,
304 //0x1b LANG_SLOVAK Slovak
305 QFont::NScripts,
306 //0x1c LANG_ALBANIAN Albanian
307 QFont::NScripts,
308 //0x1d LANG_SWEDISH Swedish
309 QFont::NScripts,
310 //0x1e LANG_THAI Thai
311 QFont::Thai,
312 //0x1f LANG_TURKISH Turkish
313 QFont::NScripts,
314
315 //0x20 LANG_URDU Urdu
316 QFont::NScripts,
317 //0x21 LANG_INDONESIAN Indonesian
318 QFont::NScripts,
319 //0x22 LANG_UKRAINIAN Ukrainian
320 QFont::NScripts,
321 //0x23 LANG_BELARUSIAN Belarusian
322 QFont::NScripts,
323 //0x24 LANG_SLOVENIAN Slovenian
324 QFont::NScripts,
325 //0x25 LANG_ESTONIAN Estonian
326 QFont::NScripts,
327 //0x26 LANG_LATVIAN Latvian
328 QFont::NScripts,
329 //0x27 LANG_LITHUANIAN Lithuanian
330 QFont::NScripts,
331 QFont::NScripts,
332 //0x29 LANG_FARSI Farsi
333 QFont::NScripts,
334 //0x2a LANG_VIETNAMESE Vietnamese
335 QFont::Latin, // ##### maybe use QFont::CombiningMarks instead?
336 //0x2b LANG_ARMENIAN Armenian
337 QFont::Armenian,
338 //0x2c LANG_AZERI Azeri
339 QFont::NScripts,
340 //0x2d LANG_BASQUE Basque
341 QFont::NScripts,
342 QFont::NScripts,
343 //0x2f LANG_MACEDONIAN FYRO Macedonian
344 QFont::NScripts,
345
346 QFont::NScripts,
347 QFont::NScripts,
348 QFont::NScripts,
349 QFont::NScripts,
350 QFont::NScripts,
351 QFont::NScripts,
352 //0x36 LANG_AFRIKAANS Afrikaans
353 QFont::NScripts,
354 //0x37 LANG_GEORGIAN Georgian
355 QFont::NScripts,
356 //0x38 LANG_FAEROESE Faeroese
357 QFont::NScripts,
358 //0x39 LANG_HINDI Hindi
359 QFont::Devanagari,
360 QFont::NScripts,
361 QFont::NScripts,
362 QFont::NScripts,
363 QFont::NScripts,
364 //0x3e LANG_MALAY Malay
365 QFont::NScripts,
366 //0x3f LANG_KAZAK Kazak
367 QFont::NScripts,
368
369 //0x40 LANG_KYRGYZ Kyrgyz
370 QFont::NScripts,
371 //0x41 LANG_SWAHILI Swahili
372 QFont::NScripts,
373 QFont::NScripts,
374 //0x43 LANG_UZBEK Uzbek
375 QFont::NScripts,
376 //0x44 LANG_TATAR Tatar
377 QFont::NScripts,
378 //0x45 LANG_BENGALI Not supported.
379 QFont::Bengali,
380 //0x46 LANG_PUNJABI Punjabi
381 QFont::Gurmukhi,
382 //0x47 LANG_GUJARATI Gujarati
383 QFont::Gujarati,
384 //0x48 LANG_ORIYA Not supported.
385 QFont::Oriya,
386 //0x49 LANG_TAMIL Tamil
387 QFont::Tamil,
388 //0x4a LANG_TELUGU Telugu
389 QFont::Telugu,
390 //0x4b LANG_KANNADA Kannada
391 QFont::Kannada,
392 //0x4c LANG_MALAYALAM Not supported.
393 QFont::Malayalam,
394 //0x4d LANG_ASSAMESE Not supported.
395 QFont::NScripts,
396 //0x4e LANG_MARATHI Marathi
397 QFont::NScripts,
398 //0x4f LANG_SANSKRIT Sanskrit
399 QFont::Devanagari,
400
401 //0x50 LANG_MONGOLIAN Mongolian
402 QFont::Mongolian,
403 QFont::NScripts,
404 QFont::NScripts,
405 QFont::NScripts,
406 QFont::NScripts,
407 QFont::NScripts,
408 //0x56 LANG_GALICIAN Galician
409 QFont::NScripts,
410 //0x57 LANG_KONKANI Konkani
411 QFont::NScripts,
412 //0x58 LANG_MANIPURI Not supported.
413 QFont::NScripts,
414 //0x59 LANG_SINDHI Not supported.
415 QFont::NScripts,
416 //0x5a LANG_SYRIAC Syriac
417 QFont::Syriac,
418 QFont::NScripts,
419 QFont::NScripts,
420 QFont::NScripts,
421 QFont::NScripts,
422 QFont::NScripts,
423
424 //0x60 LANG_KASHMIRI Not supported.
425 QFont::NScripts,
426 //0x61 LANG_NEPALI Not supported.
427 QFont::NScripts,
428 QFont::NScripts,
429 QFont::NScripts,
430 QFont::NScripts,
431 //0x65 LANG_DIVEHI Divehi
432 QFont::NScripts,
433 QFont::NScripts,
434 QFont::NScripts,
435 QFont::NScripts,
436 QFont::NScripts,
437 QFont::NScripts,
438 QFont::NScripts,
439 QFont::NScripts,
440 QFont::NScripts,
441 QFont::NScripts,
442 QFont::NScripts,
443
444 QFont::NScripts,
445 QFont::NScripts,
446 QFont::NScripts,
447 QFont::NScripts,
448 QFont::NScripts,
449 QFont::NScripts,
450 QFont::NScripts,
451 QFont::NScripts,
452 QFont::NScripts,
453 QFont::NScripts,
454 QFont::NScripts,
455 QFont::NScripts,
456 QFont::NScripts,
457 QFont::NScripts,
458 QFont::NScripts,
459 //0x7f LANG_INVARIANT
460 QFont::NScripts,
461};
462
463static inline QFont::Script scriptForWinLanguage( DWORD langid )
464{
465 QFont::Script script = (QFont::Script)script_for_win_language[langid];
466 if ( script == QFont::NScripts )
467 qWarning( "Qt Uniscribe support: Encountered unhandled language id %x", (unsigned int)langid );
468 return script;
469}
470
471static inline bool isAsian( unsigned short ch )
472{
473 return (ch > 0x2dff && ch < 0xfb00) || ((ch & 0xff00) == 0x1100);
474}
475
476
477// we're not using Uniscribe's BiDi algorithm, since it is (a) not 100% Unicode compliant and
478// (b) seems to work wrongly when trying to use it with a base level != 0.
479//
480// This function does uses Uniscribe to do the script analysis and creates items from this.
481static void uspAppendItems(QTextEngine *engine, int &start, int &stop, BidiControl &control, QChar::Direction dir)
482{
483 QScriptItemArray &items = engine->items;
484 const QChar *text = engine->string.unicode();
485
486 if ( start > stop ) {
487 // #### the algorithm is currently not really safe against this. Still needs fixing.
488// qWarning( "Bidi: appendItems() internal error" );
489 return;
490 }
491
492 int level = control.level();
493
494 if(dir != QChar::DirON) {
495 // add level of run (cases I1 & I2)
496 if( level % 2 ) {
497 if(dir == QChar::DirL || dir == QChar::DirAN || dir == QChar::DirEN )
498 level++;
499 } else {
500 if( dir == QChar::DirR )
501 level++;
502 else if( dir == QChar::DirAN || dir == QChar::DirEN )
503 level += 2;
504 }
505 }
506
507 SCRIPT_ITEM s_items[256];
508 SCRIPT_ITEM *usp_items = s_items;
509
510 int numItems;
511 HRESULT res = ScriptItemize( (WCHAR *)(text+start), stop-start+1, 255, 0, 0, usp_items, &numItems );
512
513 if ( res == E_OUTOFMEMORY ) {
514 int alloc = 256;
515 usp_items = 0;
516 while( res == E_OUTOFMEMORY ) {
517 alloc *= 2;
518 usp_items = (SCRIPT_ITEM *)realloc( usp_items, alloc * sizeof( SCRIPT_ITEM ) );
519 res = ScriptItemize( (WCHAR *)(text+start), stop-start+1, alloc-1, 0, 0, usp_items, &numItems );
520 }
521 }
522 items.resize( items.size() + numItems );
523 int i;
524 for( i = 0; i < numItems; i++ ) {
525 QScriptItem item;
526 item.analysis = usp_items[i].a;
527 item.position = usp_items[i].iCharPos+start;
528 item.analysis.bidiLevel = level;
529 item.analysis.override = control.override();
530
531 int rstart = usp_items[i].iCharPos;
532 int rstop = usp_items[i+1].iCharPos-1;
533 bool b = TRUE;
534 for ( int j = rstart; j <= rstop; j++ ) {
535
536 unsigned short uc = text[j+start].unicode();
537 QChar::Category category = ::category( uc );
538 if ( uc == 0xfffcU || uc == 0x2028U ) {
539 item.analysis.script = usp_latin_script;
540 item.isObject = TRUE;
541 b = TRUE;
542 } else if ((uc >= 9 && uc <=13) ||
543 (category >= QChar::Separator_Space && category <= QChar::Separator_Paragraph)) {
544 item.analysis.script = usp_latin_script;
545 item.isSpace = TRUE;
546 item.isTab = (uc == '\t');
547 if (item.isTab)
548 item.analysis.bidiLevel = control.baseLevel();
549 b = TRUE;
550 } else if (b) {
551 b = FALSE;
552 } else {
553 continue;
554 }
555
556 item.position = j+start;
557 items.append( item );
558 item.analysis = usp_items[i].a;
559 item.analysis.bidiLevel = level;
560 item.analysis.override = control.override();
561 item.isSpace = item.isTab = item.isObject = FALSE;
562 }
563 }
564
565 if ( usp_items != s_items )
566 free( usp_items );
567
568 ++stop;
569 start = stop;
570}
571#endif // if 0
572
573// -----------------------------------------------------------------------------------------------------
574//
575// Text engine classes
576//
577// -----------------------------------------------------------------------------------------------------
578
579
580QScriptItemArray::~QScriptItemArray()
581{
582 clear();
583 free( d );
584}
585
586void QScriptItemArray::clear()
587{
588 if ( d ) {
589 for ( unsigned int i = 0; i < d->size; i++ ) {
590 QScriptItem &si = d->items[i];
591 if ( si.fontEngine )
592 si.fontEngine->deref();
593 }
594 d->size = 0;
595 }
596}
597
598void QScriptItemArray::resize( int s )
599{
600 int alloc = ((s + 8) >> 3) << 3;
601 d = (QScriptItemArrayPrivate *)realloc( d, sizeof( QScriptItemArrayPrivate ) +
602 sizeof( QScriptItem ) * alloc );
603 d->alloc = alloc;
604}
605
606
607void QTextEngine::shape( int item ) const
608{
609 QScriptItem &si = items[item];
610
611 if ( si.num_glyphs )
612 return;
613
614 QFont::Script script = (QFont::Script)si.analysis.script;
615 int from = si.position;
616 int len = length( item );
617
618 Q_ASSERT( len > 0 );
619
620 si.glyph_data_offset = used;
621
622 if ( !si.fontEngine ) {
623//@@TODO (dmik): remove?
624// if ( hasUsp10 ) {
625// const SCRIPT_PROPERTIES *script_prop = script_properties[si.analysis.script];
626// script = scriptForWinLanguage( script_prop->langid );
627// if ( script == QFont::Latin && script_prop->fAmbiguousCharSet ) {
628// // either some asian language or something Uniscribe doesn't recognise
629// // we look at the first character to find out what it is
630// bool asian = false;
631// int l = length(item);
632// for(int i = 0; i < l; ++i) {
633// if(isAsian(string.unicode()[si.position+i].unicode())) {
634// asian = true;
635// break;
636// }
637// }
638// if (asian) {
639// // some asian language
640// int i;
641// for( i = 0; i < 5; i++ ) {
642// QFontEngine *fe = fnt->engineForScript( tryScripts[i] );
643// if ( fe->type() == QFontEngine::Box )
644// continue;
645//
646// if ( fe->canRender( string.unicode()+from, len ) ) {
647// script = tryScripts[i];
648// break;
649// }
650// }
651// }
652// }
653// }
654 si.fontEngine = fnt->engineForScript( script );
655//@@TODO (dmik): remove?
656// if ( si.fontEngine->type() == QFontEngine::Box )
657// si.fontEngine = fnt->engineForScript( QFont::NoScript );
658 si.fontEngine->ref();
659 }
660
661//@@TODO (dmik): remove?
662// if ( hasUsp10 && si.fontEngine->ttf ) {
663// int l = len;
664// si.analysis.logicalOrder = TRUE;
665// HRESULT res = E_OUTOFMEMORY;
666// HDC hdc = 0;
667//
668// do {
669// ensureSpace( l );
670//
671// res = ScriptShape( hdc, &si.fontEngine->script_cache, (WCHAR *)string.unicode() + from, len,
672// l, &si.analysis, glyphs( &si ), logClusters( &si ), glyphAttributes( &si ),
673// &si.num_glyphs );
674// if ( res == E_PENDING ) {
675// hdc = si.fontEngine->dc();
676// SelectObject( hdc, si.fontEngine->hfont );
677// } else if ( res == USP_E_SCRIPT_NOT_IN_FONT ) {
678// si.analysis.script = 0;
679// hdc = 0;
680// } else if (res == E_OUTOFMEMORY) {
681// l += 32;
682// } else if ( res != S_OK ) {
683// Q_ASSERT( FALSE );
684// }
685// } while( res != S_OK );
686//
687//
688// ABC abc;
689// res = ScriptPlace( hdc, &si.fontEngine->script_cache, glyphs( &si ), si.num_glyphs,
690// glyphAttributes( &si ), &si.analysis, advances( &si ), offsets( &si ), &abc );
691// if ( res == E_PENDING ) {
692// hdc = si.fontEngine->dc();
693// SelectObject( hdc, si.fontEngine->hfont );
694// ScriptPlace( hdc, &si.fontEngine->script_cache, glyphs( &si ), si.num_glyphs,
695// glyphAttributes( &si ), &si.analysis, advances( &si ), offsets( &si ), &abc );
696// }
697// si.width = abc.abcA + abc.abcB + abc.abcC;
698// } else {
699 Q_ASSERT( script < QFont::NScripts );
700 scriptEngines[script].shape( script, string, from, len, (QTextEngine*)this, &si );
701 si.width = 0;
702 advance_t *advances = this->advances( &si );
703 for ( int i = 0; i < si.num_glyphs; i++ )
704 si.width += advances[i];
705//@@TODO (dmik): remove?
706// }
707 si.ascent = si.fontEngine->ascent();
708 si.descent = si.fontEngine->descent();
709
710 ((QTextEngine *)this)->used += si.num_glyphs;
711}
712
Note: See TracBrowser for help on using the repository browser.