diff options
author | bungeman <bungeman@google.com> | 2017-02-15 17:49:12 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-16 00:23:39 +0000 |
commit | 4ec46aa17183ffdb18bbd8ace1e1634bbdc036ba (patch) | |
tree | 052bd12100c1dbd89e095d3d7a6ea11fa5a71f81 /src/ports/SkFontHost_mac.cpp | |
parent | 25834ffc5a4f6c45830dded7d5d135df157870e6 (diff) |
Work around Mac x- and cap-height calculation.
With at least some system fonts and apparently all fonts from data the
x-height and cap-height on at least 10.12.3 are always 0.6666 and .8888
of the ascent, respectively. The values from the 'OS/2' table appear
to be read, but then the values are overwritten. Work around this by
using the values from the 'OS/2' table when available.
This also removes fFUnitMatrix as it is no longer used.
BUG=skia:6203
Change-Id: Ib79d9d32bca77797de043499c854c35e5ef3aa4b
Reviewed-on: https://skia-review.googlesource.com/8452
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Diffstat (limited to 'src/ports/SkFontHost_mac.cpp')
-rw-r--r-- | src/ports/SkFontHost_mac.cpp | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index d4072255b0..7a46d40ec6 100644 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -33,6 +33,7 @@ #include "SkMaskGamma.h" #include "SkMathPriv.h" #include "SkMutex.h" +#include "SkOTTable_OS_2.h" #include "SkOTUtils.h" #include "SkOnce.h" #include "SkPaint.h" @@ -688,14 +689,6 @@ private: /** Returns the offset from the horizontal origin to the vertical origin in SkGlyph units. */ void getVerticalOffset(CGGlyph glyphID, SkPoint* offset) const; - - /** Converts from FUnits (em space, y up) to SkGlyph units (pixels, y down). - * - * Used on Snow Leopard to correct CTFontGetVerticalTranslationsForGlyphs. - * Used on Lion to correct CTFontGetBoundingRectsForGlyphs. - */ - SkMatrix fFUnitMatrix; - Offscreen fOffscreen; /** Unrotated variant of fCTFont. @@ -774,7 +767,7 @@ SkScalerContext_Mac::SkScalerContext_Mac(sk_sp<SkTypeface_Mac> typeface, SkVector scale; SkMatrix skTransform; bool invertible = fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, - &scale, &skTransform, nullptr, nullptr, &fFUnitMatrix); + &scale, &skTransform, nullptr, nullptr, nullptr); fTransform = MatrixToCGAffineTransform(skTransform); // CGAffineTransformInvert documents that if the transform is non-invertible it will return the // passed transform unchanged. It does so, but then also prints a message to stdout. Avoid this. @@ -789,10 +782,6 @@ SkScalerContext_Mac::SkScalerContext_Mac(sk_sp<SkTypeface_Mac> typeface, CGFloat textSize = ScalarToCG(scale.y()); fCTFont = ctfont_create_exact_copy(ctFont, textSize, nullptr); fCGFont.reset(CTFontCopyGraphicsFont(fCTFont.get(), nullptr)); - - // The fUnitMatrix includes the text size (and em) as it is used to scale the raw font data. - SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFont.get()))); - fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); } CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph, @@ -1317,6 +1306,33 @@ void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { metrics->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; metrics->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; + + // See https://bugs.chromium.org/p/skia/issues/detail?id=6203 + // At least on 10.12.3 with memory based fonts the x-height is always 0.6666 of the ascent and + // the cap-height is always 0.8888 of the ascent. It appears that the values from the 'OS/2' + // table are read, but then overwritten if the font is not a system font. As a result, if there + // is a valid 'OS/2' table available use the values from the table if they aren't too strange. + struct OS2HeightMetrics { + SK_OT_SHORT sxHeight; + SK_OT_SHORT sCapHeight; + } heights; + size_t bytesRead = this->getTypeface()->getTableData( + SkTEndian_SwapBE32(SkOTTableOS2::TAG), offsetof(SkOTTableOS2, version.v2.sxHeight), + sizeof(heights), &heights); + if (bytesRead == sizeof(heights)) { + // 'fontSize' is correct because the entire resolved size is set by the constructor. + CGFloat fontSize = CTFontGetSize(this->fCTFont.get()); + unsigned upem = CTFontGetUnitsPerEm(this->fCTFont.get()); + unsigned maxSaneHeight = upem * 2; + uint16_t xHeight = SkEndian_SwapBE16(heights.sxHeight); + if (xHeight && xHeight < maxSaneHeight) { + metrics->fXHeight = CGToScalar(xHeight * fontSize / upem); + } + uint16_t capHeight = SkEndian_SwapBE16(heights.sCapHeight); + if (capHeight && capHeight < maxSaneHeight) { + metrics->fCapHeight = CGToScalar(capHeight * fontSize / upem); + } + } } void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element) { |