Skip to content

Commit

Permalink
[Impeller] transform text path offsets so color sources match expecte…
Browse files Browse the repository at this point in the history
…d offsets for gradients. (flutter#45255)

Gradient offsets are computed based on path offsets + gradient positions, so we need to shift the points instead of just adding a concat to the canvas. Fixes flutter/flutter#132972

### Skia

![flutter_03](https://github.com/flutter/engine/assets/8975114/182dff72-cd48-4f97-a1e3-ea924f4a0eee)

### Impeller (No Patch)

![flutter_04](https://github.com/flutter/engine/assets/8975114/bb421d86-a588-49b9-879f-209738821898)

### Impeller (W/ Patch)

![flutter_05](https://github.com/flutter/engine/assets/8975114/f2d601b4-d15f-487b-aa65-a61bfc98bde9)
  • Loading branch information
jonahwilliams authored and gaaclarke committed Aug 30, 2023
1 parent f70d549 commit c35d8ff
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 4 deletions.
6 changes: 2 additions & 4 deletions impeller/display_list/dl_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1118,12 +1118,10 @@ void DlDispatcher::drawTextBlob(const sk_sp<SkTextBlob>& blob,
const auto text_frame = maybe_text_frame.value();
if (paint_.style == Paint::Style::kStroke ||
paint_.color_source.GetType() != ColorSource::Type::kColor) {
auto path = skia_conversions::PathDataFromTextBlob(blob);
auto bounds = blob->bounds();
canvas_.Save();
canvas_.Translate({x + bounds.left(), y + bounds.top(), 0.0});
auto path = skia_conversions::PathDataFromTextBlob(blob);
path.Shift(Point(x + bounds.left(), y + bounds.top()));
canvas_.DrawPath(path, paint_);
canvas_.Restore();
return;
}

Expand Down
36 changes: 36 additions & 0 deletions impeller/geometry/geometry_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2373,6 +2373,42 @@ TEST(GeometryTest, HalfConversions) {
#endif // FML_OS_WIN
}

TEST(GeometryTest, PathShifting) {
PathBuilder builder{};
auto path =
builder.AddLine(Point(0, 0), Point(10, 10))
.AddQuadraticCurve(Point(10, 10), Point(15, 15), Point(20, 20))
.AddCubicCurve(Point(20, 20), Point(25, 25), Point(-5, -5),
Point(30, 30))
.Close()
.TakePath();
path.Shift(Point(1, 1));

ContourComponent contour;
LinearPathComponent linear;
QuadraticPathComponent quad;
CubicPathComponent cubic;

ASSERT_TRUE(path.GetContourComponentAtIndex(0, contour));
ASSERT_TRUE(path.GetLinearComponentAtIndex(1, linear));
ASSERT_TRUE(path.GetQuadraticComponentAtIndex(3, quad));
ASSERT_TRUE(path.GetCubicComponentAtIndex(5, cubic));

ASSERT_EQ(contour.destination, Point(1, 1));

ASSERT_EQ(linear.p1, Point(1, 1));
ASSERT_EQ(linear.p2, Point(11, 11));

ASSERT_EQ(quad.cp, Point(16, 16));
ASSERT_EQ(quad.p1, Point(11, 11));
ASSERT_EQ(quad.p2, Point(21, 21));

ASSERT_EQ(cubic.cp1, Point(26, 26));
ASSERT_EQ(cubic.cp2, Point(-4, -4));
ASSERT_EQ(cubic.p1, Point(21, 21));
ASSERT_EQ(cubic.p2, Point(31, 31));
}

} // namespace testing
} // namespace impeller

Expand Down
27 changes: 27 additions & 0 deletions impeller/geometry/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,33 @@ void Path::SetConvexity(Convexity value) {
convexity_ = value;
}

void Path::Shift(Point shift) {
size_t currentIndex = 0;
for (const auto& component : components_) {
switch (component.type) {
case ComponentType::kLinear:
linears_[component.index].p1 += shift;
linears_[component.index].p2 += shift;
break;
case ComponentType::kQuadratic:
quads_[component.index].cp += shift;
quads_[component.index].p1 += shift;
quads_[component.index].p2 += shift;
break;
case ComponentType::kCubic:
cubics_[component.index].cp1 += shift;
cubics_[component.index].cp2 += shift;
cubics_[component.index].p1 += shift;
cubics_[component.index].p2 += shift;
break;
case ComponentType::kContour:
contours_[component.index].destination += shift;
break;
}
currentIndex++;
}
}

Path& Path::AddLinearComponent(Point p1, Point p2) {
linears_.emplace_back(p1, p2);
components_.emplace_back(ComponentType::kLinear, linears_.size() - 1);
Expand Down
3 changes: 3 additions & 0 deletions impeller/geometry/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ class Path {

void SetContourClosed(bool is_closed);

/// @brief Transform the path by the given offset in-place.
void Shift(Point shift);

template <class T>
using Applier = std::function<void(size_t index, const T& component)>;
void EnumerateComponents(
Expand Down

0 comments on commit c35d8ff

Please sign in to comment.