///|
/// Positioned glyphs for a single shaped and laid-out line.
struct GlyphRun {
glyphs : Array[PositionedGlyph]
width : Double
baseline_y : Double
} derive(Debug)
///|
pub extend GlyphRun with Debug::{to_repr}
///|
/// Create a glyph run from positioned glyphs.
fn GlyphRun::new(
glyphs : Array[PositionedGlyph],
width~ : Double,
baseline_y~ : Double,
) -> GlyphRun {
{ glyphs, width, baseline_y, }
}
///|
/// Get positioned glyphs in this run.
pub fn GlyphRun::get_glyphs(self : GlyphRun) -> Array[PositionedGlyph] {
copy_positioned_glyphs(self.glyphs)
}
///|
/// Get run width in pixels.
pub fn GlyphRun::get_width(self : GlyphRun) -> Double {
self.width
}
///|
/// Get baseline position in pixels from the layout origin.
pub fn GlyphRun::get_baseline_y(self : GlyphRun) -> Double {
self.baseline_y
}
///|
/// Get glyph count in this run.
pub fn GlyphRun::glyph_count(self : GlyphRun) -> Int {
self.glyphs.length()
}
///|
/// Stable text layout facade used by higher-level renderers and GUI code.
struct TextLayout {
runs : Array[GlyphRun]
metrics : LayoutMetrics
} derive(Debug)
///|
pub extend TextLayout with Debug::{to_repr}
///|
/// Create a text layout from glyph runs and metrics.
fn TextLayout::new(
runs : Array[GlyphRun],
metrics : LayoutMetrics,
) -> TextLayout {
{ runs, metrics, }
}
///|
/// Layout text with a parsed font face.
pub fn TextLayout::layout(
face : FontFace,
text : String,
config : LayoutConfig,
) -> TextLayout {
layout_text_face(face, text, config)
}
///|
/// Get glyph runs for this layout.
pub fn TextLayout::get_runs(self : TextLayout) -> Array[GlyphRun] {
copy_glyph_runs(self.runs)
}
///|
/// Get layout metrics.
pub fn TextLayout::get_metrics(self : TextLayout) -> LayoutMetrics {
self.metrics
}
///|
/// Get total layout width.
pub fn TextLayout::get_width(self : TextLayout) -> Double {
self.metrics.width
}
///|
/// Get total layout height.
pub fn TextLayout::get_height(self : TextLayout) -> Double {
self.metrics.height
}
///|
/// Get the first baseline from the layout origin.
pub fn TextLayout::get_baseline(self : TextLayout) -> Double {
self.metrics.baseline
}
///|
/// Get the number of glyph runs.
pub fn TextLayout::run_count(self : TextLayout) -> Int {
self.runs.length()
}
///|
/// Layout text with a parsed font face.
pub fn layout_text_face(
face : FontFace,
text : String,
config : LayoutConfig,
) -> TextLayout {
TextLayout::from_layout_result(layout_text(face.get_font(), text, config))
}
///|
/// Convert the current low-level layout result into the stable layout facade.
fn TextLayout::from_layout_result(result : LayoutResult) -> TextLayout {
let runs = []
let mut baseline = 0.0
for line in result.lines {
if runs.length() is 0 {
baseline = line.y
}
runs.push(GlyphRun::new(line.glyphs, width=line.width, baseline_y=line.y))
}
TextLayout::new(
runs,
LayoutMetrics::new(
width=result.total_width,
height=result.total_height,
baseline~,
),
)
}
///|
fn copy_positioned_glyphs(
glyphs : Array[PositionedGlyph],
) -> Array[PositionedGlyph] {
let copied = []
for glyph in glyphs {
copied.push(glyph)
}
copied
}
///|
fn copy_glyph_run(run : GlyphRun) -> GlyphRun {
GlyphRun::new(
copy_positioned_glyphs(run.glyphs),
width=run.width,
baseline_y=run.baseline_y,
)
}
///|
fn copy_glyph_runs(runs : Array[GlyphRun]) -> Array[GlyphRun] {
let copied = []
for run in runs {
copied.push(copy_glyph_run(run))
}
copied
}