Changeset 561 for trunk/src/gui/text/qfontengine_mac.mm
- 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_mac.mm
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 ** … … 120 120 121 121 122 123 void qmacfontengine_gamma_correct(QImage *image) 124 { 125 extern uchar qt_pow_rgb_gamma[256]; 126 127 // gamma correct the pixels back to linear color space... 128 int h = image->height(); 129 int w = image->width(); 130 131 for (int y=0; y<h; ++y) { 132 uint *pixels = (uint *) image->scanLine(y); 133 for (int x=0; x<w; ++x) { 134 uint p = pixels[x]; 135 uint r = qt_pow_rgb_gamma[qRed(p)]; 136 uint g = qt_pow_rgb_gamma[qGreen(p)]; 137 uint b = qt_pow_rgb_gamma[qBlue(p)]; 138 pixels[x] = (r << 16) | (g << 8) | b | 0xff000000; 139 } 140 } 141 } 142 143 122 144 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 123 145 QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning) … … 136 158 break; 137 159 } 138 160 139 161 QCFString name; 140 162 ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name); 163 141 164 QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); 142 QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0); 165 QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0); 143 166 ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits); 144 167 … … 157 180 float zero = 0.0; 158 181 QCFType<CFNumberRef> noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero); 159 CFDictionaryAddValue(attributeDict, kCTKernAttributeName, &noKern);182 CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern); 160 183 } 161 184 … … 163 186 fe->ref.ref(); 164 187 engines.append(fe); 165 188 166 189 } 167 190 … … 177 200 return i; 178 201 } 179 202 180 203 QCoreTextFontEngineMulti *that = const_cast<QCoreTextFontEngineMulti *>(this); 181 204 QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that); … … 228 251 const uint fontIndex = (fontIndexForFont(runFont) << 24); 229 252 //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); 230 QVarLengthArray<CGGlyph, 512> cgglyphs(0); 253 QVarLengthArray<CGGlyph, 512> cgglyphs(0); 231 254 const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); 232 255 if (!tmpGlyphs) { … … 261 284 CFIndex k = 0; 262 285 CFIndex i = 0; 263 for (i = stringRange.location; 286 for (i = stringRange.location; 264 287 (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { 265 288 if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { … … 382 405 QFixed QCoreTextFontEngine::descent() const 383 406 { 384 return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil(); 407 // subtract a pixel to even out the historical +1 in QFontMetrics::height(). 408 // Fix in Qt 5. 409 return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1; 385 410 } 386 411 QFixed QCoreTextFontEngine::leading() const … … 426 451 if (glyphs.size() == 0) 427 452 return; 428 453 429 454 CGContextSetFontSize(ctx, fontDef.pixelSize); 430 455 431 456 CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); 432 457 433 458 CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight); 434 459 435 460 CGAffineTransformConcat(cgMatrix, oldTextMatrix); 436 461 437 462 if (synthesisFlags & QFontEngine::SynthesizedItalic) 438 463 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); 439 464 440 465 // ### cgMatrix = CGAffineTransformConcat(cgMatrix, transform); 441 466 442 467 CGContextSetTextMatrix(ctx, cgMatrix); 443 468 444 469 CGContextSetTextDrawingMode(ctx, kCGTextFill); 445 446 470 471 447 472 QVarLengthArray<CGSize> advances(glyphs.size()); 448 473 QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size()); 449 474 450 475 for (int i = 0; i < glyphs.size() - 1; ++i) { 451 476 advances[i].width = (positions[i + 1].x - positions[i].x).toReal(); … … 456 481 advances[glyphs.size() - 1].height = 0; 457 482 cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1]; 458 483 459 484 CGContextSetFont(ctx, cgFont); 460 485 //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont)); 461 486 462 487 CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal()); 463 488 464 489 CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); 465 490 466 491 if (synthesisFlags & QFontEngine::SynthesizedBold) { 467 492 CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(), 468 493 positions[0].y.toReal()); 469 494 470 495 CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); 471 496 } 472 497 473 498 CGContextSetTextMatrix(ctx, oldTextMatrix); 474 499 } … … 524 549 525 550 if (synthesisFlags & QFontEngine::SynthesizedItalic) 526 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));551 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); 527 552 528 553 … … 534 559 } 535 560 536 QImage QCoreTextFontEngine:: alphaMapForGlyph(glyph_t glyph)561 QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa) 537 562 { 538 563 const glyph_metrics_t br = boundingBox(glyph); … … 541 566 542 567 CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); 543 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)544 568 uint cgflags = kCGImageAlphaNoneSkipFirst; 545 569 #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version 546 if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) 547 cgflags |= kCGBitmapByteOrder32Host; 548 #endif 549 #else 550 CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst; 570 cgflags |= kCGBitmapByteOrder32Host; 551 571 #endif 552 572 CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), … … 554 574 cgflags); 555 575 CGContextSetFontSize(ctx, fontDef.pixelSize); 556 CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias)); 576 CGContextSetShouldAntialias(ctx, aa || 577 (fontDef.pointSize > qt_antialiasing_threshold 578 && !(fontDef.styleStrategy & QFont::NoAntialias))); 579 CGContextSetShouldSmoothFonts(ctx, aa); 557 580 CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); 558 581 CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); … … 588 611 589 612 CGContextRelease(ctx); 613 614 return im; 615 } 616 617 QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) 618 { 619 QImage im = imageForGlyph(glyph, 0, false); 590 620 591 621 QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); … … 608 638 } 609 639 640 QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &x) 641 { 642 if (x.type() >= QTransform::TxScale) 643 return QFontEngine::alphaRGBMapForGlyph(glyph, margin, x); 644 645 QImage im = imageForGlyph(glyph, margin, true); 646 qmacfontengine_gamma_correct(&im); 647 return im; 648 } 649 610 650 void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const 611 651 { … … 623 663 bool QCoreTextFontEngine::canRender(const QChar *string, int len) 624 664 { 625 QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont, 665 QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont, 626 666 QCFType<CFStringRef>(CFStringCreateWithCharactersNoCopy(0, 627 667 reinterpret_cast<const UniChar *>(string), … … 673 713 if (fontDef.weight >= QFont::Bold) 674 714 fntStyle |= ::bold; 675 if (fontDef.style != QFont::StyleNormal) 715 if (fontDef.style != QFont::StyleNormal) 676 716 fntStyle |= ::italic; 677 717 … … 793 833 && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); 794 834 } 795 Q_ASSERT(*nfo->numGlyphs == item->length - surrogates);796 835 #endif 797 836 for (nextCharStop = item->from; nextCharStop < item->from + item->length; ++nextCharStop) … … 819 858 820 859 if (glyphId != 0xffff || i == 0) { 821 nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24); 822 823 nfo->glyphs->advances_y[i] = yAdvance; 824 nfo->glyphs->advances_x[i] = xAdvance; 860 if (i < nfo->glyphs->numGlyphs) 861 { 862 nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24); 863 864 nfo->glyphs->advances_y[i] = yAdvance; 865 nfo->glyphs->advances_x[i] = xAdvance; 866 } 825 867 } else { 826 868 // ATSUI gives us 0xffff as glyph id at the index in the glyph array for … … 956 998 tmpItem.glyphs = shaperItem.glyphs.mid(glyphIdx, glyphCount); 957 999 tmpItem.log_clusters = shaperItem.log_clusters + charIdx; 958 if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length, 1000 if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length, 959 1001 &tmpItem.glyphs, &glyphCount, flags, 960 1002 &tmpItem)) { … … 992 1034 nfo.shaperItem = shaperItem; 993 1035 1036 int prevNumGlyphs = *nglyphs; 1037 994 1038 QVarLengthArray<int> mappedFonts(len); 995 1039 for (int i = 0; i < len; ++i) … … 1018 1062 ; 1019 1063 1020 if (!(flags & QTextEngine::DesignMetrics)) { 1021 layopts |= kATSLineFractDisable | kATSLineUseDeviceMetrics 1022 | kATSLineDisableAutoAdjustDisplayPos; 1023 } 1064 layopts |= kATSLineUseDeviceMetrics; 1024 1065 1025 1066 if (fontDef.styleStrategy & QFont::NoAntialias) … … 1106 1147 1107 1148 ATSUClearLayoutCache(textLayout, kATSUFromTextBeginning); 1149 if (prevNumGlyphs < *nfo.numGlyphs) 1150 return false; 1108 1151 return true; 1109 1152 } … … 1222 1265 else 1223 1266 transform = CGAffineTransformIdentity; 1224 1267 1225 1268 ATSUTextMeasurement metric; 1226 1269 1227 1270 ATSUGetAttribute(style, kATSUAscentTag, sizeof(metric), &metric, 0); 1228 1271 m_ascent = FixRound(metric); 1229 1272 1230 1273 ATSUGetAttribute(style, kATSUDescentTag, sizeof(metric), &metric, 0); 1231 1274 m_descent = FixRound(metric); … … 1366 1409 QFixed QFontEngineMac::descent() const 1367 1410 { 1368 return m_descent; 1411 // subtract a pixel to even out the historical +1 in QFontMetrics::height(). 1412 // Fix in Qt 5. 1413 return m_descent - 1; 1369 1414 } 1370 1415 … … 1423 1468 } 1424 1469 1425 QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) 1470 1471 /*! 1472 Helper function for alphaMapForGlyph and alphaRGBMapForGlyph. The two are identical, except for 1473 the subpixel antialiasing... 1474 */ 1475 QImage QFontEngineMac::imageForGlyph(glyph_t glyph, int margin, bool colorful) 1426 1476 { 1427 1477 const glyph_metrics_t br = boundingBox(glyph); 1428 1478 QImage im(qRound(br.width)+2, qRound(br.height)+4, QImage::Format_RGB32); 1429 im.fill(0 );1479 im.fill(0xff000000); 1430 1480 1431 1481 CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); 1432 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)1433 1482 uint cgflags = kCGImageAlphaNoneSkipFirst; 1434 1483 #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version 1435 if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) 1436 cgflags |= kCGBitmapByteOrder32Host; 1437 #endif 1438 #else 1439 CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst; 1484 cgflags |= kCGBitmapByteOrder32Host; 1440 1485 #endif 1441 1486 CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), … … 1445 1490 CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias)); 1446 1491 // turn off sub-pixel hinting - no support for that in OpenGL 1447 CGContextSetShouldSmoothFonts(ctx, false);1492 CGContextSetShouldSmoothFonts(ctx, colorful); 1448 1493 CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); 1449 1494 CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); … … 1476 1521 1477 1522 CGContextRelease(ctx); 1523 1524 return im; 1525 } 1526 1527 QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) 1528 { 1529 QImage im = imageForGlyph(glyph, 2, false); 1478 1530 1479 1531 QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); … … 1496 1548 } 1497 1549 1550 QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t) 1551 { 1552 QImage im = imageForGlyph(glyph, margin, true); 1553 1554 if (t.type() >= QTransform::TxScale) { 1555 im = im.transformed(t); 1556 } 1557 1558 qmacfontengine_gamma_correct(&im); 1559 1560 return im; 1561 } 1562 1563 1498 1564 bool QFontEngineMac::canRender(const QChar *string, int len) 1499 1565 { … … 1564 1630 FaceId ret; 1565 1631 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) 1632 if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { 1566 1633 // CTFontGetPlatformFont 1567 1634 FSRef ref; … … 1571 1638 ret.index = fontID; 1572 1639 FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size()); 1573 #else 1640 }else 1641 #endif 1642 { 1574 1643 FSSpec spec; 1575 1644 if (ATSFontGetFileSpecification(FMGetATSFontRefFromFont(fontID), &spec) != noErr) … … 1581 1650 ret.index = fontID; 1582 1651 FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size()); 1583 #endif 1652 } 1584 1653 return ret; 1585 1654 } … … 1649 1718 lw = qFromBigEndian<quint16>(lw); 1650 1719 props.lineWidth = lw; 1651 1720 1652 1721 // CTFontCopyPostScriptName 1653 1722 QCFString psName; … … 1664 1733 1665 1734 int emSquare = properties().emSquare.toInt(); 1666 1735 1667 1736 const int maxAttributeCount = 4; 1668 1737 ATSUAttributeTag tags[maxAttributeCount + 1]; … … 1676 1745 values[attributeCount] = &size; 1677 1746 ++attributeCount; 1678 1747 1679 1748 Q_ASSERT(attributeCount < maxAttributeCount + 1); 1680 1749 OSStatus err = ATSUSetAttributes(unscaledStyle, attributeCount, tags, sizes, values);
Note:
See TracChangeset
for help on using the changeset viewer.