MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ lay_out()

LayoutResult MayaFlux::Portal::Text::lay_out ( std::string_view  text,
GlyphAtlas atlas,
float  pen_x = 0.F,
float  pen_y = 0.F,
uint32_t  wrap_w = 0 
)

Lay out a UTF-8 string into a sequence of screen-space quads.

Handles
(advance pen_y by atlas.line_height(), reset pen_x to the initial value) and \r (consumed silently). All other control codepoints with no glyph in the face are skipped without advancing the pen.

Bidirectional reordering and shaping are not performed. HarfBuzz slots in before the glyph index step when needed; the quad assembly loop and GlyphAtlas remain unchanged.

Parameters
textUTF-8 encoded input string.
atlasGlyphAtlas to query and populate. May be modified (dirty flag set) if new glyphs are rasterized.
pen_xStarting horizontal pen position in pixels.
pen_yStarting vertical pen position in pixels (baseline).
Returns
LayoutResult containing quads and final pen position.

Definition at line 9 of file TypeSetter.cpp.

15{
16 if (text.empty()) {
17 return { .quads = {}, .final_pen_x = pen_x, .final_pen_y = pen_y };
18 }
19
20 LayoutResult out;
21 out.quads.reserve(text.size());
22
23 const float origin_x = 0.F;
24
25 const auto* bytes = reinterpret_cast<const utf8proc_uint8_t*>(text.data());
26 auto remaining = static_cast<utf8proc_ssize_t>(text.size());
27 utf8proc_ssize_t offset = 0;
28
29 while (offset < remaining) {
30 utf8proc_int32_t codepoint = 0;
31 const utf8proc_ssize_t n = utf8proc_iterate(bytes + offset, remaining - offset, &codepoint);
32
33 if (n <= 0) {
34 MF_WARN(Journal::Component::Portal, Journal::Context::API,
35 "TypeSetter: invalid UTF-8 sequence at byte offset {}, skipping byte",
36 static_cast<size_t>(offset));
37 offset += 1;
38 continue;
39 }
40
41 offset += n;
42
43 if (codepoint < 0) {
44 continue;
45 }
46
47 if (codepoint == '\n') {
48 pen_x = origin_x;
49 pen_y += static_cast<float>(atlas.line_height());
50 continue;
51 }
52
53 if (codepoint == '\r') {
54 continue;
55 }
56
57 const GlyphMetrics* m = atlas.get_or_rasterize(static_cast<FT_ULong>(codepoint));
58 if (!m) {
59 continue;
60 }
61
62 if (m->width > 0 && m->height > 0) {
63 GlyphQuad q {};
64 q.x0 = pen_x + static_cast<float>(m->bearing_x);
65 q.y0 = pen_y - static_cast<float>(m->bearing_y);
66 q.x1 = q.x0 + static_cast<float>(m->width);
67 q.y1 = q.y0 + static_cast<float>(m->height);
68 q.uv_x0 = m->uv_x0;
69 q.uv_y0 = m->uv_y0;
70 q.uv_x1 = m->uv_x1;
71 q.codepoint = static_cast<uint32_t>(codepoint);
72 q.uv_y1 = m->uv_y1;
73 out.quads.push_back(q);
74 }
75
76 pen_x += static_cast<float>(m->advance_x);
77
78 if (wrap_w > 0 && static_cast<uint32_t>(std::ceil(pen_x)) > wrap_w) {
79 pen_x = 0.F;
80 pen_y += static_cast<float>(atlas.line_height());
81 }
82 }
83
84 out.final_pen_x = pen_x;
85 out.final_pen_y = pen_y;
86 return out;
87}
#define MF_WARN(comp, ctx,...)
double q
uint32_t line_height() const
Line advance in pixels for this atlas's pixel_size.
const GlyphMetrics * get_or_rasterize(FT_UInt glyph_index)
Return metrics for a glyph, rasterizing it into the atlas if needed.
float uv_x0
Left UV edge in atlas texture.

References MayaFlux::Portal::Text::GlyphMetrics::advance_x, MayaFlux::Journal::API, MayaFlux::Portal::Text::GlyphMetrics::bearing_x, MayaFlux::Portal::Text::GlyphMetrics::bearing_y, MayaFlux::Portal::Text::LayoutResult::final_pen_x, MayaFlux::Portal::Text::LayoutResult::final_pen_y, MayaFlux::Portal::Text::GlyphAtlas::get_or_rasterize(), MayaFlux::Portal::Text::GlyphMetrics::height, MayaFlux::Portal::Text::GlyphAtlas::line_height(), MF_WARN, MayaFlux::Journal::Portal, q, MayaFlux::Portal::Text::LayoutResult::quads, MayaFlux::Portal::Text::GlyphMetrics::uv_x0, MayaFlux::Portal::Text::GlyphMetrics::uv_x1, MayaFlux::Portal::Text::GlyphMetrics::uv_y0, MayaFlux::Portal::Text::GlyphMetrics::uv_y1, MayaFlux::Portal::Text::GlyphMetrics::width, and MayaFlux::Portal::Text::GlyphQuad::x0.

Referenced by create_layout(), and impress().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: