Commit a0586590 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Don't fold SaveAlphaLayer into DrawTextBlob

SkPaint::drawTextBlob applies alpha on each individual glyph, so
we should keep SaveAlphaLayer to ensure the alpha is applied atomically
on the whole text blob.

Bug: 1006140
Change-Id: I8b1d1868a3423ed4f0ef6541cc8db354773dfb24
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1821944
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarvmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699621}
parent 132debad
......@@ -2373,7 +2373,11 @@ void PaintOpBuffer::PlaybackFoldingIterator::FindNextOp() {
third = NextUnfoldedOp();
if (third && third->GetType() == PaintOpType::Restore) {
auto* save_op = static_cast<const SaveLayerAlphaOp*>(current_op_);
if (draw_op->IsPaintOpWithFlags()) {
if (draw_op->IsPaintOpWithFlags() &&
// SkPaint::drawTextBlob() applies alpha on each glyph so we don't
// fold SaveLayerAlpha into DrwaTextBlob to ensure correct alpha
// even if some glyphs overlap.
draw_op->GetType() != PaintOpType::DrawTextBlob) {
auto* flags_op = static_cast<const PaintOpWithFlags*>(draw_op);
if (flags_op->flags.SupportsFoldingAlpha()) {
current_alpha_ = save_op->alpha;
......
......@@ -48,7 +48,6 @@ void ValidateOps(PaintOpBuffer* buffer) {
for (auto* op : PaintOpBuffer::Iterator(buffer))
EXPECT_TRUE(static_cast<T*>(op)->IsValid());
}
} // namespace
class PaintOpSerializationTestUtils {
......@@ -240,6 +239,26 @@ TEST(PaintOpBufferTest, SaveDrawRestore) {
EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f);
}
// Verify that we don't optimize SaveLayerAlpha / DrawTextBlob / Restore.
TEST(PaintOpBufferTest, SaveDrawTextBlobRestore) {
PaintOpBuffer buffer;
uint8_t alpha = 100;
buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
PaintFlags paint_flags;
EXPECT_TRUE(paint_flags.SupportsFoldingAlpha());
buffer.push<DrawTextBlobOp>(SkTextBlob::MakeFromString("abc", SkFont()), 0, 0,
paint_flags);
buffer.push<RestoreOp>();
SaveCountingCanvas canvas;
buffer.Playback(&canvas);
EXPECT_EQ(1, canvas.save_count_);
EXPECT_EQ(1, canvas.restore_count_);
}
// The same as SaveDrawRestore, but test that the optimization doesn't apply
// when the drawing op's flags are not compatible with being folded into the
// save layer with opacity.
......
<meta name="flags" content="ahem">
<div style="opacity: 0.5; letter-spacing: -0.6em; font: 100px/1 Ahem; white-space: pre">X X X</div>
<link rel="help" href="http://www.w3.org/TR/css3-color/#transparency">
<link rel="match" href="opacity-overlapping-letters-ref.html">
<meta name="flags" content="ahem">
<meta name="assert" content="Opacity should be apply on the whole text content atomically.">
<div style="opacity: 0.5; letter-spacing: -0.6em; font: 100px/1 Ahem">XXXXX</div>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment