lib.rs
8.1 kB · rust · 240 lines
1#![allow(non_camel_case_types, non_snake_case, clippy::too_many_arguments)]23mod hand;45use wasm_bindgen::prelude::*;67/// Builds every glyph in font order: uppers, lowers, digits, extras, specials.8#[wasm_bindgen]9pub fn all() -> Result<JsValue, JsValue> {10 let value = mrlyrs::font::all();11 hand::list_to_js(&value, |x1| Ok(JsValue::from(Glyph { inner: x1.clone() })))12}1314/// Writes the text in stroke order, one cell per frame, from an empty padded board to the full raster.15#[wasm_bindgen]16pub fn animate(text: &str, pad: usize) -> Result<JsValue, JsValue> {17 let value = mrlyrs::font::animate(text, pad);18 hand::to_js(&value)19}2021/// Chains the write, the merge and their reversals into one loop, resting hold frames after each movement that has any.22#[wasm_bindgen]23pub fn cycle(write: JsValue, merge: JsValue, hold: usize) -> Result<JsValue, JsValue> {24 let write = hand::from_js::<mrlyrs::font::Anim>(&write)?;25 let merge = hand::from_js::<Vec<Vec<usize>>>(&merge)?;26 let value = mrlyrs::font::cycle(&write, &merge, hold);27 hand::to_js(&value)28}2930/// Builds the ten digit glyphs.31#[wasm_bindgen]32pub fn digits() -> Result<JsValue, JsValue> {33 let value = mrlyrs::font::digits();34 hand::list_to_js(&value, |x1| Ok(JsValue::from(Glyph { inner: x1.clone() })))35}3637/// Drafts a stroke order for a trimmed bitmap by walking its lit cells: start at a lowest-left free end, keep heading, lift when stuck.38#[wasm_bindgen]39pub fn draft(rows: JsValue) -> Result<JsValue, JsValue> {40 let rows = hand::from_js::<Vec<String>>(&rows)?;41 let value = mrlyrs::font::draft(&rows);42 hand::to_js(&value)43}4445/// Builds the punctuation, symbol and arrow glyphs.46#[wasm_bindgen]47pub fn extras() -> Result<JsValue, JsValue> {48 let value = mrlyrs::font::extras();49 hand::list_to_js(&value, |x1| Ok(JsValue::from(Glyph { inner: x1.clone() })))50}5152/// Returns the least strokes that can write a trimmed bitmap: the minimum cover of its lit cells by 4-adjacent paths, zero for a blank.53#[wasm_bindgen]54pub fn floor(rows: JsValue) -> Result<usize, JsValue> {55 let rows = hand::from_js::<Vec<String>>(&rows)?;56 let value = mrlyrs::font::floor(&rows);57 Ok(value)58}5960/// Returns an owned copy of the character's glyph, or None outside the font.61#[wasm_bindgen]62pub fn glyph(c: char) -> Result<Option<Glyph>, JsValue> {63 let value = mrlyrs::font::glyph(c);64 Ok(value.map(|inner| Glyph { inner }))65}6667/// Blanks the four corner cells of an uppercase bitmap into its rounded lowercase form.68#[wasm_bindgen]69pub fn lower(rows: JsValue) -> Result<JsValue, JsValue> {70 let rows = hand::from_js::<Vec<String>>(&rows)?;71 let rows_view: Vec<&str> = rows.iter().map(String::as_str).collect();72 let value = mrlyrs::font::lower(&rows_view);73 hand::to_js(&value)74}7576/// Builds the twenty-six lowercase glyphs by rounding the uppers' corners.77#[wasm_bindgen]78pub fn lowers() -> Result<JsValue, JsValue> {79 let value = mrlyrs::font::lowers();80 hand::list_to_js(&value, |x1| Ok(JsValue::from(Glyph { inner: x1.clone() })))81}8283/// Returns the whole font as a map from character to bitmap rows.84#[wasm_bindgen]85pub fn map() -> Result<JsValue, JsValue> {86 let value = mrlyrs::font::map();87 hand::map_to_js(&value, hand::to_js)88}8990/// Folds the written text's glyphs, frame by frame, into one centered stack.91#[wasm_bindgen]92pub fn merge(text: &str, pad: usize) -> Result<JsValue, JsValue> {93 let value = mrlyrs::font::merge(text, pad);94 hand::list_to_js(&value, |x1| Ok(hand::typed(&(*x1)[..])))95}9697/// Returns the character's Unicode name, or a U+ code point label for a character outside the font.98#[wasm_bindgen]99pub fn name_of(c: char) -> Result<String, JsValue> {100 let value = mrlyrs::font::name_of(c);101 Ok(value)102}103104/// Flattens the character's strokes into one cell-by-cell drawing order.105#[wasm_bindgen]106pub fn path(c: char) -> Result<JsValue, JsValue> {107 let value = mrlyrs::font::path(c);108 hand::to_js(&value)109}110111/// Returns the character's hand-penned strokes from the pen tables, or None outside the font.112#[wasm_bindgen]113pub fn paths_penned(c: char) -> Result<JsValue, JsValue> {114 let value = mrlyrs::font::paths::penned(c);115 hand::to_js(&value)116}117118/// Returns every pen in font order: uppers, lowers, digits, extras, specials.119#[wasm_bindgen]120pub fn pens_all() -> Result<JsValue, JsValue> {121 let value = mrlyrs::font::pens::all();122 hand::to_js(&value)123}124125/// Returns the text as a 0/1 grid, its trimmed glyphs one blank column apart.126#[wasm_bindgen]127pub fn raster(text: &str) -> Result<JsValue, JsValue> {128 let value = mrlyrs::font::raster(text);129 hand::list_to_js(&value, |x1| Ok(hand::typed(&(*x1)[..])))130}131132/// Builds the four seven-row glyphs: dollar, at, copyright and registered.133#[wasm_bindgen]134pub fn specials() -> Result<JsValue, JsValue> {135 let value = mrlyrs::font::specials();136 hand::list_to_js(&value, |x1| Ok(JsValue::from(Glyph { inner: x1.clone() })))137}138139/// Returns the character's ordered strokes over its trimmed bitmap, or none for a character outside the font.140#[wasm_bindgen]141pub fn strokes(c: char) -> Result<JsValue, JsValue> {142 let value = mrlyrs::font::strokes(c);143 hand::to_js(&value)144}145146/// Returns every character in the font, in font order.147#[wasm_bindgen]148pub fn supported() -> Result<JsValue, JsValue> {149 let value = mrlyrs::font::supported();150 hand::to_js(&value)151}152153/// Cuts blank edge columns from a bitmap, collapsing an all-blank one to a single '0' column; a row shorter than the cut keeps what it has.154#[wasm_bindgen]155pub fn trim(rows: JsValue) -> Result<JsValue, JsValue> {156 let rows = hand::from_js::<Vec<String>>(&rows)?;157 let value = mrlyrs::font::trim(&rows);158 hand::to_js(&value)159}160161/// Builds the twenty-six uppercase glyphs.162#[wasm_bindgen]163pub fn uppers() -> Result<JsValue, JsValue> {164 let value = mrlyrs::font::uppers();165 hand::list_to_js(&value, |x1| Ok(JsValue::from(Glyph { inner: x1.clone() })))166}167168/// The playback rate of every animation, in frames per second.169#[wasm_bindgen]170pub fn FPS() -> Result<usize, JsValue> {171 let value = mrlyrs::font::FPS;172 Ok(value)173}174175/// The default number of frames a cycle rests between movements.176#[wasm_bindgen]177pub fn HOLD() -> Result<usize, JsValue> {178 let value = mrlyrs::font::HOLD;179 Ok(value)180}181182/// One character's pixel bitmap.183#[wasm_bindgen]184pub struct Glyph {185 inner: mrlyrs::font::Glyph,186}187188#[wasm_bindgen]189impl Glyph {190 /// Reads the Glyph from its plain data.191 #[wasm_bindgen(js_name = "from")]192 pub fn from_plain(data: JsValue) -> Result<Glyph, JsValue> {193 Ok(Glyph { inner: hand::from_js(&data)? })194 }195 /// Writes the Glyph as plain data.196 #[wasm_bindgen(js_name = "toJSON")]197 pub fn to_plain(&self) -> Result<JsValue, JsValue> {198 hand::to_js(&self.inner)199 }200 /// The character the glyph draws.201 #[wasm_bindgen(getter)]202 pub fn char(&self) -> Result<char, JsValue> {203 let value = self.inner.char;204 Ok(value)205 }206 #[wasm_bindgen(setter)]207 pub fn set_char(&mut self, value: char) -> Result<(), JsValue> {208 self.inner.char = value;209 Ok(())210 }211 /// The bitmap rows of '0' and '1' characters.212 #[wasm_bindgen(getter)]213 pub fn rows(&self) -> Result<JsValue, JsValue> {214 let value = self.inner.rows.clone();215 hand::to_js(&value)216 }217 #[wasm_bindgen(setter)]218 pub fn set_rows(&mut self, value: JsValue) -> Result<(), JsValue> {219 let value = hand::from_js::<Vec<String>>(&value)?;220 self.inner.rows = value;221 Ok(())222 }223 /// Returns the number of rows.224 pub fn height(&self) -> Result<usize, JsValue> {225 let value = self.inner.height();226 Ok(value)227 }228 /// Builds a glyph from its character and rows.229 #[wasm_bindgen(constructor)]230 pub fn new(char: char, rows: JsValue) -> Result<Glyph, JsValue> {231 let rows = hand::from_js::<Vec<String>>(&rows)?;232 let value = mrlyrs::font::Glyph::new(char, rows);233 Ok(Glyph { inner: value })234 }235 /// Returns the cell width of the first row, or 0 for an empty glyph.236 pub fn width(&self) -> Result<usize, JsValue> {237 let value = self.inner.width();238 Ok(value)239 }240}