Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

20 changed files with 60 additions and 119 deletions

125
README.md
View File

@ -1,27 +1,17 @@
# Unicode fonts
# uf5x7: A 5x7 Unicode font
This repository contains Unicode fonts that support most of the common Unicode
blocks. They can be used in C.Basic with the custom font mechanism or in
add-ins if there is a font manager (as of March 2021 only gint has one).
There are currently two fonts in this repository:
* [uf5x7: A 5x7 Unicode extension for fx-9860G](#uf5x7-an-unicode-extension-for-fx-9860g)
* [uf8x9: An original Unicode font for fx-CG](#uf8x9-an-original-unicode-font-for-fx-cg)
The fonts are **under CC0**, there are no conditions for using them. A link
back here would be appreciated though!
Related topic on Planète Casio: [Police 5x7 Unicode pour add-ins et C.Basic](https://www.planet-casio.com/Fr/forums/topic15732-1-Police-5x7-Unicode-pour-add-ins-et-C.Basic.html)
## uf5x7: An Unicode extension for fx-9860G
uf5x7 is a basic Unicode font mostly suitable for calculators of the fx-9860G
series (the ones with small 128x64 displays).
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)
Supported blocks:
The font is **under CC0**, there are no conditions for using it. A link back here
would be appreciated though!
Related topic on Planète Casio: [Police 5x7 Unicode pour add-ins et C.Basic](https://www.planet-casio.com/Fr/forums/topic15732-1-Police-5x7-Unicode-pour-add-ins-et-C.Basic.html)
Currently the following blocks have been drawn:
* `U+0020 .. U+007F` - ASCII (128 chars)
* `U+00A0 .. U+00FF` - Latin-1 Supplement (96 chars)
@ -38,61 +28,33 @@ Supported blocks:
* `U+2440 .. U+244F` - Optical character recognition (16 chars - thanks @Alice!)
* `U+25A0 .. U+25FF` - Geometric shapes (96 chars)
* `U+2800 .. U+28FF` - Braille patterns (256 chars - thanks @Alice!)
* `U+3000 .. U+303F` - CJK Punctuation (48 chars - thanks @Alice!)
* `U+3040 .. U+309F` - Hiragana (96 chars)
* `U+30A0 .. U+30FF` - Katakana (96 chars)
The following blocks are being considered for future support:
* Finish Cyrillic
* IPA extensions and Phonetic extensions
* 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
Full font:
## Constructing a full image of the font
![](uf5x7.png)
## uf8x9: An original Unicode font for fx-CG
uf8x9 is a font designed specifically for the large fx-CG display (396x224),
which is thin vertically and thick horizontally.
Supported blocks:
* `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+16A0 .. U+16FF` - Runic (96 chars)
* `U+2010 .. U+205F` - General punctuation (80 chars)
* `U+2070 .. U+209F` - Subscripts and superscripts (48 chars)
* `U+20A0 .. U+20BF` - Currency symbols (32 chars)
* `U+2160 .. U+217F` - Roman numerals (32 chars)
* `U+2190 .. U+21FF` - Arrows (112 chars)
* `U+2200 .. U+22FF` - Mathematical operators (256 chars - partial!)
Full font:
![](uf8x9.png)
## Constructing full font images
Use `gen.py` too generate the full images from the sections. You will need
Python 3 and Pillow (PIL might be okay).
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 uf5x7/ uf5x7.png
% ./gen.py uf8x9/ uf8x9.png
% ./gen.py uf5x7/*
```
It will read each block's position from its file name (which should be on the
form `U\+[0-9A-Fa-f]{4}.png`). For image files with a different name, it will
output an anonymous block.
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.
@ -104,48 +66,19 @@ for extended font support.
## Using in gint
To convert the font with `fxconv`, pass the name of a folder containing
block images instead of a simple image and set `charset` to `unicode`. Note
that in this setting, `area` is ignored and the same grid parameters are
applied to all block images.
**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 grid.padding:1
% fxconv -f uf8x9/ name:uf8x9 charset:unicode grid.size:8x11 grid.padding:1 proportional:true height:9
% fxconv -f uf5x7/ name:uf5x7 charset:unicode grid.size:5x7
```
When using the fxSDK, add the `uf5x7` folder to your list of metadata files and
set the type as `font`.
```
uf5x7: # Note that this is a folder
type: font
name: uf5x7
charset: unicode
grid.size: 5x7
grid.padding: 1
uf8x9:
type: font
name: uf8x9
charset: unicode
grid.size: 8x11
grid.padding: 1
proportional: true
height: 9
```
To use the font, configure it with `dfont()`, then call `dtext()` as usual.
Make sure the string is encoded as UTF-8. The `u8` prefix can be used if your
source file is not encoded as UTF-8.
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
#include <gint/display.h>
extern font_t uf5x7, uf8x9;
dfont(&uf5x7);
dtext(5, 5, C_BLACK, "Mézalors Δ=2 ⇒ ∀x∈S, x⊆Δ");
dfont(&uf8x9);
dtext(5, 15, C_BLACK, "Δt+(3-θ²)! Eurêka!");
dtext(5, 5, "Mézalors Δ=2 ⇒ ∀x∈S, x⊆Δ", BLACK, WHITE);
```

54
gen.py
View File

@ -5,21 +5,21 @@ import sys
import os
import re
if len(sys.argv) != 3:
print(f"usage: {sys.argv[0]} <FONT FOLDER> <OUTPUT IMAGE>")
if len(sys.argv) <= 1:
print(f"usage: {sys.argv[0]} <block files...>")
sys.exit(1)
files = sorted(sys.argv[1] + "/" + x for x in os.listdir(sys.argv[1]))
files = sorted(sys.argv[1:])
chars = PIL.Image.open("gen-chars.png")
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
def empty_separator(width):
img = PIL.Image.new("RGB", (width, 9), color=WHITE)
def empty_separator():
img = PIL.Image.new("RGB", (112, 9), color=WHITE)
for j in range(3, 6):
for i in range(1, width-1):
for i in range(1, 111):
if not ((i + j) & 1):
img.putpixel((i, j), BLACK)
@ -41,43 +41,55 @@ def char_image(c):
index = 4 * char_index(c)
return chars.crop((index, 0, index + 3, 5))
def separator(start, width):
img = PIL.Image.new("RGB", (width, 9), color=WHITE)
def separator(start, end):
img = PIL.Image.new("RGB", (112, 9), color=WHITE)
for j in range(3, 6):
for i in range(1, width//2 - 15):
for i in range(1, 26):
if not ((i + j) & 1):
img.putpixel((i, j), BLACK)
for i in range(width//2 + 15, width-1):
for i in range(86, 111):
if not ((i + j) & 1):
img.putpixel((i, j), BLACK)
x = width//2 - 11
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)
print('{} U+{:04X}'.format(basename, self.block_start))
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, width):
def header(self):
if self.block_start is not None:
return separator(self.block_start, width)
return separator(self.block_start, self.block_end)
else:
return empty_separator(width)
return empty_separator()
def body(self):
return self.img
@ -85,11 +97,7 @@ class Block:
def height(self):
return self.img.height + 9
def width(self):
return self.img.width
blocks = [ Block(file) for file in files ]
width = max(b.width() for b in blocks)
height = sum(b.height() for b in blocks)
left_height = 0
@ -97,13 +105,13 @@ for b in blocks:
left_height += b.height()
if 2 * left_height >= height: break
result = PIL.Image.new("RGB", (2 * width + 8, left_height), color=WHITE)
result = PIL.Image.new("RGB", (2 * 112 + 8, left_height), color=WHITE)
x = 0
y = 0
for b in blocks:
header = b.header(width)
header = b.header()
result.paste(header, (x, y))
y += header.height
@ -113,6 +121,6 @@ for b in blocks:
if y >= left_height:
y = 0
x += width + 8
x += 112 + 8
result.save(sys.argv[2])
result.save("uf5x7.png")

BIN
uf5x7.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

BIN
uf8x9.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB