src/gui/text/qfontengine_mac.mm
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
    51 #include <qpixmap.h>
    51 #include <qpixmap.h>
    52 #include <qpixmapcache.h>
    52 #include <qpixmapcache.h>
    53 #include <qvarlengtharray.h>
    53 #include <qvarlengtharray.h>
    54 #include <qdebug.h>
    54 #include <qdebug.h>
    55 #include <qendian.h>
    55 #include <qendian.h>
       
    56 #include <qmath.h>
    56 
    57 
    57 #include <ApplicationServices/ApplicationServices.h>
    58 #include <ApplicationServices/ApplicationServices.h>
    58 #include <AppKit/AppKit.h>
    59 #include <AppKit/AppKit.h>
    59 
    60 
    60 QT_BEGIN_NAMESPACE
    61 QT_BEGIN_NAMESPACE
   159     }
   160     }
   160 
   161 
   161     QCFString name;
   162     QCFString name;
   162     ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
   163     ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
   163 
   164 
       
   165     transform = CGAffineTransformIdentity;
       
   166     if (fontDef.stretch != 100) {
       
   167         transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
       
   168     }
       
   169 
   164     QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
   170     QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
   165     QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0);
   171     QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform);
   166     ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits);
   172     ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits);
   167 
   173 
   168     // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does
   174     // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does
   169     // not exist for the given font. (for example italic)
   175     // not exist for the given font. (for example italic)
   170     if (ctfont == 0) {
   176     if (ctfont == 0) {
   171         ctfont = baseFont;
   177         ctfont = baseFont;
   223     HB_GlyphAttributes *outAttributes = glyphs->attributes;
   229     HB_GlyphAttributes *outAttributes = glyphs->attributes;
   224     QFixed *outAdvances_x = glyphs->advances_x;
   230     QFixed *outAdvances_x = glyphs->advances_x;
   225     QFixed *outAdvances_y = glyphs->advances_y;
   231     QFixed *outAdvances_y = glyphs->advances_y;
   226     glyph_t *initialGlyph = outGlyphs;
   232     glyph_t *initialGlyph = outGlyphs;
   227 
   233 
   228     if (arraySize == 0)
   234     if (arraySize == 0) {
   229         return false;
   235         // CoreText failed to shape the text we gave it, so we assume one glyph
       
   236         // per character and build a list of invalid glyphs with zero advance
       
   237         *nglyphs = len;
       
   238         for (int i = 0; i < len; ++i) {
       
   239             outGlyphs[i] = 0;
       
   240             logClusters[i] = i;
       
   241             outAdvances_x[i] = QFixed();
       
   242             outAdvances_y[i] = QFixed();
       
   243             outAttributes[i].clusterStart = true;
       
   244         }
       
   245         return true;
       
   246     }
   230 
   247 
   231     const bool rtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft);
   248     const bool rtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft);
   232 
   249 
   233     bool outOBounds = false;
   250     bool outOBounds = false;
   234     for (uint i = 0; i < arraySize; ++i) {
   251     for (uint i = 0; i < arraySize; ++i) {
   301             for (CFIndex i = 0; i < glyphCount - 1; ++i) {
   318             for (CFIndex i = 0; i < glyphCount - 1; ++i) {
   302                 int idx = rtlOffset + rtlSign * i;
   319                 int idx = rtlOffset + rtlSign * i;
   303                 outGlyphs[idx] = tmpGlyphs[i] | fontIndex;
   320                 outGlyphs[idx] = tmpGlyphs[i] | fontIndex;
   304                 outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x);
   321                 outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x);
   305                 outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y);
   322                 outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y);
       
   323                 
       
   324                 if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
       
   325                     outAdvances_x[idx] = outAdvances_x[idx].round();
       
   326                     outAdvances_y[idx] = outAdvances_y[idx].round();
       
   327                 }
   306             }
   328             }
   307             CGSize lastGlyphAdvance;
   329             CGSize lastGlyphAdvance;
   308             CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1);
   330             CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1);
   309 
   331 
   310             outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex;
   332             outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex;
   311             outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width).ceil();
   333             outAdvances_x[rtl ? 0 : (glyphCount - 1)] =
       
   334                     (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
   335                     ? QFixed::fromReal(lastGlyphAdvance.width).round()
       
   336                     : QFixed::fromReal(lastGlyphAdvance.width);
   312         }
   337         }
   313         outGlyphs += glyphCount;
   338         outGlyphs += glyphCount;
   314         outAttributes += glyphCount;
   339         outAttributes += glyphCount;
   315         outAdvances_x += glyphCount;
   340         outAdvances_x += glyphCount;
   316         outAdvances_y += glyphCount;
   341         outAdvances_y += glyphCount;
   356     }
   381     }
   357 
   382 
   358     if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) {
   383     if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) {
   359         synthesisFlags |= SynthesizedItalic;
   384         synthesisFlags |= SynthesizedItalic;
   360     }
   385     }
   361 
   386     transform = CGAffineTransformIdentity;
       
   387     if (fontDef.stretch != 100) {
       
   388         transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
       
   389     }
   362     QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
   390     QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
   363     if (os2Table.size() >= 10)
   391     if (os2Table.size() >= 10)
   364         fsType = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 8));
   392         fsType = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 8));
   365 }
   393 }
   366 
   394 
   376 }
   404 }
   377 
   405 
   378 glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
   406 glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
   379 {
   407 {
   380     QFixed w;
   408     QFixed w;
   381     for (int i = 0; i < glyphs.numGlyphs; ++i)
   409     for (int i = 0; i < glyphs.numGlyphs; ++i) {
   382         w += glyphs.effectiveAdvance(i);
   410         w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
   411              ? glyphs.effectiveAdvance(i).round()
       
   412              : glyphs.effectiveAdvance(i);
       
   413     }
   383     return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
   414     return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
   384 }
   415 }
   385 glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
   416 glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
   386 {
   417 {
   387     glyph_metrics_t ret;
   418     glyph_metrics_t ret;
   391     ret.height = QFixed::fromReal(rect.size.height);
   422     ret.height = QFixed::fromReal(rect.size.height);
   392     ret.x = QFixed::fromReal(rect.origin.x);
   423     ret.x = QFixed::fromReal(rect.origin.x);
   393     ret.y = -QFixed::fromReal(rect.origin.y) - ret.height;
   424     ret.y = -QFixed::fromReal(rect.origin.y) - ret.height;
   394     CGSize advances[1];
   425     CGSize advances[1];
   395     CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1);
   426     CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1);
   396     ret.xoff = QFixed::fromReal(advances[0].width).ceil();
   427     ret.xoff = QFixed::fromReal(advances[0].width);
   397     ret.yoff = QFixed::fromReal(advances[0].height).ceil();
   428     ret.yoff = QFixed::fromReal(advances[0].height);
       
   429 
       
   430     if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
       
   431         ret.xoff = ret.xoff.round();
       
   432         ret.yoff = ret.yoff.round();
       
   433     }
       
   434 
   398     return ret;
   435     return ret;
   399 }
   436 }
   400 
   437 
   401 QFixed QCoreTextFontEngine::ascent() const
   438 QFixed QCoreTextFontEngine::ascent() const
   402 {
   439 {
   403     return QFixed::fromReal(CTFontGetAscent(ctfont)).ceil();
   440     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
   441             ? QFixed::fromReal(CTFontGetAscent(ctfont)).round()
       
   442             : QFixed::fromReal(CTFontGetAscent(ctfont));
   404 }
   443 }
   405 QFixed QCoreTextFontEngine::descent() const
   444 QFixed QCoreTextFontEngine::descent() const
   406 {
   445 {
       
   446     QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont));
       
   447     if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
   448         d = d.round();
       
   449 
   407     // subtract a pixel to even out the historical +1 in QFontMetrics::height().
   450     // subtract a pixel to even out the historical +1 in QFontMetrics::height().
   408     // Fix in Qt 5.
   451     // Fix in Qt 5.
   409     return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1;
   452     return d - 1;
   410 }
   453 }
   411 QFixed QCoreTextFontEngine::leading() const
   454 QFixed QCoreTextFontEngine::leading() const
   412 {
   455 {
   413     return QFixed::fromReal(CTFontGetLeading(ctfont)).ceil();
   456     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
   457             ? QFixed::fromReal(CTFontGetLeading(ctfont)).round()
       
   458             : QFixed::fromReal(CTFontGetLeading(ctfont));
   414 }
   459 }
   415 QFixed QCoreTextFontEngine::xHeight() const
   460 QFixed QCoreTextFontEngine::xHeight() const
   416 {
   461 {
   417     return QFixed::fromReal(CTFontGetXHeight(ctfont)).ceil();
   462     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
   463             ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round()
       
   464             : QFixed::fromReal(CTFontGetXHeight(ctfont));
   418 }
   465 }
   419 QFixed QCoreTextFontEngine::averageCharWidth() const
   466 QFixed QCoreTextFontEngine::averageCharWidth() const
   420 {
   467 {
   421     // ### Need to implement properly and get the information from the OS/2 Table.
   468     // ### Need to implement properly and get the information from the OS/2 Table.
   422     return QFontEngine::averageCharWidth();
   469     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
   470             ? QFontEngine::averageCharWidth().round()
       
   471             : QFontEngine::averageCharWidth();
   423 }
   472 }
   424 
   473 
   425 qreal QCoreTextFontEngine::maxCharWidth() const
   474 qreal QCoreTextFontEngine::maxCharWidth() const
   426 {
   475 {
   427     // ### Max Help!
   476     // ### Max Help!
   460     CGAffineTransformConcat(cgMatrix, oldTextMatrix);
   509     CGAffineTransformConcat(cgMatrix, oldTextMatrix);
   461 
   510 
   462     if (synthesisFlags & QFontEngine::SynthesizedItalic)
   511     if (synthesisFlags & QFontEngine::SynthesizedItalic)
   463         cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
   512         cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
   464 
   513 
   465 // ###    cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
   514     cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
   466 
   515 
   467     CGContextSetTextMatrix(ctx, cgMatrix);
   516     CGContextSetTextMatrix(ctx, cgMatrix);
   468 
   517 
   469     CGContextSetTextDrawingMode(ctx, kCGTextFill);
   518     CGContextSetTextDrawingMode(ctx, kCGTextFill);
   470 
   519 
   583     CGAffineTransformConcat(cgMatrix, oldTextMatrix);
   632     CGAffineTransformConcat(cgMatrix, oldTextMatrix);
   584 
   633 
   585     if (synthesisFlags & QFontEngine::SynthesizedItalic)
   634     if (synthesisFlags & QFontEngine::SynthesizedItalic)
   586         cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
   635         cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
   587 
   636 
   588 // ###    cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
   637     cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
   589 
   638 
   590     CGContextSetTextMatrix(ctx, cgMatrix);
   639     CGContextSetTextMatrix(ctx, cgMatrix);
   591     CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
   640     CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
   592     CGContextSetTextDrawingMode(ctx, kCGTextFill);
   641     CGContextSetTextDrawingMode(ctx, kCGTextFill);
   593 
   642 
   785     int *numGlyphs;
   834     int *numGlyphs;
   786     bool callbackCalled;
   835     bool callbackCalled;
   787     int *mappedFonts;
   836     int *mappedFonts;
   788     QTextEngine::ShaperFlags flags;
   837     QTextEngine::ShaperFlags flags;
   789     QFontEngineMacMulti::ShaperItem *shaperItem;
   838     QFontEngineMacMulti::ShaperItem *shaperItem;
       
   839     unsigned int styleStrategy;
   790 };
   840 };
   791 
   841 
   792 static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATSULineRef lineRef, URefCon refCon,
   842 static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATSULineRef lineRef, URefCon refCon,
   793                                  void *operationExtraParameter, ATSULayoutOperationCallbackStatus *callbackStatus)
   843                                  void *operationExtraParameter, ATSULayoutOperationCallbackStatus *callbackStatus)
   794 {
   844 {
   853 
   903 
   854         ATSGlyphRef glyphId = layoutData[glyphIdx].glyphID;
   904         ATSGlyphRef glyphId = layoutData[glyphIdx].glyphID;
   855 
   905 
   856         QFixed yAdvance = FixedToQFixed(baselineDeltas[glyphIdx]);
   906         QFixed yAdvance = FixedToQFixed(baselineDeltas[glyphIdx]);
   857         QFixed xAdvance = FixedToQFixed(layoutData[glyphIdx + 1].realPos - layoutData[glyphIdx].realPos);
   907         QFixed xAdvance = FixedToQFixed(layoutData[glyphIdx + 1].realPos - layoutData[glyphIdx].realPos);
       
   908 
       
   909         if (nfo->styleStrategy & QFont::ForceIntegerMetrics) {
       
   910             yAdvance = yAdvance.round();
       
   911             xAdvance = xAdvance.round();
       
   912         }
   858 
   913 
   859         if (glyphId != 0xffff || i == 0) {
   914         if (glyphId != 0xffff || i == 0) {
   860             if (i < nfo->glyphs->numGlyphs)
   915             if (i < nfo->glyphs->numGlyphs)
   861             {
   916             {
   862                 nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
   917                 nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
  1030     nfo.glyphs = glyphs;
  1085     nfo.glyphs = glyphs;
  1031     nfo.numGlyphs = nglyphs;
  1086     nfo.numGlyphs = nglyphs;
  1032     nfo.callbackCalled = false;
  1087     nfo.callbackCalled = false;
  1033     nfo.flags = flags;
  1088     nfo.flags = flags;
  1034     nfo.shaperItem = shaperItem;
  1089     nfo.shaperItem = shaperItem;
       
  1090     nfo.styleStrategy = fontDef.styleStrategy;
  1035 
  1091 
  1036     int prevNumGlyphs = *nglyphs;
  1092     int prevNumGlyphs = *nglyphs;
  1037 
  1093 
  1038     QVarLengthArray<int> mappedFonts(len);
  1094     QVarLengthArray<int> mappedFonts(len);
  1039     for (int i = 0; i < len; ++i)
  1095     for (int i = 0; i < len; ++i)
  1058         ATSLineLayoutOptions layopts = kATSLineHasNoOpticalAlignment
  1114         ATSLineLayoutOptions layopts = kATSLineHasNoOpticalAlignment
  1059                                        | kATSLineIgnoreFontLeading
  1115                                        | kATSLineIgnoreFontLeading
  1060                                        | kATSLineNoSpecialJustification // we do kashidas ourselves
  1116                                        | kATSLineNoSpecialJustification // we do kashidas ourselves
  1061                                        | kATSLineDisableAllJustification
  1117                                        | kATSLineDisableAllJustification
  1062                                        ;
  1118                                        ;
  1063 
       
  1064 	layopts |= kATSLineUseDeviceMetrics;
       
  1065 
  1119 
  1066         if (fontDef.styleStrategy & QFont::NoAntialias)
  1120         if (fontDef.styleStrategy & QFont::NoAntialias)
  1067             layopts |= kATSLineNoAntiAliasing;
  1121             layopts |= kATSLineNoAntiAliasing;
  1068 
  1122 
  1069         if (!kerning)
  1123         if (!kerning)
  1364                               metrics.data());
  1418                               metrics.data());
  1365 
  1419 
  1366     for (int i = 0; i < glyphs->numGlyphs; ++i) {
  1420     for (int i = 0; i < glyphs->numGlyphs; ++i) {
  1367         glyphs->advances_x[i] = QFixed::fromReal(metrics[i].deviceAdvance.x);
  1421         glyphs->advances_x[i] = QFixed::fromReal(metrics[i].deviceAdvance.x);
  1368         glyphs->advances_y[i] = QFixed::fromReal(metrics[i].deviceAdvance.y);
  1422         glyphs->advances_y[i] = QFixed::fromReal(metrics[i].deviceAdvance.y);
       
  1423 
       
  1424         if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
       
  1425             glyphs->advances_x[i] = glyphs->advances_x[i].round();
       
  1426             glyphs->advances_y[i] = glyphs->advances_y[i].round();
       
  1427         }
  1369     }
  1428     }
  1370 }
  1429 }
  1371 
  1430 
  1372 glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs)
  1431 glyph_metrics_t QFontEngineMac::boundingBox(const QGlyphLayout &glyphs)
  1373 {
  1432 {
  1374     QFixed w;
  1433     QFixed w;
  1375     for (int i = 0; i < glyphs.numGlyphs; ++i)
  1434     for (int i = 0; i < glyphs.numGlyphs; ++i) {
  1376         w += glyphs.effectiveAdvance(i);
  1435         w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
  1436              ? glyphs.effectiveAdvance(i).round()
       
  1437              : glyphs.effectiveAdvance(i);
       
  1438     }
  1377     return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
  1439     return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0);
  1378 }
  1440 }
  1379 
  1441 
  1380 glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph)
  1442 glyph_metrics_t QFontEngineMac::boundingBox(glyph_t glyph)
  1381 {
  1443 {
  1396     gm.x = QFixed::fromReal(metrics.topLeft.x);
  1458     gm.x = QFixed::fromReal(metrics.topLeft.x);
  1397     gm.y = -QFixed::fromReal(metrics.topLeft.y);
  1459     gm.y = -QFixed::fromReal(metrics.topLeft.y);
  1398     gm.xoff = QFixed::fromReal(metrics.deviceAdvance.x);
  1460     gm.xoff = QFixed::fromReal(metrics.deviceAdvance.x);
  1399     gm.yoff = QFixed::fromReal(metrics.deviceAdvance.y);
  1461     gm.yoff = QFixed::fromReal(metrics.deviceAdvance.y);
  1400 
  1462 
       
  1463     if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
       
  1464         gm.x = gm.x.floor();
       
  1465         gm.y = gm.y.floor();
       
  1466         gm.xoff = gm.xoff.round();
       
  1467         gm.yoff = gm.yoff.round();
       
  1468     }
       
  1469 
  1401     return gm;
  1470     return gm;
  1402 }
  1471 }
  1403 
  1472 
  1404 QFixed QFontEngineMac::ascent() const
  1473 QFixed QFontEngineMac::ascent() const
  1405 {
  1474 {
  1406     return m_ascent;
  1475     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
  1476             ? m_ascent.round()
       
  1477             : m_ascent;
  1407 }
  1478 }
  1408 
  1479 
  1409 QFixed QFontEngineMac::descent() const
  1480 QFixed QFontEngineMac::descent() const
  1410 {
  1481 {
  1411     // subtract a pixel to even out the historical +1 in QFontMetrics::height().
  1482     // subtract a pixel to even out the historical +1 in QFontMetrics::height().
  1412     // Fix in Qt 5.
  1483     // Fix in Qt 5.
  1413     return m_descent - 1;
  1484     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
  1485             ? m_descent.round() - 1
       
  1486             : m_descent;
  1414 }
  1487 }
  1415 
  1488 
  1416 QFixed QFontEngineMac::leading() const
  1489 QFixed QFontEngineMac::leading() const
  1417 {
  1490 {
  1418     return m_leading;
  1491     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
  1492             ? m_leading.round()
       
  1493             : m_leading;
  1419 }
  1494 }
  1420 
  1495 
  1421 qreal QFontEngineMac::maxCharWidth() const
  1496 qreal QFontEngineMac::maxCharWidth() const
  1422 {
  1497 {
  1423     return m_maxCharWidth;
  1498     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
  1499             ? qRound(m_maxCharWidth)
       
  1500             : m_maxCharWidth;
  1424 }
  1501 }
  1425 
  1502 
  1426 QFixed QFontEngineMac::xHeight() const
  1503 QFixed QFontEngineMac::xHeight() const
  1427 {
  1504 {
  1428     return m_xHeight;
  1505     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
  1506             ? m_xHeight.round()
       
  1507             : m_xHeight;
  1429 }
  1508 }
  1430 
  1509 
  1431 QFixed QFontEngineMac::averageCharWidth() const
  1510 QFixed QFontEngineMac::averageCharWidth() const
  1432 {
  1511 {
  1433     return m_averageCharWidth;
  1512     return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
       
  1513             ? m_averageCharWidth.round()
       
  1514             : m_averageCharWidth;
  1434 }
  1515 }
  1435 
  1516 
  1436 static void addGlyphsToPathHelper(ATSUStyle style, glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path)
  1517 static void addGlyphsToPathHelper(ATSUStyle style, glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path)
  1437 {
  1518 {
  1438     if (!numGlyphs)
  1519     if (!numGlyphs)