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 <bungeman@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
This commit is contained in:
Julia Lavrova 2020-09-08 11:01:49 -04:00 committed by Skia Commit-Bot
parent 0ef049177f
commit b6030fb2c8
7 changed files with 44 additions and 51 deletions

View File

@ -122,7 +122,7 @@ private:
SkScalar fHeight;
TextHeightBehavior fTextHeightBehavior;
bool fHintingIsOn;
DrawOptions fDrawingOptions = DrawOptions::kReplay;
DrawOptions fDrawingOptions = DrawOptions::kDirect;
};
} // namespace textlayout
} // namespace skia

View File

@ -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;
}

View File

@ -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:

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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) {

View File

@ -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<Run> 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);