aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Ben Wagner <bungeman@google.com>2017-02-09 13:41:45 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-10 20:13:29 +0000
commita67615f370c15ed0dd7a7ca95c9f73178e3e2499 (patch)
treeae8a3f66778e0560c1d0ffaa9274d8eaf41e0cf9
parenteec6f7be5461e588210f383b8af18f324a2bdb46 (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.cpp45
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;