diff options
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r-- | Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp index 2bd77ee..132d5a4 100644 --- a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp @@ -178,13 +178,49 @@ static bool setupForText(SkPaint* paint, GraphicsContext* gc, return true; } -static FloatRect drawPosText(SkCanvas* canvas, const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint) +static void approximateTextBounds(FloatRect& rect, size_t numGlyphs, + const SkPoint pos[], float lineSpacing, bool isVertical) +{ + if (!numGlyphs || !pos) { + return; + } + + // get glyph position bounds + float minX = SkScalarToFloat(pos[0].x()); + float maxX = minX; + float minY = SkScalarToFloat(pos[0].y()); + float maxY = minY; + for (size_t i = 1; i < numGlyphs; ++i) { + float x = SkScalarToFloat(pos[i].x()); + float y = SkScalarToFloat(pos[i].y()); + minX = std::min(minX, x); + maxX = std::max(maxX, x); + minY = std::min(minY, y); + maxY = std::max(maxY, y); + } + + // set final rect + rect.setX(minX); + rect.setY(minY); + rect.setWidth(maxX - minX); + rect.setHeight(maxY - minY); + if (!isVertical) { + rect.inflateX(rect.width() * 2); + rect.inflateY(2 * lineSpacing); + } else { + rect.inflateX(2 * lineSpacing); + rect.inflateY(rect.height() * 2); + } +} + +static FloatRect drawPosText(SkCanvas* canvas, const void* text, + size_t byteLength, const SkPoint pos[], const SkPaint& paint, + float lineSpacing) { - SkRect textBounds; - paint.measureText(text, byteLength, &textBounds); - textBounds.offset(pos[0].x(), pos[0].y()); canvas->drawPosText(text, byteLength, pos, paint); + FloatRect textBounds; + approximateTextBounds(textBounds, byteLength / sizeof(uint16_t), pos, + lineSpacing, paint.isVerticalText()); return textBounds; } @@ -232,6 +268,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, if (font->platformData().orientation() == Vertical) y += SkFloatToScalar(font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent()); + float lineSpacing = font->fontMetrics().lineSpacing(); FloatRect textBounds; if (EmojiFont::IsAvailable()) { // set filtering, to make scaled images look nice(r) @@ -244,7 +281,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, if (localCount) { textBounds.unite(drawPosText(canvas, &glyphs[localIndex], localCount * sizeof(uint16_t), - &pos[localIndex], paint)); + &pos[localIndex], paint, lineSpacing)); } EmojiFont::Draw(canvas, glyphs[i], x, y, paint); float size = paint.getTextSize(); @@ -264,7 +301,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, if (localCount) { textBounds.unite(drawPosText(canvas, &glyphs[localIndex], localCount * sizeof(uint16_t), - &pos[localIndex], paint)); + &pos[localIndex], paint, lineSpacing)); } } else { for (int i = 0; i < numGlyphs; i++) { @@ -281,8 +318,8 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, rotator.setRotate(90); rotator.mapPoints(pos, numGlyphs); } - textBounds.unite(drawPosText(canvas, glyphs, numGlyphs * sizeof(uint16_t), - pos, paint)); + textBounds.unite(drawPosText(canvas, glyphs, + numGlyphs * sizeof(uint16_t), pos, paint, lineSpacing)); if (font->platformData().orientation() == Vertical) canvas->restore(); @@ -1052,18 +1089,21 @@ void Font::drawComplexText(GraphicsContext* gc, TextRun const& run, walker.setPadding(run.expansion()); FloatRect textBounds; + SkScalar lineSpacing = fontMetrics().lineSpacing(); while (walker.nextScriptRun()) { if (fill) { walker.fontPlatformDataForScriptRun()->setupPaint(&fillPaint); adjustTextRenderMode(&fillPaint, haveMultipleLayers); - textBounds.unite(drawPosText(canvas, walker.glyphs(), walker.length() << 1, - walker.positions(), fillPaint)); + textBounds.unite(drawPosText(canvas, walker.glyphs(), + walker.length() << 1, walker.positions(), fillPaint, + lineSpacing)); } if (stroke) { walker.fontPlatformDataForScriptRun()->setupPaint(&strokePaint); adjustTextRenderMode(&strokePaint, haveMultipleLayers); - textBounds.unite(drawPosText(canvas, walker.glyphs(), walker.length() << 1, - walker.positions(), strokePaint)); + textBounds.unite(drawPosText(canvas, walker.glyphs(), + walker.length() << 1, walker.positions(), strokePaint, + lineSpacing)); } } |