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

Unified Diff: src/ports/SkScalerContext_win_dw.cpp

Issue 511783003: Fix error handling in DirectWrite with tiny text. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Clarify code flow, guard against backward RECTs. Created 6 years, 4 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') | no next file » | 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 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) {
« no previous file with comments | « src/ports/SkScalerContext_win_dw.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698