MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
GlyphGeometryNode.hpp
Go to the documentation of this file.
1#pragma once
2
4
6
8class FontFace;
9}
10
12
13/**
14 * @class GlyphGeometryNode
15 * @brief GeometryWriterNode that emits glyph vector outlines as LINE_LIST geometry.
16 *
17 * Decomposes a UTF-8 string into per-glyph polyline outlines via
18 * Portal::Text::decompose_glyph(), lays them out using the same pen-advance
19 * model as lay_out(), and writes all contours as LINE_LIST vertex pairs into
20 * the inherited vertex buffer.
21 *
22 * Each contour segment becomes two LineVertex entries (one per endpoint),
23 * carrying the per-glyph color and thickness set on this node. The caller
24 * drives per-character transforms by subclassing and overriding compute_frame(),
25 * or by mutating the outline data between calls to rebuild_outlines().
26 *
27 * The outline geometry is static after set_text() / rebuild_outlines() until
28 * either is called again. compute_frame() is a no-op unless m_dirty is set,
29 * so this node is RT-safe to tick at VISUAL_RATE once built.
30 *
31 * Coordinate space: pixel-space with Y downward, pen origin at (pen_x, pen_y).
32 * Matches GlyphQuad convention. The caller applies NDC transform via the view
33 * transform on the buffer's RenderProcessor.
34 *
35 * Usage:
36 * @code
37 * Portal::Text::set_default_font("JetBrains Mono", "Medium", 72);
38 *
39 * auto node = std::make_shared<GlyphGeometryNode>("hello");
40 * node->set_color({ 1.0F, 1.0F, 1.0F });
41 * node->set_thickness(1.5F);
42 *
43 * auto buf = vega.GeometryBuffer(node) | Graphics;
44 * buf->setup_rendering({
45 * .target_window = window,
46 * .topology = Portal::Graphics::PrimitiveTopology::LINE_LIST,
47 * });
48 * @endcode
49 */
50class MAYAFLUX_API GlyphGeometryNode : public GeometryWriterNode {
51public:
52 /**
53 * @brief Construct from a UTF-8 string using the default font.
54 *
55 * Calls rebuild_outlines() immediately. Requires set_default_font() to
56 * have been called before construction.
57 *
58 * @param text UTF-8 string to decompose.
59 * @param pen_x Starting horizontal pen position in pixels.
60 * @param pen_y Starting vertical pen position in pixels (baseline).
61 * @param tolerance Bezier flatness tolerance in pixels.
62 */
63 explicit GlyphGeometryNode(
64 std::string text,
65 float pen_x = 0.F,
66 float pen_y = 0.F,
67 float tolerance = 0.5F);
68
69 /**
70 * @brief Construct from a UTF-8 string with an explicit FontFace.
71 *
72 * @param face FontFace to decompose from. Must outlive this node.
73 * @param pixel_size Glyph size in pixels.
74 * @param text UTF-8 string to decompose.
75 * @param pen_x Starting horizontal pen position in pixels.
76 * @param pen_y Starting vertical pen position in pixels (baseline).
77 * @param tolerance Bezier flatness tolerance in pixels.
78 */
81 uint32_t pixel_size,
82 std::string text,
83 float pen_x = 0.F,
84 float pen_y = 0.F,
85 float tolerance = 0.5F);
86
87 ~GlyphGeometryNode() override = default;
88
89 /**
90 * @brief Replace the text string and rebuild outlines.
91 * @param text UTF-8 string.
92 */
93 void set_text(std::string text);
94
95 /**
96 * @brief Set pen origin for layout.
97 *
98 * Clears any active center point. Takes effect on the next
99 * rebuild_outlines() or set_text() call.
100 */
101 void set_pen(float pen_x, float pen_y);
102
103 /**
104 * @brief Place the text block so its bounding box center falls on @p center.
105 *
106 * Overrides the pen origin. The bounding box is computed from the total
107 * advance width and line height of the laid-out string. Takes effect on
108 * the next rebuild_outlines() or set_text() call. Pass std::nullopt to
109 * revert to pen-origin placement.
110 *
111 * @param center Desired center position in the same coordinate space as
112 * the pen origin (pixels when using an ortho view transform).
113 */
114 void set_center(std::optional<glm::vec2> center);
115
116 /**
117 * @brief Set uniform color for all glyph contours.
118 * @param color RGB color in [0, 1].
119 */
120 void set_color(glm::vec3 color);
121
122 /**
123 * @brief Set uniform line thickness for all glyph contours.
124 * @param thickness Thickness value passed to LineVertex.
125 */
126 void set_thickness(float thickness);
127
128 /**
129 * @brief Access the per-glyph outline data produced by the last rebuild.
130 *
131 * The vector is ordered by codepoint occurrence in the source string,
132 * matching the layout order. Callers may read (not write) this data to
133 * drive per-glyph transforms externally.
134 */
135 [[nodiscard]] const std::vector<Portal::Text::GlyphOutline>& outlines() const
136 {
137 return m_outlines;
138 }
139
140 /**
141 * @brief Pen-advance offsets for each glyph, in pixels.
142 *
143 * outlines()[i] starts at pen_offsets()[i]. Useful for mapping node graph
144 * outputs (e.g. Phasor index) to a specific glyph's screen position.
145 */
146 [[nodiscard]] const std::vector<glm::vec2>& pen_offsets() const { return m_pen_offsets; }
147
148 /**
149 * @brief Override pen offsets for all glyphs.
150 *
151 * Each element corresponds to outlines()[i]. The caller computes
152 * whatever positions it wants (wave, noise, physics) and sets them
153 * here. write_vertices() uses these offsets on the next compute_frame().
154 *
155 * @param offsets Must have the same size as outlines(). Silently ignored
156 * if sizes do not match.
157 */
158 void set_pen_offsets(std::vector<glm::vec2> offsets);
159
160 /**
161 * @brief Rebuild outline geometry from the current text and pen settings.
162 *
163 * Called automatically by set_text(). Call directly after mutating pen,
164 * color, or thickness without changing text.
165 */
166 void rebuild_outlines();
167
168 /**
169 * @brief Upload cached vertex data if dirty. No-op otherwise.
170 */
171 void compute_frame() override;
172
174 {
175 return Portal::Graphics::PrimitiveTopology::LINE_LIST;
176 }
177
178private:
180 uint32_t m_pixel_size {};
181 std::string m_text;
182 float m_pen_x {};
183 float m_pen_y {};
184 float m_tolerance { 0.5F };
185 std::optional<glm::vec2> m_center;
186 float m_total_advance {};
187 float m_line_height {};
188
189 glm::vec3 m_color { 1.F, 1.F, 1.F };
190 float m_thickness { 1.F };
191
192 std::vector<Portal::Text::GlyphOutline> m_outlines;
193 std::vector<glm::vec2> m_pen_offsets;
194
195 bool m_dirty {};
196
197 void write_vertices();
198};
199
200} // namespace MayaFlux::Nodes::GpuSync
float tolerance
Base class for nodes that generate 3D geometry data.
const std::vector< Portal::Text::GlyphOutline > & outlines() const
Access the per-glyph outline data produced by the last rebuild.
std::vector< Portal::Text::GlyphOutline > m_outlines
Portal::Graphics::PrimitiveTopology get_primitive_topology() const override
Get primitive topology for rendering.
const std::vector< glm::vec2 > & pen_offsets() const
Pen-advance offsets for each glyph, in pixels.
GeometryWriterNode that emits glyph vector outlines as LINE_LIST geometry.
Owns a single FT_Face loaded from a file path.
Definition FontFace.hpp:24
PrimitiveTopology
Vertex assembly primitive topology.