| Index: src/ports/SkScalerContext_win_dw.cpp
|
| diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp
|
| index 99799a554a2ffe2c26eb41196373119a8ac8a6c8..345cefd75847548fca3fa3e983703afe916437c3 100644
|
| --- a/src/ports/SkScalerContext_win_dw.cpp
|
| +++ b/src/ports/SkScalerContext_win_dw.cpp
|
| @@ -18,6 +18,7 @@
|
| #include "SkOTTable_EBLC.h"
|
| #include "SkOTTable_EBSC.h"
|
| #include "SkOTTable_gasp.h"
|
| +#include "SkOTTable_maxp.h"
|
| #include "SkPath.h"
|
| #include "SkScalerContext.h"
|
| #include "SkScalerContext_win_dw.h"
|
| @@ -31,6 +32,27 @@ static bool isLCD(const SkScalerContext::Rec& rec) {
|
| SkMask::kLCD32_Format == rec.fMaskFormat;
|
| }
|
|
|
| +static bool is_hinted_without_gasp(DWriteFontTypeface* typeface) {
|
| + AutoTDWriteTable<SkOTTableMaximumProfile> maxp(typeface->fDWriteFontFace.get());
|
| + if (!maxp.fExists) {
|
| + return false;
|
| + }
|
| + if (maxp.fSize < sizeof(SkOTTableMaximumProfile::Version::TT)) {
|
| + return false;
|
| + }
|
| + if (maxp->version.version != SkOTTableMaximumProfile::Version::TT::VERSION) {
|
| + return false;
|
| + }
|
| +
|
| + if (0 == maxp->version.tt.maxSizeOfInstructions) {
|
| + // No hints.
|
| + return false;
|
| + }
|
| +
|
| + AutoTDWriteTable<SkOTTableGridAndScanProcedure> gasp(typeface->fDWriteFontFace.get());
|
| + return !gasp.fExists;
|
| +}
|
| +
|
| /** A PPEMRange is inclusive, [min, max]. */
|
| struct PPEMRange {
|
| int min;
|
| @@ -254,6 +276,17 @@ SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
|
| fTextSizeMeasure = gdiTextSize;
|
| fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
|
|
|
| + // Fonts that have hints but no gasp table get non-symmetric rendering.
|
| + // Usually such fonts have low quality hints which were never tested
|
| + // with anything but GDI ClearType classic. Such fonts often rely on
|
| + // drop out control in the y direction in order to be legible.
|
| + } else if (is_hinted_without_gasp(typeface)) {
|
| + fTextSizeRender = gdiTextSize;
|
| + fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
|
| + fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
|
| + fTextSizeMeasure = realTextSize;
|
| + fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
|
| +
|
| // The normal case is to use natural symmetric rendering and linear metrics.
|
| } else {
|
| fTextSizeRender = realTextSize;
|
| @@ -354,6 +387,9 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
|
| if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
|
| DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
|
| {
|
| + // DirectWrite produced 'compatible' metrics, but while close,
|
| + // the end result is not always an integer as it would be with GDI.
|
| + vecs[0].fX = SkScalarRoundToScalar(advanceX);
|
| fG_inv.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
|
| } else {
|
| fSkXform.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
|
|
|