### 7 releases (4 breaking)

0.5.0 | Jun 13, 2024 |
---|---|

0.4.0 | May 6, 2024 |

0.3.0 | Oct 18, 2023 |

0.2.0 | Oct 15, 2023 |

0.1.1 | Aug 26, 2023 |

#**103** in Graphics APIs

**190** downloads per month

**MIT**and maybe CC-PDDC

660KB

3.5K
SLoC

# fdsm

A pure-Rust reimplementation of multi-channel signed distance field generation.

This implementation mostly follows Victor Chlumský’s master thesis.
Although it is not an exact translation of the C++

library, it does follow it for some parts of the code.`msdfgen`

also uses code adapted from `fdsm`

for its tests.`msdfgen-rs`

## Crate features

: import glyphs using`ttf-parser``ttf-parser`

: helpers for visualization`visualize`

## Usage

`use` `fdsm``::``bezier``::``scanline``::`FillRule`;`
`use` `fdsm``::``generate``::`generate_msdf`;`
`use` `fdsm``::``render``::``{`correct_sign_msdf`,` render_msdf`}``;`
`use` `fdsm``::``shape``::`Shape`;`
`use` `fdsm``::``transform``::`Transform`;`
`use` `image``::``{`GrayImage`,` RgbImage`}``;`
`use` `nalgebra``::``{`Affine2`,` Similarity2`,` Vector2`}``;`
`use` `ttf_parser``::`Face`;`
`//` First, acquire a [`Shape`]. This can be done by procedurally
`//` generating one or by loading one from a font:
`let` face `=` `Face``::`parse`(``notosans``::``REGULAR_TTF``,` `0``)``.``unwrap``(``)``;`
`let` glyph_id `=` face`.``glyph_index``(``'`A`'``)``.``unwrap``(``)``;`
`let` `mut` shape `=` `Shape``::`load_from_face`(``&`face`,` glyph_id`)``;`
`//` Prepare your transformation matrix and calculate the dimensions of
`//` the resulting signed distance field. As an example, we set this up
`//` using ‘shrinkage’ (font units per texel) and ‘range’ (number of
`//` texels for the margin) values.
`//` Note that since font files interpret a positive y-offset as
`//` pointing up, the resulting distance field will be upside-down.
`//` This can be corrected either by flipping the resulting image
`//` vertically or by modifying the transformation matrix. We omit
`//` this fix for simplicity.
`let` bbox `=` face`.``glyph_bounding_box``(`glyph_id`)``.``unwrap``(``)``;`
`const` `RANGE``:` `f64` `=` `4.``0``;`
`const` `SHRINKAGE``:` `f64` `=` `16.``0``;`
`let` transformation `=` `nalgebra``::``convert``::``<``_`, Affine2`<``f64``>``>``(``Similarity2``::`new`(`
`Vector2``::`new`(`
`RANGE` `-` bbox`.`x_min `as` `f64` `/` `SHRINKAGE``,`
`RANGE` `-` bbox`.`y_min `as` `f64` `/` `SHRINKAGE``,`
`)``,`
`0.``0``,`
`1.``0` `/` `SHRINKAGE``,`
`)``)``;`
`let` width `=`
`(``(`bbox`.`x_max `as` `f64` `-` bbox`.`x_min `as` `f64``)` `/` `SHRINKAGE` `+` `2.``0` `*` `RANGE``)``.``ceil``(``)` `as` `u32``;`
`let` height `=`
`(``(`bbox`.`y_max `as` `f64` `-` bbox`.`y_min `as` `f64``)` `/` `SHRINKAGE` `+` `2.``0` `*` `RANGE``)``.``ceil``(``)` `as` `u32``;`
`//` Unlike msdfgen, the transformation is not passed into the
`//` `generate_msdf` function – the coordinates of the control points
`//` must be expressed in terms of pixels on the distance field. To get
`//` the correct units, we pre-transform the shape:
shape`.``transform``(``&`transformation`)``;`
`//` We now color the edges of the shape. We also have to prepare
`//` it for calculations:
`let` colored_shape `=` `Shape``::`edge_coloring_simple`(`shape`,` `0.``03``,` `69441337420``)``;`
`let` prepared_colored_shape `=` colored_shape`.``prepare``(``)``;`
`//` Set up the resulting image and generate the distance field:
`let` `mut` msdf `=` `RgbImage``::`new`(`width`,` height`)``;`
`generate_msdf``(``&`prepared_colored_shape`,` `RANGE``,` `&``mut` msdf`)``;`
`correct_sign_msdf``(``&``mut` msdf`,` `&`prepared_colored_shape`,` `FillRule``::`Nonzero`)``;`
`//` As a test, try previewing the distance field:
`let` `mut` preview `=` `GrayImage``::`new`(`msdf`.``width``(``)` `*` `10``,` msdf`.``height``(``)` `*` `10``)``;`
`render_msdf``(``&`msdf`,` `&``mut` preview`,` `RANGE``)``;`

## Roadmap

Currently,

has the basic functionality of generating MSDFs and generates correct distance fields for the glyphs `fdsm`

to `A`

in Noto Sans. However, it does not have all of the features present in `Z`

.`msdfgen`

- Error correction
- Error estimation
- Sign correction
- Shape simplification (cf. Section 3.1 of (Chlumský, 2015))
- Alternative edge-coloring algorithms
- Benchmarks against
`msdfgen`

#### Dependencies

~**12MB**

~85K SLoC