MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TypeSetter.cpp
Go to the documentation of this file.
1#include "TypeSetter.hpp"
2
4
5#include <utf8proc.h>
6
8
10 std::string_view text,
11 GlyphAtlas& atlas,
12 float pen_x,
13 float pen_y,
14 uint32_t wrap_w)
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) {
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}
88
89} // namespace MayaFlux::Portal::Text
#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.
Rasterizes and packs glyphs from a FontFace into a TextureContainer.
@ API
API calls from external code.
@ Portal
High-level user-facing API layer.
LayoutResult lay_out(std::string_view text, GlyphAtlas &atlas, float pen_x, float pen_y, uint32_t wrap_w)
Lay out a UTF-8 string into a sequence of screen-space quads.
Definition TypeSetter.cpp:9
int32_t bearing_x
Horizontal bearing in pixels (from FT_GlyphSlot).
float uv_x0
Left UV edge in atlas texture.
float uv_x1
Right UV edge in atlas texture.
uint32_t height
Glyph bitmap height in pixels.
int32_t advance_x
Horizontal advance in pixels (26.6 fixed-point >> 6).
uint32_t width
Glyph bitmap width in pixels.
float uv_y0
Top UV edge in atlas texture.
int32_t bearing_y
Vertical bearing in pixels (from FT_GlyphSlot).
float uv_y1
Bottom UV edge in atlas texture.
Per-glyph layout and UV data produced by GlyphAtlas.
Screen-space quad for one rasterized glyph.
std::vector< GlyphQuad > quads
Result of lay_out(), carrying the quads and the final pen position.