Index: src/ports/SkScalerContext_win_dw.cpp |
diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp |
index 216c7dce2c25dfbbcc4f88aaa83fd2c6444c71a3..33ef0d55ec29a3ee7b2efbc911cc98c5441faf6d 100644 |
--- a/src/ports/SkScalerContext_win_dw.cpp |
+++ b/src/ports/SkScalerContext_win_dw.cpp |
@@ -398,10 +398,10 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) { |
glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY); |
} |
-void SkScalerContext_DW::getBoundingBox(SkGlyph* glyph, |
- DWRITE_RENDERING_MODE renderingMode, |
- DWRITE_TEXTURE_TYPE textureType, |
- RECT* bbox) |
+HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph, |
+ DWRITE_RENDERING_MODE renderingMode, |
+ DWRITE_TEXTURE_TYPE textureType, |
+ RECT* bbox) |
{ |
//Measure raster size. |
fXform.dx = SkFixedToFloat(glyph->getSubXFixed()); |
@@ -426,50 +426,70 @@ void SkScalerContext_DW::getBoundingBox(SkGlyph* glyph, |
run.glyphOffsets = &offset; |
SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
- HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis( |
- &run, |
- 1.0f, // pixelsPerDip, |
- &fXform, |
- renderingMode, |
- fMeasuringMode, |
- 0.0f, // baselineOriginX, |
- 0.0f, // baselineOriginY, |
- &glyphRunAnalysis), |
- "Could not create glyph run analysis."); |
+ 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; |
+} |
- HRVM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox), |
- "Could not get texture bounds."); |
+/** 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; |
- this->getBoundingBox(glyph, fRenderingMode, fTextureType, &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 (bbox.left == bbox.right || bbox.top == bbox.bottom) { |
- if (DWRITE_TEXTURE_CLEARTYPE_3x1 == fTextureType) { |
- this->getBoundingBox(glyph, |
- DWRITE_RENDERING_MODE_ALIASED, |
- DWRITE_TEXTURE_ALIASED_1x1, |
- &bbox); |
- if (bbox.left != bbox.right && bbox.top != bbox.bottom) { |
- glyph->fForceBW = 1; |
- } |
+ 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. |
} |
- |
- glyph->fWidth = SkToU16(bbox.right - bbox.left); |
- glyph->fHeight = SkToU16(bbox.bottom - bbox.top); |
- glyph->fLeft = SkToS16(bbox.left); |
- glyph->fTop = SkToS16(bbox.top); |
+ // 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) { |