ghe2d 0.1.3

A tool easy to make shapes
Documentation
use regex::Regex;

pub fn draw_text(img: &mut image::RgbaImage, load_font: crate::font::LoadFont, text: String, x: f32, y: f32, size: f32, color: crate::utility::Rgba) {
    let scale = rusttype::Scale::uniform(size);
    let arabic_text = ar_reshaper::ArabicReshaper::new(
        ar_reshaper::ReshaperConfig::new(ar_reshaper::Language::ArabicV2, ar_reshaper::config::LigaturesFlags::none())
    );
    let n_text = fix_arabic_text(&arabic_text.reshape(text.clone()));
    let lines:Vec<&str> = n_text.split("\n").collect();
    let line_height = scale.y;

    for (i, line) in lines.iter().enumerate() {
        let offset = rusttype::point(x, (i as f32 * line_height) + load_font.font.v_metrics(scale).ascent + y);
        let glyphs: Vec<rusttype::PositionedGlyph> = load_font.font.layout(line, scale, offset).collect();
        for glyph in glyphs {
            if let Some(bounding_box) = glyph.pixel_bounding_box() {
                glyph.draw(|x, y, v| {
                    let x = x as i32 + bounding_box.min.x;
                    let y = y as i32 + bounding_box.min.y;
                    {
                        let pixel = img.get_pixel(x as u32, y as u32);
                        let alpha = (v * 255.) as u8;
                        let background = crate::utility::Rgba::new(pixel.0[0], pixel.0[1], pixel.0[2], pixel.0[3]);
                        let blend = crate::utility::Rgba::blend_with_alpha(&color, background, alpha);
                        crate::rect::draw_rect(
                            img,
                            x as u32,
                            y as u32, 
                            1,
                            1,
                            crate::utility::Rgba::new(blend.0[0], blend.0[1], blend.0[2], blend.0[3])
                        );
                    }
                });
            }
        }
    }
}

fn fix_arabic_text(text: &str) -> String {
    let mut text_to_vet_u16: Vec<u16> = str::encode_utf16(text).collect();

    let mut is_right = false;
    if is_arabic(text_to_vet_u16[0]) {
        is_right = true;
    }

    if is_right {
        text_to_vet_u16.reverse();
    }

    let mut index = 0;
    let mut end = 0;
    let mut sub_vec_u16: Vec<u16> = vec![];
    
    for i in 0..text_to_vet_u16.len() {
        let char_u16 = text_to_vet_u16[i];
        if (is_arabic(char_u16) && !is_right) || (!is_arabic(char_u16) && is_right) || (char_u16 == 32 && (index != 0 && end != 0)) {
            if index == 0 {
                index = i + 1;
            }
            else {
                end += 1;
            }
        }
        else if index != 0 && end != 0 {
            let mut is_space = false;
            for j in (0..end + 1).rev() {
                if text_to_vet_u16[index - 1 + j] == 32 && j == (0..end).len() && !is_right {
                    is_space = true;
                }
                else {
                    sub_vec_u16.push(text_to_vet_u16[index - 1 + j]);
                }
            }
            if is_space {
                sub_vec_u16.push(32);
            }
            sub_vec_u16.push(char_u16);
            index = 0;
            end = 0;
        }
        else {
            if index != 0 {
                sub_vec_u16.push(text_to_vet_u16[index - 1]);
            }
            index = 0;
            end = 0;
            sub_vec_u16.push(char_u16);
        }
    }

    if index != 0 && end != 0 {
        for j in (0..end + 1).rev() {
            sub_vec_u16.push(text_to_vet_u16[index - 1 + j]);
        }
    }
    else if index != 0 {
        sub_vec_u16.push(text_to_vet_u16[index - 1]);
    }

    let mut sub_fix_vec_u16: Vec<u16> = vec![];

    for i in 0..sub_vec_u16.len() {
        let mut is_push = true;
        let mut char_u16 = sub_vec_u16[i];
        if char_u16 == 65152 {
            char_u16 = 1569;
        }
        else if char_u16 == 65248 || char_u16 == 65247 {
            if sub_vec_u16[i - 1] == 65154 {
                is_push = false;
            }
        }
        else if char_u16 == 65154 {
            if text_to_vet_u16[i + 1] == 65248 {
                char_u16 = 65270;
            }
            else {
                char_u16 = 65269;
            }
        }
        else if char_u16 == 65185 {
            char_u16 = 1581;
        }
        if is_push {
            sub_fix_vec_u16.push(char_u16);
        }
    }
    
    String::from_utf16(&sub_fix_vec_u16).unwrap()
}


fn is_arabic(c: u16) -> bool {
    let ar = Regex::new(r"\p{Arabic}").unwrap();
    ar.is_match(&std::char::from_u32(c as u32).unwrap().to_string())
}