Browse Source

initial commit - basic blocks, generator script, readme

master
Lephenixnoir 2 months ago
commit
dbc62366ae
18 changed files with 192 additions and 0 deletions
  1. 77
    0
      README.md
  2. BIN
      gen-chars.png
  3. 115
    0
      gen.py
  4. BIN
      preview.png
  5. BIN
      uf5x7.png
  6. BIN
      uf5x7/U+0020.png
  7. BIN
      uf5x7/U+00A0.png
  8. BIN
      uf5x7/U+0100.png
  9. BIN
      uf5x7/U+0370.png
  10. BIN
      uf5x7/U+0400.png
  11. BIN
      uf5x7/U+2010.png
  12. BIN
      uf5x7/U+2070.png
  13. BIN
      uf5x7/U+2160.png
  14. BIN
      uf5x7/U+2190.png
  15. BIN
      uf5x7/U+2200.png
  16. BIN
      uf5x7/U+25A0.png
  17. BIN
      uf5x7/U+2800.png
  18. BIN
      uf5x7/extra.png

+ 77
- 0
README.md View File

@@ -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);
```

BIN
gen-chars.png View File


+ 115
- 0
gen.py View File

@@ -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]} <block files...>")
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")

BIN
preview.png View File


BIN
uf5x7.png View File


BIN
uf5x7/U+0020.png View File


BIN
uf5x7/U+00A0.png View File


BIN
uf5x7/U+0100.png View File


BIN
uf5x7/U+0370.png View File


BIN
uf5x7/U+0400.png View File


BIN
uf5x7/U+2010.png View File


BIN
uf5x7/U+2070.png View File


BIN
uf5x7/U+2160.png View File


BIN
uf5x7/U+2190.png View File


BIN
uf5x7/U+2200.png View File


BIN
uf5x7/U+25A0.png View File


BIN
uf5x7/U+2800.png View File


BIN
uf5x7/extra.png View File


Loading…
Cancel
Save