Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,8 @@ ORIGIN: ../../../flutter/impeller/entity/contents/clip_contents.cc + ../../../fl
ORIGIN: ../../../flutter/impeller/entity/contents/clip_contents.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/color_source_contents.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/color_source_contents.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/color_source_text_contents.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/color_source_text_contents.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/content_context.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/content_context.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/contents/contents.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -3661,6 +3663,8 @@ FILE: ../../../flutter/impeller/entity/contents/clip_contents.cc
FILE: ../../../flutter/impeller/entity/contents/clip_contents.h
FILE: ../../../flutter/impeller/entity/contents/color_source_contents.cc
FILE: ../../../flutter/impeller/entity/contents/color_source_contents.h
FILE: ../../../flutter/impeller/entity/contents/color_source_text_contents.cc
FILE: ../../../flutter/impeller/entity/contents/color_source_text_contents.h
FILE: ../../../flutter/impeller/entity/contents/content_context.cc
FILE: ../../../flutter/impeller/entity/contents/content_context.h
FILE: ../../../flutter/impeller/entity/contents/contents.cc
Expand Down
31 changes: 28 additions & 3 deletions impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "impeller/aiks/paint_pass_delegate.h"
#include "impeller/entity/contents/atlas_contents.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/color_source_text_contents.h"
#include "impeller/entity/contents/rrect_shadow_contents.h"
#include "impeller/entity/contents/text_contents.h"
#include "impeller/entity/contents/texture_contents.h"
Expand Down Expand Up @@ -380,16 +381,40 @@ void Canvas::DrawTextFrame(const TextFrame& text_frame,
const Paint& paint) {
lazy_glyph_atlas_->AddTextFrame(text_frame);

Entity entity;
entity.SetStencilDepth(GetStencilDepth());
entity.SetBlendMode(paint.blend_mode);

auto text_contents = std::make_shared<TextContents>();
text_contents->SetTextFrame(text_frame);
text_contents->SetGlyphAtlas(lazy_glyph_atlas_);

if (paint.color_source.has_value()) {
auto& source = paint.color_source.value();
auto color_text_contents = std::make_shared<ColorSourceTextContents>();
entity.SetTransformation(GetCurrentTransformation());

Entity test;
auto cvg = text_contents->GetCoverage(test).value();
color_text_contents->SetTextPosition(cvg.origin + position);

text_contents->SetInverseMatrix(
Matrix::MakeTranslation(Vector3(-cvg.origin.x, -cvg.origin.y, 0)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than creating a new parameter, just amend this matrix to the entity transform?

color_text_contents->SetTextContents(std::move(text_contents));
color_text_contents->SetColorSourceContents(source());

entity.SetContents(
paint.WithFilters(std::move(color_text_contents), false));

GetCurrentPass().AddEntity(entity);
return;
}

text_contents->SetColor(paint.color);

Entity entity;
entity.SetTransformation(GetCurrentTransformation() *
Matrix::MakeTranslation(position));
entity.SetStencilDepth(GetStencilDepth());
entity.SetBlendMode(paint.blend_mode);

entity.SetContents(paint.WithFilters(std::move(text_contents), true));

GetCurrentPass().AddEntity(entity);
Expand Down
19 changes: 19 additions & 0 deletions impeller/display_list/display_list_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ TEST_P(DisplayListTest, CanDrawTextBlob) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

TEST_P(DisplayListTest, CanDrawTextBlobWithGradient) {
flutter::DisplayListBuilder builder;

std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
flutter::DlColor::kRed()};
const float stops[2] = {0.0, 1.0};

auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
2, colors.data(), stops,
flutter::DlTileMode::kClamp);
flutter::DlPaint paint;
paint.setColorSource(linear);

builder.DrawTextBlob(
SkTextBlob::MakeFromString("Hello World", CreateTestFont()), 100, 100,
paint);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}

TEST_P(DisplayListTest, CanDrawTextWithSaveLayer) {
flutter::DisplayListBuilder builder;
builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
Expand Down
2 changes: 2 additions & 0 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ impeller_component("entity") {
"contents/clip_contents.h",
"contents/color_source_contents.cc",
"contents/color_source_contents.h",
"contents/color_source_text_contents.cc",
"contents/color_source_text_contents.h",
"contents/content_context.cc",
"contents/content_context.h",
"contents/contents.cc",
Expand Down
4 changes: 2 additions & 2 deletions impeller/entity/contents/color_source_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class ColorSourceContents : public Contents {

void SetEffectTransform(Matrix matrix);

const Matrix& GetInverseMatrix() const;

void SetAlpha(Scalar alpha);

// |Contents|
Expand All @@ -34,8 +36,6 @@ class ColorSourceContents : public Contents {
protected:
const std::shared_ptr<Geometry>& GetGeometry() const;

const Matrix& GetInverseMatrix() const;

Scalar GetAlpha() const;

private:
Expand Down
84 changes: 84 additions & 0 deletions impeller/entity/contents/color_source_text_contents.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/entity/contents/color_source_text_contents.h"

#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/texture_contents.h"
#include "impeller/renderer/render_pass.h"

namespace impeller {

ColorSourceTextContents::ColorSourceTextContents() = default;

ColorSourceTextContents::~ColorSourceTextContents() = default;

void ColorSourceTextContents::SetTextContents(
std::shared_ptr<TextContents> text_contents) {
text_contents_ = std::move(text_contents);
}

void ColorSourceTextContents::SetColorSourceContents(
std::shared_ptr<ColorSourceContents> color_source_contents) {
color_source_contents_ = std::move(color_source_contents);
}

std::optional<Rect> ColorSourceTextContents::GetCoverage(
const Entity& entity) const {
return text_contents_->GetCoverage(entity);
}

void ColorSourceTextContents::SetTextPosition(Point position) {
position_ = position;
}

bool ColorSourceTextContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
auto coverage = text_contents_->GetCoverage(entity);
if (!coverage.has_value()) {
return true;
}
auto transform = entity.GetTransformation();

text_contents_->SetColor(Color::Black());
color_source_contents_->SetGeometry(
Geometry::MakeRect(Rect::MakeSize(coverage->size)));

// offset the color source so it behaves as if it were drawn in the original
// position.
auto effect_transform =
color_source_contents_->GetInverseMatrix().Invert().Translate(-position_);
color_source_contents_->SetEffectTransform(effect_transform);

auto new_texture = renderer.MakeSubpass(
"Text Color Blending", ISize::Ceil(coverage.value().size),
[&](const ContentContext& context, RenderPass& pass) {
Entity sub_entity;
sub_entity.SetTransformation(transform);
sub_entity.SetContents(text_contents_);
sub_entity.SetBlendMode(BlendMode::kSource);
if (!sub_entity.Render(context, pass)) {
return false;
}

sub_entity.SetContents(color_source_contents_);
sub_entity.SetBlendMode(BlendMode::kSourceIn);
return sub_entity.Render(context, pass);
});
if (!new_texture) {
return false;
}

auto dest_rect = Rect::MakeSize(new_texture->GetSize())
.TransformBounds(transform.Invert())
.Shift(position_);

auto texture_contents = TextureContents::MakeRect(dest_rect);
texture_contents->SetTexture(new_texture);
texture_contents->SetSourceRect(Rect::MakeSize(new_texture->GetSize()));
return texture_contents->Render(renderer, entity, pass);
}

} // namespace impeller
48 changes: 48 additions & 0 deletions impeller/entity/contents/color_source_text_contents.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <functional>
#include <memory>
#include <variant>
#include <vector>

#include "flutter/fml/macros.h"
#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/entity/contents/text_contents.h"

namespace impeller {

class ColorSourceTextContents final : public Contents {
public:
ColorSourceTextContents();

~ColorSourceTextContents();

void SetTextContents(std::shared_ptr<TextContents> text_contents);

void SetColorSourceContents(
std::shared_ptr<ColorSourceContents> color_source_contents);

void SetTextPosition(Point position);

// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;

// |Contents|
bool Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const override;

private:
Point position_;
std::shared_ptr<TextContents> text_contents_;
std::shared_ptr<ColorSourceContents> color_source_contents_;

FML_DISALLOW_COPY_AND_ASSIGN(ColorSourceTextContents);
};

} // namespace impeller
17 changes: 12 additions & 5 deletions impeller/entity/contents/text_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ void TextContents::SetColor(Color color) {
color_ = color;
}

void TextContents::SetInverseMatrix(Matrix matrix) {
inverse_matrix_ = matrix;
}

std::optional<Rect> TextContents::GetCoverage(const Entity& entity) const {
auto bounds = frame_.GetBounds();
if (!bounds.has_value()) {
Expand All @@ -71,6 +75,7 @@ static bool CommonRender(
RenderPass& pass,
const Color& color,
const TextFrame& frame,
const Matrix& inverse_matrix,
std::shared_ptr<GlyphAtlas>
atlas, // NOLINT(performance-unnecessary-value-param)
Command& cmd) {
Expand Down Expand Up @@ -159,8 +164,10 @@ static bool CommonRender(

auto uv_scaler_a = atlas_glyph_pos->size / atlas_size;
auto uv_scaler_b = (Point::Round(atlas_glyph_pos->origin) / atlas_size);
auto translation = Matrix::MakeTranslation(
Vector3(offset_glyph_position.x, offset_glyph_position.y, 0));
auto translation =
Matrix::MakeTranslation(
Vector3(offset_glyph_position.x, offset_glyph_position.y, 0)) *
inverse_matrix;

for (const auto& point : unit_points) {
typename VS::PerVertexData vtx;
Expand Down Expand Up @@ -209,8 +216,8 @@ bool TextContents::RenderSdf(const ContentContext& renderer,
cmd.pipeline = renderer.GetGlyphAtlasSdfPipeline(opts);
cmd.stencil_reference = entity.GetStencilDepth();

return CommonRender<GlyphAtlasSdfPipeline>(renderer, entity, pass, color_,
frame_, atlas, cmd);
return CommonRender<GlyphAtlasSdfPipeline>(
renderer, entity, pass, color_, frame_, inverse_matrix_, atlas, cmd);
}

bool TextContents::Render(const ContentContext& renderer,
Expand Down Expand Up @@ -245,7 +252,7 @@ bool TextContents::Render(const ContentContext& renderer,
cmd.stencil_reference = entity.GetStencilDepth();

return CommonRender<GlyphAtlasPipeline>(renderer, entity, pass, color_,
frame_, atlas, cmd);
frame_, inverse_matrix_, atlas, cmd);
}

} // namespace impeller
3 changes: 3 additions & 0 deletions impeller/entity/contents/text_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class TextContents final : public Contents {

void SetColor(Color color);

void SetInverseMatrix(Matrix matrix);

// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;

Expand All @@ -49,6 +51,7 @@ class TextContents final : public Contents {
TextFrame frame_;
Color color_;
mutable std::shared_ptr<LazyGlyphAtlas> lazy_atlas_;
Matrix inverse_matrix_;

std::shared_ptr<GlyphAtlas> ResolveAtlas(
GlyphAtlas::Type type,
Expand Down
7 changes: 7 additions & 0 deletions impeller/geometry/geometry_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,13 @@ TEST(GeometryTest, RectGetPoints) {
ASSERT_POINT_NEAR(points[3], Point(400, 600));
}

TEST(GeometryTest, RectShift) {
auto r = Rect::MakeLTRB(0, 0, 100, 100);

ASSERT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
ASSERT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
}

TEST(GeometryTest, RectGetTransformedPoints) {
Rect r(100, 200, 300, 400);
auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
Expand Down
6 changes: 6 additions & 0 deletions impeller/geometry/rect.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ struct TRect {

return *this;
}

/// @brief Returns a new rectangle translated by the given offset.
constexpr TRect<T> Shift(TPoint<T> offset) const {
return TRect(origin.x + offset.x, origin.y + offset.y, size.width,
size.height);
}
};

using Rect = TRect<Scalar>;
Expand Down