44
55#include " impeller/entity/contents/text_contents.h"
66
7+ #include < iostream>
78#include < optional>
8- #include < type_traits>
99
1010#include " impeller/entity/contents/content_context.h"
1111#include " impeller/entity/entity.h"
@@ -28,16 +28,22 @@ void TextContents::SetTextFrame(TextFrame frame) {
2828 frame_ = std::move (frame);
2929}
3030
31+ void TextContents::SetGlyphAtlas (std::shared_ptr<GlyphAtlas> atlas) {
32+ atlas_ = std::move (atlas);
33+ }
34+
3135void TextContents::SetGlyphAtlas (std::shared_ptr<LazyGlyphAtlas> atlas) {
32- lazy_atlas_ = std::move (atlas);
36+ atlas_ = std::move (atlas);
3337}
3438
3539std::shared_ptr<GlyphAtlas> TextContents::ResolveAtlas (
36- GlyphAtlas::Type type,
3740 std::shared_ptr<Context> context) const {
38- FML_DCHECK (lazy_atlas_);
39- if (lazy_atlas_) {
40- return lazy_atlas_->CreateOrGetGlyphAtlas (type, context);
41+ if (auto lazy_atlas = std::get_if<std::shared_ptr<LazyGlyphAtlas>>(&atlas_)) {
42+ return lazy_atlas->get ()->CreateOrGetGlyphAtlas (context);
43+ }
44+
45+ if (auto atlas = std::get_if<std::shared_ptr<GlyphAtlas>>(&atlas_)) {
46+ return *atlas;
4147 }
4248
4349 return nullptr ;
@@ -55,19 +61,33 @@ std::optional<Rect> TextContents::GetCoverage(const Entity& entity) const {
5561 return bounds->TransformBounds (entity.GetTransformation ());
5662}
5763
58- template <class TPipeline >
59- static bool CommonRender (const ContentContext& renderer,
60- const Entity& entity,
61- RenderPass& pass,
62- const Color& color,
63- const TextFrame& frame,
64- std::shared_ptr<GlyphAtlas> atlas,
65- Command& cmd) {
66- using VS = typename TPipeline::VertexShader;
67- using FS = typename TPipeline::FragmentShader;
64+ bool TextContents::Render (const ContentContext& renderer,
65+ const Entity& entity,
66+ RenderPass& pass) const {
67+ if (color_.IsTransparent ()) {
68+ return true ;
69+ }
70+
71+ auto atlas = ResolveAtlas (renderer.GetContext ());
72+
73+ if (!atlas || !atlas->IsValid ()) {
74+ VALIDATION_LOG << " Cannot render glyphs without prepared atlas." ;
75+ return false ;
76+ }
77+
78+ using VS = GlyphAtlasPipeline::VertexShader;
79+ using FS = GlyphAtlasPipeline::FragmentShader;
80+
81+ // Information shared by all glyph draw calls.
82+ Command cmd;
83+ cmd.label = " TextFrame" ;
84+ cmd.primitive_type = PrimitiveType::kTriangle ;
85+ cmd.pipeline =
86+ renderer.GetGlyphAtlasPipeline (OptionsFromPassAndEntity (pass, entity));
87+ cmd.stencil_reference = entity.GetStencilDepth ();
6888
6989 // Common vertex uniforms for all glyphs.
70- typename VS::FrameInfo frame_info;
90+ VS::FrameInfo frame_info;
7191 frame_info.mvp = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
7292 entity.GetTransformation ();
7393 VS::BindFrameInfo (cmd, pass.GetTransientsBuffer ().EmplaceUniform (frame_info));
@@ -76,8 +96,8 @@ static bool CommonRender(const ContentContext& renderer,
7696 sampler_desc.min_filter = MinMagFilter::kLinear ;
7797 sampler_desc.mag_filter = MinMagFilter::kLinear ;
7898
79- typename FS::FragInfo frag_info;
80- frag_info.text_color = ToVector (color .Premultiply ());
99+ FS::FragInfo frag_info;
100+ frag_info.text_color = ToVector (color_ .Premultiply ());
81101 frag_info.atlas_size =
82102 Point{static_cast <Scalar>(atlas->GetTexture ()->GetSize ().width ),
83103 static_cast <Scalar>(atlas->GetTexture ()->GetSize ().height )};
@@ -102,15 +122,16 @@ static bool CommonRender(const ContentContext& renderer,
102122 {0 , 0 }, {1 , 0 }, {0 , 1 }, {1 , 0 }, {0 , 1 }, {1 , 1 },
103123 };
104124
105- VertexBufferBuilder<typename VS::PerVertexData> vertex_builder;
106- for (const auto & run : frame .GetRuns ()) {
125+ VertexBufferBuilder<VS::PerVertexData> vertex_builder;
126+ for (const auto & run : frame_ .GetRuns ()) {
107127 auto font = run.GetFont ();
108128 auto glyph_size = ISize::Ceil (font.GetMetrics ().GetBoundingBox ().size );
109129 for (const auto & glyph_position : run.GetGlyphPositions ()) {
110130 FontGlyphPair font_glyph_pair{font, glyph_position.glyph };
111-
131+ auto color_glyph =
132+ atlas->IsColorFontGlyphPair (font_glyph_pair) ? 1.0 : 0.0 ;
112133 for (const auto & point : unit_vertex_points) {
113- typename VS::PerVertexData vtx;
134+ VS::PerVertexData vtx;
114135 vtx.unit_vertex = point;
115136
116137 auto atlas_glyph_pos = atlas->FindFontGlyphPosition (font_glyph_pair);
@@ -128,10 +149,7 @@ static bool CommonRender(const ContentContext& renderer,
128149 1 / atlas_glyph_pos->size .height };
129150 vtx.atlas_glyph_size =
130151 Point{atlas_glyph_pos->size .width , atlas_glyph_pos->size .height };
131- if constexpr (std::is_same_v<TPipeline, GlyphAtlasPipeline>) {
132- vtx.color_glyph =
133- glyph_position.glyph .type == Glyph::Type::kBitmap ? 1.0 : 0.0 ;
134- }
152+ vtx.color_glyph = color_glyph;
135153 vertex_builder.AppendVertex (std::move (vtx));
136154 }
137155 }
@@ -147,55 +165,4 @@ static bool CommonRender(const ContentContext& renderer,
147165 return true ;
148166}
149167
150- bool TextContents::RenderSdf (const ContentContext& renderer,
151- const Entity& entity,
152- RenderPass& pass) const {
153- auto atlas = ResolveAtlas (GlyphAtlas::Type::kSignedDistanceField ,
154- renderer.GetContext ());
155-
156- if (!atlas || !atlas->IsValid ()) {
157- VALIDATION_LOG << " Cannot render glyphs without prepared atlas." ;
158- return false ;
159- }
160-
161- // Information shared by all glyph draw calls.
162- Command cmd;
163- cmd.label = " TextFrameSDF" ;
164- cmd.primitive_type = PrimitiveType::kTriangle ;
165- cmd.pipeline =
166- renderer.GetGlyphAtlasSdfPipeline (OptionsFromPassAndEntity (pass, entity));
167- cmd.stencil_reference = entity.GetStencilDepth ();
168-
169- return CommonRender<GlyphAtlasSdfPipeline>(renderer, entity, pass, color_,
170- frame_, atlas, cmd);
171- }
172-
173- bool TextContents::Render (const ContentContext& renderer,
174- const Entity& entity,
175- RenderPass& pass) const {
176- if (color_.IsTransparent ()) {
177- return true ;
178- }
179-
180- auto atlas = ResolveAtlas (frame_.HasColor () ? GlyphAtlas::Type::kColorBitmap
181- : GlyphAtlas::Type::kAlphaBitmap ,
182- renderer.GetContext ());
183-
184- if (!atlas || !atlas->IsValid ()) {
185- VALIDATION_LOG << " Cannot render glyphs without prepared atlas." ;
186- return false ;
187- }
188-
189- // Information shared by all glyph draw calls.
190- Command cmd;
191- cmd.label = " TextFrame" ;
192- cmd.primitive_type = PrimitiveType::kTriangle ;
193- cmd.pipeline =
194- renderer.GetGlyphAtlasPipeline (OptionsFromPassAndEntity (pass, entity));
195- cmd.stencil_reference = entity.GetStencilDepth ();
196-
197- return CommonRender<GlyphAtlasPipeline>(renderer, entity, pass, color_,
198- frame_, atlas, cmd);
199- }
200-
201168} // namespace impeller
0 commit comments