45 inherited_opacity_ = opacity;
53 force_text_color_ =
value;
57 return frame_->GetBounds().TransformBounds(entity.
GetTransform());
66 if (frame_->HasColor()) {
81 VS::PerVertexData* vtx_contents,
82 const std::shared_ptr<TextFrame>& frame,
84 const Matrix& entity_transform,
86 std::optional<GlyphProperties> glyph_properties,
87 const std::shared_ptr<GlyphAtlas>& atlas) {
95 constexpr std::array<Point, 6> unit_points = {
Point{0, 0},
Point{1, 0},
99 ISize atlas_size = atlas->GetTexture()->GetSize();
103 VS::PerVertexData
vtx;
105 size_t bounds_offset = 0u;
106 for (
const TextRun& run : frame->GetRuns()) {
107 const Font& font = run.GetFont();
108 Scalar rounded_scale = frame->GetScale();
114 Point subpixel_adjustment(0.5, 0.5);
119 subpixel_adjustment.
x = 0.125;
122 subpixel_adjustment.
y = 0.125;
125 subpixel_adjustment.
x = 0.125;
126 subpixel_adjustment.
y = 0.125;
130 Point screen_offset = (entity_transform *
Point(0, 0));
132 run.GetGlyphPositions()) {
133 const FrameBounds& frame_bounds = frame->GetFrameBounds(bounds_offset);
145 atlas->GetOrCreateFontGlyphAtlas(
ScaledFont{font, rounded_scale});
155 std::optional<FrameBounds> maybe_atlas_glyph_bounds =
157 glyph_position.
glyph,
161 if (!maybe_atlas_glyph_bounds.has_value()) {
165 atlas_glyph_bounds = maybe_atlas_glyph_bounds.value().atlas_bounds;
168 Rect scaled_bounds = glyph_bounds.
Scale(1.0 / rounded_scale);
174 Point uv_origin = (atlas_glyph_bounds.GetLeftTop()) / atlas_size;
179 basis_transform.
m[5] > 0 ? 1.f : -1.f, 1.f});
180 Point unrounded_glyph_position =
182 unscaled_basis * glyph_bounds.GetLeftTop() +
183 (basis_transform * glyph_position.position);
185 Point screen_glyph_position =
186 (screen_offset + unrounded_glyph_position + subpixel_adjustment)
188 for (
const Point& point : unit_points) {
190 if (is_translation_scale) {
191 position = (screen_glyph_position +
192 (unscaled_basis * point * glyph_bounds.GetSize()))
195 position = entity_transform *
196 (glyph_position.position + scaled_bounds.
GetLeftTop() +
197 point * scaled_bounds.
GetSize());
199 vtx.uv = uv_origin + (uv_size * point);
200 vtx.position = position;
201 vtx_contents[i++] =
vtx;
211 if (color.IsTransparent()) {
215 auto type = frame_->GetAtlasType();
216 const std::shared_ptr<GlyphAtlas>& atlas =
220 if (!atlas || !atlas->IsValid()) {
224 if (!frame_->IsFrameComplete()) {
236 VS::FrameInfo frame_info;
242 VS::BindFrameInfo(pass,
245 FS::FragInfo frag_info;
246 frag_info.use_text_color = force_text_color_ ? 1.0 : 0.0;
247 frag_info.text_color =
ToVector(color.Premultiply());
250 FS::BindFragInfo(pass,
254 if (is_translation_scale) {
270 FS::BindGlyphAtlasSampler(
273 renderer.
GetContext()->GetSamplerLibrary()->GetSampler(
278 size_t vertex_count = 0;
279 for (
const auto& run : frame_->GetRuns()) {
280 vertex_count += run.GetGlyphPositions().size();
285 vertex_count *
sizeof(VS::PerVertexData),
alignof(VS::PerVertexData),
286 [&](uint8_t* contents) {
287 VS::PerVertexData* vtx_contents =
288 reinterpret_cast<VS::PerVertexData*
>(contents);
290 entity_transform, offset_,
291 GetGlyphProperties(), atlas);
298 return pass.
Draw().ok();
301 std::optional<GlyphProperties> TextContents::GetGlyphProperties()
const {
302 return (properties_.
stroke || frame_->HasColor())
303 ? std::optional<GlyphProperties>(properties_)
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
const std::shared_ptr< LazyGlyphAtlas > & GetLazyGlyphAtlas() const
PipelineRef GetGlyphAtlasPipeline(ContentContextOptions opts) const
std::shared_ptr< Context > GetContext() const
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
float GetShaderClipDepth() const
An object that can look up glyph locations within the GlyphAtlas for a particular typeface.
std::optional< FrameBounds > FindGlyphBounds(const SubpixelGlyph &glyph) const
Find the location of a glyph in the atlas.
Describes a typeface along with any modifications to its intrinsic properties.
AxisAlignment GetAxisAlignment() const
BufferView EmplaceUniform(const UniformType &uniform)
Emplace uniform data onto the host buffer. Ensure that backend specific uniform alignment requirement...
Render passes encode render commands directed as one specific render target into an underlying comman...
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
virtual bool SetIndexBuffer(BufferView index_buffer, IndexType index_type)
Specify an index buffer to use for this command. To unset the index buffer, pass IndexType::kNone to ...
virtual void SetPipeline(PipelineRef pipeline)
The pipeline to use for this command.
virtual fml::Status Draw()
Record the currently pending command.
virtual void SetElementCount(size_t count)
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
VertexShader_ VertexShader
FragmentShader_ FragmentShader
void SetOffset(Vector2 offset)
void SetTextProperties(Color color, bool stroke, Scalar stroke_width, Cap stroke_cap, Join stroke_join, Scalar stroke_miter)
Must be set after text frame.
void SetInheritedOpacity(Scalar opacity) override
Inherit the provided opacity.
void SetForceTextColor(bool value)
Force the text color to apply to the rendered glyphs, even if those glyphs are bitmaps.
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
std::optional< Rect > GetCoverage(const Entity &entity) const override
Get the area of the render pass that will be affected when this contents is rendered.
void SetTextFrame(const std::shared_ptr< TextFrame > &frame)
void SetColor(Color color)
static void ComputeVertexData(GlyphAtlasPipeline::VertexShader::PerVertexData *vtx_contents, const std::shared_ptr< TextFrame > &frame, Scalar scale, const Matrix &entity_transform, Vector2 offset, std::optional< GlyphProperties > glyph_properties, const std::shared_ptr< GlyphAtlas > &atlas)
static Point ComputeSubpixelPosition(const TextRun::GlyphPosition &glyph_position, AxisAlignment alignment, const Matrix &transform)
Represents a collection of positioned glyphs from a specific font.
@ kNone
Does not use the index buffer.
GlyphAtlasPipeline::VertexShader VS
@ kBase
The texture is sampled as if it only had a single mipmap level.
Point SizeToPoint(Size size)
constexpr Vector4 ToVector(Color color)
GlyphAtlasPipeline::FragmentShader FS
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
@ kNearest
Select nearest to the sample point. Most widely supported.
SolidFillVertexShader::PerVertexData vtx
const Scalar stroke_width
constexpr Color WithAlpha(Scalar new_alpha) const
Rect atlas_bounds
The bounds of the glyph within the glyph atlas.
Rect glyph_bounds
The local glyph bounds.
A 4x4 matrix using column-major storage.
constexpr bool IsTranslationScaleOnly() const
Returns true if the matrix has a scale-only basis and is non-projective. Note that an identity matrix...
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
static constexpr Matrix MakeScale(const Vector3 &s)
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
A glyph and its subpixel position.
static constexpr TPoint Round(const TPoint< U > &other)
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
constexpr TRect Scale(Type scale) const
constexpr TPoint< T > GetLeftTop() const