45 inherited_opacity_ = opacity;
53 force_text_color_ =
value;
57 return frame_->GetBounds().TransformBounds(entity.
GetTransform());
66 if (frame_->HasColor()) {
84 const Scalar epsilon = 0.005f;
85 if (std::abs(
x - 1.f) < epsilon) {
88 if (std::abs(
x + 1.f) < epsilon) {
97 VS::PerVertexData* vtx_contents,
98 const std::shared_ptr<TextFrame>& frame,
100 const Matrix& entity_transform,
102 std::optional<GlyphProperties> glyph_properties,
103 const std::shared_ptr<GlyphAtlas>& atlas) {
111 constexpr std::array<Point, 6> unit_points = {
Point{0, 0},
Point{1, 0},
115 ISize atlas_size = atlas->GetTexture()->GetSize();
119 VS::PerVertexData
vtx;
121 size_t bounds_offset = 0u;
122 for (
const TextRun& run : frame->GetRuns()) {
123 const Font& font = run.GetFont();
124 Scalar rounded_scale = frame->GetScale();
130 Point subpixel_adjustment(0.5, 0.5);
135 subpixel_adjustment.
x = 0.125;
138 subpixel_adjustment.
y = 0.125;
141 subpixel_adjustment.
x = 0.125;
142 subpixel_adjustment.
y = 0.125;
146 Point screen_offset = (entity_transform *
Point(0, 0));
148 run.GetGlyphPositions()) {
149 const FrameBounds& frame_bounds = frame->GetFrameBounds(bounds_offset);
161 atlas->GetOrCreateFontGlyphAtlas(
ScaledFont{font, rounded_scale});
171 std::optional<FrameBounds> maybe_atlas_glyph_bounds =
173 glyph_position.
glyph,
177 if (!maybe_atlas_glyph_bounds.has_value()) {
181 atlas_glyph_bounds = maybe_atlas_glyph_bounds.value().atlas_bounds;
184 Scalar inverted_rounded_scale = 1.f / rounded_scale;
185 Rect scaled_bounds = glyph_bounds.
Scale(inverted_rounded_scale);
191 Point uv_origin = (atlas_glyph_bounds.GetLeftTop()) / atlas_size;
196 inverted_rounded_scale, 1});
200 unscaled_basis.
m[0] = AttractToOne(unscaled_basis.
m[0]);
201 unscaled_basis.
m[5] = AttractToOne(unscaled_basis.
m[5]);
203 Point unrounded_glyph_position =
205 unscaled_basis * glyph_bounds.GetLeftTop() +
206 (basis_transform * glyph_position.position);
208 Point screen_glyph_position =
209 (screen_offset + unrounded_glyph_position + subpixel_adjustment)
211 for (
const Point& point : unit_points) {
213 if (is_translation_scale) {
214 position = (screen_glyph_position +
215 (unscaled_basis * point * glyph_bounds.GetSize()))
218 position = entity_transform *
219 (glyph_position.position + scaled_bounds.
GetLeftTop() +
220 point * scaled_bounds.
GetSize());
222 vtx.uv = uv_origin + (uv_size * point);
223 vtx.position = position;
224 vtx_contents[i++] =
vtx;
234 if (color.IsTransparent()) {
238 auto type = frame_->GetAtlasType();
239 const std::shared_ptr<GlyphAtlas>& atlas =
243 if (!atlas || !atlas->IsValid()) {
247 if (!frame_->IsFrameComplete()) {
259 VS::FrameInfo frame_info;
265 VS::BindFrameInfo(pass,
268 FS::FragInfo frag_info;
269 frag_info.use_text_color = force_text_color_ ? 1.0 : 0.0;
270 frag_info.text_color =
ToVector(color.Premultiply());
273 FS::BindFragInfo(pass,
277 if (is_translation_scale) {
293 FS::BindGlyphAtlasSampler(
296 renderer.
GetContext()->GetSamplerLibrary()->GetSampler(
301 size_t vertex_count = 0;
302 for (
const auto& run : frame_->GetRuns()) {
303 vertex_count += run.GetGlyphPositions().size();
308 vertex_count *
sizeof(VS::PerVertexData),
alignof(VS::PerVertexData),
309 [&](uint8_t* contents) {
310 VS::PerVertexData* vtx_contents =
311 reinterpret_cast<VS::PerVertexData*
>(contents);
313 entity_transform, offset_,
314 GetGlyphProperties(), atlas);
321 return pass.
Draw().ok();
324 std::optional<GlyphProperties> TextContents::GetGlyphProperties()
const {
325 return (properties_.
stroke || frame_->HasColor())
326 ? 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