mplusfonts_macros/
lib.rs

1//! This crate contains **M<sup>+</sup> FONTS**, [a font family](https://mplusfonts.github.io/) by
2//! Coji Morishita; it is a dependency of [`mplusfonts`](../mplusfonts/index.html), with font
3//! rasterization powered by [`swash`].
4
5mod mplus;
6mod strings;
7
8use proc_macro::TokenStream;
9use syn::{meta, parse_macro_input};
10
11/// Collects string literals for rewriting [`mplus!`] macro invocations prior to their expansion.
12///
13/// This attribute should be applied to the item that contains both the string literals that appear
14/// in [`Text`](../embedded_graphics/text/struct.Text.html) drawables and the [`mplus!`] macro that
15/// provides the bitmap font in the [`Text`](../embedded_graphics/text/struct.Text.html)'s
16/// character style.
17///
18/// Use `#[strings::skip]` to exclude string literals or blocks from the output of
19/// [`macro@strings`], and apply `#[strings::emit]` to the macro invocations that you want to
20/// modify to have additional input --- the string literals that have been collected; appended as a
21/// single slice literal expression.
22///
23/// # Examples
24///
25/// ```
26/// # use core::convert::Infallible;
27/// #
28/// # use embedded_graphics::pixelcolor::Rgb888;
29/// # use embedded_graphics::prelude::*;
30/// # use embedded_graphics::text::Text;
31/// # use embedded_graphics_simulator::{OutputSettingsBuilder, SimulatorDisplay, Window};
32/// # use mplusfonts::mplus;
33/// # use mplusfonts::style::BitmapFontStyle;
34/// #
35/// #[mplusfonts::strings]
36/// pub fn main() -> Result<(), Infallible> {
37///     let mut display: SimulatorDisplay<Rgb888> = SimulatorDisplay::new(Size::new(120, 120));
38///
39///     #[strings::emit]
40///     let bitmap_font = mplus!(2, 480, 16, true, 4, 8, /* will inject ["It works!"] here */);
41///
42///     let character_style = BitmapFontStyle::new(&bitmap_font, Rgb888::new(0, 210, 255));
43///
44///     Text::new("It works!", Point::new(0, 120), character_style).draw(&mut display)?;
45///
46///     let output_settings = OutputSettingsBuilder::new().scale(6).pixel_spacing(2).build();
47///
48///     #[strings::skip]
49///     Window::new("Simulator", &output_settings).show_static(&display);
50///
51///     Ok(())
52/// }
53/// ```
54#[proc_macro_attribute]
55pub fn strings(args: TokenStream, input: TokenStream) -> TokenStream {
56    let message = "remove the arguments to the attribute";
57    let parser = meta::parser(|meta| Err(meta.error(message)));
58    parse_macro_input!(args with parser);
59
60    let item = parse_macro_input!(input as syn::Item);
61    strings::strings_impl(item).into()
62}
63
64/// Produces a struct expression for creating a
65/// [`BitmapFont`](../mplusfonts/struct.BitmapFont.html).
66///
67/// The generated data structure is a single self-contained expression with static references and
68/// lookup-table-like structures that point to kerning and pixel information, image offset data,
69/// etc. The individual values appear in the form of number and byte slice literals after macro
70/// expansion, so the usage of this macro is comparable to using [`include_bytes!`] with a
71/// bitmap font, but without creating any additional files in the build process.
72///
73/// The data types live in the [`mplusfonts`](../mplusfonts/index.html) crate, which also features
74/// [`BitmapFontStyle`](../mplusfonts/struct.BitmapFontStyle.html), the intended consumer of the
75/// generated data.
76///
77/// [`include_bytes!`]: https://doc.rust-lang.org/core/macro.include_bytes.html
78///
79/// # Arguments
80///
81/// * `font` - Typeface and font width. Specify `1` or `2` to use the respective variable-width
82///   **M<sup>+</sup>** font or, for a monospaced font, specify `code`, which takes a `width`
83///   parameter and uses **M<sup>+</sup> Code Latin 50/60**, falling back to **M<sup>+</sup> 1**
84///   for glyphs that are not parametrized by width.
85///   * `code(width)` - Font width. Ranges from `100` to `125`. Only available as a parameter to
86///     `code`.
87/// * `weight` - Font weight. Ranges from `100` to `900`. Capped at `700` for `code`.
88/// * `size` - Font size. Specify either as a value in pixels per _em_-size or, for convenience,
89///   specify one of helpers listed here, all of which take a `px` parameter, performing a
90///   conversion to pixels per _em_-size. In both cases, any `.0` can be omitted.
91///   * `x_height(px)` - Height of the small letter _x_.
92///   * `cap_height(px)` - Height of capital letters.
93///   * `line_height(px)` - Line height used for `1` and `2`.
94///   * `code_line_height(px)` - Line height used for `code`.
95/// * `hint` - Font hinting. Set to [`true`] to enable or [`false`] to disable this feature.
96///   Improves the clarity of fonts at small sizes at the cost of glyphs becoming less proportional
97///   along the _y_-axis.
98/// * `positions` - Number of glyph images, one for each sub-pixel offset. Ranges from `1` to `16`.
99///   Specify `1` for a single image at `.0` offset. Ignored for glyphs with square bounding
100///   boxes such as kanji, kana, and also forced to `1` for `code`.
101/// * `bit_depth` - Bit depth of glyph images. Specify `n` to use _2_<sup>`n`</sup> values of gray.
102///   Limited to `1`, `2`, `4`, `8`.
103/// * `sources` - Sources of characters for feeding the glyph shaper. Enable support for rendering
104///   the individual strings here; otherwise, this instance returns boxes (image representations of
105///   `.notdef`) when looking up glyph data.
106///   * Ranges of character literals. Use this option for arbitrary strings created at runtime.
107///   * Arrays of string literals. Specify all static text in any order, grouped in any manner.
108///
109/// The optional `sources` argument makes this a variadic-function-like procedural macro.
110///
111/// # Aliases
112///
113/// Built-in constant-like identifiers can be substituted for common weight and width values.
114///
115/// | Weight Name           | Value |
116/// |-----------------------|-------|
117/// | `THIN`                | `100` |
118/// | `EXTRA_LIGHT`         | `200` |
119/// | `LIGHT`               | `300` |
120/// | `NORMAL` or `REGULAR` | `400` |
121/// | `MEDIUM`              | `500` |
122/// | `SEMI_BOLD`           | `600` |
123/// | `BOLD`                | `700` |
124/// | `EXTRA_BOLD`          | `800` |
125/// | `BLACK`               | `900` |
126///
127/// | Width Name | Value |
128/// |------------|-------|
129/// | `NORMAL`   | `100` |
130/// | `EXPANDED` | `125` |
131///
132/// # Examples
133///
134/// ```
135/// # use mplusfonts::mplus;
136/// #
137/// mplus!(1, 750, x_height(5), false, 2, 4, ["Yes", "No"]);
138/// mplus!(1, 525, cap_height(7), false, 2, 4, ["キャンセル"]);
139/// mplus!(2, BOLD, line_height(20), false, 2, 4, ["Tokyo"], ["東京"]);
140/// mplus!(code(100), SEMI_BOLD, 18, true, 1, 4, '0'..='9', [",.-"]);
141/// mplus!(code(125), 480, 13.5, true, 1, 4, 'A'..='Z', 'ぁ'..='ゖ');
142/// ```
143///
144/// The amount of flash memory (storage space for `.rodata`) that is going to be used, will be a
145/// few **kilobytes**. In all of these examples, specifying `..` for `sources` and including all
146/// characters would change the size of each bitmap font to approximately _2_–_3_ **megabytes**.
147///
148/// ## All-inclusive bitmap font
149///
150/// The following example produces a binary output that is approximately _16_ megabytes in size:
151///
152/// ```
153/// # use mplusfonts::mplus;
154/// #
155/// mplus!(1, 500, 50, true, 4, 8, .., ["ff", "fi", "ffi", "fl", "ffl"]);
156/// ```
157#[proc_macro]
158pub fn mplus(input: TokenStream) -> TokenStream {
159    let args = parse_macro_input!(input as mplus::Arguments);
160    mplus::mplus_impl(args).into()
161}