Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Unified Diff: src/ports/SkScalerContext_win_dw.cpp

Issue 2065833002: Support pixel antialising in DirectWrite. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Use the same grid fit mode no matter the rotation. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ports/SkScalerContext_win_dw.h ('k') | src/ports/SkTypeface_win_dw.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ports/SkScalerContext_win_dw.cpp
diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp
index c9ff5d86c35e2f8efd0eb5aec882631b0cd2fb13..5143943e22dfb0c9edfa05a8361355144394c742 100644
--- a/src/ports/SkScalerContext_win_dw.cpp
+++ b/src/ports/SkScalerContext_win_dw.cpp
@@ -34,6 +34,14 @@
#include <dwrite.h>
#if SK_HAS_DWRITE_1_H
# include <dwrite_1.h>
+#else
+# pragma message("No dwrite_1.h is available, font metrics may be affected.")
+#endif
+
+#if SK_HAS_DWRITE_2_H
+# include <dwrite_2.h>
+#else
+# pragma message("No dwrite_2.h is available, pixel antialiased glyph quality may be affected.")
#endif
/* Note:
@@ -212,11 +220,9 @@ SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
, fGlyphCount(-1) {
#if SK_HAS_DWRITE_2_H
- fTypeface->fFactory->QueryInterface<IDWriteFactory2>(&fFactory2);
-
- SkTScopedComPtr<IDWriteFontFace2> fontFace2;
- fTypeface->fDWriteFontFace->QueryInterface<IDWriteFontFace2>(&fontFace2);
- fIsColorFont = fFactory2.get() && fontFace2.get() && fontFace2->IsColorFont();
+ fIsColorFont = fTypeface->fFactory2 &&
+ fTypeface->fDWriteFontFace2 &&
+ fTypeface->fDWriteFontFace2->IsColorFont();
#endif
// In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC
@@ -324,6 +330,56 @@ SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
}
+ // DirectWrite2 allows for grayscale hinting.
+#if SK_HAS_DWRITE_2_H
+ fAntiAliasMode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE;
+#ifndef SK_IGNORE_DW_GRAY_FIX
+ if (fTypeface->fFactory2 && fTypeface->fDWriteFontFace2 &&
+ !isLCD(fRec) && !(fRec.fFlags & SkScalerContext::kGenA8FromLCD_Flag))
+ {
+ // DWRITE_TEXTURE_ALIASED_1x1 is now misnamed, it must also be used with grayscale.
+ fTextureType = DWRITE_TEXTURE_ALIASED_1x1;
+ fAntiAliasMode = DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE;
+ }
+#endif
+#endif
+
+ // DirectWrite2 allows hinting to be disabled.
+#if SK_HAS_DWRITE_2_H
+ fGridFitMode = DWRITE_GRID_FIT_MODE_ENABLED;
+ if (fRec.getHinting() == SkPaint::kNo_Hinting) {
+ fGridFitMode = DWRITE_GRID_FIT_MODE_DISABLED;
+ } else if (fTypeface->fFactory2 && fTypeface->fDWriteFontFace2) {
+ [this]() {
+ SkTScopedComPtr<IDWriteRenderingParams2> renderingParams;
+ HRVM(fTypeface->fFactory2->CreateCustomRenderingParams(
+ 1.0, // gamma
+ 0.0, // enhancedContrast
+ 0.0, // grayscaleEnhancedContrast
+ 1.0, // clearTypeLevel
+ DWRITE_PIXEL_GEOMETRY_RGB,
+ fRenderingMode,
+ DWRITE_GRID_FIT_MODE_DEFAULT,
+ &renderingParams),
+ "Could not create custom rendering params.");
+ DWRITE_RENDERING_MODE ignoredRenderingMode;
+ HRVM(fTypeface->fDWriteFontFace2->GetRecommendedRenderingMode(
+ SkScalarToFloat(fTextSizeRender),
+ 1.0f, //dpiX
+ 1.0f, //dpiY
+ nullptr, //&fXform,
+ FALSE, //isSideways
+ fRec.fMaskFormat == SkMask::kBW_Format ? DWRITE_OUTLINE_THRESHOLD_ALIASED
+ : DWRITE_OUTLINE_THRESHOLD_ANTIALIASED,
+ fMeasuringMode,
+ renderingParams.get(),
+ &ignoredRenderingMode,
+ &fGridFitMode),
+ "Could not get reccomended grid fit mode.");
+ }();
+ }
+#endif
+
if (this->isSubpixel()) {
fTextSizeMeasure = realTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
@@ -432,16 +488,31 @@ HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph,
SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
{
SkAutoExclusive l(DWriteFactoryMutex);
- HRM(fTypeface->fFactory->CreateGlyphRunAnalysis(
- &run,
- 1.0f, // pixelsPerDip,
- &fXform,
- renderingMode,
- fMeasuringMode,
- 0.0f, // baselineOriginX,
- 0.0f, // baselineOriginY,
- &glyphRunAnalysis),
- "Could not create glyph run analysis.");
+ if (fTypeface->fFactory2) {
+#if SK_HAS_DWRITE_2_H
+ HRM(fTypeface->fFactory2->CreateGlyphRunAnalysis(
+ &run,
+ &fXform,
+ renderingMode,
+ fMeasuringMode,
+ fGridFitMode,
+ fAntiAliasMode,
+ 0.0f, // baselineOriginX,
+ 0.0f, // baselineOriginY,
+ &glyphRunAnalysis),
+ "Could not create DW2 glyph run analysis.");
+#endif
+ } else {
+ HRM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run,
+ 1.0f, // pixelsPerDip,
+ &fXform,
+ renderingMode,
+ fMeasuringMode,
+ 0.0f, // baselineOriginX,
+ 0.0f, // baselineOriginY,
+ &glyphRunAnalysis),
+ "Could not create glyph run analysis.");
+ }
}
{
Shared l(DWriteFactoryMutex);
@@ -498,7 +569,7 @@ bool SkScalerContext_DW::getColorGlyphRun(const SkGlyph& glyph,
run.isSideways = FALSE;
run.glyphOffsets = &offset;
- HRESULT hr = fFactory2->TranslateColorGlyphRun(
+ HRESULT hr = fTypeface->fFactory2->TranslateColorGlyphRun(
0, 0, &run, nullptr, fMeasuringMode, &fXform, 0, colorGlyph);
if (hr == DWRITE_E_NOCOLOR) {
return false;
@@ -591,8 +662,6 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) {
metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin;
return;
}
-#else
-# pragma message("No dwrite_1.h is available, font metrics may be affected.")
#endif
AutoTDWriteTable<SkOTTableHead> head(fTypeface->fDWriteFontFace.get());
@@ -656,6 +725,22 @@ static void bilevel_to_bw(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph)
}
template<bool APPLY_PREBLEND>
+static void grayscale_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
+ const uint8_t* table8) {
+ const size_t dstRB = glyph.rowBytes();
+ const U16CPU width = glyph.fWidth;
+ uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
+
+ for (U16CPU y = 0; y < glyph.fHeight; y++) {
+ for (U16CPU i = 0; i < width; i++) {
+ U8CPU a = *(src++);
+ dst[i] = sk_apply_lut_if<APPLY_PREBLEND>(a, table8);
+ }
+ dst = SkTAddOffset<uint8_t>(dst, dstRB);
+ }
+}
+
+template<bool APPLY_PREBLEND>
static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, const uint8_t* table8) {
const size_t dstRB = glyph.rowBytes();
const U16CPU width = glyph.fWidth;
@@ -668,7 +753,7 @@ static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, cons
U8CPU b = *(src++);
dst[i] = sk_apply_lut_if<APPLY_PREBLEND>((r + g + b) / 3, table8);
}
- dst = (uint8_t*)((char*)dst + dstRB);
+ dst = SkTAddOffset<uint8_t>(dst, dstRB);
}
}
@@ -693,7 +778,7 @@ static void rgb_to_lcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
}
dst[i] = SkPack888ToRGB16(r, g, b);
}
- dst = (uint16_t*)((char*)dst + dstRB);
+ dst = SkTAddOffset<uint16_t>(dst, dstRB);
}
}
@@ -702,7 +787,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
DWRITE_TEXTURE_TYPE textureType)
{
int sizeNeeded = glyph.fWidth * glyph.fHeight;
- if (DWRITE_RENDERING_MODE_ALIASED != renderingMode) {
+ if (DWRITE_TEXTURE_CLEARTYPE_3x1 == textureType) {
sizeNeeded *= 3;
}
if (sizeNeeded > fBits.count()) {
@@ -733,19 +818,33 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
run.isSideways = FALSE;
run.glyphOffsets = &offset;
{
-
SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
{
SkAutoExclusive l(DWriteFactoryMutex);
- HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run,
- 1.0f, // pixelsPerDip,
- &fXform,
- renderingMode,
- fMeasuringMode,
- 0.0f, // baselineOriginX,
- 0.0f, // baselineOriginY,
- &glyphRunAnalysis),
- "Could not create glyph run analysis.");
+ if (fTypeface->fFactory2) {
+#if SK_HAS_DWRITE_2_H
+ HRNM(fTypeface->fFactory2->CreateGlyphRunAnalysis(&run,
+ &fXform,
+ renderingMode,
+ fMeasuringMode,
+ fGridFitMode,
+ fAntiAliasMode,
+ 0.0f, // baselineOriginX,
+ 0.0f, // baselineOriginY,
+ &glyphRunAnalysis),
+ "Could not create DW2 glyph run analysis.");
+#endif
+ } else {
+ HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run,
+ 1.0f, // pixelsPerDip,
+ &fXform,
+ renderingMode,
+ fMeasuringMode,
+ 0.0f, // baselineOriginX,
+ 0.0f, // baselineOriginY,
+ &glyphRunAnalysis),
+ "Could not create glyph run analysis.");
+ }
}
//NOTE: this assumes that the glyph has already been measured
//with an exact same glyph run analysis.
@@ -865,10 +964,18 @@ void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
bilevel_to_bw(src, glyph);
const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format;
} else if (!isLCD(fRec)) {
- if (fPreBlend.isApplicable()) {
- rgb_to_a8<true>(src, glyph, fPreBlend.fG);
+ if (textureType == DWRITE_TEXTURE_ALIASED_1x1) {
+ if (fPreBlend.isApplicable()) {
+ grayscale_to_a8<true>(src, glyph, fPreBlend.fG);
+ } else {
+ grayscale_to_a8<false>(src, glyph, fPreBlend.fG);
+ }
} else {
- rgb_to_a8<false>(src, glyph, fPreBlend.fG);
+ if (fPreBlend.isApplicable()) {
+ rgb_to_a8<true>(src, glyph, fPreBlend.fG);
+ } else {
+ rgb_to_a8<false>(src, glyph, fPreBlend.fG);
+ }
}
} else {
SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat);
« no previous file with comments | « src/ports/SkScalerContext_win_dw.h ('k') | src/ports/SkTypeface_win_dw.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698