// Generated by mix skia.codegen. Do not edit by hand.
fn draw_text_blob_impl<'a>(
canvas: &skia_safe::Canvas,
args: Vec<Term<'a>>,
opts: generated_opts::TextBlobOpts<'a>,
raw_opts: &[(Atom, Term<'a>)],
) -> NifResult<()> {
let blob = text_blob_from_term(*args.first().ok_or(rustler::Error::BadArg)?)?;
let paint = match opts.fill {
Some(term) => decode_paint(term)?,
None => fill_paint(Color::BLACK),
};
let mut paint = paint;
apply_paint_effects(&mut paint, raw_opts)?;
canvas.draw_text_blob(&blob, (opts.x, opts.y), &paint);
Ok(())
}
fn draw_text_impl<'a>(
canvas: &skia_safe::Canvas,
args: Vec<Term<'a>>,
opts: generated_opts::TextOpts<'a>,
_raw_opts: &[(Atom, Term<'a>)],
) -> NifResult<()> {
let text = args.first().ok_or(rustler::Error::BadArg)?.decode::<String>()?;
let size = opts.size.unwrap_or(16.0);
let mut font = match opts.font {
Some(term) => font_from_term(term, size)?,
None => Font::default(),
};
font.set_size(size);
let paint = match opts.fill {
Some(term) => fill_paint(decode_color(term)?),
None => fill_paint(Color::BLACK),
};
if let Some(width) = opts.width {
draw_paragraph_text(canvas, &text, opts.x, opts.y, width, size, &paint, &opts)?;
} else {
canvas.draw_str(text, (opts.x, opts.y), &font, &paint);
}
Ok(())
}
fn draw_paragraph_text<'a>(
canvas: &skia_safe::Canvas,
text: &str,
x: f32,
y: f32,
width: f32,
size: f32,
paint: &Paint,
opts: &generated_opts::TextOpts<'a>,
) -> NifResult<()> {
let mut text_style = TextStyle::new();
text_style.set_font_size(size);
text_style.set_color(paint.color());
if let Some(ref family) = opts.font_family {
text_style.set_font_families(&[family]);
}
if let Some(line_height) = opts.line_height {
text_style.set_height(line_height / size);
text_style.set_height_override(true);
}
let mut paragraph_style = ParagraphStyle::new();
paragraph_style.set_text_style(&text_style);
if let Some(align) = opts.align {
paragraph_style.set_text_align(decode_text_align(align)?);
}
if let Some(direction) = opts.direction {
paragraph_style.set_text_direction(decode_text_direction(direction)?);
}
let mut font_collection = FontCollection::new();
font_collection.set_default_font_manager(FontMgr::default(), None);
let mut paragraph_builder = ParagraphBuilder::new(¶graph_style, font_collection);
if let Some(spans_term) = opts.spans {
for (span_text, style_opts) in spans_term
.decode::<Vec<(String, Vec<(Atom, Term)>)>>()?
{
let span_style = text_style_from_opts(&text_style, &style_opts)?;
paragraph_builder.push_style(&span_style);
paragraph_builder.add_text(span_text);
paragraph_builder.pop();
}
} else {
paragraph_builder.push_style(&text_style);
paragraph_builder.add_text(text);
paragraph_builder.pop();
}
let mut paragraph = paragraph_builder.build();
paragraph.layout(width);
paragraph.paint(canvas, Point::new(x, y));
Ok(())
}
fn text_style_from_opts<'a>(
base: &TextStyle,
opts: &[(Atom, Term<'a>)],
) -> NifResult<TextStyle> {
let mut style = base.clone();
if let Some(size) = opt_f32_option(opts, atoms::size())? {
style.set_font_size(size);
}
if let Some(fill) = opt_term(opts, atoms::fill()) {
style.set_color(decode_color(fill)?);
}
if let Some(ref family) = opt_term(opts, atoms::font_family())
.map(|term| term.decode::<String>())
.transpose()?
{
style.set_font_families(&[family]);
}
if let Some(line_height) = opt_f32_option(opts, atoms::line_height())? {
let font_size = opt_f32_option(opts, atoms::size())?.unwrap_or(base.font_size());
style.set_height(line_height / font_size);
style.set_height_override(true);
}
Ok(style)
}
fn decode_text_align(value: Atom) -> NifResult<TextAlign> {
if value == atoms::center() {
Ok(TextAlign::Center)
} else if value == atoms::right() {
Ok(TextAlign::Right)
} else if value == atoms::justify() {
Ok(TextAlign::Justify)
} else if value == atoms::left() {
Ok(TextAlign::Left)
} else {
Err(rustler::Error::BadArg)
}
}
fn decode_text_direction(value: Atom) -> NifResult<TextDirection> {
if value == atoms::rtl() {
Ok(TextDirection::RTL)
} else if value == atoms::ltr() {
Ok(TextDirection::LTR)
} else {
Err(rustler::Error::BadArg)
}
}