///|
/// GlyphLoader: accumulates outline data during glyph loading.
/// Used especially for composite glyphs where sub-glyphs are loaded
/// one at a time and their outlines merged. Port of ftgloadr.c.
struct GlyphLoader {
// Base outline: accumulated result so far
mut base_points : Array[@types.Vector]
mut base_tags : Array[Byte]
mut base_contours : Array[UInt]
// Current sub-glyph outline being loaded
mut current_points : Array[@types.Vector]
mut current_tags : Array[Byte]
mut current_contours : Array[UInt]
// Sub-glyph info
mut subglyphs : Array[SubGlyph]
} derive(Show)
///|
pub fn GlyphLoader::new() -> GlyphLoader {
{
base_points: [],
base_tags: [],
base_contours: [],
current_points: [],
current_tags: [],
current_contours: [],
subglyphs: [],
}
}
///|
/// Reset the loader, clearing all accumulated data.
pub fn GlyphLoader::reset(self : GlyphLoader) -> Unit {
self.base_points = []
self.base_tags = []
self.base_contours = []
self.current_points = []
self.current_tags = []
self.current_contours = []
self.subglyphs = []
}
///|
/// Add a point to the current sub-glyph.
pub fn GlyphLoader::add_point(
self : GlyphLoader,
x : Int64,
y : Int64,
tag : Byte,
) -> Unit {
self.current_points.push(@types.Vector::new(x, y))
self.current_tags.push(tag)
}
///|
/// End the current contour.
pub fn GlyphLoader::end_contour(self : GlyphLoader) -> Unit {
let n = self.current_points.length()
if n > 0 {
self.current_contours.push((n - 1).reinterpret_as_uint())
}
}
///|
/// Merge current sub-glyph outline into the base.
/// Adjusts contour indices to be relative to the combined base.
pub fn GlyphLoader::add(self : GlyphLoader) -> Unit {
let base_n_points = self.base_points.length()
// Append current points and tags to base
for i, pt in self.current_points {
self.base_points.push(pt)
self.base_tags.push(self.current_tags[i])
}
// Append contours with offset
for _, contour in self.current_contours {
let adjusted = contour.reinterpret_as_int() + base_n_points
self.base_contours.push(adjusted.reinterpret_as_uint())
}
// Clear current
self.current_points = []
self.current_tags = []
self.current_contours = []
}
///|
/// Build an Outline from the accumulated base data.
pub fn GlyphLoader::to_outline(self : GlyphLoader) -> @types.Outline {
let n_points = self.base_points.length()
let fa_points = FixedArray::make(n_points, @types.Vector::new(0L, 0L))
let fa_tags = FixedArray::make(n_points, b'\x00')
for i in 0.. Int {
self.base_points.length()
}
///|
/// Number of contours accumulated in the base.
pub fn GlyphLoader::base_n_contours(self : GlyphLoader) -> Int {
self.base_contours.length()
}