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

◆ decompose_glyph() [1/2]

MAYAFLUX_API GlyphOutline MayaFlux::Portal::Text::decompose_glyph ( FontFace face,
uint32_t  codepoint,
uint32_t  pixel_size,
float  tolerance = 0.5F 
)

Decompose a Unicode codepoint into a tessellated polyline outline.

Loads the glyph via FT_LOAD_NO_BITMAP, walks the FT_Outline with FT_Outline_Decompose, and flattens conic and cubic Bezier segments into line segments at the given flatness tolerance.

The returned outline may be empty (points and contour_ends both empty) for whitespace codepoints or when the codepoint has no outline (e.g. space, tab). advance_x is still populated in that case so layout can proceed.

Parameters
faceLoaded FontFace. Must outlive this call.
codepointUnicode codepoint.
pixel_sizeGlyph size in pixels. Passed to FT_Set_Pixel_Sizes.
toleranceFlatness tolerance in pixels. Smaller values produce more segments and higher fidelity curves.
Returns
GlyphOutline with pixel-space polyline data.

Definition at line 168 of file GlyphOutline.cpp.

173{
174 GlyphOutline result;
175 result.codepoint = codepoint;
176
177 if (!face.is_loaded()) {
178 MF_ERROR(Journal::Component::Portal, Journal::Context::API,
179 "decompose_glyph: FontFace not loaded");
180 return result;
181 }
182
183 FT_Face ft = face.get_face();
184
185 if (const FT_Error err = FT_Set_Pixel_Sizes(ft, 0, pixel_size); err != 0) {
186 MF_ERROR(Journal::Component::Portal, Journal::Context::API,
187 "decompose_glyph: FT_Set_Pixel_Sizes({}) failed: {}", pixel_size, static_cast<int>(err));
188 return result;
189 }
190
191 const FT_UInt idx = FT_Get_Char_Index(ft, static_cast<FT_ULong>(codepoint));
192 if (idx == 0) {
193 MF_WARN(Journal::Component::Portal, Journal::Context::API,
194 "decompose_glyph: no glyph for U+{:04X}", codepoint);
195 return result;
196 }
197
198 if (const FT_Error err = FT_Load_Glyph(ft, idx, FT_LOAD_NO_BITMAP); err != 0) {
199 MF_ERROR(Journal::Component::Portal, Journal::Context::API,
200 "decompose_glyph: FT_Load_Glyph({}) failed: {}", idx, static_cast<int>(err));
201 return result;
202 }
203
204 result.advance_x = static_cast<int32_t>(ft->glyph->advance.x >> 6);
205
206 if (ft->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
207 return result;
208 }
209
210 DecomposeCtx ctx {
211 .points = &result.points,
212 .contour_ends = &result.contour_ends,
213 .tolerance = tolerance,
214 .current = {}
215 };
216
217 if (const FT_Error err = FT_Outline_Decompose(&ft->glyph->outline, &k_funcs, &ctx); err != 0) {
218 MF_ERROR(Journal::Component::Portal, Journal::Context::API,
219 "decompose_glyph: FT_Outline_Decompose failed: {}", static_cast<int>(err));
220 result.points.clear();
221 result.contour_ends.clear();
222 return result;
223 }
224
225 if (!result.points.empty())
226 result.contour_ends.push_back(static_cast<uint32_t>(result.points.size()));
227
228 return result;
229}
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
float tolerance
FT_Face get_face() const
Raw FT_Face handle for use by GlyphAtlas.
Definition FontFace.hpp:57
bool is_loaded() const
Returns true after a successful load() call.
Definition FontFace.hpp:51
std::vector< glm::vec2 > points
std::vector< uint32_t > contour_ends
Vector outline for a single glyph as a flat polyline sequence.

References MayaFlux::Portal::Text::GlyphOutline::advance_x, MayaFlux::Journal::API, MayaFlux::Portal::Text::GlyphOutline::codepoint, MayaFlux::Portal::Text::GlyphOutline::contour_ends, MayaFlux::Portal::Text::FontFace::get_face(), MayaFlux::Portal::Text::FontFace::is_loaded(), MF_ERROR, MF_WARN, MayaFlux::Portal::Text::GlyphOutline::points, MayaFlux::Journal::Portal, and tolerance.

Referenced by decompose_glyph(), and MayaFlux::Nodes::GpuSync::GlyphGeometryNode::rebuild_outlines().

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