Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fontconvert: remap characters, for smaller custom fonts #395

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

nilclass
Copy link

@nilclass nilclass commented Jul 31, 2022

This change modifies fontconvert to add support for a new (optional) "remap" parameter.

If given, that parameter replaces the glyphs for certain characters with glyphs of a different character.

It's interpreted as a utf8 encoded string of pairs of characters, for example xy! 😉 would mean: for character x, put the glyph of y into the font, and for the character ! put the winking emoji into the font.

This way a font can be created which still only contains a single contiguous range of characters (thus stays small), while no longer being limited to 7 bit ASCII.

The downside of this approach is, that the characters as they appear in the code won't show up on screen the same way.

Example:

Suppose I need the following set of characters: 0123456789+-.%°.
The first 14 characters are all in the ASCII plane, so without remapping, I could get them by converting the range 37 (%) to 57 (9):

./fontconvert FreeSerifBold.ttf 24 37 57

(° is not on the ASCII plane, so I couldn't get that character this way, no matter the range).

Note that even though I needed only 15 characters, I had to specify a 20 character range to get only 14 of them. There are 6
characters (&'()*,/) for which glyphs will be included as well, but I'll never use those.

This isn't ideal, so "remap" to the rescue!

First I'm choosing an ASCII range that includes as many of the characters as I need, by having as little extra characters as
possible.
In this case that range is 43 (+) to 57 (9), which has two characters I don't need: , and /. Luckily I also have two characters which are not in that range (% and °).

By using the ° glyph for the , character and the % glyph for the / character, I get a single range of characters which contains only the symbols I need:

Charcode ASCII Glyph
43 + +
44 , °
45 - -
46 . .
47 / %
48 0 0
49 1 1
50 2 2
51 3 3
52 4 4
53 5 5
54 6 6
55 7 7
56 8 8
57 9 9

The remap parameter for this case is ,°/%:

./fontconvert FreeSerifBold.ttf 24 43 57 ,°/%

From arduino code then, I can just write:

  display.display("37.5,");

Which will render "37.5°".

Add support for a new (optional) "remap" parameter for `fontconvert`.

If given, that parameter replaces the glyphs for certain characters
with glyphs of a different character.

This way a font can be created which contains a single contiguous
range of characters, without being limited to 7 bit ASCII.

The downside of this approach is, that the characters as they appear
in the code won't show up on screen the same way.

Example:

Suppose I need the following set of characters: `0123456789+-.%°`.
The first 14 characters are all in the ASCII plane, so without
remapping, I could get them by converting the range 37 (%) to 57 (9):

    ./fontconvert FreeSerifBold.ttf 24 37 57

(`°` is not on the ASCII plane, so I cannot get that character, no
matter the range).

Note that even though I needed only 15 characters, I had to specify a
20 character range to get only 14 of them. There are 6
characters (`&'()*,/`) for which glyphs will be included as well, but
I'll never use them.

This isn't ideal, so "remap" to the rescue!

First I'm choosing an ASCII range that includes as many of the
characters as I need, by having as little extra characters as
possible.
In this case that range is 43 (`+`) to 57 (`9`), which has two
characters I don't need: `,` and `/`. Luckily I also have two
characters which are *not* in that range (`%` and `°`).

By using the `°` glyph for the `,` character and the `%` glyph for the
`/` character, I get a contigious range of characters which contains
only the symbols I need:

| Charcode | ASCII | Glyph |
|----------|-------|-------|
| 43       | `+`   | `+`   |
| 44       | `,`   | `°`   |
| 45       | `-`   | `-`   |
| 46       | `.`   | `.`   |
| 47       | `/`   | `%`   |
| 48       | `0`   | `0`   |
| 49       | `1`   | `1`   |
| 50       | `2`   | `2`   |
| 51       | `3`   | `3`   |
| 52       | `4`   | `4`   |
| 53       | `5`   | `5`   |
| 54       | `6`   | `6`   |
| 55       | `7`   | `7`   |
| 56       | `8`   | `8`   |
| 57       | `9`   | `9`   |

The remap parameter for this case is `,°/%`:

    ./fontconvert FreeSerifBold.ttf 24 43 57 ,°/%

From arduino code then, I can just write:

  display.display("37.5,");

Which will render "37.5°".
@nilclass nilclass mentioned this pull request Jul 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant