Skip to content

Commit

Permalink
Delay color premultiplication until RenderContext to keep intermediat…
Browse files Browse the repository at this point in the history
…e colors unpremultiplied. (#425)
  • Loading branch information
Hparty authored Jan 9, 2025
1 parent 02cad7c commit 3bb314f
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 18 deletions.
2 changes: 1 addition & 1 deletion resources/apitest/mask_invert_picture_image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion resources/apitest/mask_picture_image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions src/core/Canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ static FillStyle CreateFillStyle(const Paint& paint) {
Color color = {};
if (shader && shader->asColor(&color)) {
color.alpha *= paint.getAlpha();
style.color = color.premultiply();
style.color = color;
shader = nullptr;
} else {
style.color = paint.getColor().premultiply();
style.color = paint.getColor();
}
style.shader = shader;
style.antiAlias = paint.isAntiAlias();
Expand Down Expand Up @@ -504,7 +504,7 @@ void Canvas::drawAtlas(std::shared_ptr<Image> atlas, const Matrix matrix[], cons
state.matrix.preTranslate(-rect.x(), -rect.y());
auto glyphStyle = style;
if (colors) {
glyphStyle.color = colors[i].premultiply();
glyphStyle.color = colors[i];
}
if (rect == atlasRect) {
drawContext->drawImage(atlas, sampling, state, glyphStyle);
Expand Down
2 changes: 1 addition & 1 deletion src/core/FillStyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class FillStyle {
bool antiAlias = true;

/**
* The input color, premultiplied, as four floating point values.
* The input color, unpremultiplied, as four floating point values.
*/
Color color = Color::White();

Expand Down
13 changes: 7 additions & 6 deletions src/gpu/RenderContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void RenderContext::drawRect(const Rect& rect, const MCState& state, const FillS
if (localBounds.isEmpty()) {
return;
}
auto drawOp = RectDrawOp::Make(style.color, localBounds, state.matrix);
auto drawOp = RectDrawOp::Make(style.color.premultiply(), localBounds, state.matrix);
addDrawOp(std::move(drawOp), localBounds, state, style);
}

Expand All @@ -111,7 +111,7 @@ bool RenderContext::drawAsClear(const Rect& rect, const MCState& state, const Fi
if (!HasColorOnly(style) || !style.isOpaque() || !state.matrix.rectStaysRect()) {
return false;
}
auto color = style.color;
auto color = style.color.premultiply();
auto bounds = rect;
state.matrix.mapRect(&bounds);
auto [clipRect, useScissor] = getClipRect(state.clip, &bounds);
Expand All @@ -136,7 +136,7 @@ void RenderContext::drawRRect(const RRect& rRect, const MCState& state, const Fi
if (localBounds.isEmpty()) {
return;
}
auto drawOp = RRectDrawOp::Make(style.color, rRect, state.matrix);
auto drawOp = RRectDrawOp::Make(style.color.premultiply(), rRect, state.matrix);
addDrawOp(std::move(drawOp), localBounds, state, style);
}

Expand All @@ -153,7 +153,8 @@ void RenderContext::drawShape(std::shared_ptr<Shape> shape, const MCState& state
return;
}
auto clipBounds = getClipBounds(state.clip);
auto drawOp = ShapeDrawOp::Make(style.color, std::move(shape), state.matrix, clipBounds);
auto drawOp =
ShapeDrawOp::Make(style.color.premultiply(), std::move(shape), state.matrix, clipBounds);
addDrawOp(std::move(drawOp), localBounds, state, style);
}

Expand Down Expand Up @@ -184,7 +185,7 @@ void RenderContext::drawImageRect(std::shared_ptr<Image> image, const Rect& rect
if (processor == nullptr) {
return;
}
auto drawOp = RectDrawOp::Make(style.color, localBounds, state.matrix, uvMatrix);
auto drawOp = RectDrawOp::Make(style.color.premultiply(), localBounds, state.matrix, uvMatrix);
drawOp->addColorFP(std::move(processor));
addDrawOp(std::move(drawOp), localBounds, state, style);
}
Expand Down Expand Up @@ -224,7 +225,7 @@ void RenderContext::drawGlyphRunList(std::shared_ptr<GlyphRunList> glyphRunList,
if (processor == nullptr) {
return;
}
auto drawOp = RectDrawOp::Make(style.color, localBounds, state.matrix);
auto drawOp = RectDrawOp::Make(style.color.premultiply(), localBounds, state.matrix);
drawOp->addCoverageFP(std::move(processor));
addDrawOp(std::move(drawOp), localBounds, state, style);
}
Expand Down
4 changes: 2 additions & 2 deletions test/baseline/version.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"Path_addArc_reversed7": "4802e56",
"Path_addArc_reversed8": "4802e56",
"Path_complex": "e031f25",
"Picture": "b062b9a",
"Picture": "002c391",
"PictureImage": "c28a93c",
"PictureImage_Path": "2212c4e",
"PictureImage_Text": "b062b9a",
Expand Down Expand Up @@ -100,7 +100,7 @@
"DropShadowStyle-stroke-behindLayer": "002c391",
"DropShadowStyle-stroke-blur": "002c391",
"DropShadowStyle-stroke-blur-behindLayer": "002c391",
"DropShadowStyle2": "19dcc4d",
"DropShadowStyle2": "7a9c80a",
"InnerShadowStyle": "19dcc4d",
"Layer_hitTestPoint": "50c58e6",
"Layer_hitTestPointNested": "b062b9a",
Expand Down
8 changes: 4 additions & 4 deletions test/src/SVGExportTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ TGFX_TEST(SVGExportTest, OpacityColor) {
std::string compareString =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?><svg xmlns=\"http://www.w3.org/2000/svg\" "
"xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"200\" height=\"200\"><circle "
"fill=\"#00007F\" fill-opacity=\"0.5\" cx=\"100\" cy=\"100\" r=\"100\"/></svg>";
"fill=\"#00F\" fill-opacity=\"0.5\" cx=\"100\" cy=\"100\" r=\"100\"/></svg>";

ContextScope scope;
auto* context = scope.getContext();
ASSERT_TRUE(context != nullptr);

tgfx::Paint paint;
Paint paint;
paint.setColor(Color::Blue());
paint.setAlpha(0.5f);

Expand All @@ -131,7 +131,7 @@ TGFX_TEST(SVGExportTest, OpacityColorFile) {
std::string compareString =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?><svg xmlns=\"http://www.w3.org/2000/svg\" "
"xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"200\" height=\"200\"><circle "
"fill=\"#00007F\" fill-opacity=\"0.5\" cx=\"100\" cy=\"100\" r=\"100\"/></svg>";
"fill=\"#00F\" fill-opacity=\"0.5\" cx=\"100\" cy=\"100\" r=\"100\"/></svg>";

ContextScope scope;
auto* context = scope.getContext();
Expand All @@ -156,7 +156,7 @@ TGFX_TEST(SVGExportTest, OpacityColorFile) {

auto readStream = Stream::MakeFromFile(path);
EXPECT_TRUE(readStream != nullptr);
EXPECT_EQ(readStream->size(), 222U);
EXPECT_EQ(readStream->size(), 219U);
Buffer buffer(readStream->size());
readStream->read(buffer.data(), buffer.size());
EXPECT_EQ(std::string((char*)buffer.data(), buffer.size()), compareString);
Expand Down

0 comments on commit 3bb314f

Please sign in to comment.