///|
/// A floating-point Cairo rectangle.
///
/// `x` and `y` locate the left and top edges; `width` and `height` give its
/// size. The coordinate space is defined by the API that produces or consumes
/// the rectangle.
pub struct Rectangle {
x : Double
y : Double
width : Double
height : Double
} derive(Eq, Hash, Debug)
///|
/// Construct a rectangle without validating its dimensions.
pub fn Rectangle::new(
x : Double,
y : Double,
width : Double,
height : Double,
) -> Rectangle {
{ x, y, width, height }
}
///|
/// Return `(x, y, width, height)` in pycairo tuple order.
pub fn Rectangle::components(
self : Rectangle,
) -> (Double, Double, Double, Double) {
(self.x, self.y, self.width, self.height)
}
///|
/// Return component `0..3` from `(x, y, width, height)`.
///
/// Raises `CairoInvalidArgument(InvalidIndex, _)` for any other index.
pub fn Rectangle::component(
self : Rectangle,
index : Int,
) -> Double raise CairoError {
match index {
0 => self.x
1 => self.y
2 => self.width
3 => self.height
_ => raise CairoInvalidArgument(InvalidIndex, InvalidIndex.message())
}
}
///|
/// Index the `(x, y, width, height)` component sequence.
///
/// Raises `CairoInvalidArgument(InvalidIndex, _)` outside `0..3`.
#alias("_[_]")
pub fn Rectangle::at(self : Rectangle, index : Int) -> Double raise CairoError {
self.component(index)
}
///|
/// An integer Cairo rectangle, commonly used by regions and image mappings.
///
/// `x` and `y` locate the left and top edges; `width` and `height` give its
/// size in the coordinate space of the consuming API.
pub struct RectangleInt {
x : Int
y : Int
width : Int
height : Int
} derive(Eq, Debug)
///|
/// Construct an integer rectangle; omitted components default to zero.
///
/// Construction does not validate dimensions.
pub fn RectangleInt::new(
x? : Int = 0,
y? : Int = 0,
width? : Int = 0,
height? : Int = 0,
) -> RectangleInt {
{ x, y, width, height }
}
///|
/// Return `(x, y, width, height)`.
pub fn RectangleInt::components(self : RectangleInt) -> (Int, Int, Int, Int) {
(self.x, self.y, self.width, self.height)
}
///|
/// Return component `0..3` from `(x, y, width, height)`.
///
/// Raises `CairoInvalidArgument(InvalidIndex, _)` for any other index.
pub fn RectangleInt::component(
self : RectangleInt,
index : Int,
) -> Int raise CairoError {
match index {
0 => self.x
1 => self.y
2 => self.width
3 => self.height
_ => raise CairoInvalidArgument(InvalidIndex, InvalidIndex.message())
}
}
///|
/// The canonical Cairo glyph value re-exported from its owning package.
///
/// This alias is the same type used by Context and ScaledFont glyph APIs.
pub type Glyph = @glyph.Glyph
///|
/// A mapping between a run of UTF-8 bytes and a run of glyphs.
///
/// Cairo requires both counts to be non-negative and at least one to be
/// nonzero when the value is consumed by a text-cluster API. This pure value
/// preserves the supplied counts; construction itself performs no validation.
pub struct TextCluster {
num_bytes : Int
num_glyphs : Int
} derive(Eq, Hash, Debug)
///|
/// Construct a text cluster from its UTF-8 byte and glyph counts.
pub fn TextCluster::new(num_bytes : Int, num_glyphs : Int) -> TextCluster {
{ num_bytes, num_glyphs }
}
///|
/// Return `(num_bytes, num_glyphs)` in pycairo tuple order.
pub fn TextCluster::components(self : TextCluster) -> (Int, Int) {
(self.num_bytes, self.num_glyphs)
}
///|
fn text_cluster_field_arrays(
clusters : ArrayView[TextCluster],
) -> (FixedArray[Int], FixedArray[Int]) {
let count = clusters.length()
(
FixedArray::makei(count, index => clusters[index].num_bytes),
FixedArray::makei(count, index => clusters[index].num_glyphs),
)
}
///|
/// Return component `0..1` from `(num_bytes, num_glyphs)`.
///
/// Raises `CairoInvalidArgument(InvalidIndex, _)` for any other index.
pub fn TextCluster::component(
self : TextCluster,
index : Int,
) -> Int raise CairoError {
match index {
0 => self.num_bytes
1 => self.num_glyphs
_ => raise CairoInvalidArgument(InvalidIndex, InvalidIndex.message())
}
}
///|
/// Index the `(num_bytes, num_glyphs)` component sequence.
///
/// Raises `CairoInvalidArgument(InvalidIndex, _)` outside `0..1`.
#alias("_[_]")
pub fn TextCluster::at(self : TextCluster, index : Int) -> Int raise CairoError {
self.component(index)
}
///|
/// User-space ink bounds and advances for text or glyphs.
///
/// Bearings locate the ink rectangle relative to the origin; width and height
/// describe that rectangle; advances locate the next text origin. Metrics can
/// vary slightly with the current transform because of font hinting.
pub struct TextExtents {
x_bearing : Double
y_bearing : Double
width : Double
height : Double
x_advance : Double
y_advance : Double
} derive(Eq, Hash, Debug)
///|
/// Construct text extents from six explicit metric values.
///
/// This pure constructor performs no metric validation.
pub fn TextExtents::new(
x_bearing : Double,
y_bearing : Double,
width : Double,
height : Double,
x_advance : Double,
y_advance : Double,
) -> TextExtents {
{ x_bearing, y_bearing, width, height, x_advance, y_advance }
}
///|
/// Return `(x_bearing, y_bearing, width, height, x_advance, y_advance)`.
pub fn TextExtents::components(
self : TextExtents,
) -> (Double, Double, Double, Double, Double, Double) {
(
self.x_bearing,
self.y_bearing,
self.width,
self.height,
self.x_advance,
self.y_advance,
)
}
///|
/// Return metric `0..5` in pycairo tuple order.
///
/// Raises `CairoInvalidArgument(InvalidIndex, _)` for any other index.
pub fn TextExtents::component(
self : TextExtents,
index : Int,
) -> Double raise CairoError {
match index {
0 => self.x_bearing
1 => self.y_bearing
2 => self.width
3 => self.height
4 => self.x_advance
5 => self.y_advance
_ => raise CairoInvalidArgument(InvalidIndex, InvalidIndex.message())
}
}
///|
/// Index the six text-extents metrics in pycairo tuple order.
///
/// Raises `CairoInvalidArgument(InvalidIndex, _)` outside `0..5`.
#alias("_[_]")
pub fn TextExtents::at(
self : TextExtents,
index : Int,
) -> Double raise CairoError {
self.component(index)
}
///|
/// Glyphs plus their UTF-8 cluster mapping from text shaping.
///
/// `flags` describes glyph traversal order. The arrays are ordinary mutable
/// MoonBit arrays, so callers should copy them before independent mutation.
pub struct TextGlyphRun {
glyphs : Array[Glyph]
clusters : Array[TextCluster]
flags : TextClusterFlags
} derive(Eq, Debug)
///|
/// Group glyph, cluster, and flag arrays without copying or validating them.
///
/// Cairo validates complete cluster coverage when a run is consumed by a
/// text-cluster operation.
pub fn TextGlyphRun::new(
glyphs : Array[Glyph],
clusters : Array[TextCluster],
flags : TextClusterFlags,
) -> TextGlyphRun {
{ glyphs, clusters, flags }
}
///|
/// Return the same glyph and cluster arrays together with their flags.
///
/// The returned arrays alias the arrays stored in this run.
pub fn TextGlyphRun::components(
self : TextGlyphRun,
) -> (Array[Glyph], Array[TextCluster], TextClusterFlags) {
(self.glyphs, self.clusters, self.flags)
}
///|
/// User-space line metrics for a scaled font.
///
/// Ascent and descent extend above and below the baseline; height is the
/// recommended baseline spacing; maximum advances bound glyph-origin motion.
pub struct FontExtents {
ascent : Double
descent : Double
height : Double
max_x_advance : Double
max_y_advance : Double
} derive(Eq, Hash, Debug)
///|
/// Construct font extents from five explicit metric values.
///
/// This pure constructor performs no metric validation.
pub fn FontExtents::new(
ascent : Double,
descent : Double,
height : Double,
max_x_advance : Double,
max_y_advance : Double,
) -> FontExtents {
{ ascent, descent, height, max_x_advance, max_y_advance }
}
///|
/// Return `(ascent, descent, height, max_x_advance, max_y_advance)`.
pub fn FontExtents::components(
self : FontExtents,
) -> (Double, Double, Double, Double, Double) {
(
self.ascent,
self.descent,
self.height,
self.max_x_advance,
self.max_y_advance,
)
}
///|
/// Return metric `0..4` in pycairo tuple order.
///
/// Raises `CairoInvalidArgument(InvalidIndex, _)` for any other index.
pub fn FontExtents::component(
self : FontExtents,
index : Int,
) -> Double raise CairoError {
match index {
0 => self.ascent
1 => self.descent
2 => self.height
3 => self.max_x_advance
4 => self.max_y_advance
_ => raise CairoInvalidArgument(InvalidIndex, InvalidIndex.message())
}
}