Chromium Code Reviews| 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..1b33ac92439fed5784e7c4da6a1a4d2cfe1b8c0c 100644 |
| --- a/src/ports/SkScalerContext_win_dw.cpp |
| +++ b/src/ports/SkScalerContext_win_dw.cpp |
| @@ -212,11 +212,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 +322,28 @@ 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; |
| + if (fTypeface->fFactory2 && fTypeface->fDWriteFontFace2 && |
| + !isLCD(fRec) && !(fRec.fFlags & SkScalerContext::kGenA8FromLCD_Flag)) |
| + { |
| + // DWRITE_TEXTURE_ALIASED_1x1 is not misnamed, it must also be used with grayscale. |
|
bungeman-skia
2016/06/14 14:40:52
s/not/now, will fix
|
| + fTextureType = DWRITE_TEXTURE_ALIASED_1x1; |
| + fAntiAliasMode = DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE; |
| + } |
| +#endif |
| + |
| + // DirectWrite2 allows hinting to be disabled. |
| +#if SK_HAS_DWRITE_2_H |
| + fGridFitMode = DWRITE_GRID_FIT_MODE_ENABLED; |
| + if (fTypeface->fFactory2 && fTypeface->fDWriteFontFace2 && |
| + fRec.getHinting() == SkPaint::kNo_Hinting) |
| + { |
| + fGridFitMode = DWRITE_GRID_FIT_MODE_DISABLED; |
| + } |
| +#endif |
| + |
| if (this->isSubpixel()) { |
| fTextSizeMeasure = realTextSize; |
| fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
| @@ -432,16 +452,33 @@ 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 |
| + HRNM(fTypeface->fFactory2->CreateGlyphRunAnalysis( |
| + &run, |
| + &fXform, |
| + renderingMode, |
| + fMeasuringMode, |
| + fGridFitMode, |
| + fAntiAliasMode, |
| + 0.0f, // baselineOriginX, |
| + 0.0f, // baselineOriginY, |
| + &glyphRunAnalysis), |
| + "Could not create DW2 glyph run analysis."); |
| +#else |
| +# pragma message("No dwrite_2.h is available, pixel antialiased glyph quality may be affected.") |
| +#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."); |
| + } |
| } |
| { |
| Shared l(DWriteFactoryMutex); |
| @@ -498,7 +535,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; |
| @@ -656,6 +693,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 +721,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 +746,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 +755,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 +786,35 @@ 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."); |
| +#else |
| +# pragma message("No dwrite_2.h is available, pixel antialiased glyph quality may be affected.") |
| +#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 +934,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); |