MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TextRun.cpp
Go to the documentation of this file.
1#include "TextRun.hpp"
2
3#include "TypeFaceFoundry.hpp"
4
7
9
10namespace {
11 constexpr uint32_t k_tab_width = 4;
12}
13
15 : m_params(std::move(params))
16{
17}
18
19void TextRun::set(std::string_view text)
20{
21 m_text = text;
23}
24
26{
27 m_params = std::move(params);
29}
30
31void TextRun::assign(std::string_view text, PressParams params)
32{
33 m_text = text;
34 m_params = std::move(params);
36}
37
42
43bool TextRun::stale() const
44{
45 const GlyphAtlas* current = atlas();
46 return current != m_atlas || (current && current->atlas_size() != m_atlas_size);
47}
48
50{
52 if (!current) {
54 "TextRun: no atlas available, call set_default_font first");
55 m_layout = {};
56 m_atlas = nullptr;
57 m_atlas_size = 0;
58 return;
59 }
60
62 m_text, *current, 0.F, static_cast<float>(current->ascender()),
63 m_params.render_bounds.x, k_tab_width);
66}
67
68glm::vec2 TextRun::extent() const
69{
70 const GlyphAtlas* current = atlas();
71 const float line = current ? static_cast<float>(current->line_height()) : 0.F;
72 return { static_cast<float>(m_params.render_bounds.x),
73 std::max(static_cast<float>(m_params.render_bounds.y), line) };
74}
75
77{
78 const GlyphAtlas* atlas = m_atlas;
79 if (!atlas) {
80 return 0.F;
81 }
82 return m_layout.final_pen_y - static_cast<float>(atlas->ascender())
83 + static_cast<float>(atlas->line_height());
84}
85
86std::vector<Kakshya::MeshVertex> TextRun::vertices(const GlyphMap& map, uint32_t slot)
87{
88 if (stale()) {
90 }
91
92 std::vector<Kakshya::MeshVertex> out;
93
94 if (m_params.background.a > 0.F) {
95 const glm::vec2 a = map({ 0.F, 0.F });
96 const glm::vec2 b = map(extent());
97 const auto quad = Kinesis::textured_mesh_rect(
98 { .min = glm::min(a, b), .max = glm::max(a, b) },
99 0.F, glm::vec3(m_params.background));
100 out.insert(out.end(), quad.begin(), quad.end());
101 }
102
103 const auto glyphs = glyph_vertices(m_layout.quads, m_params.color, m_params.spans, map, slot);
104 out.insert(out.end(), glyphs.begin(), glyphs.end());
105 return out;
106}
107
108Kinesis::AABB2D TextRun::caret(size_t byte_offset, float width_px)
109{
110 if (stale()) {
111 lay_out_text();
112 }
113 if (!m_atlas) {
114 return {};
115 }
116
117 const auto ascender = static_cast<float>(m_atlas->ascender());
119 const PenPosition pen = x_at(
120 m_text, current, byte_offset, 0.F, ascender, m_params.render_bounds.x, k_tab_width);
121
122 const float top = pen.y - ascender;
123 return {
124 .min = { pen.x, top },
125 .max = { pen.x + width_px, top + static_cast<float>(current.line_height()) },
126 };
127}
128
129size_t TextRun::index_at(glm::vec2 px)
130{
131 if (stale()) {
132 lay_out_text();
133 }
134 if (!m_atlas) {
135 return 0;
136 }
137
139 return Text::index_at(
140 m_text, m_layout, current, px.x, px.y,
141 0.F, static_cast<float>(current.ascender()), m_params.render_bounds.x, k_tab_width);
142}
143
144} // namespace MayaFlux::Portal::Text
#define MF_ERROR(comp, ctx,...)
glm::vec2 current
size_t a
size_t b
std::vector< float > * out
uint32_t px
uint32_t line_height() const
Line advance in pixels for this atlas's pixel_size.
uint32_t ascender() const
Ascender in pixels for this atlas's pixel_size.
uint32_t atlas_size() const
Atlas texture dimension (width == height == atlas_size).
Rasterizes and packs glyphs from a FontFace into a TextureContainer.
glm::vec2 extent() const
Size in pixels the run is drawn at.
Definition TextRun.cpp:68
const PressParams & params() const noexcept
Definition TextRun.hpp:47
const std::string & text() const noexcept
Definition TextRun.hpp:46
float content_height() const
Height in pixels the text occupies, from the top of the first line to the bottom of the last.
Definition TextRun.cpp:76
std::vector< Kakshya::MeshVertex > vertices(const GlyphMap &map, uint32_t slot)
Vertices for the background, if any, then every glyph.
Definition TextRun.cpp:86
size_t index_at(glm::vec2 px)
Byte offset of the codepoint boundary nearest a layout pixel.
Definition TextRun.cpp:129
GlyphAtlas * atlas() const
The atlas the run draws from: params().atlas, else the default.
Definition TextRun.cpp:38
bool stale() const
True when the atlas the layout was built against has since been replaced or has grown,...
Definition TextRun.cpp:43
void assign(std::string_view text, PressParams params)
Replace text and parameters together, laying out once.
Definition TextRun.cpp:31
TextRun(PressParams params={})
Definition TextRun.cpp:14
void set(std::string_view text)
Replace the text and lay it out.
Definition TextRun.cpp:19
void set_params(PressParams params)
Replace the parameters and lay the current text out again.
Definition TextRun.cpp:25
Kinesis::AABB2D caret(size_t byte_offset, float width_px)
Pixel rectangle of a caret at a byte offset of the text.
Definition TextRun.cpp:108
const GlyphAtlas * m_atlas
Definition TextRun.hpp:105
GlyphAtlas * get_default_glyph_atlas() const
Return the default GlyphAtlas, or nullptr if set_default_font() has not been called successfully.
@ API
API calls from external code.
@ Portal
High-level user-facing API layer.
std::array< Kakshya::MeshVertex, 6 > textured_mesh_rect(Kinesis::AABB2D region, float weight, glm::vec3 color)
Generate a UV-mapped TRIANGLE_LIST quad (6 vertices, 2 triangles) from an AABB2D, as Kakshya::MeshVer...
void move(EditableText &s, int n)
Move the cursor by n codepoints.
Definition TextEdit.cpp:20
PenPosition x_at(std::string_view text, GlyphAtlas &atlas, size_t byte_offset, float pen_x, float pen_y, uint32_t wrap_w, uint32_t tab_width)
Pen position immediately before byte_offset, in lay_out()'s space.
std::vector< Kakshya::MeshVertex > glyph_vertices(std::span< const GlyphQuad > quads, glm::vec4 color, std::span< const StyleSpan > spans, const GlyphMap &map, uint32_t slot)
Triangle list vertices for glyph quads, six per quad.
Definition GlyphMesh.cpp:14
LayoutResult lay_out(std::string_view text, GlyphAtlas &atlas, float pen_x, float pen_y, uint32_t wrap_w, uint32_t tab_width)
Lay out a UTF-8 string into a sequence of screen-space quads.
size_t index_at(std::string_view text, const LayoutResult &layout, GlyphAtlas &atlas, float x, float y, float pen_x, float pen_y, uint32_t wrap_w, uint32_t tab_width)
Byte offset of the codepoint boundary nearest a screen-space point.
Axis-aligned bounding rectangle in a 2D coordinate space.
Definition Bounds.hpp:63
Linear map from layout pixels to whatever space the vertices are drawn in.
Definition GlyphMesh.hpp:21
std::vector< GlyphQuad > quads
Pen coordinates returned by x_at(), in the same space as GlyphQuad.
GlyphAtlas * atlas
Glyph atlas to use. Null selects the TypeFaceFoundry default at call time.
Definition InkPress.hpp:67
glm::vec4 color
RGBA color applied to all glyphs not covered by a span in spans.
Definition InkPress.hpp:70
std::vector< StyleSpan > spans
Optional per-byte-range color overrides. Empty applies color uniformly.
Definition InkPress.hpp:94
glm::uvec2 render_bounds
Hard render bounds in pixels.
Definition InkPress.hpp:88
glm::vec4 background
RGBA fill composited beneath every glyph.
Definition InkPress.hpp:84
Construction parameters for press().
Definition InkPress.hpp:65