Add all files for building the charset table and the tutorial (alpha)

This commit is contained in:
Memallox 2018-10-01 22:24:18 +02:00
parent 23e74f7c00
commit 66fb17b753
7 changed files with 725 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
casio_charset/
casio_charset_table.md
*.html

26
Makefile Normal file
View File

@ -0,0 +1,26 @@
MDS=casio_charset_table.md casio_encoding_tutorial.md
HTMLS=$(MDS:.md=.html)
CSS=github-pandoc.css custom.css
all: $(MDS) $(HTMLS)
%.html: %.md $(CSS)
pandoc $< $(patsubst %,-c %, $(CSS)) -H reload_img_onerror.html -o $@
casio_charset_table.md: reload_img_onerror.html $(CSS)
cd util; python3 generate_charset_imgs.py
cd util; python3 generate_charset_table.py >../casio_charset_table.md
%.css:
clean:
rm -fv $(HTMLS)
rm -fv casio_charset_table.md
rm -frv casio_charset/

105
casio_encoding_tutorial.md Normal file
View File

@ -0,0 +1,105 @@
# Casio Encoding
One of the most important aspects about creating Add-ins is wo write text on the display. The Casio SDK provides us with a very unflexible way of doing that:
```c
Print("Hello World");
```
As you might already know, the standard C library has a much more elegant solution which is much more flexible:
```c
#include <stdio.h>
printf("Hello World");
```
No matter which way we want to use to print letters, numbers or special symbols, we need to understand how all these characters are represented internally.
## Basics
### Strings
A *string* is an group of *characters*, e.g. "Hello World" contains the characters 'H', 'a', 'l', etc. As you might have notices, strings are enclosed by "..." while we use '...' for characters.
More technically speaking, a string is an array of multiple `char`s.
```c
char message[] = "Hello World";
printf(message);
```
### Characters
Actually the type `char` is a number which indicates, which letter/symbol is meant. E.g. 98 means 'a', 99 means 'b', 100 means 'c' etc.
There is a whole table of 127 number/character pairs which is called the ASCII table.
## ASCII
The way of mapping numbers to characters is called *encoding*. The most basic encoding is called ASCII. Note that the C compiler and the underlying operating system do not have to comply with ASCII, but generally they do (except CASIO of course). I'll come to that in a second.
Here you see a part of the ASCII table. In the Internet, you also find the [whole ASCII table](https://www.rapidtables.com/code/text/ascii-table.html).
| Number | Character |
| ------ | --------- |
| ...|...|
| 88 | X |
| 89 | Y |
| 90 | Z |
| 91 | [ |
| 92 | \ |
| 93 | ] |
| 94 | ^ |
| 95 | _ |
| 96 | ` |
| 97 | a |
| 98 | b |
| 99 | c |
| ...|...|
To print an ASCII character using its number, you must convert this number into hexadecimal first. For example, `'o'` = `111` = `0x6F` = `'\x6F'`:
```c
printf("Hell\x6F World");
```
In fact, 'o', 111, 0x6F and '\x6F' are *really* the same for the C compiler. As a consequence, `'o' == 111` will always be true (as long as the C compiler complies to ASCII).
Note that ASCII only covers the characters for 0-127 and is de-facto standard for all platforms. The characters 128-255 are sometimes referred to as *extended ASCII*. However, extended ASCII is non-standard and should be avoided if possible.
## Unicode
Of course there are much more symbols than 256 if we think about the chinese alphabet, greek letters etc. To be able to use them in C, we need another encoding which is called *Unicode*. While each character in ACSII requires one byte of memory, Unicode needs more.
Since the data type `char` is not sufficient for Unicode anymore, `char16_t`, `char32_t` or `wchar_t` are used. I do not want to go too much into detail here, because Casio does **not** support Unicode anyway. If you are interested, however, in the Internet you will find many good [examples](http://doc.bccnsoft.com/docs/cppreference2015/en/c/language/string_literal.html).
## Casio encoding
The Casio encoding is partly ASCII-compliant and not Unicode-compliant at all. All printable characters (32-126) of ASCII have the same value in the Casio encoding and can be used without care:
```
!"#$%&'()*+,-./
0123456789
:;<=>?@
ABCDEFGHIJKLMNOPQRSTUVWXYZ
[\]^_`
abcdefghijklmnopqrstuvwxyz
{|}~
```
However, Casio decided to replace the non-printable characters with their own symbols. E.g. what is in ASCII the formfeed character `'\f'` = `12` = `0x0C` = `'\x0C'` was replaced by the character `'◢'`. That means that `Print("\x0C")` will now print `◢`.
Casio also added characters to the extended ASCII section 128-255. Details to all characters can be looked up in the [Casio charset table](casio_charset_table.md).
### Multi-byte Characters
Additionally, certain combinations of values print special characters, e.g. `Print("\xE5\x51")` will print the greek capital *sigma* (also known as sum sign) `'Σ'`. The two bytes `\E5` and `\x51` will be evaluated as *one character* here. In the [Casio charset table](casio_charset_table.md), this character can be found as `0xE551`.
Note that the first byte of two-byte characters can be either `0x7F`, `0xF7`, `0xF9`, `0xE5`, `0xE6` or `0xE7`. The second byte can be anything from `0x00` to `0xFF`.
### Casio charset table
Please have a look at the [Casio charset table](casio_charset_table.md) for details to all characters Casio is capable to handle. Some of them are not printable. We do not need to care about them.

38
custom.css Normal file
View File

@ -0,0 +1,38 @@
/* all images showing the Casio font */
.pixelated {
/* do not blur the pixels into each other when scaling up */
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -o-crisp-edges; /* Opera */
image-rendering: -webkit-optimize-contrast;/* Webkit (non-standard naming) */
image-rendering: crisp-edges;
image-rendering: pixelated;
-ms-interpolation-mode: nearest-neighbor; /* IE (non-standard property) */
/* speed of the hover effect */
transition: -webkit-transform 0.25s ease;
}
.pixelated:hover {
/* hover effect: zoom in */
-webkit-transform: scale(7);
}
/* the images showing the normal font */
.normal_font {
height: 1em;
}
/* the images showing the mini font */
.mini_font {
height: 0.71em;
}
/* increase the width of the whole body */
html {
max-width: 70em !important;
}
body {
max-width: 70em !important;
}

424
github-pandoc.css Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,57 @@
import os, errno
from PIL import Image
def generate_imgs(inpath, outpath, prefixes, w, h):
try:
os.makedirs(os.getcwd() + "/../" + outpath)
except OSError as e:
if e.errno != errno.EEXIST:
raise
img_filename = "XX.pbm";
for pre in prefixes:
img = Image.open(os.getcwd() + "/../" + inpath + "/" + pre + img_filename)
# add alpha channel
img = img.convert("RGBA")
# for every char (w x h pixels)
for col in range(0, 16):
for row in range(0, 16):
bounds = (col*w, row*h, (col+1)*w, (row+1)*h)
sec = img.crop(bounds)
# turn all white pixels transparent
isallalpha = True
pixdata = sec.load()
for y in range(h):
for x in range(w):
if pixdata[x, y] == (255, 255, 255, 255):
pixdata[x, y] = (255, 255, 255, 0)
else:
isallalpha = False
# skip all alpha chars (non-printable)
if isallalpha:
continue
filename = pre + "%X%X.png" % (row, col)
if sec.getbbox() is not None:
print(os.getcwd() + "/../" + outpath + filename)
sec.save(os.getcwd() + "/../" + outpath + filename)
# mini
inpath = "fontcharacter/reference/mini/"
outpath = "casio_charset/mini/"
prefixes = ("0x", "0x7F", "0xE5", "0xE6")
generate_imgs(inpath, outpath, prefixes, 5, 5)
# normal
inpath = "fontcharacter/reference/normal/"
outpath = "casio_charset/normal/"
prefixes = ("0x", "0x7F", "0xE5", "0xE6", "0xE7")
generate_imgs(inpath, outpath, prefixes, 5, 7)

View File

@ -0,0 +1,72 @@
import os
import yaml
import cgi
from pathlib import Path
stream = open(os.getcwd() + "/../fontcharacter/reference/characters.yml", "r")
docs = yaml.load_all(stream)
print("# Casio Charset\n")
print("|Casio value|Casio font (normal) |Casio font (mini) |Unicode character|Meaning <span style=\"visibility: hidden;\">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span>|ASCII value|Unicode value|");
print("|-----------|:----------------------------------------------------------------------:|:----------------------------------------------------------------------:|:---------------:|----------------------------------------------------|-----------|-------------|")
for doc in docs:
for charspec in doc:
#print(charspec)
code = charspec.get("code")
name = charspec.get("name")
category = charspec.get("category")
unicode = charspec.get("unicode")
multi = charspec.get("multi")
tokens = charspec.get("tokens")
id_ = charspec.get("id")
args = charspec.get("args")
action = charspec.get("action")
return_ = charspec.get("return")
flags = charspec.get("flags")
ascii_ = charspec.get("ascii")
tab_code = ("0x%02X" % code)
if Path(os.getcwd() + "/../casio_charset/normal/0x%02X.png" % code).exists():
tab_pic_normal = "![ ](casio_charset/normal/0x%02X.png){class=\"normal_font pixelated\" onerror=\"reload_img(this);\"}" % code
else:
tab_pic_normal = ""
if Path(os.getcwd() + "/../casio_charset/mini/0x%02X.png" % code).exists():
tab_pic_mini = "![ ](casio_charset/mini/0x%02X.png){class=\"mini_font pixelated\" onerror=\"reload_img(this);\"}" % code
else:
tab_pic_mini = ""
tab_char = ""
if code == 0x0D:
tab_char = "" # '\n'
elif code == 0x20:
tab_char = "&nbsp;" # ' '
elif code == 0x7c:
tab_char = "&#x7c;" # '|'
elif unicode is not None:
for u in unicode:
tab_char = tab_char + chr(u).encode("ascii", "xmlcharrefreplace").decode('utf-8')
tab_meaning = name
if args is not None:
tab_meaning = tab_meaning + "<br/>args: " + ",".join(args)
if return_ is not None:
tab_meaning = tab_meaning + "<br/>return: " + return_
tab_ascii = []
tab_unicode = []
if unicode is not None:
for u in unicode:
if u <= 0xFF:
tab_ascii.append("0x%02X" % u)
else:
tab_unicode.append("0x%02X" % u)
tab_ascii = ",".join(tab_ascii)
tab_unicode = ",".join(tab_unicode)
print("| %9s | %70s | %70s | %15s | %50s | %9s | %11s |" % (tab_code, tab_pic_normal, tab_pic_mini, tab_char, tab_meaning, tab_ascii, tab_unicode))