aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports/SkFontHost_mac.cpp
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2017-02-15 17:49:12 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-16 00:23:39 +0000
commit4ec46aa17183ffdb18bbd8ace1e1634bbdc036ba (patch)
tree052bd12100c1dbd89e095d3d7a6ea11fa5a71f81 /src/ports/SkFontHost_mac.cpp
parent25834ffc5a4f6c45830dded7d5d135df157870e6 (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.cpp42
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) {