commit dbc62366aec1d43e2646b4672f25b42b2d3df2f3 Author: Lephenixnoir Date: Tue Jun 18 17:40:02 2019 -0400 initial commit - basic blocks, generator script, readme diff --git a/README.md b/README.md new file mode 100644 index 0000000..b802268 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# uf5x7: A 5x7 Unicode font + +uf5x7 is a 5x7 font that suports most of the common Unicode blocks. It can be +used in C.Basic with the custom font mechanism or in add-ins if the font +manager supports it. + +![Preview image: "Mézalors Δ=2 ⇒ ∀x∈S, x⊆Δ"](https://www.planet-casio.com/files/forums/preview-166451.png) + +Currently the following blocks have been drawn: + +* `U+0020 .. U+007F` - ASCII (128 chars) +* `U+00A0 .. U+00FF` - Latin-1 Supplement (96 chars) +* `U+0100 .. U+017F` - Latin Extended-A (128 chars) +* `U+0370 .. U+03FF` - Greek (144 chars) +* `U+0400 .. U+047F` - Cyrillic (128 chars) +* `U+2010 .. U+205F` - General punctuation (80 chars) +* `U+2070 .. U+209F` - Subscripts and superscripts (48 chars) +* `U+2160 .. U+217F` - Roman numerals (32 chars) +* `U+2190 .. U+21FF` - Arrows (112 chars) +* `U+2200 .. U+22FF` - Mathematical operators (256 chars) +* `U+25A0 .. U+25FF` - Geometric shapes (96 chars) +* `U+2800 .. U+28FF` - Braille patterns (256 chars - thanks @Alice!) + +The following blocks are being considered for future support: + +* Finish Cyrillic +* IPA extensions and Phonetic extensions +* Currency symbols +* Hiragana and Katakana + +Other characters supported in `FONTCHARACTER` (incomplete list): + +* `U+2139` - Imaginary number +* `U+231F` - Fraction symbol +* `U+3010` - Special bracket +* `U+3011` - Special bracket + +## Constructing a full image of the font + +The `gen.py` script can be used to generate `uf5x7.png`, the full image of the +font. You will need Python 3 and Pillow (PIL might be okay). + +```sh +% ./gen.py blocks/* +``` + +It will read each block's position from its file name (which should be on the +form `U\+[0-9A-Fa-f]{4}.png`) and guess the block end from the image +dimensions. For image files with a different name, it will output an anonymous +block. + +The file `gen-chars.png` provides some character templates for it to render the +full image. + +## Using in C.Basic + +TODO - Check out the [documentation](https://egadget2.web.fc2.com/CBasic/Interpreter/CBasic_interpreter.html) (egadget2.web.fc2.com) +for extended font support. + +## Using in gint + +**Disclaimer**: this is being worked on, but not implemented in gint yet. + +When converting the font with `fxconv`, pass the name of a folder containing +block images instead of a simple image and set `charset` to `unicode`. + +```sh +% fxconv -f uf5x7/ name:uf5x7 charset:unicode grid.size:5x7 +``` + +When using the font, just call `dtext()` as usual and make sure the string is +encoded as utf8. The `u8` prefix can be used if your source file is not +encoded as utf8. + +```c +dtext(5, 5, "Mézalors Δ=2 ⇒ ∀x∈S, x⊆Δ", BLACK, WHITE); +``` diff --git a/gen-chars.png b/gen-chars.png new file mode 100644 index 0000000..1f1f377 Binary files /dev/null and b/gen-chars.png differ diff --git a/gen.py b/gen.py new file mode 100755 index 0000000..feb0605 --- /dev/null +++ b/gen.py @@ -0,0 +1,115 @@ +#! /usr/bin/python3 + +import PIL.Image +import sys +import os +import re + +if len(sys.argv) <= 1: + print(f"usage: {sys.argv[0]} ") + sys.exit(1) + +files = sorted(sys.argv[1:]) +chars = PIL.Image.open("gen-chars.png") + +WHITE = (255, 255, 255) +BLACK = (0, 0, 0) + +def empty_separator(): + img = PIL.Image.new("RGB", (112, 9), color=WHITE) + + for j in range(3, 6): + for i in range(1, 111): + if not ((i + j) & 1): + img.putpixel((i, j), BLACK) + + return img + +def char_index(c): + o = ord(c) + if ord('0') <= o <= ord('9'): + return o - ord('0') + if ord('A') <= o <= ord('F'): + return o - ord('A') + 10 + if c == 'U': + return 16 + if c == '+': + return 17 + raise Exception(f"Unsupported char '{c}'") + +def char_image(c): + index = 4 * char_index(c) + return chars.crop((index, 0, index + 3, 5)) + +def separator(start, end): + img = PIL.Image.new("RGB", (112, 9), color=WHITE) + + for j in range(3, 6): + for i in range(1, 26): + if not ((i + j) & 1): + img.putpixel((i, j), BLACK) + for i in range(86, 111): + if not ((i + j) & 1): + img.putpixel((i, j), BLACK) + + x = 27 + for c in "U+{:04X}".format(start): + img.paste(char_image(c), (x, 2)) + x += 4 + + for i in range(54, 58): + img.putpixel((i, 4), BLACK) + + x = 62 + for c in "U+{:04X}".format(end): + img.paste(char_image(c), (x, 2)) + x += 4 + + return img + +class Block: + def __init__(self, path): + basename = os.path.basename(path) + match = re.search(r'U\+([0-9A-Za-z]{4})', basename) + + self.block_start = None + self.block_end = None + + self.img = PIL.Image.open(path) + + if match is not None: + self.block_start = int(match[1], 16) + self.block_end = self.block_start + 16 * (self.img.height // 9) - 1 + print('{} U+{:04X} - U+{:04X}'.format(basename, self.block_start, + self.block_end)) + else: + print(f'{basename} not a block') + + def header(self): + if self.block_start is not None: + return separator(self.block_start, self.block_end) + else: + return empty_separator() + + def body(self): + return self.img + + def height(self): + return self.img.height + 9 + +blocks = [ Block(file) for file in files ] +height = sum(b.height() for b in blocks) + +result = PIL.Image.new("RGB", (112, height)) + +y = 0 +for b in blocks: + header = b.header() + result.paste(header, (0, y)) + y += header.height + + body = b.body() + result.paste(body, (0, y)) + y += body.height + +result.save("uf5x7.png") diff --git a/preview.png b/preview.png new file mode 100644 index 0000000..b70b508 Binary files /dev/null and b/preview.png differ diff --git a/uf5x7.png b/uf5x7.png new file mode 100644 index 0000000..abe8b6f Binary files /dev/null and b/uf5x7.png differ diff --git a/uf5x7/U+0020.png b/uf5x7/U+0020.png new file mode 100644 index 0000000..45168db Binary files /dev/null and b/uf5x7/U+0020.png differ diff --git a/uf5x7/U+00A0.png b/uf5x7/U+00A0.png new file mode 100644 index 0000000..7c962fc Binary files /dev/null and b/uf5x7/U+00A0.png differ diff --git a/uf5x7/U+0100.png b/uf5x7/U+0100.png new file mode 100644 index 0000000..b360215 Binary files /dev/null and b/uf5x7/U+0100.png differ diff --git a/uf5x7/U+0370.png b/uf5x7/U+0370.png new file mode 100644 index 0000000..64dedbf Binary files /dev/null and b/uf5x7/U+0370.png differ diff --git a/uf5x7/U+0400.png b/uf5x7/U+0400.png new file mode 100644 index 0000000..24bba3a Binary files /dev/null and b/uf5x7/U+0400.png differ diff --git a/uf5x7/U+2010.png b/uf5x7/U+2010.png new file mode 100644 index 0000000..7467317 Binary files /dev/null and b/uf5x7/U+2010.png differ diff --git a/uf5x7/U+2070.png b/uf5x7/U+2070.png new file mode 100644 index 0000000..0402019 Binary files /dev/null and b/uf5x7/U+2070.png differ diff --git a/uf5x7/U+2160.png b/uf5x7/U+2160.png new file mode 100644 index 0000000..a2abcf3 Binary files /dev/null and b/uf5x7/U+2160.png differ diff --git a/uf5x7/U+2190.png b/uf5x7/U+2190.png new file mode 100644 index 0000000..c9b3406 Binary files /dev/null and b/uf5x7/U+2190.png differ diff --git a/uf5x7/U+2200.png b/uf5x7/U+2200.png new file mode 100644 index 0000000..759ddb4 Binary files /dev/null and b/uf5x7/U+2200.png differ diff --git a/uf5x7/U+25A0.png b/uf5x7/U+25A0.png new file mode 100644 index 0000000..6f771db Binary files /dev/null and b/uf5x7/U+25A0.png differ diff --git a/uf5x7/U+2800.png b/uf5x7/U+2800.png new file mode 100644 index 0000000..863c85b Binary files /dev/null and b/uf5x7/U+2800.png differ diff --git a/uf5x7/extra.png b/uf5x7/extra.png new file mode 100644 index 0000000..897c900 Binary files /dev/null and b/uf5x7/extra.png differ