///|
/// Outline representation: a set of contours made of points.
struct Outline {
mut points : FixedArray[Vector] // coordinates (may be larger than n_points)
mut tags : FixedArray[Byte] // point flags (on-curve, conic, cubic)
mut contours : FixedArray[UInt] // end-point index for each contour
mut n_points_ : Int // actual point count (may be < points.length())
mut n_contours_ : Int // actual contour count
mut flags : Int // FT_OUTLINE_XXX
} derive(Eq, Show)
///|
pub fn Outline::new() -> Outline {
{
points: FixedArray::default(),
tags: FixedArray::default(),
contours: FixedArray::default(),
n_points_: 0,
n_contours_: 0,
flags: 0,
}
}
///|
pub fn Outline::create(
points : FixedArray[Vector],
tags : FixedArray[Byte],
contours : FixedArray[UInt],
flags? : Int = 0,
) -> Outline {
{
points,
tags,
contours,
n_points_: points.length(),
n_contours_: contours.length(),
flags,
}
}
///|
/// Create an outline with explicit point/contour counts.
/// Used when arrays may be larger than the actual data (reusable buffers).
pub fn Outline::create_with_counts(
points : FixedArray[Vector],
tags : FixedArray[Byte],
contours : FixedArray[UInt],
n_points : Int,
n_contours : Int,
) -> Outline {
{
points,
tags,
contours,
n_points_: n_points,
n_contours_: n_contours,
flags: 0,
}
}
///|
pub fn Outline::set_flags(self : Outline, flags : Int) -> Unit {
self.flags = flags
}
///|
pub fn Outline::n_points(self : Outline) -> Int {
self.n_points_
}
///|
pub fn Outline::n_contours(self : Outline) -> Int {
self.n_contours_
}
///|
pub fn Outline::points(self : Outline) -> FixedArray[Vector] {
self.points
}
///|
pub fn Outline::tags(self : Outline) -> FixedArray[Byte] {
self.tags
}
///|
pub fn Outline::contours(self : Outline) -> FixedArray[UInt] {
self.contours
}
///|
pub fn Outline::flags(self : Outline) -> Int {
self.flags
}
///|
pub fn Outline::set_points(self : Outline, points : FixedArray[Vector]) -> Unit {
self.points = points
}
///|
pub fn Outline::set_tags(self : Outline, tags : FixedArray[Byte]) -> Unit {
self.tags = tags
}
///|
pub fn Outline::set_contours(
self : Outline,
contours : FixedArray[UInt],
) -> Unit {
self.contours = contours
}
// Outline flag constants
///|
pub const OUTLINE_NONE : Int = 0x0
///|
pub const OUTLINE_OWNER : Int = 0x1
///|
pub const OUTLINE_EVEN_ODD_FILL : Int = 0x2
///|
pub const OUTLINE_REVERSE_FILL : Int = 0x4
///|
pub const OUTLINE_IGNORE_DROPOUTS : Int = 0x8
///|
pub const OUTLINE_SMART_DROPOUTS : Int = 0x10
///|
pub const OUTLINE_INCLUDE_STUBS : Int = 0x20
///|
pub const OUTLINE_OVERLAP : Int = 0x40
///|
pub const OUTLINE_HIGH_PRECISION : Int = 0x100
///|
pub const OUTLINE_SINGLE_PASS : Int = 0x200
// Curve tag enum — preferred over raw Byte constants
///|
/// Curve point classification.
pub(all) enum CurveTag {
On // on-curve point (was 0x01)
Conic // off-curve conic/quadratic (was 0x00)
Cubic // off-curve cubic (was 0x02)
} derive(Eq, Show)
///|
/// Convert a raw tag byte to a CurveTag, masking to the low 2 bits.
pub fn CurveTag::from_byte(b : Byte) -> CurveTag {
match (b & 0x03).to_int() {
0x01 => On
0x02 => Cubic
_ => Conic
}
}
// Legacy Byte constants — kept for backward compatibility
///|
/// Extract curve tag from point flag byte.
pub fn curve_tag(flag : Byte) -> Byte {
flag & 0x03
}
///|
/// On-curve point. (legacy — prefer CurveTag::On)
pub const CURVE_TAG_ON : Byte = 0x01
///|
/// Off-curve conic (quadratic) control point. (legacy — prefer CurveTag::Conic)
pub const CURVE_TAG_CONIC : Byte = 0x00
///|
/// Off-curve cubic control point. (legacy — prefer CurveTag::Cubic)
pub const CURVE_TAG_CUBIC : Byte = 0x02
///|
pub const CURVE_TAG_HAS_SCANMODE : Byte = 0x04
///|
/// TrueType hinter: x-touched.
pub const CURVE_TAG_TOUCH_X : Byte = 0x08
///|
/// TrueType hinter: y-touched.
pub const CURVE_TAG_TOUCH_Y : Byte = 0x10
///|
pub const CURVE_TAG_TOUCH_BOTH : Byte = 0x18