Sign in

    #gmlewis/moonbit-fonts

    check

    This is an experimental package to manipulate open source fonts with MoonBit.

    All fonts are open source and their licenses can all be found in their corresponding repos which are organized by the first letter of the name of the font:

    mbt-fonts-* packages contain hardcoded font data using Map[String, @fonts.Glyph].

    • font: https://github.com/gmlewis/mbt-fonts-a/tree/master/aaarghnormal
    • license: https://github.com/gmlewis/go-fonts-a/tree/master/fonts/aaarghnormal
    • ...
    • font: https://github.com/gmlewis/mbt-fonts-b/tree/master/baloo
    • license: https://github.com/gmlewis/go-fonts-b/tree/master/fonts/baloo
    • ...
    • font: https://github.com/gmlewis/mbt-fonts-z/tree/master/znikomitno24
    • license: https://github.com/gmlewis/go-fonts-z/tree/master/fonts/znikomitno24

    #Examples

    #checkerboard

    checkerboard is a simple example to create a draw.Graphic using the @draw API.

    #canvas-checkerboard

    canvas-checkerboard renders the checkerboard Graphic to an HTML5 canvas. Type ./run-canvas-checkerboard.sh in a terminal then open your browser to http://localhost:8080/examples/canvas-checkerboard to view it.

    #svg-checkerboard

    svg-checkerboard "renders" the checkerboard Graphic to an SVG file. Type moon run examples/svg-checkerboard > examples/svg-checkerboard/checkerboard.svg in a terminal then open this file in your browser to view it. For example, google-chrome examples/svg-checkerboard/checkerboard.svg.

    #Status

    The code has been updated to support compiler:

    $ moon version --all moon 0.1.20251117 (2a4820a 2025-11-17) ~/.moon/bin/moon moonc v0.6.32+6f48aae3f (2025-11-17) ~/.moon/bin/moonc moonrun 0.1.20251117 (2a4820a 2025-11-17) ~/.moon/bin/moonrun moon-pilot 0.0.1-df92511 (2025-11-17) ~/.moon/bin/moon-pilot


    Enjoy!


    #License

    Please note that all fonts have their own licenses which are included in their respective original directories (see above).

    Copyright 2019-2024 Glenn M. Lewis. All Rights Reserved.

    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


    FontError

    pub(all) suberror FontError String

    impl Eq for FontError
    impl Show for FontError

    AbsoluteCmd

    pub(all) enum AbsoluteCmd {
    M
    L
    C
    Q
    Z
    }

    AbsoluteCmd represents a supported absolute SVG command.
    impl Eq for AbsoluteCmd
    impl Show for AbsoluteCmd

    Anchor

    pub(all) enum Anchor {
    Unchanged
    TopLeft
    TopCenter
    TopRight
    CenterLeft
    Center
    CenterRight
    BaselineLeft
    BaselineCenter
    BaselineRight
    BottomLeft
    BottomCenter
    BottomRight
    RatioXY(Double, Double)
    }

    Anchor represents where to place the origin (0,0) of the glyph relative to its minimum bounding box.
    impl Eq for Anchor
    impl Show for Anchor

    Cmd

    type Cmd

    Cmd represents an SVG command along with its parameters.
    impl Eq for Cmd
    impl Show for Cmd

    Font

    pub(all) struct Font {
    id : String
    horiz_adv_x : Double
    units_per_em : Double
    ascent : Double
    descent : Double
    glyphs : Map[String, Glyph]
    }

    Font represents an entire font.
    impl Eq for Font
    impl Show for Font
    impl ToJson for Font

    Font::gen_path

    fn Font::gen_path(self : Font, text : String, anchor? : Anchor, y_up? : Bool) -> Glyph raise FontError

    gen_path "renders" the provided text string into an SVG path using the provided font information. It performs the necessary path translations in order to combine the individual glyphs into a "super glyph" that can be rendered as a whole.

    Note that gen_path operates on the string as a left-justified whole and anchors the entire path relative to anchor accordingly.

    If you want multiple lines centered horizontally, use gen_paths instead.

    Note that the SVG standard states that positive-Y is "down" with origin coordinates in the upper-left, however, all SVG fonts appear to have their origin in the lower left with positive-Y moving "up". This package attempts to convert the SVG paths such that the font is equally readable in both the "y_up=false" SVG canvas environment or in a 3D "y_up=true" rendering environment.

    Font::gen_paths

    fn Font::gen_paths(self : Font, lines : Array[String], anchor? : Anchor, y_up? : Bool) -> Array[Glyph] raise FontError

    gen_paths handles multiple strings independently so that they can be aligned and distributed more flexibly.

    GerberLP

    pub(all) enum GerberLP {
    Dark
    Clear
    }

    GerberLP represents whether a subpath is Dark or Clear.
    impl Eq for GerberLP
    impl Show for GerberLP

    Glyph

    pub(all) struct Glyph {
    char : String
    horiz_adv_x : Double
    gerber_lp : String
    d : String
    xmin : Double
    ymin : Double
    xmax : Double
    ymax : Double
    }

    Glyph represents a single glyph within each Font and also represents multiple glyphs combined together (for example after using Font.gen_path and switching back and forth between Glyphs which are optimized for storage, and Paths which are optimized for processing).
    impl Eq for Glyph
    impl Show for Glyph
    impl ToJson for Glyph

    ParamPair

    pub(all) struct ParamPair {
    x : Double
    y : Double
    }

    ParamPair represents an X,Y absolute coordinate pair of parameters.
    impl Eq for ParamPair

    ParamPair::to_string

    fn ParamPair::to_string(self : ParamPair) -> String

    Params

    type Params

    Params represents the parameters to an SVG command.
    impl Eq for Params
    impl Show for Params

    Params::length

    fn Params::length(self : Params) -> Int

    Path

    pub(all) struct Path {
    char : String
    cmds : Array[PathCmd]
    xmin : Double
    ymin : Double
    xmax : Double
    ymax : Double
    }

    A Path is identical to a Glyph but has been optimized internally for further manipulation, whereas a Glyph is optimized for compact storage of font data within all the font packages. A Path can be converted to a Glpyh and vice versa.
    impl Eq for Path
    impl Show for Path

    Path::clone

    fn Path::clone(self : Path) -> Path

    clone makes a deep copy of a Path.

    Path::from_glyph

    fn Path::from_glyph(g : Glyph, path_cmd_fn? : PathCmdFn) -> Path raise FontError

    from_glyph returns a Path from a Glyph, optionally processing every Cmd with a processing function. Note that apart from path_cmd_fn, from_glyph makes no attempt to process the invidual glyphs and simply transforms the representation.

    Path::to_glyph

    fn Path::to_glyph(self : Path, path_cmd_fn? : PathCmdFn) -> Glyph

    to_glyph returns a "super" Glyph from a Path, optionally processing every PathCmd with a processing function. Note that apart from path_cmd_fn, to_glyph makes no attempt to process the invidual glyphs and simply transforms the representation.

    PathCmd

    pub(all) struct PathCmd {
    cmd : AbsoluteCmd
    gerber_lp : GerberLP
    params : Array[ParamPair]
    }

    Cmd represents an individual absolute SVG command.
    impl Eq for PathCmd
    impl Show for PathCmd

    PathCmd::bbox

    fn PathCmd::bbox(self : PathCmd) -> Rectangle

    bbox returns the minimum bounding box of a PathCmd.

    PathCmd::clone

    fn PathCmd::clone(self : PathCmd) -> PathCmd

    clone makes a deep copy of a PatchCmd.

    PathCmd::from_svg_cmd

    fn PathCmd::from_svg_cmd(svg_cmd : Cmd, gerber_lp : GerberLP) -> PathCmd raise FontError

    PathCmd::to_svg_cmd

    fn PathCmd::to_svg_cmd(self : PathCmd) -> (Cmd, String)

    PathCmdFn

    pub(all) type PathCmdFn (Int, PathCmd) -> PathCmd

    PathCmdFn represents a function that processes or transforms individual commands. The first argument is the index within the command.

    PathCmdFn::inner

    #deprecated("Use `struct T(A)` to declare a newtype and use `.0` access the underlying type instead.")
    fn PathCmdFn::inner(self : PathCmdFn) -> ((Int, PathCmd) -> PathCmd)
    Convert newtype to its underlying type, automatically derived.

    Point

    pub(all) struct Point {
    x : Double
    y : Double
    }

    impl Add for Point
    impl Eq for Point
    impl Show for Point
    impl Sub for Point

    Point::div

    fn Point::div(self : Point, k : Double) -> Point

    div returns the vector p/k.

    Point::is_in

    fn Point::is_in(self : Point, r : Rectangle) -> Bool

    is_in reports whether p is in r.

    Point::mul

    fn Point::mul(self : Point, k : Double) -> Point

    mul returns the vector p*k.

    Point::to_string

    fn Point::to_string(self : Point) -> String

    to_string returns a string representation of p like "(3,4)".

    Rectangle

    pub(all) struct Rectangle {
    min : Point
    max : Point
    }

    A Rectangle contains the points with Min.X <= X < Max.X, Min.Y <= Y < Max.Y. It is well-formed if Min.X <= Max.X and likewise for Y. Points are always well-formed. A rectangle's methods always return well-formed outputs for well-formed inputs.

    A Rectangle is also an [Image] whose bounds are the rectangle itself. At returns color.Opaque for points in the rectangle and color.Transparent otherwise.
    impl Eq for Rectangle
    impl Show for Rectangle

    Rectangle::add

    fn Rectangle::add(self : Rectangle, p : Point) -> Rectangle

    add returns the rectangle r translated by p.

    Rectangle::bounds

    fn Rectangle::bounds(self : Rectangle) -> (Double, Double, Double, Double)

    bounds returns the tuple (xmin, ymin, xmax, ymax).

    Rectangle::canon

    fn Rectangle::canon(self : Rectangle) -> Rectangle

    canon returns the canonical version of r. The returned rectangle has minimum and maximum coordinates swapped if necessary so that it is well-formed.

    Rectangle::clone

    fn Rectangle::clone(self : Rectangle) -> Rectangle

    clone makes a copy of the provided rectangle without changing it.

    Rectangle::dx

    fn Rectangle::dx(self : Rectangle) -> Double

    dx returns r's width.

    Rectangle::dy

    fn Rectangle::dy(self : Rectangle) -> Double

    dy returns r's height.

    Rectangle::empty

    fn Rectangle::empty(self : Rectangle) -> Bool

    empty reports whether the rectangle contains no points.

    Rectangle::extend

    fn Rectangle::extend(self : Rectangle, pt : Point) -> Unit

    extend extends the current rectangle to include the provided point.

    Rectangle::inset

    fn Rectangle::inset(self : Rectangle, n : Double) -> Rectangle

    inset returns the rectangle r inset by n, which may be negative. If either of r's dimensions is less than 2*n then an empty rectangle near the center of r will be returned.

    Rectangle::intersect

    fn Rectangle::intersect(self : Rectangle, s : Rectangle) -> Rectangle

    intersect returns the largest rectangle contained by both r and s. If the two rectangles do not overlap then the zero rectangle will be returned.

    Rectangle::is_in

    fn Rectangle::is_in(self : Rectangle, s : Rectangle) -> Bool

    is_in reports whether every point in r is in s.

    Rectangle::new

    fn Rectangle::new() -> Rectangle

    Rectangle::new returns an empty (all zeros) rectangle.

    Rectangle::overlaps

    fn Rectangle::overlaps(self : Rectangle, s : Rectangle) -> Bool

    overlaps reports whether r and s have a non-empty intersection.

    Rectangle::size

    fn Rectangle::size(self : Rectangle) -> Point

    size returns r's width and height.

    Rectangle::sub

    fn Rectangle::sub(self : Rectangle, p : Point) -> Rectangle

    sub returns the rectangle r translated by -p.

    Rectangle::to_string

    fn Rectangle::to_string(self : Rectangle) -> String

    to_string returns a string representation of r like "(3,4)-(6,5)".

    Rectangle::union

    fn Rectangle::union(self : Rectangle, s : Rectangle) -> Rectangle

    union returns the smallest rectangle that contains both r and s.

    all_fonts

    let all_fonts : ReadOnlyArray[String]

    glyph_bbox

    fn glyph_bbox(d : String) -> Rectangle raise FontError

    glyph_bbox returns the conservative bounding box of a Glyph path. It only supports the absolute SVG commands: M, L, C, Q, Z.

    Note that this function does NOT fully analyze the Cubic or Quadratic Bézier curves to determine their exact bounding boxes, but instead takes a naive and concervative approach by encapsulating the bounds of all control points in addition to curve anchor points which may result in returning a much larger bounding box than is actually needed to fully contain the glyph.
    fn pt(x : Double, y : Double) -> Point

    pt is shorthand for [Point]{X, Y}.

    rect

    fn rect(x0 : Double, y0 : Double, x1 : Double, y1 : Double) -> Rectangle

    rect is shorthand for Rectangle::{min: pt(x0, y0), max: pt(x1, y1)}. The returned rectangle has minimum and maximum coordinates swapped if necessary so that it is well-formed.

    translate_path

    fn translate_path(d : String, x : Double, y : Double, invert_y? : Bool) -> String raise FontError

    translate_path translates (moves) an SVG path by the provided offsets. If invert_y is true, all y values are scaled by -1.