[svg] Deferred text position adjustments

Upcoming textPath changes require position adjustments (relative offset,
rotation) to be applied after mapping to path, at chunk flush time.

Bug: skia:10840
Change-Id: Ifccea2983d5d5c57876d0a25e1da113e4c9cd51a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350018
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
This commit is contained in:
Florin Malita 2021-01-05 10:51:33 -05:00 committed by Skia Commit-Bot
parent 4bf7c21571
commit 736c992966
2 changed files with 18 additions and 19 deletions

View File

@ -328,9 +328,11 @@ void SkSVGTextContext::flushChunk(const SkSVGRenderContext& ctx) {
const auto& buf = blobBuilder.allocRunRSXform(run.font, SkToInt(run.glyphCount));
std::copy(run.glyphs.get(), run.glyphs.get() + run.glyphCount, buf.glyphs);
for (size_t i = 0; i < run.glyphCount; ++i) {
const auto& pos = run.glyphPos[i];
const auto& pos_adjust = run.glyhPosAdjust[i];
const auto pos = run.glyphPos[i] + pos_adjust.offset;
buf.xforms()[i] = SkRSXform::MakeFromRadians(/*scale=*/ 1,
SkDegreesToRadians(run.glyphRot[i]),
SkDegreesToRadians(pos_adjust.rotation),
pos.fX, pos.fY, 0, 0);
}
@ -359,9 +361,9 @@ SkShaper::RunHandler::Buffer SkSVGTextContext::runBuffer(const RunInfo& ri) {
ri.fFont,
fCurrentFill ? std::make_unique<SkPaint>(*fCurrentFill) : nullptr,
fCurrentStroke ? std::make_unique<SkPaint>(*fCurrentStroke) : nullptr,
std::make_unique<SkGlyphID[]>(ri.glyphCount),
std::make_unique<SkPoint[] >(ri.glyphCount),
std::make_unique<float[] >(ri.glyphCount),
std::make_unique<SkGlyphID[] >(ri.glyphCount),
std::make_unique<SkPoint[] >(ri.glyphCount),
std::make_unique<PositionAdjustment[]>(ri.glyphCount),
ri.glyphCount,
ri.fAdvance,
});
@ -381,16 +383,13 @@ SkShaper::RunHandler::Buffer SkSVGTextContext::runBuffer(const RunInfo& ri) {
void SkSVGTextContext::commitRunBuffer(const RunInfo& ri) {
const auto& current_run = fRuns.back();
// apply position adjustments
// stash position adjustments
for (size_t i = 0; i < ri.glyphCount; ++i) {
const auto utf8_index = fShapeClusterBuffer[i];
const auto& pos = fShapeBuffer.fUtf8PosAdjust[SkToInt(utf8_index)];
current_run.glyphPos[i] += pos.offset;
current_run.glyphRot[i] = pos.rotation;
current_run.glyhPosAdjust[i] = fShapeBuffer.fUtf8PosAdjust[SkToInt(utf8_index)];
}
// Position adjustments are cumulative - we only need to advance the current chunk
// Offset adjustments are cumulative - we only need to advance the current chunk
// with the last value.
fChunkAdvance += ri.fAdvance + fShapeBuffer.fUtf8PosAdjust.back().offset;
}

View File

@ -127,14 +127,14 @@ private:
};
struct RunRec {
SkFont font;
std::unique_ptr<SkPaint> fillPaint,
strokePaint;
std::unique_ptr<SkGlyphID[]> glyphs;
std::unique_ptr<SkPoint[]> glyphPos;
std::unique_ptr<float[]> glyphRot;
size_t glyphCount;
SkVector advance;
SkFont font;
std::unique_ptr<SkPaint> fillPaint,
strokePaint;
std::unique_ptr<SkGlyphID[]> glyphs; // filled by SkShaper
std::unique_ptr<SkPoint[]> glyphPos; // filled by SkShaper
std::unique_ptr<PositionAdjustment[]> glyhPosAdjust; // deferred positioning adjustments
size_t glyphCount;
SkVector advance;
};
void shapePendingBuffer(const SkFont&);