X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fthird_party%2Fskia%2Fsrc%2Fports%2FSkScalerContext_win_dw.cpp;h=33ef0d55ec29a3ee7b2efbc911cc98c5441faf6d;hb=d41e52f18cc3fee3627acf2db026b2a86c2a9d18;hp=f27497be62ef7e40fdc88fede12c183624cbb227;hpb=4e9e197c26c34b7055b2c5de6d4a770d317b468c;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/third_party/skia/src/ports/SkScalerContext_win_dw.cpp b/src/third_party/skia/src/ports/SkScalerContext_win_dw.cpp index f27497b..33ef0d5 100644 --- a/src/third_party/skia/src/ports/SkScalerContext_win_dw.cpp +++ b/src/third_party/skia/src/ports/SkScalerContext_win_dw.cpp @@ -398,11 +398,11 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) { glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY); } -void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { - glyph->fWidth = 0; - - this->generateAdvance(glyph); - +HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph, + DWRITE_RENDERING_MODE renderingMode, + DWRITE_TEXTURE_TYPE textureType, + RECT* bbox) +{ //Measure raster size. fXform.dx = SkFixedToFloat(glyph->getSubXFixed()); fXform.dy = SkFixedToFloat(glyph->getSubYFixed()); @@ -426,25 +426,70 @@ void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { run.glyphOffsets = &offset; SkTScopedComPtr glyphRunAnalysis; - HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis( - &run, - 1.0f, // pixelsPerDip, - &fXform, - fRenderingMode, - fMeasuringMode, - 0.0f, // baselineOriginX, - 0.0f, // baselineOriginY, - &glyphRunAnalysis), - "Could not create glyph run analysis."); - - RECT bbox; - HRVM(glyphRunAnalysis->GetAlphaTextureBounds(fTextureType, &bbox), - "Could not get texture bounds."); + HRM(fTypeface->fFactory->CreateGlyphRunAnalysis( + &run, + 1.0f, // pixelsPerDip, + &fXform, + renderingMode, + fMeasuringMode, + 0.0f, // baselineOriginX, + 0.0f, // baselineOriginY, + &glyphRunAnalysis), + "Could not create glyph run analysis."); + + HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox), + "Could not get texture bounds."); + + return S_OK; +} +/** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like + * { 0x80000000, 0x80000000, 0x80000000, 0x80000000 } + * for small, but not quite zero, sized glyphs. + * Only set as non-empty if the returned bounds are non-empty. + */ +static bool glyph_check_and_set_bounds(SkGlyph* glyph, const RECT& bbox) { + if (bbox.left >= bbox.right || bbox.top >= bbox.bottom) { + return false; + } glyph->fWidth = SkToU16(bbox.right - bbox.left); glyph->fHeight = SkToU16(bbox.bottom - bbox.top); glyph->fLeft = SkToS16(bbox.left); glyph->fTop = SkToS16(bbox.top); + return true; +} + +void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { + glyph->fWidth = 0; + glyph->fHeight = 0; + glyph->fLeft = 0; + glyph->fTop = 0; + + this->generateAdvance(glyph); + + RECT bbox; + HRVM(this->getBoundingBox(glyph, fRenderingMode, fTextureType, &bbox), + "Requested bounding box could not be determined."); + + if (glyph_check_and_set_bounds(glyph, bbox)) { + return; + } + + // GetAlphaTextureBounds succeeds but returns an empty RECT if there are no + // glyphs of the specified texture type. When this happens, try with the + // alternate texture type. + if (DWRITE_TEXTURE_CLEARTYPE_3x1 == fTextureType) { + HRVM(this->getBoundingBox(glyph, + DWRITE_RENDERING_MODE_ALIASED, + DWRITE_TEXTURE_ALIASED_1x1, + &bbox), + "Fallback bounding box could not be determined."); + if (glyph_check_and_set_bounds(glyph, bbox)) { + glyph->fForceBW = 1; + } + } + // TODO: handle the case where a request for DWRITE_TEXTURE_ALIASED_1x1 + // fails, and try DWRITE_TEXTURE_CLEARTYPE_3x1. } void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) { @@ -602,9 +647,12 @@ static void rgb_to_lcd32(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, } } -const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) { +const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph, + DWRITE_RENDERING_MODE renderingMode, + DWRITE_TEXTURE_TYPE textureType) +{ int sizeNeeded = glyph.fWidth * glyph.fHeight; - if (DWRITE_RENDERING_MODE_ALIASED != fRenderingMode) { + if (DWRITE_RENDERING_MODE_ALIASED != renderingMode) { sizeNeeded *= 3; } if (sizeNeeded > fBits.count()) { @@ -639,7 +687,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) { HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, 1.0f, // pixelsPerDip, &fXform, - fRenderingMode, + renderingMode, fMeasuringMode, 0.0f, // baselineOriginX, 0.0f, // baselineOriginY, @@ -653,7 +701,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) { bbox.top = glyph.fTop; bbox.right = glyph.fLeft + glyph.fWidth; bbox.bottom = glyph.fTop + glyph.fHeight; - HRNM(glyphRunAnalysis->CreateAlphaTexture(fTextureType, + HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType, &bbox, fBits.begin(), sizeNeeded), @@ -663,7 +711,13 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) { void SkScalerContext_DW::generateImage(const SkGlyph& glyph) { //Create the mask. - const void* bits = this->drawDWMask(glyph); + DWRITE_RENDERING_MODE renderingMode = fRenderingMode; + DWRITE_TEXTURE_TYPE textureType = fTextureType; + if (glyph.fForceBW) { + renderingMode = DWRITE_RENDERING_MODE_ALIASED; + textureType = DWRITE_TEXTURE_ALIASED_1x1; + } + const void* bits = this->drawDWMask(glyph, renderingMode, textureType); if (!bits) { sk_bzero(glyph.fImage, glyph.computeImageSize()); return; @@ -671,7 +725,7 @@ void SkScalerContext_DW::generateImage(const SkGlyph& glyph) { //Copy the mask into the glyph. const uint8_t* src = (const uint8_t*)bits; - if (DWRITE_RENDERING_MODE_ALIASED == fRenderingMode) { + if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) { bilevel_to_bw(src, glyph); const_cast(glyph).fMaskFormat = SkMask::kBW_Format; } else if (!isLCD(fRec)) {