diff options
author | 2017-02-09 13:41:45 -0500 | |
---|---|---|
committer | 2017-02-10 20:13:29 +0000 | |
commit | a67615f370c15ed0dd7a7ca95c9f73178e3e2499 (patch) | |
tree | ae8a3f66778e0560c1d0ffaa9274d8eaf41e0cf9 | |
parent | eec6f7be5461e588210f383b8af18f324a2bdb46 (diff) |
'gasp' to control symmetric rendering on Windows.
Currently Skia tries hard to use symmetric rendering with DirectWrite
as often as possible. However, particularly on Windows 7 with CJK fonts,
thin horizontal strokes can be rendered without sufficient contrast
because the font was relying on the 6x1 oversampling for what is
effecitvely drop-out control. This change will only allow symmetric
rendering if the font allows it in the 'gasp' table.
BUG=chromium:645055
Change-Id: I45a9d5e4a0b49bb969c44fb20dc92528dfe9c48d
Reviewed-on: https://skia-review.googlesource.com/8268
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Ben Wagner <bungeman@google.com>
-rw-r--r-- | src/ports/SkScalerContext_win_dw.cpp | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp index 7fe9551d6b..43accd929a 100644 --- a/src/ports/SkScalerContext_win_dw.cpp +++ b/src/ports/SkScalerContext_win_dw.cpp @@ -118,6 +118,45 @@ static void expand_range_if_gridfit_only(DWriteFontTypeface* typeface, int size, } } +/** If the rendering mode for the specified 'size' sets SymmetricSmoothing, return true. */ +static bool gasp_allows_cleartype_symmetric(DWriteFontTypeface* typeface, int size) { +#ifdef SK_IGNORE_DIRECTWRITE_GASP_FIX + return true; +#endif + AutoTDWriteTable<SkOTTableGridAndScanProcedure> gasp(typeface->fDWriteFontFace.get()); + if (!gasp.fExists) { + return false; + } + if (gasp.fSize < sizeof(SkOTTableGridAndScanProcedure)) { + return false; + } + if (gasp->version != SkOTTableGridAndScanProcedure::version0 && + gasp->version != SkOTTableGridAndScanProcedure::version1) + { + return false; + } + + uint16_t numRanges = SkEndianSwap16(gasp->numRanges); + if (numRanges > 1024 || + gasp.fSize < sizeof(SkOTTableGridAndScanProcedure) + + sizeof(SkOTTableGridAndScanProcedure::GaspRange) * numRanges) + { + return false; + } + + const SkOTTableGridAndScanProcedure::GaspRange* rangeTable = + SkTAfter<const SkOTTableGridAndScanProcedure::GaspRange>(gasp.get()); + int minPPEM = -1; + for (uint16_t i = 0; i < numRanges; ++i, ++rangeTable) { + int maxPPEM = SkEndianSwap16(rangeTable->maxPPEM); + if (minPPEM < size && size <= maxPPEM) { + return rangeTable->flags.field.SymmetricSmoothing; + } + minPPEM = maxPPEM; + } + return false; +} + static bool has_bitmap_strike(DWriteFontTypeface* typeface, PPEMRange range) { SkAutoExclusive l(DWriteFactoryMutex); { @@ -315,10 +354,12 @@ SkScalerContext_DW::SkScalerContext_DW(sk_sp<DWriteFontTypeface> typefaceRef, fTextSizeMeasure = realTextSize; fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; - // The normal case is to use natural symmetric rendering and linear metrics. + // The normal case is to use natural symmetric rendering (if permitted) and linear metrics. } else { fTextSizeRender = realTextSize; - fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; + fRenderingMode = gasp_allows_cleartype_symmetric(typeface, realTextSize) + ? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC + : DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL; fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; fTextSizeMeasure = realTextSize; fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |