SkShaper per-line callback
Tweak SkShaper to call out for each line, instead of bundling everything
as a text blob.
Change-Id: Ic522f88afcf31cefd873dc8b5cde1ac2e107c64f
Reviewed-on: https://skia-review.googlesource.com/c/176592
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/modules/skshaper/src/SkShaper_primitive.cpp b/modules/skshaper/src/SkShaper_primitive.cpp
index 7b798e7..3d54262 100644
--- a/modules/skshaper/src/SkShaper_primitive.cpp
+++ b/modules/skshaper/src/SkShaper_primitive.cpp
@@ -8,7 +8,6 @@
#include "SkShaper.h"
#include "SkStream.h"
-#include "SkTextBlob.h"
#include "SkTo.h"
#include "SkTypeface.h"
@@ -32,7 +31,7 @@
return (((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1;
}
-SkPoint SkShaper::shape(SkTextBlobBuilder* builder,
+SkPoint SkShaper::shape(LineHandler* handler,
const SkFont& srcFont,
const char* utf8text,
size_t textBytes,
@@ -40,6 +39,7 @@
SkPoint point,
SkScalar width) const {
sk_ignore_unused_variable(leftToRight);
+ sk_ignore_unused_variable(width);
SkFont font(srcFont);
font.setTypeface(fImpl->fTypeface);
@@ -47,32 +47,29 @@
if (glyphCount <= 0) {
return point;
}
- SkRect bounds;
+
SkFontMetrics metrics;
font.getMetrics(&metrics);
point.fY -= metrics.fAscent;
- (void)font.measureText(utf8text, textBytes, SkTextEncoding::kUTF8, &bounds);
- const SkTextBlobBuilder::RunBuffer& runBuffer =
- builder->allocRunTextPosH(font, glyphCount, point.y(), textBytes, SkString(), &bounds);
- memcpy(runBuffer.utf8text, utf8text, textBytes);
- const char* txtPtr = utf8text;
- for (int i = 0; i < glyphCount; ++i) {
- // Each charater maps to exactly one glyph via SkGlyphCache::unicharToGlyph().
- runBuffer.clusters[i] = SkToU32(txtPtr - utf8text);
- txtPtr += utf8_lead_byte_to_count(txtPtr);
- SkASSERT(txtPtr <= utf8text + textBytes);
- }
- (void)font.textToGlyphs(utf8text, textBytes, SkTextEncoding::kUTF8,
- runBuffer.glyphs, glyphCount);
- // replace with getPos()?
- (void)font.getWidths(runBuffer.glyphs, glyphCount, runBuffer.pos);
- SkScalar x = point.x();
- for (int i = 0; i < glyphCount; ++i) {
- SkScalar w = runBuffer.pos[i];
- runBuffer.pos[i] = x;
- x += w;
- }
- point.fY += metrics.fDescent + metrics.fLeading;
- return point;
+ const auto buffer = handler->newLineBuffer(font, glyphCount, textBytes);
+ SkAssertResult(font.textToGlyphs(utf8text, textBytes, SkTextEncoding::kUTF8, buffer.glyphs,
+ glyphCount) == glyphCount);
+ font.getPos(buffer.glyphs, glyphCount, buffer.positions, point);
+
+ if (buffer.utf8text) {
+ memcpy(buffer.utf8text, utf8text, textBytes);
+ }
+
+ if (buffer.clusters) {
+ const char* txtPtr = utf8text;
+ for (int i = 0; i < glyphCount; ++i) {
+ // Each charater maps to exactly one glyph via SkGlyphCache::unicharToGlyph().
+ buffer.clusters[i] = SkToU32(txtPtr - utf8text);
+ txtPtr += utf8_lead_byte_to_count(txtPtr);
+ SkASSERT(txtPtr <= utf8text + textBytes);
+ }
+ }
+
+ return point + SkVector::Make(0, metrics.fDescent + metrics.fLeading);
}