mplusfonts-macros 0.3.4

Procedural macros re-exported in the mplusfonts crate
Documentation
mod double;
mod single;

use swash::zeno::{Mask, PathData, Point, Stroke, Vector};

use super::{Chain, ChainList, GlyphMetrics, Image, ImageCluster};

pub use double::*;
pub use single::with_arc::*;
pub use single::with_double::*;
pub use single::with_heavy::*;
pub use single::with_single::*;
pub use single::*;

type Points = [[Point; 3]; 3];
type Matrix = [[Vector; 2]; 2];

fn offset_table(offset: Vector) -> Matrix {
    let mut offset_table = [[offset, offset], [offset, offset]];
    offset_table[0][1].x = offset_table[0][1].x.round();
    offset_table[1][0].y = offset_table[1][0].y.round();
    offset_table[1][1].x = offset_table[0][1].x;
    offset_table[1][1].y = offset_table[1][0].y;

    offset_table
}

fn render_image(data: impl PathData, stroke: &Stroke) -> Image {
    Mask::new(data).style(stroke).render()
}

fn trim_image((mut data, mut placement): Image) -> Image {
    let data_top = data.iter();
    let diff_top = data_top
        .take_while(|value| **value == 0)
        .count()
        .checked_div(placement.width as usize)
        .unwrap_or_default();

    let diff_top = diff_top.try_into().unwrap_or(u32::MAX);
    let diff_top = diff_top.min(placement.height);
    placement.top = placement.top.saturating_add_unsigned(diff_top);
    placement.height = placement.height.saturating_sub(diff_top);

    let mut data = data.split_off(placement.width as usize * diff_top as usize);
    let data_bottom = data.iter().rev();
    let diff_height = data_bottom
        .take_while(|value| **value == 0)
        .count()
        .checked_div(placement.width as usize)
        .unwrap_or_default();

    let diff_height = diff_height.try_into().unwrap_or(u32::MAX);
    placement.height = placement.height.saturating_sub(diff_height);

    data.truncate(placement.width as usize * placement.height as usize);

    let (data, placement) = trim_left((data, placement));
    let (data, placement) = trim_right((data, placement));

    (data, placement)
}

fn trim_left((mut data, mut placement): Image) -> Image {
    let data_left = (0..placement.width as usize)
        .flat_map(|n| data.iter().skip(n).step_by(placement.width as usize));

    let diff_left = data_left
        .take_while(|value| **value == 0)
        .count()
        .checked_div(placement.height as usize)
        .unwrap_or_default();

    let diff_left = diff_left.try_into().unwrap_or(u32::MAX);
    let diff_left = diff_left.min(placement.width);
    placement.left = placement.left.saturating_add_unsigned(diff_left);

    'trim_op: for _ in 0..diff_left {
        if let Some(width) = placement.width.checked_sub(1) {
            for index in (0..placement.height as usize).map(|n| n * width as usize) {
                let _ = data.remove(index);
            }

            placement.width = width;
        } else {
            break 'trim_op;
        }
    }

    (data, placement)
}

fn trim_right((mut data, mut placement): Image) -> Image {
    let data_right = (0..placement.width as usize)
        .flat_map(|n| data.iter().rev().skip(n).step_by(placement.width as usize));

    let diff_width = data_right
        .take_while(|value| **value == 0)
        .count()
        .checked_div(placement.height as usize)
        .unwrap_or_default();

    let diff_width = diff_width.try_into().unwrap_or(u32::MAX);

    'trim_op: for _ in 0..diff_width {
        if let Some(width) = placement.width.checked_sub(1) {
            let rows = 0..placement.height as usize;
            for index in rows.map(|n| (n + 1) * width as usize) {
                let _ = data.remove(index);
            }

            placement.width = width;
        } else {
            break 'trim_op;
        }
    }

    (data, placement)
}