From b6030fb2c818ceea64469a613a8f3fe66cc32595 Mon Sep 17 00:00:00 2001 From: Julia Lavrova Date: Tue, 8 Sep 2020 11:01:49 -0400 Subject: [PATCH] Direct paint by default; remove save/translate/restore Change-Id: Ic0c85d106012374ae5c467edd3a43a93ff2b57d2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315603 Reviewed-by: Ben Wagner Commit-Queue: Julia Lavrova --- modules/skparagraph/include/ParagraphStyle.h | 2 +- modules/skparagraph/src/Decorations.cpp | 2 +- modules/skparagraph/src/Decorations.h | 2 +- modules/skparagraph/src/ParagraphImpl.cpp | 21 +++----- modules/skparagraph/src/ParagraphImpl.h | 4 +- modules/skparagraph/src/TextLine.cpp | 54 ++++++++++---------- modules/skparagraph/src/TextLine.h | 10 ++-- 7 files changed, 44 insertions(+), 51 deletions(-) diff --git a/modules/skparagraph/include/ParagraphStyle.h b/modules/skparagraph/include/ParagraphStyle.h index d075432959..43fb71f590 100644 --- a/modules/skparagraph/include/ParagraphStyle.h +++ b/modules/skparagraph/include/ParagraphStyle.h @@ -122,7 +122,7 @@ private: SkScalar fHeight; TextHeightBehavior fTextHeightBehavior; bool fHintingIsOn; - DrawOptions fDrawingOptions = DrawOptions::kReplay; + DrawOptions fDrawingOptions = DrawOptions::kDirect; }; } // namespace textlayout } // namespace skia diff --git a/modules/skparagraph/src/Decorations.cpp b/modules/skparagraph/src/Decorations.cpp index 59943495e7..6c1bf23170 100644 --- a/modules/skparagraph/src/Decorations.cpp +++ b/modules/skparagraph/src/Decorations.cpp @@ -20,7 +20,7 @@ namespace skia { namespace textlayout { static const float kDoubleDecorationSpacing = 3.0f; -void Decorations::paint(SkCanvas* canvas, const TextStyle& textStyle, const TextLine::ClipContext& context, SkScalar baseline, SkPoint offset) { +void Decorations::paint(SkCanvas* canvas, const TextStyle& textStyle, const TextLine::ClipContext& context, SkScalar baseline) { if (textStyle.getDecorationType() == TextDecoration::kNoDecoration) { return; } diff --git a/modules/skparagraph/src/Decorations.h b/modules/skparagraph/src/Decorations.h index 95df4a0154..b92722e74e 100644 --- a/modules/skparagraph/src/Decorations.h +++ b/modules/skparagraph/src/Decorations.h @@ -12,7 +12,7 @@ namespace textlayout { class Decorations { public: - void paint(SkCanvas* canvas, const TextStyle& textStyle, const TextLine::ClipContext& context, SkScalar baseline, SkPoint offset); + void paint(SkCanvas* canvas, const TextStyle& textStyle, const TextLine::ClipContext& context, SkScalar baseline); private: diff --git a/modules/skparagraph/src/ParagraphImpl.cpp b/modules/skparagraph/src/ParagraphImpl.cpp index 42c3fcc3b8..82216d2ce4 100644 --- a/modules/skparagraph/src/ParagraphImpl.cpp +++ b/modules/skparagraph/src/ParagraphImpl.cpp @@ -206,29 +206,22 @@ void ParagraphImpl::paint(SkCanvas* canvas, SkScalar x, SkScalar y) { if (fParagraphStyle.getDrawOptions() == DrawOptions::kDirect) { // Paint the text without recording it - canvas->save(); - canvas->translate(x, y); - this->paintLines(canvas); - canvas->restore(); + this->paintLines(canvas, x, y); return; } if (fState < kDrawn) { // Record the picture anyway (but if we have some pieces in the cache they will be used) - this->paintLinesIntoPicture(); + this->paintLinesIntoPicture(x, y); fState = kDrawn; } if (fParagraphStyle.getDrawOptions() == DrawOptions::kReplay) { // Replay the recorded picture - canvas->save(); - canvas->translate(x, y); fPicture->playback(canvas); - canvas->restore(); } else { // Draw the picture - SkMatrix matrix = SkMatrix::Translate(x, y); - canvas->drawPicture(fPicture, &matrix, nullptr); + canvas->drawPicture(fPicture); } } @@ -482,22 +475,22 @@ void ParagraphImpl::formatLines(SkScalar maxWidth) { } } -void ParagraphImpl::paintLinesIntoPicture() { +void ParagraphImpl::paintLinesIntoPicture(SkScalar x, SkScalar y) { SkPictureRecorder recorder; SkCanvas* textCanvas = recorder.beginRecording(this->getMaxWidth(), this->getHeight()); auto bounds = SkRect::MakeEmpty(); for (auto& line : fLines) { - auto boundaries = line.paint(textCanvas); + auto boundaries = line.paint(textCanvas, x, y); bounds.joinPossiblyEmptyRect(boundaries); } fPicture = recorder.finishRecordingAsPictureWithCull(bounds); } -void ParagraphImpl::paintLines(SkCanvas* canvas) { +void ParagraphImpl::paintLines(SkCanvas* canvas, SkScalar x, SkScalar y) { for (auto& line : fLines) { - line.paint(canvas); + line.paint(canvas, x, y); } } diff --git a/modules/skparagraph/src/ParagraphImpl.h b/modules/skparagraph/src/ParagraphImpl.h index 420c345bf7..4bd3d904be 100644 --- a/modules/skparagraph/src/ParagraphImpl.h +++ b/modules/skparagraph/src/ParagraphImpl.h @@ -191,8 +191,8 @@ public: void spaceGlyphs(); bool shapeTextIntoEndlessLine(); void breakShapedTextIntoLines(SkScalar maxWidth); - void paintLinesIntoPicture(); - void paintLines(SkCanvas* canvas); + void paintLinesIntoPicture(SkScalar x, SkScalar y); + void paintLines(SkCanvas* canvas, SkScalar x, SkScalar y); void updateTextAlign(TextAlign textAlign) override; void updateText(size_t from, SkString text) override; diff --git a/modules/skparagraph/src/TextLine.cpp b/modules/skparagraph/src/TextLine.cpp index 50047a64b0..1eddb93b56 100644 --- a/modules/skparagraph/src/TextLine.cpp +++ b/modules/skparagraph/src/TextLine.cpp @@ -159,7 +159,7 @@ TextLine::TextLine(ParagraphImpl* owner, } } -SkRect TextLine::paint(SkCanvas* textCanvas) { +SkRect TextLine::paint(SkCanvas* textCanvas, SkScalar x, SkScalar y) { auto bounds = SkRect::MakeEmpty(); if (this->empty()) { return bounds; @@ -167,12 +167,12 @@ SkRect TextLine::paint(SkCanvas* textCanvas) { if (fHasBackground) { this->iterateThroughVisualRuns(false, - [textCanvas, this] + [textCanvas, x, y, this] (const Run* run, SkScalar runOffsetInLine, TextRange textRange, SkScalar* runWidthInLine) { *runWidthInLine = this->iterateThroughSingleRunByStyles( run, runOffsetInLine, textRange, StyleType::kBackground, - [textCanvas, this](TextRange textRange, const TextStyle& style, const ClipContext& context) { - this->paintBackground(textCanvas, textRange, style, context); + [textCanvas, x, y, this](TextRange textRange, const TextStyle& style, const ClipContext& context) { + this->paintBackground(textCanvas, x, y, textRange, style, context); }); return true; }); @@ -180,12 +180,12 @@ SkRect TextLine::paint(SkCanvas* textCanvas) { if (fHasShadows) { this->iterateThroughVisualRuns(false, - [textCanvas, &bounds, this] + [textCanvas, x, y, &bounds, this] (const Run* run, SkScalar runOffsetInLine, TextRange textRange, SkScalar* runWidthInLine) { *runWidthInLine = this->iterateThroughSingleRunByStyles( run, runOffsetInLine, textRange, StyleType::kShadow, - [textCanvas, &bounds, this](TextRange textRange, const TextStyle& style, const ClipContext& context) { - auto shadowBounds = this->paintShadow(textCanvas, textRange, style, context); + [textCanvas, x, y, &bounds, this](TextRange textRange, const TextStyle& style, const ClipContext& context) { + auto shadowBounds = this->paintShadow(textCanvas, x, y, textRange, style, context); bounds.joinPossiblyEmptyRect(shadowBounds); }); return true; @@ -193,7 +193,7 @@ SkRect TextLine::paint(SkCanvas* textCanvas) { } this->iterateThroughVisualRuns(false, - [textCanvas, &bounds, this] + [textCanvas, x, y, &bounds, this] (const Run* run, SkScalar runOffsetInLine, TextRange textRange, SkScalar* runWidthInLine) { if (run->placeholderStyle() != nullptr) { *runWidthInLine = run->advance().fX; @@ -201,8 +201,8 @@ SkRect TextLine::paint(SkCanvas* textCanvas) { } *runWidthInLine = this->iterateThroughSingleRunByStyles( run, runOffsetInLine, textRange, StyleType::kForeground, - [textCanvas, &bounds, this](TextRange textRange, const TextStyle& style, const ClipContext& context) { - auto textBounds = this->paintText(textCanvas, textRange, style, context); + [textCanvas, x, y, &bounds, this](TextRange textRange, const TextStyle& style, const ClipContext& context) { + auto textBounds = this->paintText(textCanvas, x, y, textRange, style, context); bounds.joinPossiblyEmptyRect(textBounds); }); return true; @@ -210,12 +210,12 @@ SkRect TextLine::paint(SkCanvas* textCanvas) { if (fHasDecorations) { this->iterateThroughVisualRuns(false, - [textCanvas, this] + [textCanvas, x, y, this] (const Run* run, SkScalar runOffsetInLine, TextRange textRange, SkScalar* runWidthInLine) { *runWidthInLine = this->iterateThroughSingleRunByStyles( run, runOffsetInLine, textRange, StyleType::kDecorations, - [textCanvas, this](TextRange textRange, const TextStyle& style, const ClipContext& context) { - this->paintDecorations(textCanvas, textRange, style, context); + [textCanvas, x, y, this](TextRange textRange, const TextStyle& style, const ClipContext& context) { + this->paintDecorations(textCanvas, x, y, textRange, style, context); }); return true; }); @@ -294,7 +294,7 @@ SkScalar TextLine::metricsWithoutMultiplier(TextHeightBehavior correction) { return delta; } -SkRect TextLine::paintText(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const { +SkRect TextLine::paintText(SkCanvas* canvas, SkScalar x, SkScalar y, TextRange textRange, const TextStyle& style, const ClipContext& context) const { if (context.run->placeholderStyle() != nullptr) { return SkRect::MakeEmpty(); @@ -312,7 +312,7 @@ SkRect TextLine::paintText(SkCanvas* canvas, TextRange textRange, const TextStyl context.run->copyTo(builder, SkToU32(context.pos), context.size); if (context.clippingNeeded) { canvas->save(); - canvas->clipRect(extendHeight(context).makeOffset(this->offset())); + canvas->clipRect(extendHeight(context).makeOffset(this->offset() + SkPoint::Make(x, y))); } SkRect textBounds = SkRect::MakeEmpty(); @@ -320,12 +320,12 @@ SkRect TextLine::paintText(SkCanvas* canvas, TextRange textRange, const TextStyl auto blob = builder.make(); if (blob != nullptr) { auto bounds = blob->bounds(); - bounds.offset(this->offset().fX, this->offset().fY); + bounds.offset(x + this->offset().fX, y + this->offset().fY); textBounds.joinPossiblyEmptyRect(bounds); } canvas->drawTextBlob(blob, - this->offset().fX + context.fTextShift, this->offset().fY + correctedBaseline, paint); + x + this->offset().fX + context.fTextShift, y + this->offset().fY + correctedBaseline, paint); if (context.clippingNeeded) { canvas->restore(); @@ -334,13 +334,13 @@ SkRect TextLine::paintText(SkCanvas* canvas, TextRange textRange, const TextStyl return textBounds; } -void TextLine::paintBackground(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const { +void TextLine::paintBackground(SkCanvas* canvas, SkScalar x, SkScalar y, TextRange textRange, const TextStyle& style, const ClipContext& context) const { if (style.hasBackground()) { - canvas->drawRect(context.clip.makeOffset(this->offset()), style.getBackground()); + canvas->drawRect(context.clip.makeOffset(this->offset() + SkPoint::Make(x, y)), style.getBackground()); } } -SkRect TextLine::paintShadow(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const { +SkRect TextLine::paintShadow(SkCanvas* canvas, SkScalar x, SkScalar y, TextRange textRange, const TextStyle& style, const ClipContext& context) const { SkScalar correctedBaseline = SkScalarFloorToScalar(this->baseline() + 0.5); SkRect shadowBounds = SkRect::MakeEmpty(); @@ -369,14 +369,14 @@ SkRect TextLine::paintShadow(SkCanvas* canvas, TextRange textRange, const TextSt if (blob != nullptr) { auto bounds = blob->bounds(); bounds.offset( - this->offset().fX + shadow.fOffset.x(), - this->offset().fY + shadow.fOffset.y() + x + this->offset().fX + shadow.fOffset.x(), + y + this->offset().fY + shadow.fOffset.y() ); shadowBounds.joinPossiblyEmptyRect(bounds); } canvas->drawTextBlob(blob, - this->offset().fX + shadow.fOffset.x() + context.fTextShift, - this->offset().fY + shadow.fOffset.y() + correctedBaseline, + x + this->offset().fX + shadow.fOffset.x() + context.fTextShift, + y + this->offset().fY + shadow.fOffset.y() + correctedBaseline, paint); if (context.clippingNeeded) { canvas->restore(); @@ -386,13 +386,13 @@ SkRect TextLine::paintShadow(SkCanvas* canvas, TextRange textRange, const TextSt return shadowBounds; } -void TextLine::paintDecorations(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const { +void TextLine::paintDecorations(SkCanvas* canvas, SkScalar x, SkScalar y, TextRange textRange, const TextStyle& style, const ClipContext& context) const { SkAutoCanvasRestore acr(canvas, true); - canvas->translate(this->offset().fX, this->offset().fY); + canvas->translate(x + this->offset().fX, y + this->offset().fY); Decorations decorations; SkScalar correctedBaseline = SkScalarFloorToScalar(this->baseline() + 0.5); - decorations.paint(canvas, style, context, correctedBaseline, this->offset()); + decorations.paint(canvas, style, context, correctedBaseline); } void TextLine::justify(SkScalar maxWidth) { diff --git a/modules/skparagraph/src/TextLine.h b/modules/skparagraph/src/TextLine.h index 899ab9a1ef..113a3943c9 100644 --- a/modules/skparagraph/src/TextLine.h +++ b/modules/skparagraph/src/TextLine.h @@ -84,7 +84,7 @@ public: void iterateThroughClustersInGlyphsOrder(bool reverse, bool includeGhosts, const ClustersVisitor& visitor) const; void format(TextAlign align, SkScalar maxWidth); - SkRect paint(SkCanvas* canvas); + SkRect paint(SkCanvas* canvas, SkScalar x, SkScalar y); void createEllipsis(SkScalar maxWidth, const SkString& ellipsis, bool ltr); @@ -121,10 +121,10 @@ private: std::unique_ptr shapeEllipsis(const SkString& ellipsis, Run* run); void justify(SkScalar maxWidth); - SkRect paintText(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const; - void paintBackground(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const; - SkRect paintShadow(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const; - void paintDecorations(SkCanvas* canvas, TextRange textRange, const TextStyle& style, const ClipContext& context) const; + SkRect paintText(SkCanvas* canvas, SkScalar x, SkScalar y, TextRange textRange, const TextStyle& style, const ClipContext& context) const; + void paintBackground(SkCanvas* canvas, SkScalar x, SkScalar y, TextRange textRange, const TextStyle& style, const ClipContext& context) const; + SkRect paintShadow(SkCanvas* canvas, SkScalar x, SkScalar y, TextRange textRange, const TextStyle& style, const ClipContext& context) const; + void paintDecorations(SkCanvas* canvas, SkScalar x, SkScalar y, TextRange textRange, const TextStyle& style, const ClipContext& context) const; void shiftCluster(const Cluster* cluster, SkScalar shift, SkScalar prevShift);