45 inherited_opacity_ = opacity;
53 force_text_color_ =
value;
57 return frame_->GetBounds().TransformBounds(entity.
GetTransform());
62 const std::optional<StrokeParameters>& stroke) {
63 if (frame_->HasColor()) {
68 properties_.
stroke = stroke;
75 const Scalar epsilon = 0.005f;
76 if (std::abs(
x - 1.f) < epsilon) {
79 if (std::abs(
x + 1.f) < epsilon) {
88 VS::PerVertexData* vtx_contents,
89 const std::shared_ptr<TextFrame>& frame,
91 const Matrix& entity_transform,
93 std::optional<GlyphProperties> glyph_properties,
94 const std::shared_ptr<GlyphAtlas>& atlas) {
102 constexpr std::array<Point, 4> unit_points = {
Point{0, 0},
Point{1, 0},
105 ISize atlas_size = atlas->GetTexture()->GetSize();
109 VS::PerVertexData vtx;
111 size_t bounds_offset = 0u;
112 Rational rounded_scale = frame->GetScale();
120 unscaled_basis.
m[0] = AttractToOne(unscaled_basis.
m[0]);
121 unscaled_basis.
m[5] = AttractToOne(unscaled_basis.
m[5]);
123 for (
const TextRun& run : frame->GetRuns()) {
124 const Font& font = run.GetFont();
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 Rect scaled_bounds = glyph_bounds.
Scale(inverted_rounded_scale);
190 Point uv_origin = atlas_glyph_bounds.GetLeftTop() / atlas_size;
193 Point unrounded_glyph_position =
195 unscaled_basis * glyph_bounds.GetLeftTop() +
196 (basis_transform * glyph_position.position);
198 Point screen_glyph_position =
199 (screen_offset + unrounded_glyph_position + subpixel_adjustment)
201 for (
const Point& point : unit_points) {
203 if (is_translation_scale) {
204 position = (screen_glyph_position +
205 (unscaled_basis * point * glyph_bounds.GetSize()))
208 position = entity_transform *
209 (glyph_position.position + scaled_bounds.
GetLeftTop() +
210 point * scaled_bounds.
GetSize());
212 vtx.uv = uv_origin + (uv_size * point);
213 vtx.position = position;
214 vtx_contents[i++] = vtx;
229 const std::shared_ptr<GlyphAtlas>& atlas =
233 if (!atlas || !atlas->IsValid()) {
237 if (!frame_->IsFrameComplete()) {
249 VS::FrameInfo frame_info;
255 VS::BindFrameInfo(pass,
258 FS::FragInfo frag_info;
259 frag_info.use_text_color = force_text_color_ ? 1.0 : 0.0;
263 FS::BindFragInfo(pass,
267 if (is_translation_scale) {
283 FS::BindGlyphAtlasSampler(
286 renderer.
GetContext()->GetSamplerLibrary()->GetSampler(
291 size_t glyph_count = 0;
292 for (
const auto& run : frame_->GetRuns()) {
293 glyph_count += run.GetGlyphPositions().size();
295 size_t vertex_count = glyph_count * 4;
296 size_t index_count = glyph_count * 6;
299 vertex_count *
sizeof(VS::PerVertexData),
alignof(VS::PerVertexData),
301 VS::PerVertexData* vtx_contents =
302 reinterpret_cast<VS::PerVertexData*
>(
data);
308 GetGlyphProperties(),
312 index_count *
sizeof(uint16_t),
alignof(uint16_t), [&](uint8_t*
data) {
313 uint16_t* indices =
reinterpret_cast<uint16_t*
>(
data);
315 for (
auto i = 0u; i < glyph_count; i++) {
317 indices[j++] = base + 0;
318 indices[j++] = base + 1;
319 indices[j++] = base + 2;
320 indices[j++] = base + 1;
321 indices[j++] = base + 2;
322 indices[j++] = base + 3;
330 return pass.
Draw().ok();
333 std::optional<GlyphProperties> TextContents::GetGlyphProperties()
const {
334 return (properties_.
stroke || frame_->HasColor())
335 ? 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
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
Type
Describes how the glyphs are represented in the texture.
BufferView Emplace(const BufferType &buffer, size_t alignment=0)
Emplace non-uniform data (like contiguous vertices) onto the host buffer.
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 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.
void SetTextProperties(Color color, const std::optional< StrokeParameters > &stroke)
Must be set after text frame.
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 SubpixelPosition ComputeSubpixelPosition(const TextRun::GlyphPosition &glyph_position, AxisAlignment alignment, const Matrix &transform)
Represents a collection of positioned glyphs from a specific font.
LinePipeline::FragmentShader FS
@ kBase
The texture is sampled as if it only had a single mipmap level.
Point SizeToPoint(Size size)
constexpr Vector4 ToVector(Color color)
LinePipeline::VertexShader VS
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
@ kNearest
Select nearest to the sample point. Most widely supported.
constexpr bool IsTransparent() const
constexpr Color WithAlpha(Scalar new_alpha) const
constexpr Color Premultiply() const
Rect atlas_bounds
The bounds of the glyph within the glyph atlas.
Rect glyph_bounds
The local glyph bounds.
std::optional< StrokeParameters > stroke
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
std::shared_ptr< const fml::Mapping > data