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, 4> unit_points = {
Point{0, 0},
Point{1, 0},
114 ISize atlas_size = atlas->GetTexture()->GetSize();
118 VS::PerVertexData
vtx;
120 size_t bounds_offset = 0u;
121 Rational rounded_scale = frame->GetScale();
129 unscaled_basis.
m[0] = AttractToOne(unscaled_basis.
m[0]);
130 unscaled_basis.
m[5] = AttractToOne(unscaled_basis.
m[5]);
132 for (
const TextRun& run : frame->GetRuns()) {
133 const Font& font = run.GetFont();
139 Point subpixel_adjustment(0.5, 0.5);
144 subpixel_adjustment.
x = 0.125;
147 subpixel_adjustment.
y = 0.125;
150 subpixel_adjustment.
x = 0.125;
151 subpixel_adjustment.
y = 0.125;
155 Point screen_offset = (entity_transform *
Point(0, 0));
157 run.GetGlyphPositions()) {
158 const FrameBounds& frame_bounds = frame->GetFrameBounds(bounds_offset);
170 atlas->GetOrCreateFontGlyphAtlas(
ScaledFont{font, rounded_scale});
180 std::optional<FrameBounds> maybe_atlas_glyph_bounds =
182 glyph_position.
glyph,
186 if (!maybe_atlas_glyph_bounds.has_value()) {
190 atlas_glyph_bounds = maybe_atlas_glyph_bounds.value().atlas_bounds;
193 Rect scaled_bounds = glyph_bounds.
Scale(inverted_rounded_scale);
199 Point uv_origin = atlas_glyph_bounds.GetLeftTop() / atlas_size;
202 Point unrounded_glyph_position =
204 unscaled_basis * glyph_bounds.GetLeftTop() +
205 (basis_transform * glyph_position.position);
207 Point screen_glyph_position =
208 (screen_offset + unrounded_glyph_position + subpixel_adjustment)
210 for (
const Point& point : unit_points) {
212 if (is_translation_scale) {
213 position = (screen_glyph_position +
214 (unscaled_basis * point * glyph_bounds.GetSize()))
217 position = entity_transform *
218 (glyph_position.position + scaled_bounds.
GetLeftTop() +
219 point * scaled_bounds.
GetSize());
221 vtx.uv = uv_origin + (uv_size * point);
222 vtx.position = position;
223 vtx_contents[i++] =
vtx;
238 const std::shared_ptr<GlyphAtlas>& atlas =
242 if (!atlas || !atlas->IsValid()) {
246 if (!frame_->IsFrameComplete()) {
258 VS::FrameInfo frame_info;
264 VS::BindFrameInfo(pass,
267 FS::FragInfo frag_info;
268 frag_info.use_text_color = force_text_color_ ? 1.0 : 0.0;
272 FS::BindFragInfo(pass,
276 if (is_translation_scale) {
292 FS::BindGlyphAtlasSampler(
295 renderer.
GetContext()->GetSamplerLibrary()->GetSampler(
300 size_t glyph_count = 0;
301 for (
const auto& run : frame_->GetRuns()) {
302 glyph_count += run.GetGlyphPositions().size();
304 size_t vertex_count = glyph_count * 4;
305 size_t index_count = glyph_count * 6;
308 vertex_count *
sizeof(VS::PerVertexData),
alignof(VS::PerVertexData),
310 VS::PerVertexData* vtx_contents =
311 reinterpret_cast<VS::PerVertexData*
>(
data);
317 GetGlyphProperties(),
321 index_count *
sizeof(uint16_t),
alignof(uint16_t), [&](uint8_t*
data) {
322 uint16_t* indices =
reinterpret_cast<uint16_t*
>(
data);
324 for (
auto i = 0u; i < glyph_count; i++) {
326 indices[j++] = base + 0;
327 indices[j++] = base + 1;
328 indices[j++] = base + 2;
329 indices[j++] = base + 1;
330 indices[j++] = base + 2;
331 indices[j++] = base + 3;
339 return pass.
Draw().ok();
342 std::optional<GlyphProperties> TextContents::GetGlyphProperties()
const {
343 return (properties_.
stroke || frame_->HasColor())
344 ? 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
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 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 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.
SolidFillVertexShader::PerVertexData vtx
const Scalar stroke_width
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.
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