Symmetric rendering when >20px with DirectWrite.
If the font has a gasp table use it to determine symmetric. Otherwise,
use symmetric if the the font isn't hinted or is >20px. The remaining
cases use non-symmetric.
BUG=chromium:706792,skia:6432
Change-Id: I91b66a9615aae27c195e1545298a9d36bc58a705
Reviewed-on: https://skia-review.googlesource.com/11400
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp
index 1dfe8e0..f8e44e2 100644
--- a/src/ports/SkScalerContext_win_dw.cpp
+++ b/src/ports/SkScalerContext_win_dw.cpp
@@ -46,7 +46,7 @@
return SkMask::kLCD16_Format == rec.fMaskFormat;
}
-static bool is_hinted_without_gasp(DWriteFontTypeface* typeface) {
+static bool is_hinted(DWriteFontTypeface* typeface) {
SkAutoExclusive l(DWriteFactoryMutex);
AutoTDWriteTable<SkOTTableMaximumProfile> maxp(typeface->fDWriteFontFace.get());
if (!maxp.fExists) {
@@ -58,14 +58,7 @@
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;
+ return (0 != maxp->version.tt.maxSizeOfInstructions);
}
/** A GaspRange is inclusive, [min, max]. */
@@ -121,14 +114,6 @@
return flags.raw.value == GaspRange::Behavior::Raw::GridfitMask;
}
-/** If the rendering mode for the specified 'size' sets SymmetricSmoothing, return true. */
-static bool gasp_allows_cleartype_symmetric(GaspRange::Behavior flags) {
-#ifdef SK_IGNORE_DIRECTWRITE_GASP_FIX
- return true;
-#endif
- return flags.field.SymmetricSmoothing;
-}
-
static bool has_bitmap_strike(DWriteFontTypeface* typeface, GaspRange range) {
SkAutoExclusive l(DWriteFactoryMutex);
{
@@ -280,6 +265,8 @@
axisAlignedBitmap = is_axis_aligned(fRec);
}
+ GaspRange range(0, 0xFFFF, GaspRange::Behavior());
+
// If the user requested aliased, do so with aliased compatible metrics.
if (SkMask::kBW_Format == fRec.fMaskFormat) {
fTextSizeRender = gdiTextSize;
@@ -306,25 +293,37 @@
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_NATURAL;
+ // If the font has a gasp table, use it to determine symmetric rendering.
+ } else if (get_gasp_range(typeface, SkScalarRoundToInt(gdiTextSize), &range)) {
+ fTextSizeRender = realTextSize;
+ fRenderingMode = range.fFlags.field.SymmetricSmoothing
+ ? DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
+ : DWRITE_RENDERING_MODE_NATURAL;
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
fTextSizeMeasure = realTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
- // The normal case is to use natural symmetric rendering (if permitted) and linear metrics.
- } else {
+ // If the requested size is above 20px or there are no bytecode hints, use symmetric rendering.
+ } else if (realTextSize > SkIntToScalar(20) || !is_hinted(typeface)) {
fTextSizeRender = realTextSize;
- GaspRange range(0, 0xFFFF, GaspRange::Behavior());
- get_gasp_range(typeface, SkScalarRoundToInt(gdiTextSize), &range);
- fRenderingMode = gasp_allows_cleartype_symmetric(range.fFlags)
- ? DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
- : DWRITE_RENDERING_MODE_NATURAL;
+ fRenderingMode = DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
+ fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
+ fTextSizeMeasure = realTextSize;
+ fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
+
+ // Fonts that have hints, no gasp table, and below 20px get non-symmetric rendering.
+ // Often 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.
+ // Tenor Sans
+ // https://fonts.google.com/specimen/Tenor+Sans
+ // Gill Sans W04
+ // https://cdn.leagueoflegends.com/lolkit/1.1.9/resources/fonts/gill-sans-w04-book.woff
+ // https://na.leagueoflegends.com/en/news/game-updates/patch/patch-410-notes
+ // See https://crbug.com/385897
+ } else {
+ fTextSizeRender = gdiTextSize;
+ fRenderingMode = DWRITE_RENDERING_MODE_NATURAL;
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
fTextSizeMeasure = realTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;