Changeset 561 for trunk/src/gui/text/qfontengine_win.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/gui/text/qfontengine_win.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtGui module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 49 49 #include <qpaintdevice.h> 50 50 #include <qpainter.h> 51 #include <qlibrary.h>52 51 #include <limits.h> 53 52 … … 66 65 #include <private/qnativeimage_p.h> 67 66 68 #if defined(Q_ OS_WINCE)67 #if defined(Q_WS_WINCE) 69 68 #include "qguifunctions_wince.h" 70 69 #endif … … 86 85 ) 87 86 88 typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);89 90 87 // common DC for all fonts 91 88 … … 129 126 #endif 130 127 131 static HFONT stock_sysfont = 0; 132 128 #ifndef Q_WS_WINCE 129 typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT); 133 130 static PtrGetCharWidthI ptrGetCharWidthI = 0; 134 131 static bool resolvedGetCharWidthI = false; … … 141 138 ptrGetCharWidthI = (PtrGetCharWidthI)QLibrary::resolve(QLatin1String("gdi32"), "GetCharWidthI"); 142 139 } 143 144 // Copy a LOGFONTW struct into a LOGFONTA by converting the face name to an 8 bit value. 145 // This is needed when calling CreateFontIndirect on non-unicode windowses. 146 inline static void wa_copy_logfont(LOGFONTW *lfw, LOGFONTA *lfa) 147 { 148 lfa->lfHeight = lfw->lfHeight; 149 lfa->lfWidth = lfw->lfWidth; 150 lfa->lfEscapement = lfw->lfEscapement; 151 lfa->lfOrientation = lfw->lfOrientation; 152 lfa->lfWeight = lfw->lfWeight; 153 lfa->lfItalic = lfw->lfItalic; 154 lfa->lfUnderline = lfw->lfUnderline; 155 lfa->lfCharSet = lfw->lfCharSet; 156 lfa->lfOutPrecision = lfw->lfOutPrecision; 157 lfa->lfClipPrecision = lfw->lfClipPrecision; 158 lfa->lfQuality = lfw->lfQuality; 159 lfa->lfPitchAndFamily = lfw->lfPitchAndFamily; 160 161 QString fam = QString::fromUtf16((const ushort*)lfw->lfFaceName); 162 memcpy(lfa->lfFaceName, fam.toLocal8Bit().constData(), fam.length() + 1); 163 } 140 #endif // !defined(Q_WS_WINCE) 164 141 165 142 // defined in qtextengine_win.cpp … … 188 165 } 189 166 190 static inline HFONT systemFont()191 {192 if (stock_sysfont == 0)193 stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT);194 return stock_sysfont;195 }196 197 198 167 // general font engine 199 168 … … 206 175 } 207 176 208 #if defined(Q_OS_WINCE) 209 static OUTLINETEXTMETRICW *getOutlineTextMetric(HDC hdc) 177 static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc) 210 178 { 211 179 int size; 212 size = GetOutlineTextMetrics W(hdc, 0, 0);213 OUTLINETEXTMETRIC W *otm = (OUTLINETEXTMETRICW*)malloc(size);214 GetOutlineTextMetrics W(hdc, size, otm);180 size = GetOutlineTextMetrics(hdc, 0, 0); 181 OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size); 182 GetOutlineTextMetrics(hdc, size, otm); 215 183 return otm; 216 184 } 217 #else218 static OUTLINETEXTMETRICA *getOutlineTextMetric(HDC hdc)219 {220 int size;221 size = GetOutlineTextMetricsA(hdc, 0, 0);222 OUTLINETEXTMETRICA *otm = (OUTLINETEXTMETRICA *)malloc(size);223 GetOutlineTextMetricsA(hdc, size, otm);224 return otm;225 }226 #endif227 185 228 186 void QFontEngineWin::getCMap() 229 187 { 230 QT_WA({ 231 ttf = (bool)(tm.w.tmPitchAndFamily & TMPF_TRUETYPE); 232 } , { 233 ttf = (bool)(tm.a.tmPitchAndFamily & TMPF_TRUETYPE); 234 }); 188 ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE); 235 189 HDC hdc = shared_dc(); 236 190 SelectObject(hdc, hfont); … … 250 204 _faceId.index = 0; 251 205 if(cmap) { 252 #if defined(Q_OS_WINCE) 253 OUTLINETEXTMETRICW *otm = getOutlineTextMetric(hdc); 254 #else 255 OUTLINETEXTMETRICA *otm = getOutlineTextMetric(hdc); 256 #endif 206 OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); 257 207 designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight); 258 208 unitsPerEm = otm->otmEMSquare; 259 209 x_height = (int)otm->otmsXHeight; 260 210 loadKerningPairs(designToDevice); 261 _faceId.filename = (char *)otm + (int)otm->otmpFullName;211 _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFullName)).toLatin1(); 262 212 lineWidth = otm->otmsUnderscoreSize; 263 213 fsType = otm->otmfsType; 264 214 free(otm); 265 215 } else { 266 unitsPerEm = tm. w.tmHeight;216 unitsPerEm = tm.tmHeight; 267 217 } 268 218 } … … 287 237 int glyph_pos = 0; 288 238 if (mirrored) { 289 #if defined(Q_ OS_WINCE)239 #if defined(Q_WS_WINCE) 290 240 { 291 241 #else … … 304 254 } else { 305 255 #endif 306 ushort first, last; 307 QT_WA({ 308 first = tm.w.tmFirstChar; 309 last = tm.w.tmLastChar; 310 }, { 311 first = tm.a.tmFirstChar; 312 last = tm.a.tmLastChar; 313 }); 256 wchar_t first = tm.tmFirstChar; 257 wchar_t last = tm.tmLastChar; 258 314 259 for (; i < numChars; ++i, ++glyph_pos) { 315 260 uint ucs = QChar::mirroredChar(getChar(str, i, numChars)); 316 261 if ( 317 #ifdef Q_ OS_WINCE318 tm. w.tmFirstChar > 60000 || // see line 375262 #ifdef Q_WS_WINCE 263 tm.tmFirstChar > 60000 || // see line 375 319 264 #endif 320 265 ucs >= first && ucs <= last) … … 325 270 } 326 271 } else { 327 #if defined(Q_ OS_WINCE)272 #if defined(Q_WS_WINCE) 328 273 { 329 274 #else … … 342 287 } else { 343 288 #endif 344 ushort first, last; 345 QT_WA({ 346 first = tm.w.tmFirstChar; 347 last = tm.w.tmLastChar; 348 }, { 349 first = tm.a.tmFirstChar; 350 last = tm.a.tmLastChar; 351 }); 289 wchar_t first = tm.tmFirstChar; 290 wchar_t last = tm.tmLastChar; 291 352 292 for (; i < numChars; ++i, ++glyph_pos) { 353 293 uint uc = getChar(str, i, numChars); 354 294 if ( 355 #ifdef Q_ OS_WINCE356 tm. w.tmFirstChar > 60000 || // see comment in QFontEngineWin295 #ifdef Q_WS_WINCE 296 tm.tmFirstChar > 60000 || // see comment in QFontEngineWin 357 297 #endif 358 298 uc >= first && uc <= last) … … 388 328 x_height = -1; 389 329 390 BOOL res; 391 QT_WA({ 392 res = GetTextMetricsW(hdc, &tm.w); 393 } , { 394 res = GetTextMetricsA(hdc, &tm.a); 395 }); 396 fontDef.fixedPitch = !(tm.w.tmPitchAndFamily & TMPF_FIXED_PITCH); 397 if (!res) 330 BOOL res = GetTextMetrics(hdc, &tm); 331 fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); 332 if (!res) { 398 333 qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); 399 400 cache_cost = tm.w.tmHeight * tm.w.tmAveCharWidth * 2000; 334 ZeroMemory(&tm, sizeof(TEXTMETRIC)); 335 } 336 337 cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000; 401 338 getCMap(); 402 339 403 useTextOutA = false;404 #ifndef Q_OS_WINCE405 // TextOutW doesn't work for symbol fonts on Windows 95!406 // since we're using glyph indices we don't care for ttfs about this!407 if (QSysInfo::WindowsVersion == QSysInfo::WV_95 && !ttf &&408 (_name == QLatin1String("Marlett") || _name == QLatin1String("Symbol") ||409 _name == QLatin1String("Webdings") || _name == QLatin1String("Wingdings")))410 useTextOutA = true;411 #endif412 340 widthCache = 0; 413 341 widthCacheSize = 0; … … 415 343 designAdvancesSize = 0; 416 344 345 #ifndef Q_WS_WINCE 417 346 if (!resolvedGetCharWidthI) 418 347 resolveGetCharWidthI(); 348 #endif 419 349 } 420 350 … … 428 358 429 359 // make sure we aren't by accident still selected 430 SelectObject(shared_dc(), systemFont());360 SelectObject(shared_dc(), (HFONT)GetStockObject(SYSTEM_FONT)); 431 361 432 362 if (!stockFont) { … … 436 366 } 437 367 438 HGDIOBJ QFontEngineWin::selectDesignFont( QFixed *overhang) const368 HGDIOBJ QFontEngineWin::selectDesignFont() const 439 369 { 440 370 LOGFONT f = logfont; 441 371 f.lfHeight = unitsPerEm; 442 HFONT designFont; 443 QT_WA({ 444 designFont = CreateFontIndirectW(&f); 445 }, { 446 LOGFONTA fa; 447 wa_copy_logfont(&f, &fa); 448 designFont = CreateFontIndirectA(&fa); 449 }); 450 HGDIOBJ oldFont = SelectObject(shared_dc(), designFont); 451 452 if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { 453 BOOL res; 454 QT_WA({ 455 TEXTMETRICW tm; 456 res = GetTextMetricsW(shared_dc(), &tm); 457 if (!res) 458 qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); 459 *overhang = QFixed((int)tm.tmOverhang) / designToDevice; 460 } , { 461 TEXTMETRICA tm; 462 res = GetTextMetricsA(shared_dc(), &tm); 463 if (!res) 464 qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); 465 *overhang = QFixed((int)tm.tmOverhang) / designToDevice; 466 }); 467 } else { 468 *overhang = 0; 469 } 470 return oldFont; 372 HFONT designFont = CreateFontIndirect(&f); 373 return SelectObject(shared_dc(), designFont); 471 374 } 472 375 … … 483 386 return true; 484 387 485 #if defined(Q_OS_WINCE) 486 HDC hdc = shared_dc(); 487 if (flags & QTextEngine::DesignMetrics) { 488 HGDIOBJ oldFont = 0; 489 QFixed overhang = 0; 490 491 int glyph_pos = 0; 492 for(register int i = 0; i < len; i++) { 493 bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1 494 && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); 495 unsigned int glyph = glyphs->glyphs[glyph_pos]; 496 if(int(glyph) >= designAdvancesSize) { 497 int newSize = (glyph + 256) >> 8 << 8; 498 designAdvances = (QFixed *)realloc(designAdvances, newSize*sizeof(QFixed)); 499 for(int i = designAdvancesSize; i < newSize; ++i) 500 designAdvances[i] = -1000000; 501 designAdvancesSize = newSize; 502 } 503 if(designAdvances[glyph] < -999999) { 504 if(!oldFont) 505 oldFont = selectDesignFont(&overhang); 506 SIZE size = {0, 0}; 507 GetTextExtentPoint32W(hdc, (wchar_t *)(str+i), surrogate ? 2 : 1, &size); 508 designAdvances[glyph] = QFixed((int)size.cx)/designToDevice; 509 } 510 glyphs->advances_x[glyph_pos] = designAdvances[glyph]; 511 glyphs->advances_y[glyph_pos] = 0; 512 if (surrogate) 513 ++i; 514 ++glyph_pos; 515 } 516 if(oldFont) 517 DeleteObject(SelectObject(hdc, oldFont)); 518 } else { 519 int glyph_pos = 0; 520 HGDIOBJ oldFont = 0; 521 522 for(register int i = 0; i < len; i++) { 523 bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1 524 && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); 525 unsigned int glyph = glyphs->glyphs[glyph_pos]; 526 527 glyphs->advances_y[glyph_pos] = 0; 528 529 if (glyph >= widthCacheSize) { 530 int newSize = (glyph + 256) >> 8 << 8; 531 widthCache = (unsigned char *)realloc(widthCache, newSize*sizeof(QFixed)); 532 memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize); 533 widthCacheSize = newSize; 534 } 535 glyphs->advances_x[glyph_pos] = widthCache[glyph]; 536 // font-width cache failed 537 if (glyphs->advances_x[glyph_pos] == 0) { 538 SIZE size = {0, 0}; 539 if (!oldFont) 540 oldFont = SelectObject(hdc, hfont); 541 GetTextExtentPoint32W(hdc, (wchar_t *)str + i, surrogate ? 2 : 1, &size); 542 glyphs->advances_x[glyph_pos] = size.cx; 543 // if glyph's within cache range, store it for later 544 if (size.cx > 0 && size.cx < 0x100) 545 widthCache[glyph] = size.cx; 546 } 547 548 if (surrogate) 549 ++i; 550 ++glyph_pos; 551 } 552 553 if (oldFont) 554 SelectObject(hdc, oldFont); 555 } 388 recalcAdvances(glyphs, flags); 389 return true; 390 } 391 392 inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width) 393 { 394 #if defined(Q_WS_WINCE) 395 GetCharWidth32(hdc, glyph, glyph, &width); 556 396 #else 557 recalcAdvances(glyphs, flags);558 #endif 559 return true; 397 if (ptrGetCharWidthI) 398 ptrGetCharWidthI(hdc, glyph, 1, 0, &width); 399 #endif 560 400 } 561 401 … … 565 405 HDC hdc = shared_dc(); 566 406 if (ttf && (flags & QTextEngine::DesignMetrics)) { 567 QFixed overhang = 0;568 569 407 for(int i = 0; i < glyphs->numGlyphs; i++) { 570 408 unsigned int glyph = glyphs->glyphs[i]; 571 409 if(int(glyph) >= designAdvancesSize) { 572 410 int newSize = (glyph + 256) >> 8 << 8; 573 designAdvances = (QFixed *)realloc(designAdvances, newSize*sizeof(QFixed)); 411 designAdvances = q_check_ptr((QFixed *)realloc(designAdvances, 412 newSize*sizeof(QFixed))); 574 413 for(int i = designAdvancesSize; i < newSize; ++i) 575 414 designAdvances[i] = -1000000; 576 415 designAdvancesSize = newSize; 577 416 } 578 if(designAdvances[glyph] < -999999) { 579 if(!oldFont) 580 oldFont = selectDesignFont(&overhang); 581 582 if (ptrGetCharWidthI) { 583 int width = 0; 584 ptrGetCharWidthI(hdc, glyph, 1, 0, &width); 585 586 designAdvances[glyph] = QFixed(width) / designToDevice; 587 } else { 588 #ifndef Q_OS_WINCE 589 GLYPHMETRICS gm; 590 DWORD res = GDI_ERROR; 591 MAT2 mat; 592 mat.eM11.value = mat.eM22.value = 1; 593 mat.eM11.fract = mat.eM22.fract = 0; 594 mat.eM21.value = mat.eM12.value = 0; 595 mat.eM21.fract = mat.eM12.fract = 0; 596 QT_WA({ 597 res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat); 598 } , { 599 res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat); 600 }); 601 602 if (res != GDI_ERROR) { 603 designAdvances[glyph] = QFixed(gm.gmCellIncX) / designToDevice; 604 } 605 #endif 606 } 417 if (designAdvances[glyph] < -999999) { 418 if (!oldFont) 419 oldFont = selectDesignFont(); 420 421 int width = 0; 422 calculateTTFGlyphWidth(hdc, glyph, width); 423 designAdvances[glyph] = QFixed(width) / designToDevice; 607 424 } 608 425 glyphs->advances_x[i] = designAdvances[glyph]; … … 612 429 DeleteObject(SelectObject(hdc, oldFont)); 613 430 } else { 614 int overhang = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) ? tm.a.tmOverhang : 0;615 616 431 for(int i = 0; i < glyphs->numGlyphs; i++) { 617 432 unsigned int glyph = glyphs->glyphs[i]; … … 621 436 if (glyph >= widthCacheSize) { 622 437 int newSize = (glyph + 256) >> 8 << 8; 623 widthCache = (unsigned char *)realloc(widthCache, newSize*sizeof(QFixed)); 438 widthCache = q_check_ptr((unsigned char *)realloc(widthCache, 439 newSize*sizeof(QFixed))); 624 440 memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize); 625 441 widthCacheSize = newSize; … … 641 457 } 642 458 SIZE size = {0, 0}; 643 GetTextExtentPoint32 W(hdc, (wchar_t *)ch, chrLen, &size);459 GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size); 644 460 width = size.cx; 645 } else if (ptrGetCharWidthI) {646 ptrGetCharWidthI(hdc, glyph, 1, 0, &width);647 648 width -= overhang;649 461 } else { 650 #ifndef Q_OS_WINCE 651 GLYPHMETRICS gm; 652 DWORD res = GDI_ERROR; 653 MAT2 mat; 654 mat.eM11.value = mat.eM22.value = 1; 655 mat.eM11.fract = mat.eM22.fract = 0; 656 mat.eM21.value = mat.eM12.value = 0; 657 mat.eM21.fract = mat.eM12.fract = 0; 658 QT_WA({ 659 res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); 660 } , { 661 res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); 662 }); 663 664 if (res != GDI_ERROR) { 665 width = gm.gmCellIncX; 666 } 667 #endif 462 calculateTTFGlyphWidth(hdc, glyph, width); 668 463 } 669 464 glyphs->advances_x[i] = width; … … 688 483 w += glyphs.effectiveAdvance(i); 689 484 690 return glyph_metrics_t(0, -tm.w.tmAscent, w, tm.w.tmHeight, w, 0); 691 } 692 693 694 695 696 #ifndef Q_OS_WINCE 697 typedef HRESULT (WINAPI *pGetCharABCWidthsFloat)(HDC, UINT, UINT, LPABCFLOAT); 698 static pGetCharABCWidthsFloat qt_GetCharABCWidthsFloat = 0; 485 return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0); 486 } 487 488 #ifndef Q_WS_WINCE 489 bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const 490 { 491 Q_ASSERT(metrics != 0); 492 493 HDC hdc = shared_dc(); 494 495 GLYPHMETRICS gm; 496 DWORD res = 0; 497 MAT2 mat; 498 mat.eM11.value = mat.eM22.value = 1; 499 mat.eM11.fract = mat.eM22.fract = 0; 500 mat.eM21.value = mat.eM12.value = 0; 501 mat.eM21.fract = mat.eM12.fract = 0; 502 503 if (t.type() > QTransform::TxTranslate) { 504 // We need to set the transform using the HDC's world 505 // matrix rather than using the MAT2 above, because the 506 // results provided when transforming via MAT2 does not 507 // match the glyphs that are drawn using a WorldTransform 508 XFORM xform; 509 xform.eM11 = t.m11(); 510 xform.eM12 = t.m12(); 511 xform.eM21 = t.m21(); 512 xform.eM22 = t.m22(); 513 xform.eDx = 0; 514 xform.eDy = 0; 515 SetGraphicsMode(hdc, GM_ADVANCED); 516 SetWorldTransform(hdc, &xform); 517 } 518 519 uint format = GGO_METRICS; 520 if (ttf) 521 format |= GGO_GLYPH_INDEX; 522 res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat); 523 524 if (t.type() > QTransform::TxTranslate) { 525 XFORM xform; 526 xform.eM11 = xform.eM22 = 1; 527 xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0; 528 SetWorldTransform(hdc, &xform); 529 SetGraphicsMode(hdc, GM_COMPATIBLE); 530 } 531 532 if (res != GDI_ERROR) { 533 *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y, 534 (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY); 535 return true; 536 } else { 537 return false; 538 } 539 } 699 540 #endif 700 541 701 542 glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) 702 543 { 703 #ifndef Q_OS_WINCE 704 GLYPHMETRICS gm; 705 544 #ifndef Q_WS_WINCE 706 545 HDC hdc = shared_dc(); 707 546 SelectObject(hdc, hfont); 708 if(!ttf) { 709 SIZE s = {0, 0}; 710 WCHAR ch = glyph; 711 int width; 712 int overhang = 0; 713 static bool resolved = false; 714 if (!resolved) { 715 QLibrary lib(QLatin1String("gdi32")); 716 qt_GetCharABCWidthsFloat = (pGetCharABCWidthsFloat) lib.resolve("GetCharABCWidthsFloatW"); 717 resolved = true; 718 } 719 if (QT_WA_INLINE(true, false) && qt_GetCharABCWidthsFloat) { 720 ABCFLOAT abc; 721 qt_GetCharABCWidthsFloat(hdc, ch, ch, &abc); 722 width = qRound(abc.abcfB); 723 } else { 724 GetTextExtentPoint32W(hdc, &ch, 1, &s); 725 overhang = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) ? tm.a.tmOverhang : 0; 726 width = s.cx; 727 } 728 729 return glyph_metrics_t(0, -tm.a.tmAscent, 730 width, tm.a.tmHeight, 731 width-overhang, 0).transformed(t); 732 } else { 733 DWORD res = 0; 734 MAT2 mat; 735 mat.eM11.value = mat.eM22.value = 1; 736 mat.eM11.fract = mat.eM22.fract = 0; 737 mat.eM21.value = mat.eM12.value = 0; 738 mat.eM21.fract = mat.eM12.fract = 0; 739 740 if (t.type() > QTransform::TxTranslate) { 741 // We need to set the transform using the HDC's world 742 // matrix rather than using the MAT2 above, because the 743 // results provided when transforming via MAT2 does not 744 // match the glyphs that are drawn using a WorldTransform 745 XFORM xform; 746 xform.eM11 = t.m11(); 747 xform.eM12 = t.m12(); 748 xform.eM21 = t.m21(); 749 xform.eM22 = t.m22(); 750 xform.eDx = 0; 751 xform.eDy = 0; 752 SetGraphicsMode(hdc, GM_ADVANCED); 753 SetWorldTransform(hdc, &xform); 754 } 755 756 QT_WA({ 757 res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); 758 } , { 759 res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); 760 }); 761 if (t.type() > QTransform::TxTranslate) { 762 XFORM xform; 763 xform.eM11 = xform.eM22 = 1; 764 xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0; 765 SetWorldTransform(hdc, &xform); 766 SetGraphicsMode(hdc, GM_COMPATIBLE); 767 } 768 769 if (res != GDI_ERROR) { 770 return glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y, 771 (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY); 772 } 773 } 774 return glyph_metrics_t(); 547 548 glyph_metrics_t glyphMetrics; 549 bool success = getOutlineMetrics(glyph, t, &glyphMetrics); 550 551 if (!ttf && !success) { 552 // Bitmap fonts 553 wchar_t ch = glyph; 554 ABCFLOAT abc; 555 GetCharABCWidthsFloat(hdc, ch, ch, &abc); 556 int width = qRound(abc.abcfB); 557 558 return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t); 559 } 560 561 return glyphMetrics; 775 562 #else 776 563 HDC hdc = shared_dc(); … … 794 581 #endif 795 582 { // fallback 796 width = tm. w.tmMaxCharWidth;583 width = tm.tmMaxCharWidth; 797 584 advance = width; 798 585 } 799 586 800 587 SelectObject(hdc, oldFont); 801 return glyph_metrics_t(0, -tm. w.tmAscent, width, tm.w.tmHeight, advance, 0).transformed(t);588 return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, advance, 0).transformed(t); 802 589 #endif 803 590 } … … 805 592 QFixed QFontEngineWin::ascent() const 806 593 { 807 return tm. w.tmAscent;594 return tm.tmAscent; 808 595 } 809 596 810 597 QFixed QFontEngineWin::descent() const 811 598 { 812 return tm.w.tmDescent; 599 // ### we substract 1 to even out the historical +1 in QFontMetrics's 600 // ### height=asc+desc+1 equation. Fix in Qt5. 601 return tm.tmDescent - 1; 813 602 } 814 603 815 604 QFixed QFontEngineWin::leading() const 816 605 { 817 return tm. w.tmExternalLeading;606 return tm.tmExternalLeading; 818 607 } 819 608 … … 828 617 QFixed QFontEngineWin::averageCharWidth() const 829 618 { 830 return tm. w.tmAveCharWidth;619 return tm.tmAveCharWidth; 831 620 } 832 621 833 622 qreal QFontEngineWin::maxCharWidth() const 834 623 { 835 return tm. w.tmMaxCharWidth;624 return tm.tmMaxCharWidth; 836 625 } 837 626 … … 872 661 qreal QFontEngineWin::minRightBearing() const 873 662 { 874 #ifdef Q_ OS_WINCE663 #ifdef Q_WS_WINCE 875 664 if (rbearing == SHRT_MIN) { 876 665 int ml = 0; … … 880 669 if (ttf) { 881 670 ABC *abc = 0; 882 int n = QT_WA_INLINE(tm.w.tmLastChar - tm.w.tmFirstChar, tm.a.tmLastChar - tm.a.tmFirstChar);671 int n = tm.tmLastChar - tm.tmFirstChar; 883 672 if (n <= max_font_count) { 884 673 abc = new ABC[n+1]; 885 GetCharABCWidths(hdc, tm. w.tmFirstChar, tm.w.tmLastChar, abc);674 GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc); 886 675 } else { 887 676 abc = new ABC[char_table_entries+1]; … … 899 688 } 900 689 delete [] abc; 901 } else {902 ml = 0;903 mr = -tm.a.tmOverhang;904 690 } 905 691 lbearing = ml; … … 916 702 if (ttf) { 917 703 ABC *abc = 0; 918 int n = QT_WA_INLINE(tm.w.tmLastChar - tm.w.tmFirstChar, tm.a.tmLastChar - tm.a.tmFirstChar);704 int n = tm.tmLastChar - tm.tmFirstChar; 919 705 if (n <= max_font_count) { 920 706 abc = new ABC[n+1]; 921 QT_WA({ 922 GetCharABCWidths(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc); 923 }, { 924 GetCharABCWidthsA(hdc,tm.a.tmFirstChar,tm.a.tmLastChar,abc); 925 }); 707 GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc); 926 708 } else { 927 709 abc = new ABC[char_table_entries+1]; 928 QT_WA({ 929 for(int i = 0; i < char_table_entries; i++) 930 GetCharABCWidths(hdc, char_table[i], char_table[i], abc+i); 931 }, { 932 for(int i = 0; i < char_table_entries; i++) { 933 QByteArray w = QString(QChar(char_table[i])).toLocal8Bit(); 934 if (w.length() == 1) { 935 uint ch8 = (uchar)w[0]; 936 GetCharABCWidthsA(hdc, ch8, ch8, abc+i); 937 } 938 } 939 }); 710 for(int i = 0; i < char_table_entries; i++) 711 GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i); 940 712 n = char_table_entries; 941 713 } … … 950 722 delete [] abc; 951 723 } else { 952 QT_WA({ 953 ABCFLOAT *abc = 0; 954 int n = tm.w.tmLastChar - tm.w.tmFirstChar+1; 955 if (n <= max_font_count) { 956 abc = new ABCFLOAT[n]; 957 GetCharABCWidthsFloat(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc); 958 } else { 959 abc = new ABCFLOAT[char_table_entries]; 960 for(int i = 0; i < char_table_entries; i++) 961 GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i); 962 n = char_table_entries; 724 ABCFLOAT *abc = 0; 725 int n = tm.tmLastChar - tm.tmFirstChar+1; 726 if (n <= max_font_count) { 727 abc = new ABCFLOAT[n]; 728 GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc); 729 } else { 730 abc = new ABCFLOAT[char_table_entries]; 731 for(int i = 0; i < char_table_entries; i++) 732 GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i); 733 n = char_table_entries; 734 } 735 float fml = abc[0].abcfA; 736 float fmr = abc[0].abcfC; 737 for (int i=1; i<n; i++) { 738 if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) { 739 fml = qMin(fml,abc[i].abcfA); 740 fmr = qMin(fmr,abc[i].abcfC); 963 741 } 964 float fml = abc[0].abcfA; 965 float fmr = abc[0].abcfC; 966 for (int i=1; i<n; i++) { 967 if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) { 968 fml = qMin(fml,abc[i].abcfA); 969 fmr = qMin(fmr,abc[i].abcfC); 970 } 971 } 972 ml = int(fml-0.9999); 973 mr = int(fmr-0.9999); 974 delete [] abc; 975 } , { 976 ml = 0; 977 mr = -tm.a.tmOverhang; 978 }); 742 } 743 ml = int(fml - 0.9999); 744 mr = int(fmr - 0.9999); 745 delete [] abc; 979 746 } 980 747 lbearing = ml; … … 1013 780 } 1014 781 } else { 1015 QT_WA({ 1016 while(len--) { 1017 if (tm.w.tmFirstChar > string->unicode() || tm.w.tmLastChar < string->unicode()) 1018 return false; 1019 } 1020 }, { 1021 while(len--) { 1022 if (tm.a.tmFirstChar > string->unicode() || tm.a.tmLastChar < string->unicode()) 1023 return false; 1024 } 1025 }); 782 while(len--) { 783 if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode()) 784 return false; 785 } 1026 786 } 1027 787 return true; … … 1048 808 QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1) 1049 809 { 1050 #if defined(Q_ OS_WINCE)810 #if defined(Q_WS_WINCE) 1051 811 Q_UNUSED(glyph); 1052 812 Q_UNUSED(hdc); … … 1065 825 memset(&gMetric, 0, sizeof(GLYPHMETRICS)); 1066 826 int bufferSize = GDI_ERROR; 1067 #if !defined(Q_OS_WINCE) 1068 QT_WA( { 1069 bufferSize = GetGlyphOutlineW(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); 1070 }, { 1071 bufferSize = GetGlyphOutlineA(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); 1072 }); 827 #if !defined(Q_WS_WINCE) 828 bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); 1073 829 #endif 1074 830 if ((DWORD)bufferSize == GDI_ERROR) { … … 1078 834 void *dataBuffer = new char[bufferSize]; 1079 835 DWORD ret = GDI_ERROR; 1080 #if !defined(Q_OS_WINCE) 1081 QT_WA( { 1082 ret = GetGlyphOutlineW(hdc, glyph, glyphFormat, &gMetric, bufferSize, 1083 dataBuffer, &mat); 1084 }, { 1085 ret = GetGlyphOutlineA(hdc, glyph, glyphFormat, &gMetric, bufferSize, 1086 dataBuffer, &mat); 1087 } ); 836 #if !defined(Q_WS_WINCE) 837 ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat); 1088 838 #endif 1089 839 if (ret == GDI_ERROR) { … … 1172 922 lf.lfHeight = -unitsPerEm; 1173 923 lf.lfWidth = 0; 1174 HFONT hf; 1175 QT_WA({ 1176 hf = CreateFontIndirectW(&lf); 1177 }, { 1178 LOGFONTA lfa; 1179 wa_copy_logfont(&lf, &lfa); 1180 hf = CreateFontIndirectA(&lfa); 1181 }); 924 HFONT hf = CreateFontIndirect(&lf); 1182 925 HDC hdc = shared_dc(); 1183 926 HGDIOBJ oldfont = SelectObject(hdc, hf); … … 1200 943 QPainterPath *path, QTextItem::RenderFlags flags) 1201 944 { 1202 #if !defined(Q_ OS_WINCE)1203 if(tm. w.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {945 #if !defined(Q_WS_WINCE) 946 if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) { 1204 947 hasOutline = true; 1205 948 QFontEngine::addOutlineToPath(x, y, glyphs, path, flags); … … 1235 978 GetFontData(hdc, HEAD, 44, &data, 4); 1236 979 USHORT macStyle = getUShort(data); 1237 if (tm. w.tmItalic && !(macStyle & 2))980 if (tm.tmItalic && !(macStyle & 2)) 1238 981 synthesized_flags = SynthesizedItalic; 1239 982 if (fontDef.stretch != 100 && ttf) 1240 983 synthesized_flags |= SynthesizedStretch; 1241 if (tm. w.tmWeight >= 500 && !(macStyle & 1))984 if (tm.tmWeight >= 500 && !(macStyle & 1)) 1242 985 synthesized_flags |= SynthesizedBold; 1243 986 //qDebug() << "font is" << _name << … … 1255 998 QFontEngine::Properties QFontEngineWin::properties() const 1256 999 { 1257 1258 1000 LOGFONT lf = logfont; 1259 1001 lf.lfHeight = unitsPerEm; 1260 HFONT hf; 1261 QT_WA({ 1262 hf = CreateFontIndirectW(&lf); 1263 }, { 1264 LOGFONTA lfa; 1265 wa_copy_logfont(&lf, &lfa); 1266 hf = CreateFontIndirectA(&lfa); 1267 }); 1002 HFONT hf = CreateFontIndirect(&lf); 1268 1003 HDC hdc = shared_dc(); 1269 1004 HGDIOBJ oldfont = SelectObject(hdc, hf); 1270 #if defined(Q_OS_WINCE) 1271 OUTLINETEXTMETRICW *otm = getOutlineTextMetric(hdc); 1272 #else 1273 OUTLINETEXTMETRICA *otm = getOutlineTextMetric(hdc); 1274 #endif 1005 OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); 1275 1006 Properties p; 1276 1007 p.emSquare = unitsPerEm; 1277 1008 p.italicAngle = otm->otmItalicAngle; 1278 p.postscriptName = (char *)otm + (int)otm->otmpFamilyName;1279 p.postscriptName += (char *)otm + (int)otm->otmpStyleName;1009 p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFamilyName)).toLatin1(); 1010 p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpStyleName)).toLatin1(); 1280 1011 #ifndef QT_NO_PRINTER 1281 1012 p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); … … 1302 1033 lf.lfItalic = false; 1303 1034 lf.lfWidth = 0; 1304 HFONT hf; 1305 QT_WA({ 1306 hf = CreateFontIndirectW(&lf); 1307 }, { 1308 LOGFONTA lfa; 1309 wa_copy_logfont(&lf, &lfa); 1310 hf = CreateFontIndirectA(&lfa); 1311 }); 1035 HFONT hf = CreateFontIndirect(&lf); 1312 1036 HDC hdc = shared_dc(); 1313 1037 HGDIOBJ oldfont = SelectObject(hdc, hf); … … 1334 1058 #endif 1335 1059 1060 extern bool qt_cleartype_enabled; 1336 1061 1337 1062 QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin, 1338 const QTransform &t) 1339 { 1063 const QTransform &t, QImage::Format mask_format) 1064 { 1065 Q_UNUSED(mask_format) 1340 1066 glyph_metrics_t gm = boundingBox(glyph); 1341 1067 … … 1352 1078 bool has_transformation = t.type() > QTransform::TxTranslate; 1353 1079 1354 #ifndef Q_ OS_WINCE1080 #ifndef Q_WS_WINCE 1355 1081 unsigned int options = ttf ? ETO_GLYPH_INDEX : 0; 1356 1082 XFORM xform; … … 1377 1103 mat.eM11.value = mat.eM22.value = 1; 1378 1104 1379 int error = 0; 1380 QT_WA( { 1381 error = GetGlyphOutlineW(hdc, glyph, ggo_options, &tgm, 0, 0, &mat); 1382 }, { 1383 error = GetGlyphOutlineA(hdc, glyph, ggo_options, &tgm, 0, 0, &mat); 1384 } ); 1385 1386 if (error == GDI_ERROR) { 1105 if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) { 1387 1106 qWarning("QWinFontEngine: unable to query transformed glyph metrics..."); 1388 1107 return 0; … … 1407 1126 #endif 1408 1127 1409 QNativeImage *ni = new QNativeImage(iw + 2 * margin, 1410 ih + 2 * margin, 1411 QNativeImage::systemFormat(), true); 1128 QNativeImage *ni = new QNativeImage(iw + 2 * margin + 4, 1129 ih + 2 * margin + 4, 1130 QNativeImage::systemFormat(), !qt_cleartype_enabled); 1131 1132 /*If cleartype is enabled we use the standard system format even on Windows CE 1133 and not the special textbuffer format we have to use if cleartype is disabled*/ 1134 1412 1135 ni->image.fill(0xffffffff); 1413 1136 … … 1426 1149 SetGraphicsMode(hdc, GM_ADVANCED); 1427 1150 SetWorldTransform(hdc, &xform); 1428 ExtTextOut W(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0);1151 ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0); 1429 1152 } else 1430 1153 #endif 1431 1154 { 1432 ExtTextOut W(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0);1433 } 1434 1155 ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0); 1156 } 1157 1435 1158 SelectObject(hdc, old_font); 1436 1159 return ni; … … 1438 1161 1439 1162 1440 extern bool qt_cleartype_enabled;1441 1163 extern uint qt_pow_gamma[256]; 1442 1164 … … 1447 1169 LOGFONT lf = logfont; 1448 1170 lf.lfQuality = ANTIALIASED_QUALITY; 1449 font = CreateFontIndirectW(&lf); 1450 } 1451 1452 QNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform); 1171 font = CreateFontIndirect(&lf); 1172 } 1173 QImage::Format mask_format = QNativeImage::systemFormat(); 1174 #ifndef Q_OS_WINCE 1175 mask_format = QImage::Format_RGB32; 1176 #endif 1177 1178 QNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format); 1453 1179 if (mask == 0) 1454 1180 return QImage(); … … 1467 1193 for (int y=0; y<mask->height(); ++y) { 1468 1194 uchar *dest = indexed.scanLine(y); 1469 if (mask-> systemFormat() == QImage::Format_RGB16) {1195 if (mask->image.format() == QImage::Format_RGB16) { 1470 1196 const qint16 *src = (qint16 *) ((const QImage &) mask->image).scanLine(y); 1471 for (int x=0; x<mask->width(); ++x) { 1472 #ifdef Q_OS_WINCE 1197 for (int x=0; x<mask->width(); ++x) 1473 1198 dest[x] = 255 - qGray(src[x]); 1474 #else1475 dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.);1476 #endif1477 }1478 1199 } else { 1479 1200 const uint *src = (uint *) ((const QImage &) mask->image).scanLine(y); … … 1482 1203 dest[x] = 255 - qGray(src[x]); 1483 1204 #else 1484 dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.); 1205 if (QNativeImage::systemFormat() == QImage::Format_RGB16) 1206 dest[x] = 255 - qGray(src[x]); 1207 else 1208 dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.); 1485 1209 #endif 1486 1210 } … … 1508 1232 SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0); 1509 1233 1510 QNativeImage *mask = drawGDIGlyph(font, glyph, margin, t );1234 QNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32); 1511 1235 SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) contrast, 0); 1512 1236 … … 1552 1276 1553 1277 LOGFONT lf = static_cast<QFontEngineWin *>(engines.at(0))->logfont; 1554 HFONT hfont; 1555 QT_WA({ 1556 memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32)); // 32 = Windows hard-coded 1557 hfont = CreateFontIndirectW(&lf); 1558 } , { 1559 // LOGFONTA and LOGFONTW are binary compatible 1560 QByteArray lname = fam.toLocal8Bit(); 1561 memcpy(lf.lfFaceName,lname.data(), 1562 qMin(lname.length()+1,32)); // 32 = Windows hard-coded 1563 hfont = CreateFontIndirectA((LOGFONTA*)&lf); 1564 }); 1278 memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded 1279 HFONT hfont = CreateFontIndirect(&lf); 1280 1565 1281 bool stockFont = false; 1566 1282 if (hfont == 0) {
Note:
See TracChangeset
for help on using the changeset viewer.