44
55#include " impeller/entity/contents/text_contents.h"
66
7- #include < iostream>
87#include < optional>
8+ #include < type_traits>
99
1010#include " impeller/entity/contents/content_context.h"
1111#include " impeller/entity/entity.h"
@@ -28,22 +28,16 @@ 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-
3531void TextContents::SetGlyphAtlas (std::shared_ptr<LazyGlyphAtlas> atlas) {
36- atlas_ = std::move (atlas);
32+ lazy_atlas_ = std::move (atlas);
3733}
3834
3935std::shared_ptr<GlyphAtlas> TextContents::ResolveAtlas (
36+ GlyphAtlas::Type type,
4037 std::shared_ptr<Context> context) const {
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;
38+ FML_DCHECK (lazy_atlas_);
39+ if (lazy_atlas_) {
40+ return lazy_atlas_->CreateOrGetGlyphAtlas (type, context);
4741 }
4842
4943 return nullptr ;
@@ -61,33 +55,19 @@ std::optional<Rect> TextContents::GetCoverage(const Entity& entity) const {
6155 return bounds->TransformBounds (entity.GetTransformation ());
6256}
6357
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 ();
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;
8868
8969 // Common vertex uniforms for all glyphs.
90- VS::FrameInfo frame_info;
70+ typename VS::FrameInfo frame_info;
9171 frame_info.mvp = Matrix::MakeOrthographic (pass.GetRenderTargetSize ()) *
9272 entity.GetTransformation ();
9373 VS::BindFrameInfo (cmd, pass.GetTransientsBuffer ().EmplaceUniform (frame_info));
@@ -96,8 +76,8 @@ bool TextContents::Render(const ContentContext& renderer,
9676 sampler_desc.min_filter = MinMagFilter::kLinear ;
9777 sampler_desc.mag_filter = MinMagFilter::kLinear ;
9878
99- FS::FragInfo frag_info;
100- frag_info.text_color = ToVector (color_ .Premultiply ());
79+ typename FS::FragInfo frag_info;
80+ frag_info.text_color = ToVector (color .Premultiply ());
10181 frag_info.atlas_size =
10282 Point{static_cast <Scalar>(atlas->GetTexture ()->GetSize ().width ),
10383 static_cast <Scalar>(atlas->GetTexture ()->GetSize ().height )};
@@ -122,16 +102,15 @@ bool TextContents::Render(const ContentContext& renderer,
122102 {0 , 0 }, {1 , 0 }, {0 , 1 }, {1 , 0 }, {0 , 1 }, {1 , 1 },
123103 };
124104
125- VertexBufferBuilder<VS::PerVertexData> vertex_builder;
126- for (const auto & run : frame_ .GetRuns ()) {
105+ VertexBufferBuilder<typename VS::PerVertexData> vertex_builder;
106+ for (const auto & run : frame .GetRuns ()) {
127107 auto font = run.GetFont ();
128108 auto glyph_size = ISize::Ceil (font.GetMetrics ().GetBoundingBox ().size );
129109 for (const auto & glyph_position : run.GetGlyphPositions ()) {
130110 FontGlyphPair font_glyph_pair{font, glyph_position.glyph };
131- auto color_glyph =
132- atlas->IsColorFontGlyphPair (font_glyph_pair) ? 1.0 : 0.0 ;
111+
133112 for (const auto & point : unit_vertex_points) {
134- VS::PerVertexData vtx;
113+ typename VS::PerVertexData vtx;
135114 vtx.unit_vertex = point;
136115
137116 auto atlas_glyph_pos = atlas->FindFontGlyphPosition (font_glyph_pair);
@@ -149,7 +128,10 @@ bool TextContents::Render(const ContentContext& renderer,
149128 1 / atlas_glyph_pos->size .height };
150129 vtx.atlas_glyph_size =
151130 Point{atlas_glyph_pos->size .width , atlas_glyph_pos->size .height };
152- vtx.color_glyph = color_glyph;
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+ }
153135 vertex_builder.AppendVertex (std::move (vtx));
154136 }
155137 }
@@ -165,4 +147,55 @@ bool TextContents::Render(const ContentContext& renderer,
165147 return true ;
166148}
167149
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+
168201} // namespace impeller
0 commit comments