Skip to content

Commit

Permalink
Relay text color from Paint. (flutter#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde authored and dnfield committed Apr 27, 2022
1 parent 9f9c557 commit 4e323c6
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 69 deletions.
106 changes: 40 additions & 66 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,11 @@ static sk_sp<SkData> OpenFixtureAsSkData(const char* fixture_name) {
mapping.release());
}

TEST_F(AiksTest, CanRenderTextFrame) {
Canvas canvas;

bool RenderTextInCanvas(std::shared_ptr<Context> context,
Canvas& canvas,
const std::string& text,
const std::string& font_fixture,
Scalar font_size = 50.0) {
Scalar baseline = 200.0;
Point text_position = {100, baseline};

Expand All @@ -314,84 +316,56 @@ TEST_F(AiksTest, CanRenderTextFrame) {
Paint{.color = Color::Red().WithAlpha(0.25)});

// Construct the text blob.
auto mapping = OpenFixtureAsSkData("Roboto-Regular.ttf");
ASSERT_TRUE(mapping);
auto mapping = OpenFixtureAsSkData(font_fixture.c_str());
if (!mapping) {
return false;
}
SkFont sk_font(SkTypeface::MakeFromData(mapping), 50.0);
auto blob = SkTextBlob::MakeFromString(
"the quick brown fox jumped over the lazy dog!.?", sk_font);
ASSERT_TRUE(blob);
auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
if (!blob) {
return false;
}

// Create the Impeller text frame and draw it at the designated baseline.
auto frame = TextFrameFromTextBlob(blob);
TextRenderContextSkia text_context(GetContext());
ASSERT_TRUE(text_context.IsValid());
TextRenderContextSkia text_context(context);
if (!text_context.IsValid()) {
return false;
}
auto atlas = text_context.CreateGlyphAtlas(frame);
ASSERT_NE(atlas, nullptr);
canvas.DrawTextFrame(std::move(frame), std::move(atlas), text_position);
if (!atlas) {
return false;
}

Paint text_paint;
text_paint.color = Color::Yellow();
canvas.DrawTextFrame(std::move(frame), std::move(atlas), text_position,
text_paint);
return true;
}

TEST_F(AiksTest, CanRenderTextFrame) {
Canvas canvas;
ASSERT_TRUE(RenderTextInCanvas(
GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
"Roboto-Regular.ttf"));
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

TEST_F(AiksTest, CanRenderItalicizedText) {
Canvas canvas;

Scalar baseline = 200.0;
Point text_position = {100, baseline};

// Draw the baseline.
canvas.DrawRect({50, baseline, 900, 10},
Paint{.color = Color::Aqua().WithAlpha(0.25)});

// Mark the point at which the text is drawn.
canvas.DrawCircle(text_position, 5.0,
Paint{.color = Color::Red().WithAlpha(0.25)});

// Construct the text blob.
auto mapping = OpenFixtureAsSkData("HomemadeApple.ttf");
ASSERT_TRUE(mapping);
SkFont sk_font(SkTypeface::MakeFromData(mapping), 50.0);
auto blob = SkTextBlob::MakeFromString(
"the quick brown fox jumped over the lazy dog!.?", sk_font);
ASSERT_TRUE(blob);

// Create the Impeller text frame and draw it at the designated baseline.
auto frame = TextFrameFromTextBlob(blob);
TextRenderContextSkia text_context(GetContext());
ASSERT_TRUE(text_context.IsValid());
auto atlas = text_context.CreateGlyphAtlas(frame);
ASSERT_NE(atlas, nullptr);
canvas.DrawTextFrame(std::move(frame), std::move(atlas), text_position);
ASSERT_TRUE(RenderTextInCanvas(
GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
"HomemadeApple.ttf"));
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

TEST_F(AiksTest, CanRenderEmojiTextFrame) {
Canvas canvas;

Scalar baseline = 200.0;
Point text_position = {100, baseline};

// Draw the baseline.
canvas.DrawRect({50, baseline, 900, 10},
Paint{.color = Color::Aqua().WithAlpha(0.25)});

// Mark the point at which the text is drawn.
canvas.DrawCircle(text_position, 5.0,
Paint{.color = Color::Red().WithAlpha(0.25)});

// Construct the text blob.
auto mapping = OpenFixtureAsSkData("NotoColorEmoji.ttf");
ASSERT_TRUE(mapping);
SkFont sk_font(SkTypeface::MakeFromData(mapping), 50.0);
auto blob = SkTextBlob::MakeFromString(
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 ☺️ 😊", sk_font);
ASSERT_TRUE(blob);

// Create the Impeller text frame and draw it at the designated baseline.
auto frame = TextFrameFromTextBlob(blob);
TextRenderContextSkia text_context(GetContext());
ASSERT_TRUE(text_context.IsValid());
auto atlas = text_context.CreateGlyphAtlas(frame);
ASSERT_NE(atlas, nullptr);
canvas.DrawTextFrame(std::move(frame), std::move(atlas), text_position);
ASSERT_TRUE(RenderTextInCanvas(
GetContext(), canvas,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 ☺️ 😊",
"NotoColorEmoji.ttf"));
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}

Expand Down
4 changes: 3 additions & 1 deletion impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,16 @@ void Canvas::Save(bool create_subpass) {

void Canvas::DrawTextFrame(TextFrame text_frame,
std::shared_ptr<GlyphAtlas> atlas,
Point position) {
Point position,
Paint paint) {
if (!atlas || !atlas->IsValid()) {
return;
}

auto text_contents = std::make_shared<TextContents>();
text_contents->SetTextFrame(std::move(text_frame));
text_contents->SetGlyphAtlas(std::move(atlas));
text_contents->SetColor(paint.color);

Entity entity;
entity.SetTransformation(GetCurrentTransformation() *
Expand Down
3 changes: 2 additions & 1 deletion impeller/aiks/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ class Canvas {

void DrawTextFrame(TextFrame text_frame,
std::shared_ptr<GlyphAtlas> atlas,
Point position);
Point position,
Paint paint);

Picture EndRecordingAsPicture();

Expand Down
9 changes: 9 additions & 0 deletions impeller/entity/contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -568,9 +568,17 @@ void TextContents::SetGlyphAtlas(std::shared_ptr<GlyphAtlas> atlas) {
atlas_ = std::move(atlas);
}

void TextContents::SetColor(Color color) {
color_ = color;
}

bool TextContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
if (color_.IsTransparent()) {
return true;
}

if (!atlas_ || !atlas_->IsValid()) {
VALIDATION_LOG << "Cannot render glyphs without prepared atlas.";
return false;
Expand All @@ -593,6 +601,7 @@ bool TextContents::Render(const ContentContext& renderer,
frame_info.atlas_size =
Point{static_cast<Scalar>(atlas_->GetTexture()->GetSize().width),
static_cast<Scalar>(atlas_->GetTexture()->GetSize().height)};
frame_info.text_color = ToVector(color_);
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));

// Common fragment uniforms for all glyphs.
Expand Down
3 changes: 3 additions & 0 deletions impeller/entity/contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,16 @@ class TextContents final : public Contents {

void SetGlyphAtlas(std::shared_ptr<GlyphAtlas> atlas);

void SetColor(Color color);

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

private:
TextFrame frame_;
Color color_;
std::shared_ptr<GlyphAtlas> atlas_;

FML_DISALLOW_COPY_AND_ASSIGN(TextContents);
Expand Down
3 changes: 2 additions & 1 deletion impeller/entity/shaders/glyph_atlas.frag
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ in vec2 v_unit_vertex;
in vec2 v_atlas_position;
in vec2 v_atlas_glyph_size;
in vec2 v_atlas_size;
in vec4 v_text_color;

out vec4 frag_color;

Expand All @@ -18,5 +19,5 @@ void main() {
frag_color = texture(
glyph_atlas_sampler,
v_unit_vertex * scale_perspective + offset
);
) * v_text_color;
}
3 changes: 3 additions & 0 deletions impeller/entity/shaders/glyph_atlas.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
uniform FrameInfo {
mat4 mvp;
vec2 atlas_size;
vec4 text_color;
} frame_info;

uniform GlyphInfo {
Expand All @@ -20,6 +21,7 @@ out vec2 v_unit_vertex;
out vec2 v_atlas_position;
out vec2 v_atlas_glyph_size;
out vec2 v_atlas_size;
out vec4 v_text_color;

void main() {
mat4 scale = mat4(
Expand All @@ -37,4 +39,5 @@ void main() {
v_atlas_position = glyph_info.atlas_position;
v_atlas_glyph_size = glyph_info.atlas_glyph_size;
v_atlas_size = frame_info.atlas_size;
v_text_color = frame_info.text_color;
}
4 changes: 4 additions & 0 deletions impeller/renderer/shader_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,8 @@ struct Padding {
uint8_t pad_[Size];
};

inline constexpr Vector4 ToVector(Color color) {
return {color.red, color.green, color.blue, color.alpha};
}

} // namespace impeller

0 comments on commit 4e323c6

Please sign in to comment.