summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp66
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));
}
}