///|
#borrow(text, family_name)
extern "C" fn native_paragraph_layout_utf8(
text : Bytes,
family_name : Bytes,
size : Float,
weight : Int,
width : Int,
slant : Int,
max_width : Float,
left_to_right : Bool,
) -> ParagraphHandle = "moonbit_skia_paragraph_layout_utf8"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_is_null(paragraph : ParagraphHandle) -> Bool = "moonbit_skia_paragraph_is_null"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_width(paragraph : ParagraphHandle) -> Float = "moonbit_skia_paragraph_width"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_height(paragraph : ParagraphHandle) -> Float = "moonbit_skia_paragraph_height"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_count(paragraph : ParagraphHandle) -> Int = "moonbit_skia_paragraph_line_count"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_start(
paragraph : ParagraphHandle,
index : Int,
) -> Int = "moonbit_skia_paragraph_line_start"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_end(
paragraph : ParagraphHandle,
index : Int,
) -> Int = "moonbit_skia_paragraph_line_end"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_end_excluding_whitespace(
paragraph : ParagraphHandle,
index : Int,
) -> Int = "moonbit_skia_paragraph_line_end_excluding_whitespace"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_end_including_newline(
paragraph : ParagraphHandle,
index : Int,
) -> Int = "moonbit_skia_paragraph_line_end_including_newline"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_number(
paragraph : ParagraphHandle,
index : Int,
) -> Int = "moonbit_skia_paragraph_line_number"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_hard_break(
paragraph : ParagraphHandle,
index : Int,
) -> Bool = "moonbit_skia_paragraph_line_hard_break"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_left(
paragraph : ParagraphHandle,
index : Int,
) -> Float = "moonbit_skia_paragraph_line_left"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_width(
paragraph : ParagraphHandle,
index : Int,
) -> Float = "moonbit_skia_paragraph_line_width"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_baseline(
paragraph : ParagraphHandle,
index : Int,
) -> Float = "moonbit_skia_paragraph_line_baseline"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_ascent(
paragraph : ParagraphHandle,
index : Int,
) -> Float = "moonbit_skia_paragraph_line_ascent"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_descent(
paragraph : ParagraphHandle,
index : Int,
) -> Float = "moonbit_skia_paragraph_line_descent"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_line_height(
paragraph : ParagraphHandle,
index : Int,
) -> Float = "moonbit_skia_paragraph_line_height"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_text_boxes_utf8_count(
paragraph : ParagraphHandle,
start : Int,
end : Int,
) -> Int = "moonbit_skia_paragraph_text_boxes_utf8_count"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_text_boxes_utf8_at_left(
paragraph : ParagraphHandle,
start : Int,
end : Int,
index : Int,
) -> Float = "moonbit_skia_paragraph_text_boxes_utf8_at_left"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_text_boxes_utf8_at_top(
paragraph : ParagraphHandle,
start : Int,
end : Int,
index : Int,
) -> Float = "moonbit_skia_paragraph_text_boxes_utf8_at_top"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_text_boxes_utf8_at_right(
paragraph : ParagraphHandle,
start : Int,
end : Int,
index : Int,
) -> Float = "moonbit_skia_paragraph_text_boxes_utf8_at_right"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_text_boxes_utf8_at_bottom(
paragraph : ParagraphHandle,
start : Int,
end : Int,
index : Int,
) -> Float = "moonbit_skia_paragraph_text_boxes_utf8_at_bottom"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_text_box_directions_utf8_count(
paragraph : ParagraphHandle,
start : Int,
end : Int,
) -> Int = "moonbit_skia_paragraph_text_box_directions_utf8_count"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_text_box_directions_utf8_at(
paragraph : ParagraphHandle,
start : Int,
end : Int,
index : Int,
) -> Int = "moonbit_skia_paragraph_text_box_directions_utf8_at"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_hit_test_utf8_offset(
paragraph : ParagraphHandle,
x : Float,
y : Float,
) -> Int = "moonbit_skia_paragraph_hit_test_utf8_offset"
///|
#borrow(paragraph)
extern "C" fn native_paragraph_hit_test_utf8_downstream(
paragraph : ParagraphHandle,
x : Float,
y : Float,
) -> Bool = "moonbit_skia_paragraph_hit_test_utf8_downstream"
///|
#borrow(canvas, paragraph)
extern "C" fn native_canvas_draw_paragraph(
canvas : CanvasHandle,
paragraph : ParagraphHandle,
x : Float,
y : Float,
) -> Bool = "moonbit_skia_canvas_draw_paragraph"
///|
pub fn Paragraph::layout_utf8(
text : Bytes,
family_name? : Bytes = b"",
size? : Float = 12.0,
weight? : Int = 400,
width? : Int = 5,
slant? : Int = 0,
max_width? : Float = 1000000000.0,
left_to_right? : Bool = true,
) -> Paragraph? {
if text.is_empty() ||
!native_paragraph_scalar_is_positive(size) ||
!native_paragraph_scalar_is_positive(max_width) {
return None
}
let handle = native_paragraph_layout_utf8(
text,
family_name,
size,
weight.clamp(min=1, max=1000),
width.clamp(min=1, max=9),
slant.clamp(min=0, max=2),
max_width,
left_to_right,
)
if native_paragraph_is_null(handle) {
None
} else {
Some({ handle, })
}
}
///|
pub fn Paragraph::is_available(self : Paragraph) -> Bool {
!native_paragraph_is_null(self.handle)
}
///|
pub fn Paragraph::width(self : Paragraph) -> Float {
native_paragraph_width(self.handle)
}
///|
pub fn Paragraph::height(self : Paragraph) -> Float {
native_paragraph_height(self.handle)
}
///|
pub fn Paragraph::line_count(self : Paragraph) -> Int {
native_paragraph_line_count(self.handle).max(0)
}
///|
pub fn Paragraph::line_metrics(self : Paragraph) -> Array[ParagraphLineMetric] {
let count = self.line_count()
let metrics : Array[ParagraphLineMetric] = Array::new(capacity=count)
for index in 0.. Array[@skia.Rect] {
// Build the result in MoonBit rather than returning the C batch array.
// The C MoonbitSkiaRectArray* memory layout is incompatible with
// MoonBit's Array[@skia.Rect].
if end <= start {
[]
} else {
let s = start.max(0)
let e = end.max(start)
let count = native_paragraph_text_boxes_utf8_count(self.handle, s, e)
let boxes : Array[@skia.Rect] = Array::new(capacity=count)
for index in 0.. Array[Int] {
// Build the result in MoonBit; the C MoonbitSkiaInt32Array* layout is
// incompatible with MoonBit's Array[Int].
if end <= start {
[]
} else {
let s = start.max(0)
let e = end.max(start)
let count = native_paragraph_text_box_directions_utf8_count(
self.handle,
s,
e,
)
let directions : Array[Int] = Array::new(capacity=count)
for index in 0.. ParagraphHitTestResult {
if !native_paragraph_scalar_is_finite(x) ||
!native_paragraph_scalar_is_finite(y) {
{ offset: 0, downstream: true }
} else {
{
offset: native_paragraph_hit_test_utf8_offset(self.handle, x, y).max(0),
downstream: native_paragraph_hit_test_utf8_downstream(self.handle, x, y),
}
}
}
///|
pub fn Canvas::draw_paragraph(
self : Canvas,
paragraph : Paragraph,
origin? : @skia.Point = @skia.Point::zero(),
) -> Bool {
if !origin.is_finite() || !paragraph.is_available() {
false
} else {
native_canvas_draw_paragraph(
self.handle,
paragraph.handle,
origin.x,
origin.y,
)
}
}
///|
fn native_paragraph_scalar_is_finite(value : Float) -> Bool {
value == value && value - value == 0.0
}
///|
fn native_paragraph_scalar_is_positive(value : Float) -> Bool {
native_paragraph_scalar_is_finite(value) && value > 0.0
}