Skip to main content

native/skia_native/src/generated_text.rs

// 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(&paragraph_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)
    }
}