Init 🏴☠️
This commit is contained in:
commit
a2e6ddbac9
20
.editorconfig
Normal file
20
.editorconfig
Normal file
@ -0,0 +1,20 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[{*.c,*.h}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
24
LICENSE
Normal file
24
LICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
20
README.md
Normal file
20
README.md
Normal file
@ -0,0 +1,20 @@
|
||||
## 🧰 Build
|
||||
|
||||
1. Clone Flipper Zero firmware.
|
||||
|
||||
```sh
|
||||
git clone --depth 1 --branch 0.82.3 https://github.com/flipperdevices/flipperzero-firmware.git
|
||||
```
|
||||
|
||||
2. Copy this repo to firmware sources directory.
|
||||
|
||||
```sh
|
||||
cd /path/to/flipperzero-firmware
|
||||
ln -s /path/to/cyr_fap .
|
||||
```
|
||||
|
||||
3. Build application
|
||||
|
||||
```sh
|
||||
./fbt fap_cyr_example
|
||||
```
|
5
font/bdfconv/.editorconfig
Normal file
5
font/bdfconv/.editorconfig
Normal file
@ -0,0 +1,5 @@
|
||||
root = true
|
||||
|
||||
[{*.c,*.h}]
|
||||
indent_style = unset
|
||||
indent_size = unset
|
520
font/bdfconv/Makefile
Normal file
520
font/bdfconv/Makefile
Normal file
@ -0,0 +1,520 @@
|
||||
# works within ubuntu and min-gw (win7) environment
|
||||
# win7 exe uploaded on google drive
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -Wall
|
||||
#CFLAGS = -O4 -Wall
|
||||
|
||||
SRC = main.c bdf_font.c bdf_glyph.c bdf_parser.c bdf_map.c bdf_rle.c bdf_tga.c fd.c bdf_8x8.c bdf_kern.c
|
||||
|
||||
OBJ = $(SRC:.c=.o)
|
||||
ASM = $(SRC:.c=.s)
|
||||
|
||||
.c.s:
|
||||
$(CC) $(CFLAGS) -S -o $@ $<
|
||||
|
||||
bdfconv: $(OBJ) $(ASM)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o bdfconv
|
||||
|
||||
clean:
|
||||
-rm $(OBJ) $(ASM) bdfconv
|
||||
|
||||
test: bdfconv
|
||||
./bdfconv
|
||||
|
||||
issue_1811: bdfconv
|
||||
./bdfconv -f 1 -v -m '32-127,$$980-$$9FF,$$A00-$$A7F,$$A80-$$AFF,$$B00-$$B7f,$$B80-$$BFF,$$C00-$$C7f,$$C80-$$CFF' ../bdf/unifont.bdf -n unifont_1811 -o unifont_1811.c -d ../bdf/7x13.bdf
|
||||
convert -trim bdf.tga issue_1811.png
|
||||
|
||||
greek: bdfconv
|
||||
./bdfconv -f 1 -v -m '32-127,$$370-$$3ff' ../bdf/unifont.bdf -n unifont_greek -o unifont_greek.c -d ../bdf/7x13.bdf
|
||||
|
||||
|
||||
cyrillic: bdfconv
|
||||
./bdfconv -f 1 -v -m '$$20-$$7E, $$410-$$44F' ../bdf/unifont.bdf -n unifont_cyrillic_44f -o unifont_cyrillic_44f.c -d ../bdf/7x13.bdf
|
||||
convert bdf.tga unifont_cyrillic_44f.png
|
||||
./bdfconv -f 1 -v -m '$$20-$$7E, $$400-$$4ff' ../bdf/unifont.bdf -n unifont_cyrillic_4ff -o unifont_cyrillic_4ff.c -d ../bdf/7x13.bdf
|
||||
convert bdf.tga unifont_cyrillic_4ff.png
|
||||
|
||||
battery19: bdfconv
|
||||
./bdfconv -f 1 -v -m '32-127' ../bdf/battery19.bdf -n battery19 -o battery19.c -d ../bdf/7x13.bdf
|
||||
|
||||
battery24: bdfconv
|
||||
./bdfconv -f 1 -v -m '32-127s' ../bdf/battery24.bdf -n battery24 -o battery24.c -d ../bdf/7x13.bdf
|
||||
convert -trim bdf.tga battery24.png
|
||||
|
||||
hornet: bdfconv
|
||||
./bdfconv -a -f 1 -v -m '32-127s' ./tmp/hornet.bdf -n hornet -o hornet.c -d ../bdf/7x13.bdf
|
||||
convert -trim bdf.tga hornet.png
|
||||
|
||||
10x20greek: bdfconv
|
||||
./bdfconv -f 1 -v -m '32-127,$$370-$$3ff' ../bdf/10x20.bdf -n 10x20_greek -o 10x20_greek.c -d ../bdf/7x13.bdf
|
||||
|
||||
5x7: bdfconv
|
||||
./bdfconv -b 4 -f 1 -a -v -m '32-255' ../bdf/5x7.bdf -n 5x7lcd -o 5x7lcd.c -d ../bdf/7x13.bdf
|
||||
|
||||
ti83: bdfconv
|
||||
-../otf2bdf/otf2bdf -n -p 5 -o ../bdf/ti83.bdf ../ttf/ti83.ttf
|
||||
./bdfconv -b 4 -f 1 -a -v -m '32-65000' ../bdf/ti83.bdf -n u8g2_ti83_5x7 -o ti83.c -d ../bdf/7x13.bdf
|
||||
|
||||
kalpurush: bdfconv
|
||||
-../otf2bdf/otf2bdf -g -v -p 16 -o ../bdf/kalpurush.bdf kalpurush.ttf
|
||||
./bdfconv -f 1 -m '0-65000>32' ../bdf/kalpurush.bdf -n u8g2_kalpurush -o kalpurush.c -d ../bdf/7x13.bdf
|
||||
convert bdf.tga -trim kalpurush.png
|
||||
|
||||
|
||||
polish: bdfconv
|
||||
./bdfconv -f 1 -v -m '32-127,$$104-$$107,$$118-$$119,$$141-$$144,$$15a-$$15b,$$179-$$17c,$$d3,$$f3' ../bdf/unifont.bdf -n unifont_polish -o unifont_polish.c -d ../bdf/7x13.bdf
|
||||
|
||||
helvb18: bdfconv
|
||||
./bdfconv -f 1 -m '32-127,x32-64,x91-96,x123-191,x247,x697-879' -p 10 ../bdf/helvB18.bdf -o helvb18_tr.c -n u8g2_font_helvB18_tr -k helvb18_tr_k.c
|
||||
|
||||
helvb18n: bdfconv
|
||||
./bdfconv -v -f 1 -m '32,48-57' ../bdf/helvB18.bdf -o helvb18_tn.c -n u8g2_font_helvB18_tn -d ../bdf/helvB18.bdf
|
||||
|
||||
dseg7: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-65000' dseg7_classic_regular.bdf -o u8g2_font_dseg7_classic_regular_all.c -n u8g2_font_dseg7_classic_regular_all -d ../bdf/helvR12.bdf
|
||||
convert bdf.tga -trim u8g2_font_dseg7_classic_regular_all.png
|
||||
|
||||
nmv1: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-65000' NMV1.bdf -o u8g2_font_nmv1.c -n u8g2_font_nmv1 -d ../bdf/helvR12.bdf
|
||||
convert bdf.tga -trim u8g2_font_nmv1.png
|
||||
|
||||
dseg7cr: bdfconv
|
||||
./bdfconv -v -f 1 -b 2 -m '48-57,65-90,97-122' dseg7_classic_regular.bdf -o u8g2_font_dseg7_cr.c -n u8g2_font_dseg7_cr -d ../bdf/helvR12.bdf
|
||||
convert bdf.tga -trim u8g2_font_dseg7_cr.png
|
||||
|
||||
dseg14cr: bdfconv
|
||||
./bdfconv -v -f 1 -b 2 -m '32-255' dseg14_classic_regular.bdf -o u8g2_font_dseg14_cr.c -n u8g2_font_dseg14_cr -d ../bdf/helvR12.bdf
|
||||
convert bdf.tga -trim u8g2_font_dseg14_cr.png
|
||||
|
||||
issue1769: bdfconv
|
||||
./bdfconv -v -f 1 -b 2 -m '32-128' 3x7_Multi_V7.bdf -o u8g2_font_3x7_multi.c -n u8g2_font_3x7_multi -d ../bdf/helvR12.bdf
|
||||
convert bdf.tga -trim u8g2_font_3x7_multi.png
|
||||
|
||||
|
||||
emoticons21: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-64' ../emoticons/emoticons21.bdf -o emoticons21.c -n u8g2_font_emoticons21_tn -d ../bdf/helvB18.bdf
|
||||
|
||||
mmmicons: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-700' mmmicons.bdf -o mmmicons.c -n u8g2_font_mmmicons -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga -trim mmmicons.png
|
||||
|
||||
ded: bdfconv
|
||||
./bdfconv -v -b 0 -f 1 ./F16_DED.bdf -o ded.c -n ded -d ../bdf/helvB12.bdf
|
||||
|
||||
old16x16: bdfconv
|
||||
-../otf2bdf/otf2bdf -r 72 -p 16 -o tmp.bdf ../ttf/Px437_Wyse700a.ttf
|
||||
./bdfconv -x 0 -y 8 -v -f 2 -m '32-59' tmp.bdf -o u8x8_font_px437wyse700a_ul_n.c -n u8x8_font_px437wyse700a_ul_n
|
||||
./bdfconv -x 8 -y 8 -v -f 2 -m '32-59' tmp.bdf -o u8x8_font_px437wyse700a_ur_n.c -n u8x8_font_px437wyse700a_ur_n
|
||||
./bdfconv -x 0 -y 0 -v -f 2 -m '32-59' tmp.bdf -o u8x8_font_px437wyse700a_ll_n.c -n u8x8_font_px437wyse700a_ll_n
|
||||
./bdfconv -x 8 -y 0 -v -f 2 -m '32-59' tmp.bdf -o u8x8_font_px437wyse700a_lr_n.c -n u8x8_font_px437wyse700a_lr_n
|
||||
./bdfconv -x 0 -y 8 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700a_ul_r.c -n u8x8_font_px437wyse700a_ul_r
|
||||
./bdfconv -x 8 -y 8 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700a_ur_r.c -n u8x8_font_px437wyse700a_ur_r
|
||||
./bdfconv -x 0 -y 0 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700a_ll_r.c -n u8x8_font_px437wyse700a_ll_r
|
||||
./bdfconv -x 8 -y 0 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700a_lr_r.c -n u8x8_font_px437wyse700a_lr_r
|
||||
./bdfconv -x 0 -y 8 -v -f 2 -m '32-255' tmp.bdf -o u8x8_font_px437wyse700a_ul_f.c -n u8x8_font_px437wyse700a_ul_f
|
||||
./bdfconv -x 8 -y 8 -v -f 2 -m '32-255' tmp.bdf -o u8x8_font_px437wyse700a_ur_f.c -n u8x8_font_px437wyse700a_ur_f
|
||||
./bdfconv -x 0 -y 0 -v -f 2 -m '32-255' tmp.bdf -o u8x8_font_px437wyse700a_ll_f.c -n u8x8_font_px437wyse700a_ll_f
|
||||
./bdfconv -x 8 -y 0 -v -f 2 -m '32-255' tmp.bdf -o u8x8_font_px437wyse700a_lr_f.c -n u8x8_font_px437wyse700a_lr_f
|
||||
-../otf2bdf/otf2bdf -r 72 -p 16 -o tmp.bdf ../ttf/Px437_Wyse700b.ttf
|
||||
./bdfconv -x 0 -y 8 -v -f 2 -m '32-59' tmp.bdf -o u8x8_font_px437wyse700b_ul_n.c -n u8x8_font_px437wyse700b_ul_n
|
||||
./bdfconv -x 8 -y 8 -v -f 2 -m '32-59' tmp.bdf -o u8x8_font_px437wyse700b_ur_n.c -n u8x8_font_px437wyse700b_ur_n
|
||||
./bdfconv -x 0 -y 0 -v -f 2 -m '32-59' tmp.bdf -o u8x8_font_px437wyse700b_ll_n.c -n u8x8_font_px437wyse700b_ll_n
|
||||
./bdfconv -x 8 -y 0 -v -f 2 -m '32-59' tmp.bdf -o u8x8_font_px437wyse700b_lr_n.c -n u8x8_font_px437wyse700b_lr_n
|
||||
./bdfconv -x 0 -y 8 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700b_ul_r.c -n u8x8_font_px437wyse700b_ul_r
|
||||
./bdfconv -x 8 -y 8 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700b_ur_r.c -n u8x8_font_px437wyse700b_ur_r
|
||||
./bdfconv -x 0 -y 0 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700b_ll_r.c -n u8x8_font_px437wyse700b_ll_r
|
||||
./bdfconv -x 8 -y 0 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700b_lr_r.c -n u8x8_font_px437wyse700b_lr_r
|
||||
./bdfconv -x 0 -y 8 -v -f 2 -m '32-255' tmp.bdf -o u8x8_font_px437wyse700b_ul_f.c -n u8x8_font_px437wyse700b_ul_f
|
||||
./bdfconv -x 8 -y 8 -v -f 2 -m '32-255' tmp.bdf -o u8x8_font_px437wyse700b_ur_f.c -n u8x8_font_px437wyse700b_ur_f
|
||||
./bdfconv -x 0 -y 0 -v -f 2 -m '32-255' tmp.bdf -o u8x8_font_px437wyse700b_ll_f.c -n u8x8_font_px437wyse700b_ll_f
|
||||
./bdfconv -x 8 -y 0 -v -f 2 -m '32-255' tmp.bdf -o u8x8_font_px437wyse700b_lr_f.c -n u8x8_font_px437wyse700b_lr_f
|
||||
cat u8x8_font_px437*.c >16x16.c
|
||||
|
||||
16x16: bdfconv
|
||||
-../otf2bdf/otf2bdf -r 72 -p 16 -o tmp.bdf ../ttf/Px437_Wyse700b.ttf
|
||||
./bdfconv -y -1 -th 2 -tv 2 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700b_2x2_r.c -n u8x8_font_px437wyse700b_2x2_r
|
||||
-../otf2bdf/otf2bdf -r 72 -p 16 -o tmp.bdf ../ttf/Px437_Wyse700a.ttf
|
||||
./bdfconv -y -1 -th 2 -tv 2 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_px437wyse700a_2x2_r.c -n u8x8_font_px437wyse700a_2x2_r
|
||||
-../otf2bdf/otf2bdf -r 72 -p 32 -o tmp.bdf ../ttf/BALTT_0.ttf
|
||||
./bdfconv -y 0 -th 1 -tv 2 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_balthasar_titling_nbp_1x2_r.c -n u8x8_font_balthasar_titling_nbp_1x2_r
|
||||
-../otf2bdf/otf2bdf -r 72 -p 32 -o tmp.bdf ../ttf/lucasarts-scumm-subtitle-roman-outline.ttf
|
||||
./bdfconv -y 1 -th 2 -tv 2 -v -f 2 -m '32-127' tmp.bdf -o lucasarts_scumm_subtitle_o_2x2_r.c -n lucasarts_scumm_subtitle_o_2x2_r
|
||||
-../otf2bdf/otf2bdf -r 72 -p 16 -o tmp.bdf ../ttf/lucasarts-scumm-subtitle-roman.ttf
|
||||
./bdfconv -y 0 -th 2 -tv 2 -v -f 2 -m '32-127' tmp.bdf -o lucasarts_scumm_subtitle_r_2x2_r.c -n lucasarts_scumm_subtitle_r_2x2_r
|
||||
./bdfconv -y -1 -th 2 -tv 3 -v -f 2 -m '32-127' ../bdf/courB18.bdf -o u8x8_font_courb18_2x3_r.c -n u8x8_font_courB18_2x3_r
|
||||
./bdfconv -y -1 -th 2 -tv 3 -v -f 2 -m '32-127' ../bdf/courR18.bdf -o u8x8_font_courr18_2x3_r.c -n u8x8_font_courR18_2x3_r
|
||||
./bdfconv -y -2 -th 3 -tv 4 -v -f 2 -m '32-127' ../bdf/courB24.bdf -o u8x8_font_courb24_3x4_r.c -n u8x8_font_courB24_3x4_r
|
||||
./bdfconv -y -2 -th 3 -tv 4 -v -f 2 -m '32-127' ../bdf/courR24.bdf -o u8x8_font_courr24_3x4_r.c -n u8x8_font_courR24_3x4_r
|
||||
./bdfconv -y 0 -th 2 -tv 3 -v -f 2 -m '32-127' ../bdf/profont29.bdf -o u8x8_font_profont29_2x3_r.c -n u8x8_font_profont29_2x3_r
|
||||
./bdfconv -y -2 -th 1 -tv 2 -v -f 2 -m '32-127' ../bdf/8x13.bdf -o u8x8_font_8x13_r.c -n u8x8_font_8x13_1x2_r
|
||||
./bdfconv -y -2 -th 1 -tv 2 -v -f 2 -m '32-127' ../bdf/8x13B.bdf -o u8x8_font_8x13b_r.c -n u8x8_font_8x13B_1x2_r
|
||||
./bdfconv -y -1 -x -1 -th 1 -tv 2 -v -f 2 -m '32-127' ../bdf/7x14.bdf -o u8x8_font_7x14_r.c -n u8x8_font_7x14_1x2_r
|
||||
./bdfconv -y -1 -x -1 -th 1 -tv 2 -v -f 2 -m '32-127' ../bdf/7x14B.bdf -o u8x8_font_7x14b_r.c -n u8x8_font_7x14B_1x2_r
|
||||
-../otf2bdf/otf2bdf -r 72 -p 16 -o tmp.bdf ../ttf/shylock_nbp.ttf
|
||||
./bdfconv -y -1 -th 1 -tv 2 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_shylock_nbp_1x2_r.c -n u8x8_font_shylock_nbp_1x2_r
|
||||
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 30 -o tmp.bdf ../ttf/inr.otf
|
||||
./bdfconv -y -1 -x 1 -th 2 -tv 4 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_inr21_2x4_r.c -n u8x8_font_inr21_2x4_r
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 44 -o tmp.bdf ../ttf/inr.otf
|
||||
./bdfconv -y -1 -x 2 -th 3 -tv 6 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_inr33_3x6_r.c -n u8x8_font_inr33_3x6_r
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 62 -o tmp.bdf ../ttf/inr.otf
|
||||
./bdfconv -y 0 -x 3 -th 4 -tv 8 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_inr46_4x8_r.c -n u8x8_font_inr46_4x8_r
|
||||
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 30 -o tmp.bdf ../ttf/inb.otf
|
||||
./bdfconv -y -1 -x 1 -th 2 -tv 4 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_inb21_2x4_r.c -n u8x8_font_inb21_2x4_r
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 44 -o tmp.bdf ../ttf/inb.otf
|
||||
./bdfconv -y -1 -x 2 -th 3 -tv 6 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_inb33_3x6_r.c -n u8x8_font_inb33_3x6_r
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 62 -o tmp.bdf ../ttf/inb.otf
|
||||
./bdfconv -y 0 -x 3 -th 4 -tv 8 -v -f 2 -m '32-127' tmp.bdf -o u8x8_font_inb46_4x8_r.c -n u8x8_font_inb46_4x8_r
|
||||
|
||||
./bdfconv -y 0 -th 2 -tv 2 -v -f 2 -m '32-127' ../bdf/open_iconic_weather_2x.bdf -o u8x8_font_open_iconic_weather_2x2.c -n u8x8_font_open_iconic_weather_2x2
|
||||
./bdfconv -y 0 -th 4 -tv 4 -v -f 2 -m '32-127' ../bdf/open_iconic_weather_4x.bdf -o u8x8_font_open_iconic_weather_4x4.c -n u8x8_font_open_iconic_weather_4x4
|
||||
./bdfconv -y 0 -th 8 -tv 8 -v -f 2 -m '32-127' ../bdf/open_iconic_weather_8x.bdf -o u8x8_font_open_iconic_weather_8x8.c -n u8x8_font_open_iconic_weather_8x8
|
||||
|
||||
|
||||
falconded: bdfconv
|
||||
-../otf2bdf/otf2bdf -n -p 12 -o falconded.bdf FalconDED2.ttf
|
||||
./bdfconv -v -f 1 -b 2 -a -m '32-96' falconded.bdf -o u8g2_font_falconded_mr.c -n u8g2_font_falconded_mr -d ../bdf/helvR12.bdf
|
||||
-../otf2bdf/otf2bdf -n -p 12 -o falconded.bdf FalconDED2.ttf
|
||||
./bdfconv -v -f 1 -b 1 -a -m '32-96' falconded.bdf -o u8g2_font_falconded_hr.c -n u8g2_font_falconded_hr -d ../bdf/helvR12.bdf
|
||||
|
||||
falconded9: bdfconv
|
||||
./bdfconv -v -f 1 -b 2 -a -m '32-99' falconded.bdf -o u8g2_font_falconded_mr.c -n u8g2_font_falconded_mr -d ../bdf/helvR12.bdf
|
||||
convert bdf.tga -trim u8g2_font_falconded_mr.png
|
||||
./bdfconv -v -f 1 -b 1 -a -m '32-99' falconded.bdf -o u8g2_font_falconded_hr.c -n u8g2_font_falconded_hr -d ../bdf/helvR12.bdf
|
||||
convert bdf.tga -trim u8g2_font_falconded_hr.png
|
||||
|
||||
|
||||
analecta: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -p 20 -o analecta.bdf Analecta.otf
|
||||
./bdfconv -v -f 1 -m '32-65535' analecta.bdf -o u8g2_font_analecta.c -n u8g2_font_analecta -d ../bdf/helvB18.bdf
|
||||
|
||||
logisoso: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 131 -o tmp.bdf ../ttf/Logisoso.ttf
|
||||
./bdfconv -v -f 1 -m '32,42-57' tmp.bdf -o u8g2_font_logisoso_tn.c -n u8g2_font_logisoso_tn -d ../bdf/helvB18.bdf
|
||||
|
||||
tpss: bdfconv
|
||||
-../otf2bdf/otf2bdf -r 72 -p 8 -o tmp.bdf ../ttf/TEACPSS_.TTF
|
||||
./bdfconv -v -f 1 -m '32-255' tmp.bdf -o u8g2_font_tpss_tf.c -n u8g2_font_tpss_tn -d ../bdf/helvR10.bdf
|
||||
|
||||
|
||||
q_pixia: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 13 -o tmp.bdf q_pixia.ttf
|
||||
./bdfconv -v -f 1 -m '32-65534' tmp.bdf -o u8g2_font_q_pixia.c -n u8g2_font_q_pixia -d ../bdf/helvB18.bdf
|
||||
|
||||
inr: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 86 -o tmp.bdf ../ttf/inr.otf
|
||||
./bdfconv -v -b 2 -f 1 -m '42-57' tmp.bdf -o u8g2_font_inr64_m.c -n u8g2_font_inr64_m -d ../bdf/helvB18.bdf
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 43 -o tmp.bdf ../ttf/inr.otf
|
||||
./bdfconv -v -b 2 -f 1 -m '42-57' tmp.bdf -o u8g2_font_inr32_m.c -n u8g2_font_inr32_m -d ../bdf/helvB18.bdf
|
||||
# ./bdfconv -v -b 2 -f 1 -m '32-128,$$400-$$52f' tmp.bdf -o u8g2_font_inr_m.c -n u8g2_font_inr_m -d ../bdf/helvB18.bdf
|
||||
|
||||
logisoso92x: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 131 -o tmp.bdf ../ttf/Logisoso.ttf
|
||||
./bdfconv -v -f 1 -m '32,42-57,65-70' tmp.bdf -o u8g2_font_logisoso92_tx.c -n u8g2_font_logisoso92_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
fub: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 40 -o tmp.bdf ../ttf/FreeUniversal-Bold.ttf
|
||||
./bdfconv -v -f 2 -m '32-255' tmp.bdf -o fub30_tf.c -n fub30_tf -d ../bdf/helvB18.bdf
|
||||
|
||||
fub20x: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 27 -o tmp.bdf ../ttf/FreeUniversal-Bold.ttf
|
||||
./bdfconv -v -f 1 -m '32-127,8364' tmp.bdf -o u8g2_font_fub20_tx.c -n u8g2_font_fub20_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
unifont_emoticon: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$01f600-$$01f64f>$$20, $$01f910-$$01f92f>$$70, $$01f970-$$01f971>$$90, $$01f973-$$01f976>$$92,$$01f97a>$$96, $$01f9b8-$$01f9b9>$$97, $$01f9d0-$$01f9d6>$$99' ../bdf/unifont_upper.bdf -o u8g2_font_unifont_emoticon.c -n u8g2_font_unifont_emoticon_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
unifont_misc_sym_and_pic: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$01f300-$$01f5ff>$$f300' ../bdf/unifont_upper.bdf -o u8g2_font_unifont_misc_sym_and_pic.c -n u8g2_font_unifont_misc_sym_and_pic_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
unifont_animals: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$01f400-$$01f43f>$$20,$$01f980-$$01f9af>$$60' ../bdf/unifont_upper.bdf -o u8g2_font_unifont_animal.c -n u8g2_font_unifont_animal_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
unifont_domino: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$01f030-$$01f093>$$20' ../bdf/unifont_upper.bdf -o u8g2_font_unifont_domino.c -n u8g2_font_unifont_domino_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
unifont_cards: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$01f0a0-$$01f0f5>$$20' ../bdf/unifont_upper.bdf -o u8g2_font_unifont_cards.c -n u8g2_font_unifont_cards_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
unifont_weather: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$01f310-$$01f32c>$$20' ../bdf/unifont_upper.bdf -o u8g2_font_unifont_weather.c -n u8g2_font_unifont_weather_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
|
||||
climacons: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 32 -o tmp.bdf Climacons.ttf
|
||||
./bdfconv -v -f 1 -m '32-256' tmp.bdf -o u8g2_font_climacons.c -n u8g2_font_climacons -d ../bdf/helvB18.bdf
|
||||
|
||||
logisoso20x: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 30 -o tmp.bdf ../ttf/Logisoso.ttf
|
||||
./bdfconv -v -f 1 -m '32-127,8364' tmp.bdf -o u8g2_font_logisoso20_tx.c -n u8g2_font_logisoso20_tx -d ../bdf/helvB18.bdf
|
||||
|
||||
xlogisoso: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 131 -o tmp.bdf ../ttf/Logisoso.ttf
|
||||
./bdfconv -v -f 1 -m '32,42-57,$$370-$$3ff,$$2100-$$21ff' tmp.bdf -o u8g2_font_logisoso_tn.c -n u8g2_font_logisoso_tn -d ../bdf/helvB18.bdf
|
||||
|
||||
omega: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 32 -o tmp.bdf ../ttf/FreeUniversal-Regular.ttf
|
||||
./bdfconv -v -f 1 -m '32,35-57,$$300-$$3ff,$$2030-$$3000' tmp.bdf -o u8g2_font_omega_tn.c -n u8g2_font_omega_tn -d ../bdf/helvB18.bdf
|
||||
|
||||
tga: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-255' ../bdf/helvB18.bdf -o helvb18_tn.c -n u8g2_font_helvB18_tn -d ../bdf/7x13.bdf
|
||||
|
||||
etl: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-127,128-255>3552' ../bdf/etl16-thai.bdf -o etl16_t.c -n u8g2_font_etl16_t -d ../bdf/7x13.bdf
|
||||
|
||||
etl2: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-127,128-255>14*256-32' ../bdf/etl16-thai.bdf -o etl16_t.c -n u8g2_font_etl16_t -d ../bdf/7x13.bdf
|
||||
|
||||
artos: bdfconv
|
||||
./bdfconv -b 3 -d ../bdf/7x13.bdf ../bdf/ArtosSerif-8.bdf -a -v
|
||||
|
||||
hebrew: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-128,$$590-$$5ff,$$fb1d-$$fb4f' ../bdf/unifont.bdf -o u8g2_hebrew.c -n u8g2_hebrew -d ../bdf/helvB18.bdf
|
||||
|
||||
korean: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-128,$$AC00-$$D7AF' ../bdf/unifont.bdf -o u8g2_korean.c -n u8g2_korean -d ../bdf/helvB18.bdf
|
||||
|
||||
bengali: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-128,$$980-$$9ff' ../bdf/unifont.bdf -o u8g2_bengali.c -n u8g2_bengali -d ../bdf/helvB12.bdf
|
||||
|
||||
urdu: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-128,$$600-$$6ff,$$750-$$77f,$$fb50-$$fdff,$$fe70-$$feff' ../bdf/unifont.bdf -o u8g2_urdu.c -n u8g2_urdu -d ../bdf/helvB12.bdf
|
||||
|
||||
malayalam: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-128,$$d00-$$d7f' ../bdf/unifont.bdf -o u8g2_malayalam.c -n u8g2_font_malayalam -d ../bdf/helvB12.bdf
|
||||
|
||||
lubr24: bdfconv
|
||||
./bdfconv -f 1 -m '32-65500' -p 10 lubR24.bdf -o lubR24.c -n u8g2_font_lubR24 -d ../bdf/helvB12.bdf
|
||||
|
||||
lurs24: bdfconv
|
||||
./bdfconv -f 1 -m '32-255' -p 10 luRS24.bdf -o luRS24.c -n u8g2_font_luRS24 -d ../bdf/helvB12.bdf
|
||||
|
||||
luBS18: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-34,36-125,176>35,8364>126' -p 10 ../bdf/luBS18.bdf -o luBS18.c -n u8g2_font_luBS18 -d ../bdf/helvB12.bdf
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
siji: bdfconv
|
||||
# ./bdfconv -v -f 1 -m '32-$$ffff' ./siji.bdf -o test1.c -n test -d ../bdf/helvB12.bdf
|
||||
./bdfconv -v -f 1 -m '32-$$ffff' ../bdf/siji_with_6x10.bdf -o test2.c -n test -d ../bdf/helvB12.bdf
|
||||
|
||||
wqy: bdfconv
|
||||
./bdfconv -v -f 1 -M ../build/gb2312.map ../bdf/wenquanyi_9pt.bdf -o test.c -n test -d ../bdf/helvB12.bdf
|
||||
|
||||
# ./bdfconv -v -f 1 -M ../build/gb2312.map ../bdf/wenquanyi_10pt.bdf -o test.c -n test -d ../bdf/helvB12.bdf
|
||||
# ./bdfconv -v -f 1 -M ../build/gb2312.map ../bdf/wenquanyi_13px.bdf -o test.c -n test -d ../bdf/helvB12.bdf
|
||||
# ./bdfconv -v -f 1 -M ../build/gb2312.map ../bdf/wenquanyi_11pt.bdf -o test.c -n test -d ../bdf/helvB12.bdf
|
||||
# ./bdfconv -v -f 1 -M ../build/gb2312.map ../bdf/wenquanyi_12pt.bdf -o test.c -n test -d ../bdf/helvB12.bdf
|
||||
|
||||
|
||||
ncenR24: bdfconv
|
||||
./bdfconv -v -f 1 -b 0 -m '32-701>32,7838' ../bdf/ncenR24.bdf -n u8g2_font_ncenR24_te -o test.c
|
||||
|
||||
ncenR10: bdfconv
|
||||
./bdfconv -v -f 1 -m '48-57,88,89' ../bdf/ncenR10.bdf -n u8g2_font_ncenR10 -o test.c -d ../bdf/helvB12.bdf
|
||||
convert bdf.tga -trim ncenR10.png
|
||||
|
||||
|
||||
profont12v2: bdfconv
|
||||
#./bdfconv -v -f 1 -b 0 -m '32-701>32,7838' ../bdf/profont12v2.bdf -n u8g2_font_profont12v2_te -o test.c
|
||||
./bdfconv -v -f 1 -b 0 -m '32-127' ../bdf/profont12v2.bdf -n u8g2_font_profont12v2_tr -o test.c
|
||||
|
||||
|
||||
# http://stackoverflow.com/questions/713397/what-is-a-minimal-set-of-unicode-characters-for-reasonable-japanese-support
|
||||
|
||||
chinese: bdfconv
|
||||
./bdfconv ../bdf/wenquanyi_9pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_wqy12_t_chinese1
|
||||
convert bdf.tga -trim u8g2_font_wqy12_t_chinese1.png
|
||||
./bdfconv ../bdf/wenquanyi_9pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese2.map -d ../bdf/7x13.bdf -n u8g2_font_wqy12_t_chinese2
|
||||
convert bdf.tga -trim u8g2_font_wqy12_t_chinese2.png
|
||||
./bdfconv ../bdf/wenquanyi_9pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese3.map -d ../bdf/7x13.bdf -n u8g2_font_wqy12_t_chinese3
|
||||
convert bdf.tga -trim u8g2_font_wqy12_t_chinese3.png
|
||||
./bdfconv ../bdf/wenquanyi_9pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312.map -d ../bdf/7x13.bdf -n u8g2_font_wqy12_t_gb2312
|
||||
convert bdf.tga -trim u8g2_font_wqy12_t_gb2312.png
|
||||
./bdfconv ../bdf/wenquanyi_9pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312a.map -d ../bdf/7x13.bdf -n u8g2_font_wqy12_t_gb2312a
|
||||
convert bdf.tga -trim u8g2_font_wqy12_t_gb2312a.png
|
||||
./bdfconv ../bdf/wenquanyi_9pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312b.map -d ../bdf/7x13.bdf -n u8g2_font_wqy12_t_gb2312b
|
||||
convert bdf.tga -trim u8g2_font_wqy12_t_gb2312b.png
|
||||
|
||||
./bdfconv ../bdf/wenquanyi_10pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_wqy13_t_chinese1
|
||||
convert bdf.tga -trim u8g2_font_wqy13_t_chinese1.png
|
||||
./bdfconv ../bdf/wenquanyi_10pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese2.map -d ../bdf/7x13.bdf -n u8g2_font_wqy13_t_chinese2
|
||||
convert bdf.tga -trim u8g2_font_wqy13_t_chinese2.png
|
||||
./bdfconv ../bdf/wenquanyi_10pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese3.map -d ../bdf/7x13.bdf -n u8g2_font_wqy13_t_chinese3
|
||||
convert bdf.tga -trim u8g2_font_wqy13_t_chinese3.png
|
||||
./bdfconv ../bdf/wenquanyi_10pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312.map -d ../bdf/7x13.bdf -n u8g2_font_wqy13_t_gb2312
|
||||
convert bdf.tga -trim u8g2_font_wqy13_t_gb2312.png
|
||||
./bdfconv ../bdf/wenquanyi_10pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312a.map -d ../bdf/7x13.bdf -n u8g2_font_wqy13_t_gb2312a
|
||||
convert bdf.tga -trim u8g2_font_wqy13_t_gb2312a.png
|
||||
./bdfconv ../bdf/wenquanyi_10pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312b.map -d ../bdf/7x13.bdf -n u8g2_font_wqy13_t_gb2312b
|
||||
convert bdf.tga -trim u8g2_font_wqy13_t_gb2312b.png
|
||||
|
||||
./bdfconv ../bdf/wenquanyi_13px.bdf -g 32 -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_wqy14_t_chinese1
|
||||
convert bdf.tga -trim u8g2_font_wqy14_t_chinese1.png
|
||||
./bdfconv ../bdf/wenquanyi_13px.bdf -g 32 -b 0 -f 1 -M ../build/chinese2.map -d ../bdf/7x13.bdf -n u8g2_font_wqy14_t_chinese2
|
||||
convert bdf.tga -trim u8g2_font_wqy14_t_chinese2.png
|
||||
./bdfconv ../bdf/wenquanyi_13px.bdf -g 32 -b 0 -f 1 -M ../build/chinese3.map -d ../bdf/7x13.bdf -n u8g2_font_wqy14_t_chinese3
|
||||
convert bdf.tga -trim u8g2_font_wqy14_t_chinese3.png
|
||||
./bdfconv ../bdf/wenquanyi_13px.bdf -g 32 -b 0 -f 1 -M ../build/gb2312.map -d ../bdf/7x13.bdf -n u8g2_font_wqy14_t_gb2312
|
||||
convert bdf.tga -trim u8g2_font_wqy14_t_gb2312.png
|
||||
./bdfconv ../bdf/wenquanyi_13px.bdf -g 32 -b 0 -f 1 -M ../build/gb2312a.map -d ../bdf/7x13.bdf -n u8g2_font_wqy14_t_gb2312a
|
||||
convert bdf.tga -trim u8g2_font_wqy14_t_gb2312a.png
|
||||
./bdfconv ../bdf/wenquanyi_13px.bdf -g 32 -b 0 -f 1 -M ../build/gb2312b.map -d ../bdf/7x13.bdf -n u8g2_font_wqy14_t_gb2312b
|
||||
convert bdf.tga -trim u8g2_font_wqy14_t_gb2312b.png
|
||||
|
||||
./bdfconv ../bdf/wenquanyi_11pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_wqy15_t_chinese1
|
||||
convert bdf.tga -trim u8g2_font_wqy15_t_chinese1.png
|
||||
./bdfconv ../bdf/wenquanyi_11pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese2.map -d ../bdf/7x13.bdf -n u8g2_font_wqy15_t_chinese2
|
||||
convert bdf.tga -trim u8g2_font_wqy15_t_chinese2.png
|
||||
./bdfconv ../bdf/wenquanyi_11pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese3.map -d ../bdf/7x13.bdf -n u8g2_font_wqy15_t_chinese3
|
||||
convert bdf.tga -trim u8g2_font_wqy15_t_chinese3.png
|
||||
./bdfconv ../bdf/wenquanyi_11pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312.map -d ../bdf/7x13.bdf -n u8g2_font_wqy15_t_gb2312
|
||||
convert bdf.tga -trim u8g2_font_wqy15_t_gb2312.png
|
||||
./bdfconv ../bdf/wenquanyi_11pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312a.map -d ../bdf/7x13.bdf -n u8g2_font_wqy15_t_gb2312a
|
||||
convert bdf.tga -trim u8g2_font_wqy15_t_gb2312a.png
|
||||
./bdfconv ../bdf/wenquanyi_11pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312b.map -d ../bdf/7x13.bdf -n u8g2_font_wqy15_t_gb2312b
|
||||
convert bdf.tga -trim u8g2_font_wqy15_t_gb2312b.png
|
||||
|
||||
./bdfconv ../bdf/wenquanyi_12pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_wqy16_t_chinese1
|
||||
convert bdf.tga -trim u8g2_font_wqy16_t_chinese1.png
|
||||
./bdfconv ../bdf/wenquanyi_12pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese2.map -d ../bdf/7x13.bdf -n u8g2_font_wqy16_t_chinese2
|
||||
convert bdf.tga -trim u8g2_font_wqy16_t_chinese2.png
|
||||
./bdfconv ../bdf/wenquanyi_12pt.bdf -g 32 -b 0 -f 1 -M ../build/chinese3.map -d ../bdf/7x13.bdf -n u8g2_font_wqy16_t_chinese3
|
||||
convert bdf.tga -trim u8g2_font_wqy16_t_chinese3.png
|
||||
./bdfconv ../bdf/wenquanyi_12pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312.map -d ../bdf/7x13.bdf -n u8g2_font_wqy16_t_gb2312
|
||||
convert bdf.tga -trim u8g2_font_wqy16_t_gb2312.png
|
||||
./bdfconv ../bdf/wenquanyi_12pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312a.map -d ../bdf/7x13.bdf -n u8g2_font_wqy16_t_gb2312a
|
||||
convert bdf.tga -trim u8g2_font_wqy16_t_gb2312a.png
|
||||
./bdfconv ../bdf/wenquanyi_12pt.bdf -g 32 -b 0 -f 1 -M ../build/gb2312b.map -d ../bdf/7x13.bdf -n u8g2_font_wqy16_t_gb2312b
|
||||
convert bdf.tga -trim u8g2_font_wqy16_t_gb2312b.png
|
||||
|
||||
|
||||
./bdfconv ../bdf/unifont.bdf -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_unifont_t_chinese1
|
||||
convert bdf.tga -trim u8g2_font_unifont_t_chinese1.png
|
||||
./bdfconv ../bdf/unifont.bdf -b 0 -f 1 -M ../build/chinese2.map -d ../bdf/7x13.bdf -n u8g2_font_unifont_t_chinese2
|
||||
convert bdf.tga -trim u8g2_font_unifont_t_chinese2.png
|
||||
./bdfconv ../bdf/unifont.bdf -b 0 -f 1 -M ../build/chinese3.map -d ../bdf/7x13.bdf -n u8g2_font_unifont_t_chinese3
|
||||
convert bdf.tga -trim u8g2_font_unifont_t_chinese3.png
|
||||
|
||||
./bdfconv ../bdf/gb16st.bdf -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_gb16st_t_1
|
||||
convert bdf.tga -trim u8g2_font_gb16st_t_1.png
|
||||
./bdfconv ../bdf/gb16st.bdf -b 0 -f 1 -M ../build/chinese2.map -d ../bdf/7x13.bdf -n u8g2_font_gb16st_t_2
|
||||
convert bdf.tga -trim u8g2_font_gb16st_t_2.png
|
||||
./bdfconv ../bdf/gb16st.bdf -b 0 -f 1 -M ../build/chinese3.map -d ../bdf/7x13.bdf -n u8g2_font_gb16st_t_3
|
||||
convert bdf.tga -trim u8g2_font_gb16st_t_3.png
|
||||
./bdfconv ../bdf/gb24st.bdf -b 0 -f 1 -M ../build/chinese1.map -d ../bdf/7x13.bdf -n u8g2_font_gb24st_t_1
|
||||
convert bdf.tga -trim u8g2_font_gb24st_t_1.png
|
||||
./bdfconv ../bdf/gb24st.bdf -b 0 -f 1 -M ../build/chinese2.map -d ../bdf/7x13.bdf -n u8g2_font_gb24st_t_2
|
||||
convert bdf.tga -trim u8g2_font_gb24st_t_2.png
|
||||
./bdfconv ../bdf/gb24st.bdf -b 0 -f 1 -M ../build/chinese3.map -d ../bdf/7x13.bdf -n u8g2_font_gb24st_t_3
|
||||
convert bdf.tga -trim u8g2_font_gb24st_t_3.png
|
||||
|
||||
gayathri: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 24 -o gayathri.bdf Gayatri.ttf
|
||||
./bdfconv -v -f 1 -m '$$21-$$1fd,$$d00-$$d7f,$$200c-$$20b9,$$10003-$$102bc>$$e003' gayathri.bdf -o u8g2_font_gayathri_tn.c -n u8g2_font_gayathri_tn -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga gayathri.png
|
||||
|
||||
meera: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 24 -o meera.bdf Meera.ttf
|
||||
./bdfconv -v -f 1 -m '$$21-$$2dc,$$d02-$$d6f,$$200c-$$2215,$$10003-$$1043f>$$e003' meera.bdf -o u8g2_font_meera_tn.c -n u8g2_font_meera_tn -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga meera.png
|
||||
|
||||
gess: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$20-$$ffff,~1588,~65010,~65205,~65206' GESSTwoBold-Bold-75.bdf -o u8g2_font_gess.c -n u8g2_font_gess -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_gess.png
|
||||
|
||||
CARSYMBOL: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$20-$$ffff' CARSYMBOL.bdf -o u8g2_font_carsymbol.c -n u8g2_font_carsymbol -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_carsymbol.png
|
||||
|
||||
Aurebesh: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$20-$$ff' Aurebesh.bdf -o u8g2_font_aurebesh.c -n u8g2_font_aurebesh -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_aurebesh.png
|
||||
|
||||
aurebesh_small: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$20-$$ff' aurebesh_small.bdf -o u8g2_font_aurebesh_small.c -n u8g2_font_aurebesh_small -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_aurebesh_small.png
|
||||
|
||||
issue_1521: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$0000-$$3B97' ../bdf/unifont.bdf -o unifont_custom.c -n unifont_custom -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga unifont_custom.png
|
||||
|
||||
out: bdfconv
|
||||
./bdfconv -v -f 1 -m '$$0000-$$3B97' out.bdf -o out.c -n out -d ../bdf/helvR14.bdf
|
||||
convert bdf.tga out.png
|
||||
|
||||
issue833: bdfconv
|
||||
./bdfconv -v -f 1 -m '19968-40959' unifont-13.0.06.bdf -o out.c -n out -d unifont-13.0.06.bdf
|
||||
convert bdf.tga out.png
|
||||
|
||||
|
||||
waffle: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-65535' ../bdf/waffle-10.bdf -o tmp.c -n u8g2_font_helvB18_tn -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga out.png
|
||||
|
||||
CalBlk36: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-65535' ../bdf/CalBlk36.bdf -o tmp.c -n u8g2_font_helvB18_tn -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga out.png
|
||||
|
||||
CalLite24: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-65535' ../bdf/CalLite24.bdf -o tmp.c -n u8g2_font_helvB18_tn -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga out.png
|
||||
|
||||
7seg_33x19: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-79' ./tmp/7_Seg_33x19.bdf -o tmp.c -n u8g2_font_helvB18_tn -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga out.png
|
||||
|
||||
notos: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-65535,~9939,~10084' NotoEmoji-SemiBold-32.bdf -o u8g2_font_noto_semi_32_t.c -n u8g2_font_noto_semi_32_t -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_semi_32_t.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f300-$$1ffff>$$f300,~127995' NotoEmoji-SemiBold-32.bdf -o u8g2_font_noto_semi_32_t2.c -n u8g2_font_noto_semi_32_t2 -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_semi_32_t2.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f300-$$1f32c>$$f300,$$2600-$$2604,$$2614,$$26c4,$$26c5,$$26c8,$$26f1' NotoEmoji-SemiBold-24.bdf -o u8g2_font_noto_semi_24_t_weather.c -n u8g2_font_noto_semi_24_t_weather -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_semi_24_t_weather.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f600-$$1f637>$$f600,$$1f641-$$1f64f>$$f641, $$1f910-$$1f917>$$f910, $$1f920-$$1f92f>$$f920, $$1f970-$$1f97a>$$f970, $$1fae0-$$1fae5>$$fae0' NotoEmoji-SemiBold-24.bdf -o u8g2_font_noto_semi_24_t_emoji.c -n u8g2_font_noto_semi_24_t_emoji -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_semi_24_t_emoji.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f300-$$1f32c>$$f300,$$2600-$$2604,$$2614,$$26c4,$$26c5,$$26c8,$$26f1' NotoEmoji-SemiBold-32.bdf -o u8g2_font_noto_semi_32_t_weather.c -n u8g2_font_noto_semi_32_t_weather -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_semi_32_t_weather.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f600-$$1f637>$$f600,$$1f641-$$1f64f>$$f641, $$1f910-$$1f917>$$f910, $$1f920-$$1f92f>$$f920, $$1f970-$$1f97a>$$f970, $$1fae0-$$1fae5>$$fae0' NotoEmoji-SemiBold-32.bdf -o u8g2_font_noto_semi_32_t_emoji.c -n u8g2_font_noto_semi_32_t_emoji -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_semi_32_t_emoji.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f300-$$1f32c>$$f300,$$2600-$$2604,$$2614,$$26c4,$$26c5,$$26c8,$$26f1,~127747,~127751' NotoEmoji-SemiBold-40.bdf -o u8g2_font_noto_semi_40_t_weather.c -n u8g2_font_noto_semi_40_t_weather -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_semi_40_t_weather.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f600-$$1f637>$$f600,$$1f641-$$1f64f>$$f641, $$1f910-$$1f917>$$f910, $$1f920-$$1f92f>$$f920, $$1f970-$$1f97a>$$f970, $$1fae0-$$1fae5>$$fae0, ~128561, ~128576' NotoEmoji-SemiBold-40.bdf -o u8g2_font_noto_semi_40_t_emoji.c -n u8g2_font_noto_semi_40_t_emoji -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_semi_40_t_emoji.png
|
||||
|
||||
notob: bdfconv
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f300-$$1f32c>$$f300,$$2600-$$2604,$$2614,$$26c4,$$26c5,$$26c8,$$26f1' NotoEmoji-Bold-24.bdf -o u8g2_font_noto_bold_24_t_weather.c -n u8g2_font_noto_bold_24_t_weather -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_bold_24_t_weather.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f600-$$1f637>$$f600,$$1f641-$$1f64f>$$f641, $$1f910-$$1f917>$$f910, $$1f920-$$1f92f>$$f920, $$1f970-$$1f97a>$$f970, $$1fae0-$$1fae5>$$fae0' NotoEmoji-Bold-24.bdf -o u8g2_font_noto_bold_24_t_emoji.c -n u8g2_font_noto_bold_24_t_emoji -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_bold_24_t_emoji.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f300-$$1f32c>$$f300,$$2600-$$2604,$$2614,$$26c4,$$26c5,$$26c8,$$26f1' NotoEmoji-Bold-32.bdf -o u8g2_font_noto_bold_32_t_weather.c -n u8g2_font_noto_bold_32_t_weather -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_bold_32_t_weather.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f600-$$1f637>$$f600,$$1f641-$$1f64f>$$f641, $$1f910-$$1f917>$$f910, $$1f920-$$1f92f>$$f920, $$1f970-$$1f97a>$$f970, $$1fae0-$$1fae5>$$fae0' NotoEmoji-Bold-32.bdf -o u8g2_font_noto_bold_32_t_emoji.c -n u8g2_font_noto_bold_32_t_emoji -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_bold_32_t_emoji.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f300-$$1f32c>$$f300,$$2600-$$2604,$$2614,$$26c4,$$26c5,$$26c8,$$26f1,~127747,~127751' NotoEmoji-Bold-40.bdf -o u8g2_font_noto_bold_40_t_weather.c -n u8g2_font_noto_bold_40_t_weather -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_bold_40_t_weather.png
|
||||
./bdfconv -v -f 1 -m '32-127,$$1f600-$$1f637>$$f600,$$1f641-$$1f64f>$$f641, $$1f910-$$1f917>$$f910, $$1f920-$$1f92f>$$f920, $$1f970-$$1f97a>$$f970, $$1fae0-$$1fae5>$$fae0, ~128561, ~128576, ~128588' NotoEmoji-Bold-40.bdf -o u8g2_font_noto_bold_40_t_emoji.c -n u8g2_font_noto_bold_40_t_emoji -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_noto_bold_40_t_emoji.png
|
||||
|
||||
|
||||
mystery_quest: bdfconv
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 24 -o mystery-quest.regular.bdf ../ttf/mystery-quest.regular.ttf
|
||||
./bdfconv -v -f 1 -m '32-127' mystery-quest.regular.bdf -o u8g2_font_mystery_quest_24_t.c -n u8g2_font_mystery_quest_24_t -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_mystery_quest_24_t.png
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 28 -o mystery-quest.regular.bdf ../ttf/mystery-quest.regular.ttf
|
||||
./bdfconv -v -f 1 -m '32-127' mystery-quest.regular.bdf -o u8g2_font_mystery_quest_28_t.c -n u8g2_font_mystery_quest_28_t -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_mystery_quest_28_t.png
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 32 -o mystery-quest.regular.bdf ../ttf/mystery-quest.regular.ttf
|
||||
./bdfconv -v -f 1 -m '32-127' mystery-quest.regular.bdf -o u8g2_font_mystery_quest_32_t.c -n u8g2_font_mystery_quest_32_t -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_mystery_quest_32_t.png
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 36 -o mystery-quest.regular.bdf ../ttf/mystery-quest.regular.ttf
|
||||
./bdfconv -v -f 1 -m '32-127' mystery-quest.regular.bdf -o u8g2_font_mystery_quest_36_t.c -n u8g2_font_mystery_quest_36_t -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_mystery_quest_36_t.png
|
||||
-../otf2bdf/otf2bdf -a -r 72 -p 42 -o mystery-quest.regular.bdf ../ttf/mystery-quest.regular.ttf
|
||||
./bdfconv -v -f 1 -m '32-127' mystery-quest.regular.bdf -o u8g2_font_mystery_quest_42_t.c -n u8g2_font_mystery_quest_42_t -d ../bdf/helvB18.bdf
|
||||
convert bdf.tga u8g2_font_mystery_quest_42_t.png
|
||||
|
196
font/bdfconv/bdf_8x8.c
Normal file
196
font/bdfconv/bdf_8x8.c
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
|
||||
bdf_8x8.c
|
||||
|
||||
unencoded font format for 8x8 pixel font
|
||||
|
||||
offset bytes desc
|
||||
0 1 first char
|
||||
1 1 last char
|
||||
2 1 horizontal tile count (x), new 2019 format, issue 771
|
||||
3 1 vertical tile count (y), new 2019 format, issue 771
|
||||
4 n font data, n = (last char - first char + 1)*8
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "bdf_font.h"
|
||||
|
||||
|
||||
static int bg_8x8_convert(bg_t *bg, bbx_t *bbx, int xo, int yo)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int d;
|
||||
|
||||
if ( bbx == NULL )
|
||||
bbx = &(bg->bbx);
|
||||
|
||||
|
||||
/*
|
||||
if ( bbx->w != 8 )
|
||||
return 0;
|
||||
if ( bbx->h != 8 )
|
||||
return 0;
|
||||
*/
|
||||
|
||||
/*
|
||||
for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
|
||||
{
|
||||
d = 0;
|
||||
for( x = bbx->x; x < bbx->x + bbx->w; x++)
|
||||
{
|
||||
d <<= 1;
|
||||
if ( bg_GetBBXPixel(bg, x, y) != 0 )
|
||||
{
|
||||
d++;
|
||||
}
|
||||
}
|
||||
if ( bg_AddTargetData(bg, d) < 0 )
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
for( x = bbx->x; x < bbx->x + bbx->w; x++)
|
||||
{
|
||||
d = 0;
|
||||
for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
|
||||
{
|
||||
d >>= 1;
|
||||
if ( bg_GetBBXPixel(bg, x+xo, y+yo) != 0 )
|
||||
{
|
||||
d |= 128;
|
||||
}
|
||||
}
|
||||
if ( bg_AddTargetData(bg, d) < 0 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void bf_Generate8x8Font(bf_t *bf, int xo, int yo)
|
||||
{
|
||||
int i, j, k;
|
||||
bg_t *bg;
|
||||
int first, last;
|
||||
bbx_t local_bbx;
|
||||
int is_glyph_written;
|
||||
int x, y;
|
||||
|
||||
/* Step 1: Generate 8x8 bitmap data */
|
||||
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
bf_copy_bbx_and_update_shift(bf, &local_bbx, bg);
|
||||
|
||||
if ( (local_bbx.w & 7) != 0 )
|
||||
{
|
||||
bf_Log(bf, "Generate8x8Font: Error, glyph width is not multiple of 8, width=%d, encoding=%d", local_bbx.w, bg->encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (local_bbx.h & 7) != 0 )
|
||||
{
|
||||
bf_Log(bf, "Generate8x8Font: Error, glyph height is not multiple of 8, height=%d, encoding=%d", local_bbx.h, bg->encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
bg_ClearTargetData(bg);
|
||||
for( y = 0; y < bf->tile_v_size; y++ )
|
||||
{
|
||||
for( x = 0; x < bf->tile_h_size; x++ )
|
||||
{
|
||||
//bf_Log(bf, "Generate8x8Font: Encoding %d, x=%d, y=%d", bg->encoding, x, y);
|
||||
|
||||
if ( bg_8x8_convert(bg, &local_bbx, xo+8*x, yo+8*(bf->tile_v_size-y-1)) == 0 )
|
||||
{
|
||||
bf_Log(bf, "Generate8x8Font: Error, 8x8 conversion, encoding=%d", bg->target_cnt, bg->encoding);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 2: Calculate first and last char */
|
||||
|
||||
first = -1;
|
||||
last = -1;
|
||||
|
||||
for( j = 0; j < 256; j++ )
|
||||
{
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to == j )
|
||||
{
|
||||
if ( bg->target_data != NULL )
|
||||
{
|
||||
//bf_Log(bf, "Generate8x8Font: Encoding %d, size=%d", bg->encoding, bg->target_cnt);
|
||||
|
||||
if ( bg->target_cnt != bf->tile_h_size*bf->tile_v_size*8)
|
||||
{
|
||||
bf_Log(bf, "Generate8x8Font: Error, glyph size incorrect, size=%d, encoding=%d", bg->target_cnt, bg->encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( first < 0 )
|
||||
first = j;
|
||||
last = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 3: Write font data */
|
||||
|
||||
bf_AddTargetData(bf, first);
|
||||
bf_AddTargetData(bf, last);
|
||||
bf_AddTargetData(bf, bf->tile_h_size);
|
||||
bf_AddTargetData(bf, bf->tile_v_size);
|
||||
bf_Log(bf, "Generate8x8Font: Tile size width=%d height=%d", bf->tile_h_size, bf->tile_v_size);
|
||||
|
||||
|
||||
for( j = first; j <= last; j++ )
|
||||
{
|
||||
is_glyph_written = 0;
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to == j )
|
||||
{
|
||||
if ( bg->target_data != NULL )
|
||||
{
|
||||
|
||||
if ( bg->target_cnt == bf->tile_h_size*bf->tile_v_size*8)
|
||||
{
|
||||
for( k = 0; k < bg->target_cnt; k++ )
|
||||
{
|
||||
bf_AddTargetData(bf, bg->target_data[k]);
|
||||
}
|
||||
is_glyph_written = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( is_glyph_written == 0 )
|
||||
{
|
||||
for( k = 0; k < bf->tile_h_size*bf->tile_v_size*8; k++ )
|
||||
{
|
||||
bf_AddTargetData(bf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bf_Log(bf, "Generate8x8Font: Font size %d", bf->target_cnt);
|
||||
}
|
763
font/bdfconv/bdf_font.c
Normal file
763
font/bdfconv/bdf_font.c
Normal file
@ -0,0 +1,763 @@
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "bdf_font.h"
|
||||
|
||||
void bf_Error(bf_t *bf, char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
vprintf(fmt, va);
|
||||
printf("\n");
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void bf_Log(bf_t *bf, char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
if ( bf->is_verbose != 0 )
|
||||
{
|
||||
vprintf(fmt, va);
|
||||
printf("\n");
|
||||
}
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
/*
|
||||
bf_Open(0, BDF_BBX_MODE_MINIMAL)
|
||||
*/
|
||||
bf_t *bf_Open(int is_verbose, int bbx_mode)
|
||||
{
|
||||
bf_t *bf;
|
||||
bf = (bf_t *)malloc(sizeof(bf_t));
|
||||
if ( bf != NULL )
|
||||
{
|
||||
bf->is_verbose = is_verbose;
|
||||
bf->glyph_list = NULL;
|
||||
bf->glyph_cnt = 0;
|
||||
bf->glyph_max = 0;
|
||||
bf->str_font = NULL; /* argument for FONT in bdf file */
|
||||
bf->str_copyright = NULL; /* argument for COPYRIGHT in bdf file */
|
||||
bf->target_data = NULL;
|
||||
bf->target_max = 0;
|
||||
bf->target_cnt = 0;
|
||||
bf->selected_glyphs = 0;
|
||||
|
||||
bf->enc_w = 0;
|
||||
bf->enc_h = 0;
|
||||
bf->enc_x = 0;
|
||||
bf->enc_y = 0;
|
||||
|
||||
bf->bbx_mode = bbx_mode;
|
||||
bf->tile_h_size = 1;
|
||||
bf->tile_v_size = 1;
|
||||
|
||||
return bf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void bf_Clear(bf_t *bf)
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
free( bf->glyph_list[i] );
|
||||
}
|
||||
bf->glyph_cnt = 0;
|
||||
|
||||
if ( bf->str_font != NULL )
|
||||
free(bf->str_font);
|
||||
bf->str_font = NULL;
|
||||
if ( bf->str_copyright != NULL )
|
||||
free(bf->str_copyright);
|
||||
bf->str_copyright = NULL;
|
||||
}
|
||||
|
||||
void bf_Close(bf_t *bf)
|
||||
{
|
||||
bf_Clear(bf);
|
||||
if ( bf->glyph_list != NULL )
|
||||
free(bf->glyph_list);
|
||||
if ( bf->target_data != NULL )
|
||||
free(bf->target_data);
|
||||
bf->glyph_list = NULL;
|
||||
bf->glyph_max = 0;
|
||||
free(bf);
|
||||
}
|
||||
|
||||
static int bf_extend(bf_t *bf)
|
||||
{
|
||||
int extend = 16;
|
||||
void *ptr;
|
||||
if ( bf->glyph_list == NULL )
|
||||
{
|
||||
ptr = malloc(extend*sizeof(bg_t *));
|
||||
bf->glyph_max = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = realloc(bf->glyph_list, (bf->glyph_max + extend)*sizeof(bg_t *));
|
||||
}
|
||||
if ( ptr == NULL )
|
||||
return 0;
|
||||
bf->glyph_max += extend;
|
||||
bf->glyph_list = (bg_t **)ptr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns glyph position or -1 */
|
||||
int bf_AddGlyph(bf_t *bf)
|
||||
{
|
||||
while( bf->glyph_max <= bf->glyph_cnt )
|
||||
if ( bf_extend(bf) == 0 )
|
||||
return -1;
|
||||
bf->glyph_list[bf->glyph_cnt] = bg_Open();
|
||||
if ( bf->glyph_list[bf->glyph_cnt] == NULL )
|
||||
return -1;
|
||||
bf->glyph_list[bf->glyph_cnt]->bf = bf;
|
||||
bf->glyph_cnt++;
|
||||
return bf->glyph_cnt-1;
|
||||
}
|
||||
|
||||
|
||||
static int bf_extend_target_data(bf_t *bf)
|
||||
{
|
||||
int extend = 16;
|
||||
int i;
|
||||
void *ptr;
|
||||
if ( bf->target_data == NULL )
|
||||
{
|
||||
ptr = malloc(extend*sizeof(uint8_t));
|
||||
bf->target_max = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = realloc(bf->target_data, (bf->target_max + extend)*sizeof(uint8_t));
|
||||
}
|
||||
if ( ptr == NULL )
|
||||
return 0;
|
||||
bf->target_data = (uint8_t *)ptr;
|
||||
for( i = bf->target_max; i < bf->target_max + extend; i++ )
|
||||
bf->target_data[i] = 0;
|
||||
bf->target_max += extend;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bf_AddTargetData(bf_t *bf, uint8_t data)
|
||||
{
|
||||
while( bf->target_max <= bf->target_cnt )
|
||||
if ( bf_extend_target_data(bf) == 0 )
|
||||
return -1;
|
||||
bf->target_data[bf->target_cnt] = data;
|
||||
bf->target_cnt++;
|
||||
return bf->target_cnt-1;
|
||||
}
|
||||
|
||||
void bf_ClearTargetData(bf_t *bf)
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < bf->target_max; i++ )
|
||||
bf->target_data[i] = 0;
|
||||
bf->target_cnt = 0;
|
||||
}
|
||||
|
||||
void bf_CalculateSelectedNumberOfGlyphs(bf_t *bf)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
bf->selected_glyphs = 0;
|
||||
|
||||
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
bf->selected_glyphs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bf_ReduceAllGlyph(bf_t *bf)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
int red_x, red_y;
|
||||
|
||||
bf_Log(bf, "Reduce: Start");
|
||||
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
bg_ReduceGlyph(bg);
|
||||
//bg_ShowBitmap(bg, &(bg->bbx));
|
||||
red_x = bg->bitmap_width - bg->bbx.w;
|
||||
red_y = bg->bitmap_height - bg->bbx.h;
|
||||
if ( red_x > 0 || red_y > 0 )
|
||||
{
|
||||
//bf_Log(bf, "Reduce: Encoding %ld, x by %d, y by %d", bg->encoding, red_x, red_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
bf_Log(bf, "Reduce: End");
|
||||
|
||||
}
|
||||
|
||||
void bf_ShowAllGlyphs(bf_t *bf, bbx_t *bbx)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
bg_ShowBitmap(bg, bbx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int bf_GetIndexByEncoding(bf_t *bf, long encoding)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->encoding == encoding )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void bf_CalculateMaxBBX(bf_t *bf)
|
||||
{
|
||||
int i;
|
||||
int is_first = 1;
|
||||
int enc_idx;
|
||||
bg_t *bg;
|
||||
|
||||
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
if ( is_first != 0 )
|
||||
{
|
||||
bf->max = bg->bbx;
|
||||
bf->enc_x = bg->encoding;
|
||||
bf->enc_y = bg->encoding;
|
||||
bf->enc_w = bg->encoding;
|
||||
bf->enc_h = bg->encoding;
|
||||
is_first = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
enc_idx = bg_Max(bg, &(bf->max));
|
||||
switch(enc_idx)
|
||||
{
|
||||
case 1:
|
||||
bf->enc_w = bg->encoding;
|
||||
break;
|
||||
case 2:
|
||||
bf->enc_h = bg->encoding;
|
||||
break;
|
||||
case 3:
|
||||
bf->enc_x = bg->encoding;
|
||||
break;
|
||||
case 4:
|
||||
bf->enc_y = bg->encoding;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bf->bbx_mode == BDF_BBX_MODE_M8 )
|
||||
{
|
||||
/* old
|
||||
bf->max.w = ( bf->max.w + 7 ) & ~7;
|
||||
bf->max.h = ( bf->max.h + 7 ) & ~7;
|
||||
*/
|
||||
bf->max.w = 8;
|
||||
bf->max.h = 7;
|
||||
}
|
||||
|
||||
|
||||
bf_Log(bf, "CalculateMaxBBX: x=%ld, y=%ld, w=%ld, h=%ld", bf->max.x, bf->max.y, bf->max.w, bf->max.h);
|
||||
bf_Log(bf, "CalculateMaxBBX: Encodings x=%ld, y=%ld, w=%ld, h=%ld", bf->enc_x, bf->enc_y, bf->enc_w, bf->enc_h);
|
||||
}
|
||||
|
||||
void bf_CalculateMinMaxDWidth(bf_t *bf)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
|
||||
bf->dx_min = 0x07fff;
|
||||
bf->dx_max = -0x07fff;
|
||||
|
||||
bf->x_min = 0x07fff;
|
||||
bf->x_max = -0x07fff;
|
||||
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
if ( bf->dx_min > bg->dwidth_x )
|
||||
bf->dx_min = bg->dwidth_x;
|
||||
if ( bf->dx_max < bg->dwidth_x )
|
||||
bf->dx_max = bg->dwidth_x;
|
||||
|
||||
if ( bf->x_min > bg->bbx.x )
|
||||
bf->x_min = bg->bbx.x;
|
||||
if ( bf->x_max < bg->bbx.x )
|
||||
bf->x_max = bg->bbx.x;
|
||||
|
||||
}
|
||||
}
|
||||
bf_Log(bf, "bf_CalculateMinMaxDWidth: dx_min=%ld, dx_max=%ld", bf->dx_min, bf->dx_max);
|
||||
bf_Log(bf, "bf_CalculateMinMaxDWidth: x_min=%ld, x_max=%ld", bf->x_min, bf->x_max);
|
||||
if ( bf->dx_min == bf->dx_max && bf->x_min >= 0 )
|
||||
{
|
||||
bf_Log(bf, "bf_CalculateMinMaxDWidth: Monospaced font."); /* not sufficient: also bbx.x must be >= 0 for all glyphs */
|
||||
/* for a monospaced font, dx must be identical to bbx.w */
|
||||
}
|
||||
}
|
||||
|
||||
int get_unsigned_bit_size(unsigned long v)
|
||||
{
|
||||
int i = 0;
|
||||
while( v != 0 )
|
||||
{
|
||||
v = v / 2;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int get_signed_bit_size(long v)
|
||||
{
|
||||
if ( v < 0 )
|
||||
return get_unsigned_bit_size(-v-1) + 1;
|
||||
return get_unsigned_bit_size(v) + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
#define BDF_BBX_MODE_MINIMAL 0
|
||||
#define BDF_BBX_MODE_HEIGHT 1
|
||||
#define BDF_BBX_MODE_MAX 2
|
||||
#define BDF_BBX_MODE_M8 3
|
||||
*/
|
||||
void bf_copy_bbx_and_update_shift(bf_t *bf, bbx_t *target_bbx, bg_t *bg)
|
||||
{
|
||||
/* modifing the following code requires update ind bdf_rle.c also */
|
||||
if ( bf->bbx_mode == BDF_BBX_MODE_MINIMAL ) // mode 0
|
||||
{
|
||||
*target_bbx = bg->bbx;
|
||||
}
|
||||
else if ( bf->bbx_mode == BDF_BBX_MODE_MAX ) // mode 2 (monospace)
|
||||
{
|
||||
*target_bbx = bf->max;
|
||||
target_bbx->x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
bg->shift_x = bg->bbx.x;
|
||||
if ( target_bbx->w < bg->dwidth_x )
|
||||
target_bbx->w = bg->dwidth_x;
|
||||
}
|
||||
else if ( bf->bbx_mode == BDF_BBX_MODE_5X7 ) // mode 4 (5x7 displays)
|
||||
{
|
||||
*target_bbx = bf->max;
|
||||
target_bbx->x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
bg->shift_x = bg->bbx.x;
|
||||
target_bbx->w = 5;
|
||||
}
|
||||
else if ( bf->bbx_mode == BDF_BBX_MODE_M8 )
|
||||
{
|
||||
/* old
|
||||
target_bbx->w = bf->max.w;
|
||||
if ( target_bbx->w < bg->dwidth_x )
|
||||
target_bbx->w = bg->dwidth_x;
|
||||
target_bbx->w = (target_bbx->w+7) & ~7;
|
||||
target_bbx->h = (bf->max.h+7) & ~7;
|
||||
*/
|
||||
target_bbx->w = 8;
|
||||
target_bbx->h = 8;
|
||||
target_bbx->x = bf->max.x;
|
||||
target_bbx->y = bf->max.y;
|
||||
target_bbx->x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
*target_bbx = bf->max;
|
||||
target_bbx->w = bg->bbx.w;
|
||||
target_bbx->x = bg->bbx.x;
|
||||
target_bbx->x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
{
|
||||
/* e.g. "j" */
|
||||
target_bbx->w -= bg->bbx.x;
|
||||
bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* e.g. "B" */
|
||||
target_bbx->w += bg->bbx.x;
|
||||
//bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
if ( target_bbx->w < bg->dwidth_x )
|
||||
target_bbx->w = bg->dwidth_x;
|
||||
}
|
||||
|
||||
bg->width_deviation = target_bbx->w - bg->bbx.w;
|
||||
}
|
||||
|
||||
void bf_CalculateMaxBitFieldSize(bf_t *bf)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
int bs;
|
||||
bbx_t local_bbx;
|
||||
bf->bbx_x_max_bit_size = 0;
|
||||
bf->bbx_y_max_bit_size = 0;
|
||||
bf->bbx_w_max_bit_size = 0;
|
||||
bf->bbx_h_max_bit_size = 0;
|
||||
bf->dx_max_bit_size = 0;
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
|
||||
bf_copy_bbx_and_update_shift(bf, &local_bbx, bg);
|
||||
#ifdef OLD_CLODE
|
||||
/* modifing the following code requires update ind bdf_rle.c also */
|
||||
if ( bf->bbx_mode == BDF_BBX_MODE_MINIMAL )
|
||||
{
|
||||
local_bbx = bg->bbx;
|
||||
}
|
||||
else if ( bf->bbx_mode == BDF_BBX_MODE_MAX )
|
||||
{
|
||||
local_bbx = bf->max;
|
||||
local_bbx.x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
bg->shift_x = bg->bbx.x;
|
||||
if ( local_bbx.w < bg->dwidth_x )
|
||||
local_bbx.w = bg->dwidth_x;
|
||||
}
|
||||
else if ( bf->bbx_mode == BDF_BBX_MODE_M8 )
|
||||
{
|
||||
local_bbx.w = bf->max.w;
|
||||
if ( local_bbx.w < bg->dwidth_x )
|
||||
local_bbx.w = bg->dwidth_x;
|
||||
local_bbx.w = (local_bbx.w+7) & ~7;
|
||||
local_bbx.h = (bf->max.h+7) & ~7;
|
||||
local_bbx.x = bf->max.x;
|
||||
local_bbx.y = bf->max.y;
|
||||
local_bbx.x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
local_bbx = bf->max;
|
||||
local_bbx.w = bg->bbx.w;
|
||||
local_bbx.x = bg->bbx.x;
|
||||
local_bbx.x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
{
|
||||
/* e.g. "j" */
|
||||
local_bbx.w -= bg->bbx.x;
|
||||
bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* e.g. "B" */
|
||||
local_bbx.w += bg->bbx.x;
|
||||
//bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
if ( local_bbx.w < bg->dwidth_x )
|
||||
local_bbx.w = bg->dwidth_x;
|
||||
}
|
||||
#endif
|
||||
bs = get_unsigned_bit_size(local_bbx.w);
|
||||
if ( bf->bbx_w_max_bit_size < bs )
|
||||
bf->bbx_w_max_bit_size = bs;
|
||||
|
||||
bs = get_unsigned_bit_size(local_bbx.h);
|
||||
if ( bf->bbx_h_max_bit_size < bs )
|
||||
bf->bbx_h_max_bit_size = bs;
|
||||
|
||||
//printf("%ld ", local_bbx.x);
|
||||
bs = get_signed_bit_size(local_bbx.x);
|
||||
if ( bf->bbx_x_max_bit_size < bs )
|
||||
bf->bbx_x_max_bit_size = bs;
|
||||
//printf("%d:%d ",(int)local_bbx->x, (int)bs);
|
||||
|
||||
bs = get_signed_bit_size(local_bbx.y);
|
||||
if ( bf->bbx_y_max_bit_size < bs )
|
||||
bf->bbx_y_max_bit_size = bs;
|
||||
|
||||
if ( bf->bbx_mode == BDF_BBX_MODE_MINIMAL )
|
||||
{
|
||||
bs = get_signed_bit_size(bg->dwidth_x);
|
||||
}
|
||||
else if ( bf->bbx_mode == BDF_BBX_MODE_MAX )
|
||||
{
|
||||
bs = get_signed_bit_size(local_bbx.w);
|
||||
}
|
||||
else
|
||||
{
|
||||
bs = get_signed_bit_size(local_bbx.w);
|
||||
}
|
||||
if ( bf->dx_max_bit_size < bs )
|
||||
bf->dx_max_bit_size = bs;
|
||||
|
||||
}
|
||||
}
|
||||
bf_Log(bf, "bf_CalculateMaxBitFieldSize: bbx.x=%d, bbx.y=%d, bbx.w=%d, bbx.h=%d, dwidth=%d",
|
||||
bf->bbx_x_max_bit_size, bf->bbx_y_max_bit_size, bf->bbx_w_max_bit_size, bf->bbx_h_max_bit_size, bf->dx_max_bit_size);
|
||||
|
||||
}
|
||||
|
||||
void bf_ShowMonospaceStatistics(bf_t *bf)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
long cnt = 0;
|
||||
long max = 0;
|
||||
long sum = 0;
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
if ( max < bg->width_deviation )
|
||||
max = bg->width_deviation;
|
||||
sum += bg->width_deviation;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if ( cnt == 0 )
|
||||
cnt++;
|
||||
bf_Log(bf, "Monospace Statistics: Max width extention %ld, average width extention %ld.%ld", max, sum/cnt, (sum*10/cnt) % 10 );
|
||||
/*
|
||||
Monospaced font: average width extention does not differ much between -b 1 and --b 2
|
||||
Variable width font: big difference for the average width extention between modes 1 and 2.
|
||||
|
||||
Examples:
|
||||
|
||||
./bdfconv -b 1 -v ../bdf/profont12.bdf
|
||||
Monospace Statistics: Max width extention 6, average width extention 1.7
|
||||
./bdfconv -b 2 -v ../bdf/profont12.bdf
|
||||
Monospace Statistics: Max width extention 6, average width extention 1.7
|
||||
--> profont12.bdf is a monospaced font
|
||||
|
||||
./bdfconv -b 1 -v ../bdf/helvR12.bdf
|
||||
Monospace Statistics: Max width extention 6, average width extention 1.9
|
||||
./bdfconv -b 2 -v ../bdf/helvR12.bdf
|
||||
Monospace Statistics: Max width extention 15, average width extention 8.0
|
||||
--> helvR12.bdf is not a monospaced font
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
int bf_WriteUCGCByFP(bf_t *bf, FILE *out_fp, const char *fontname, const char *indent)
|
||||
{
|
||||
int i;
|
||||
int bytes_per_line = 16;
|
||||
|
||||
fprintf(out_fp, "/*\n");
|
||||
fprintf(out_fp, " Fontname: %s\n", bf->str_font);
|
||||
fprintf(out_fp, " Copyright: %s\n", bf->str_copyright);
|
||||
fprintf(out_fp, " Glyphs: %d/%d\n", (int)bf->selected_glyphs, (int)bf->glyph_cnt );
|
||||
fprintf(out_fp, " BBX Build Mode: %d\n", (int)bf->bbx_mode);
|
||||
fprintf(out_fp, "*/\n");
|
||||
fprintf(out_fp, "#include \"ucg.h\"\n");
|
||||
fprintf(out_fp, "const ucg_fntpgm_uint8_t %s[%d] UCG_FONT_SECTION(\"%s\") = {\n", fontname, bf->target_cnt, fontname);
|
||||
fprintf(out_fp, " ");
|
||||
|
||||
for( i = 0; i < bf->target_cnt; i++ )
|
||||
{
|
||||
fprintf(out_fp, "%d", bf->target_data[i]);
|
||||
if ( i+1 != bf->target_cnt )
|
||||
fprintf(out_fp, ",");
|
||||
if ( (i+1) % bytes_per_line == 0 )
|
||||
fprintf(out_fp, "\n%s", indent);
|
||||
}
|
||||
|
||||
fprintf(out_fp, "};\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bf_WriteU8G2CByFP(bf_t *bf, FILE *out_fp, const char *fontname, const char *indent)
|
||||
{
|
||||
int i;
|
||||
int bytes_per_line = 32;
|
||||
int extra1;
|
||||
|
||||
fprintf(out_fp, "/*\n");
|
||||
fprintf(out_fp, " Fontname: %s\n", bf->str_font);
|
||||
fprintf(out_fp, " Copyright: %s\n", bf->str_copyright);
|
||||
fprintf(out_fp, " Glyphs: %d/%d\n", (int)bf->selected_glyphs, (int)bf->glyph_cnt );
|
||||
fprintf(out_fp, " BBX Build Mode: %d\n", (int)bf->bbx_mode);
|
||||
fprintf(out_fp, "*/\n");
|
||||
|
||||
if ( bf->target_data[bf->target_cnt-1] == 0 )
|
||||
extra1 = 0;
|
||||
else
|
||||
extra1 = 1;
|
||||
|
||||
if ( bf->target_cnt-1+extra1 > 32760 )
|
||||
{
|
||||
fprintf(out_fp, "#ifdef U8G2_USE_LARGE_FONTS\n");
|
||||
}
|
||||
|
||||
if ( bf->bbx_mode == 3 ) // maybe better check for the font_format
|
||||
{
|
||||
//fprintf(out_fp, "#include \"u8x8.h\"\n");
|
||||
fprintf(out_fp, "const uint8_t %s[%d] U8X8_FONT_SECTION(\"%s\") = \n", fontname, bf->target_cnt+extra1, fontname);
|
||||
}
|
||||
else
|
||||
{
|
||||
//fprintf(out_fp, "#include \"u8g2.h\"\n");
|
||||
fprintf(out_fp, "const uint8_t %s[%d] U8G2_FONT_SECTION(\"%s\") = \n", fontname, bf->target_cnt+extra1, fontname);
|
||||
}
|
||||
fprintf(out_fp, "%s\"", indent);
|
||||
|
||||
for( i = 0; i < bf->target_cnt-1+extra1; i++ )
|
||||
{
|
||||
if ( bf->target_data[i] < 32 || bf->target_data[i] == '\"' || bf->target_data[i] == '\\' || bf->target_data[i] == '?' || ( bf->target_data[i] >= '0' && bf->target_data[i] <= '9' ))
|
||||
{
|
||||
fprintf(out_fp, "\\%o", bf->target_data[i]);
|
||||
//fprintf(out_fp, "\\x%02x", bf->target_data[i]);
|
||||
}
|
||||
else if ( bf->target_data[i] < 127 ) /* issue 482, do not output ASCII char 127, instead use octal code for 127 */
|
||||
{
|
||||
fprintf(out_fp, "%c", bf->target_data[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out_fp, "\\%o", bf->target_data[i]);
|
||||
}
|
||||
if ( (i+1) % bytes_per_line == 0 )
|
||||
fprintf(out_fp, "\"\n%s\"", indent);
|
||||
}
|
||||
|
||||
fprintf(out_fp, "\";\n");
|
||||
|
||||
if ( bf->target_cnt-1+extra1 > 32760 )
|
||||
{
|
||||
fprintf(out_fp, "#endif /* U8G2_USE_LARGE_FONTS */\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bf_WriteUCGCByFilename(bf_t *bf, const char *filename, const char *fontname, const char *indent)
|
||||
{
|
||||
FILE *fp;
|
||||
fp = fopen(filename, "wb");
|
||||
if ( fp == NULL )
|
||||
{
|
||||
bf_Log(bf, "bf_WriteUCGCByFilename: Open error '%s'", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bf_WriteUCGCByFP(bf, fp, fontname, indent);
|
||||
bf_Log(bf, "bf_WriteUCGCByFilename: Write file '%s'", filename);
|
||||
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* called from main() */
|
||||
int bf_WriteU8G2CByFilename(bf_t *bf, const char *filename, const char *fontname, const char *indent)
|
||||
{
|
||||
FILE *fp;
|
||||
fp = fopen(filename, "wb");
|
||||
if ( fp == NULL )
|
||||
{
|
||||
bf_Log(bf, "bf_WriteU8G2CByFilename: Open error '%s'", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bf_WriteU8G2CByFP(bf, fp, fontname, indent);
|
||||
bf_Log(bf, "bf_WriteU8G2CByFilename: Write file '%s'", filename);
|
||||
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
xo, yo: offset for 8x8 fonts (font_format==2)
|
||||
called from main()
|
||||
*/
|
||||
bf_t *bf_OpenFromFile(const char *bdf_filename, int is_verbose, int bbx_mode, const char *map_str, const char *map_file_name, int font_format, int xo, int yo, int th, int tv)
|
||||
{
|
||||
bf_t *bf;
|
||||
|
||||
bf = bf_Open(is_verbose, bbx_mode);
|
||||
if ( bf != NULL )
|
||||
{
|
||||
bf->tile_h_size = th;
|
||||
bf->tile_v_size = tv;
|
||||
|
||||
if ( bf_ParseFile(bf, bdf_filename) != 0 )
|
||||
{
|
||||
if ( map_file_name[0] != '\0' )
|
||||
{
|
||||
bf_MapFile(bf, map_file_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
bf_Map(bf, map_str);
|
||||
}
|
||||
bf_CalculateSelectedNumberOfGlyphs(bf);
|
||||
|
||||
bf_ReduceAllGlyph(bf);
|
||||
bf_CalculateMaxBBX(bf);
|
||||
//bf_ShowAllGlyphs(bf, &(bf->max));
|
||||
bf_CalculateMinMaxDWidth(bf);
|
||||
|
||||
/* issue 669 */
|
||||
if ( bf->bbx_mode == BDF_BBX_MODE_MAX )
|
||||
if ( bf->max.w < bf->dx_max )
|
||||
bf->max.w = bf->dx_max;
|
||||
|
||||
bf_CalculateMaxBitFieldSize(bf);
|
||||
|
||||
|
||||
if ( font_format == 0 || font_format == 1 )
|
||||
{
|
||||
bf_RLECompressAllGlyphs(bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bf_Generate8x8Font(bf, xo, yo); /* bdf_8x8.c */
|
||||
}
|
||||
|
||||
if ( bf->bbx_mode != BDF_BBX_MODE_MINIMAL )
|
||||
bf_ShowMonospaceStatistics(bf); /* Show stats only for none minimal mode. For minimal mode it will always be zero */
|
||||
|
||||
return bf;
|
||||
}
|
||||
bf_Close(bf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
162
font/bdfconv/bdf_font.h
Normal file
162
font/bdfconv/bdf_font.h
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
|
||||
bdf_font.h
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BDF_FONT_H
|
||||
#define _BDF_FONT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bdf_glyph.h"
|
||||
|
||||
#define BDF_LINE_LEN 1024
|
||||
|
||||
#define BDF_BBX_MODE_MINIMAL 0
|
||||
#define BDF_BBX_MODE_HEIGHT 1
|
||||
#define BDF_BBX_MODE_MAX 2
|
||||
#define BDF_BBX_MODE_M8 3
|
||||
#define BDF_BBX_MODE_5X7 4
|
||||
|
||||
struct _bdf_font_struct
|
||||
{
|
||||
int is_verbose;
|
||||
|
||||
bg_t **glyph_list;
|
||||
int glyph_cnt;
|
||||
int glyph_max;
|
||||
|
||||
/* variables for the parser */
|
||||
char line_buf[BDF_LINE_LEN];
|
||||
int line_pos;
|
||||
int is_bitmap_parsing;
|
||||
|
||||
long encoding;
|
||||
|
||||
long dwidth_x;
|
||||
long dwidth_y;
|
||||
|
||||
long bbx_w;
|
||||
long bbx_h;
|
||||
long bbx_x;
|
||||
long bbx_y;
|
||||
|
||||
int bitmap_x; /* x position within bitmap parsing */
|
||||
int bitmap_y; /* y position within bitmap parsing */
|
||||
int glyph_pos; /* the position to which the glyph has been added in the list */
|
||||
FILE *fp;
|
||||
|
||||
char *str_font; /* argument for FONT in bdf file */
|
||||
char *str_copyright; /* argument for COPYRIGHT in bdf file */
|
||||
|
||||
long selected_glyphs; /* number of mapped glyphs */
|
||||
|
||||
int bbx_mode; /* bounding box mode, one of BDF_BBX_MODE_xxx */
|
||||
/* bf_CalculateMaxBBX */
|
||||
bbx_t max; /* max bbx, calculated from the mapped glyphs by bf_CalculateMaxBBX */
|
||||
|
||||
/* remember which encoding has caused the max value */
|
||||
long enc_w;
|
||||
long enc_h;
|
||||
long enc_x;
|
||||
long enc_y;
|
||||
|
||||
/* bf_CalculateMinMaxDWidth */
|
||||
long dx_min; /* calculated minimum and maximum dwidth value from the mapped glyphs by bf_CalculateMinMaxDWidth */
|
||||
long dx_max; /* it is a monospaced font if max and min values are identical */
|
||||
|
||||
/* bf_CalculateMinMaxDWidth */
|
||||
long x_min; /* calculated minimum and maximum bbx.x value from the mapped glyphs by bf_CalculateMinMaxDWidth */
|
||||
long x_max; /* it is a monospaced font if x_min >= 0 */
|
||||
|
||||
/* bf_CalculateMaxBitFieldSize */
|
||||
int bbx_x_max_bit_size;
|
||||
int bbx_y_max_bit_size;
|
||||
int bbx_w_max_bit_size;
|
||||
int bbx_h_max_bit_size;
|
||||
int dx_max_bit_size;
|
||||
|
||||
/* font target data */
|
||||
uint8_t *target_data;
|
||||
int target_max;
|
||||
int target_cnt;
|
||||
|
||||
|
||||
int tile_h_size; // new 2019 8x8 font format
|
||||
int tile_v_size; // new 2019 8x8 font format
|
||||
};
|
||||
|
||||
/* bdf_font.c */
|
||||
|
||||
|
||||
/* output error & log messages */
|
||||
void bf_Error(bf_t *bf, char *fmt, ...);
|
||||
void bf_Log(bf_t *bf, char *fmt, ...);
|
||||
|
||||
/* constructor/destructor */
|
||||
bf_t *bf_Open(int is_verbose, int bbx_mode);
|
||||
void bf_Close(bf_t *bf);
|
||||
|
||||
/* returns glyph position or -1 */
|
||||
int bf_AddGlyph(bf_t *bf);
|
||||
|
||||
/* add binary data */
|
||||
void bf_ClearTargetData(bf_t *bf);
|
||||
int bf_AddTargetData(bf_t *bf, uint8_t data);
|
||||
|
||||
void bf_CalculateSelectedNumberOfGlyphs(bf_t *bf);
|
||||
|
||||
void bf_ReduceAllGlyph(bf_t *bf);
|
||||
|
||||
int bf_GetIndexByEncoding(bf_t *bf, long encoding);
|
||||
|
||||
/* only shows glyphs, which will be mapped (call bf_Map() first) */
|
||||
void bf_ShowAllGlyphs(bf_t *bf, bbx_t *bbx);
|
||||
|
||||
void bf_ShowMonospaceStatistics(bf_t *bf);
|
||||
|
||||
|
||||
/* calculate the max bbx for all mapped glyphs (call bf_Map() first) */
|
||||
void bf_CalculateMaxBBX(bf_t *bf);
|
||||
|
||||
void bf_CalculateMinMaxDWidth(bf_t *bf);
|
||||
void bf_copy_bbx_and_update_shift(bf_t *bf, bbx_t *target_bbx, bg_t *bg);
|
||||
void bf_CalculateMaxBitFieldSize(bf_t *bf);
|
||||
void bf_RLECompressAllGlyphs(bf_t *bf);
|
||||
void bf_Generate8x8Font(bf_t *bf, int xo, int yo);
|
||||
|
||||
|
||||
int bf_WriteUCGCByFilename(bf_t *bf, const char *filename, const char *fontname, const char *indent);
|
||||
int bf_WriteU8G2CByFilename(bf_t *bf, const char *filename, const char *fontname, const char *indent);
|
||||
|
||||
bf_t *bf_OpenFromFile(const char *bdf_filename, int is_verbose, int bbx_mode, const char *map_str, const char *map_file_name, int font_format, int xo, int yo, int th, int tv);
|
||||
|
||||
|
||||
/* bdf_parser.c */
|
||||
int bf_ParseFile(bf_t *bf, const char *name);
|
||||
|
||||
/* bdf_map.c */
|
||||
void bf_Map(bf_t *bf, const char *map_cmd_list);
|
||||
int bf_MapFile(bf_t *bf, const char *map_file_name);
|
||||
|
||||
/* bdf_tga.c */
|
||||
int tga_init(uint16_t w, uint16_t h);
|
||||
void tga_clear(void);
|
||||
void tga_set_pixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b);
|
||||
void tga_save(const char *name);
|
||||
void tga_set_font(uint8_t *font);
|
||||
uint8_t *tga_get_glyph_data(uint16_t encoding);
|
||||
int tga_get_char_width(void);
|
||||
int tga_get_char_height(void);
|
||||
unsigned tga_draw_glyph(unsigned x, unsigned y, uint16_t encoding, int is_hints);
|
||||
unsigned tga_draw_string(unsigned x, unsigned y, const char *s, int is_hints, unsigned max_dx);
|
||||
int tga_is_pixel_intersection(void);
|
||||
void tga_clear_pixel_intersection(void);
|
||||
|
||||
/* bdf_kern.c */
|
||||
unsigned bdf_calculate_kerning(uint8_t *font, uint16_t e1, uint16_t e2, uint8_t min_distance_in_per_cent_of_char_width);
|
||||
void bdf_calculate_all_kerning(bf_t *bf, const char *filename, const char *fontname, uint8_t min_distance_in_per_cent_of_char_width);
|
||||
|
||||
|
||||
#endif
|
439
font/bdfconv/bdf_glyph.c
Normal file
439
font/bdfconv/bdf_glyph.c
Normal file
@ -0,0 +1,439 @@
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "bdf_glyph.h"
|
||||
|
||||
|
||||
bg_t *bg_Open(void)
|
||||
{
|
||||
bg_t *bg;
|
||||
|
||||
bg = (bg_t *)malloc(sizeof(bg_t));
|
||||
if ( bg != NULL )
|
||||
{
|
||||
bg->encoding = 0;
|
||||
bg->map_to = -1;
|
||||
bg->bitmap_data = NULL;
|
||||
bg->target_data = NULL;
|
||||
bg->target_max = 0;
|
||||
bg->target_cnt = 0;
|
||||
bg->shift_x = 0;
|
||||
bg->is_excluded_from_kerning = 0;
|
||||
|
||||
return bg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void bg_Close(bg_t *bg)
|
||||
{
|
||||
if ( bg->bitmap_data != NULL )
|
||||
free(bg->bitmap_data);
|
||||
if ( bg->target_data != NULL )
|
||||
free(bg->target_data);
|
||||
bg->bitmap_data = NULL;
|
||||
bg->target_data =NULL;
|
||||
bg->target_max = 0;
|
||||
bg->target_cnt = 0;
|
||||
bg->target_bit_pos = 0;
|
||||
bg->encoding = 0;
|
||||
free(bg);
|
||||
}
|
||||
|
||||
static int bg_extend_target_data(bg_t *bg)
|
||||
{
|
||||
int extend = 16;
|
||||
int i;
|
||||
void *ptr;
|
||||
if ( bg->target_data == NULL )
|
||||
{
|
||||
ptr = malloc(extend*sizeof(uint8_t));
|
||||
bg->target_max = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = realloc(bg->target_data, (bg->target_max + extend)*sizeof(uint8_t));
|
||||
}
|
||||
if ( ptr == NULL )
|
||||
return 0;
|
||||
bg->target_data = (uint8_t *)ptr;
|
||||
for( i = bg->target_max; i < bg->target_max + extend; i++ )
|
||||
bg->target_data[i] = 0;
|
||||
bg->target_max += extend;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bg_AddTargetData(bg_t *bg, uint8_t data)
|
||||
{
|
||||
while( bg->target_max <= bg->target_cnt )
|
||||
if ( bg_extend_target_data(bg) == 0 )
|
||||
return -1;
|
||||
bg->target_data[bg->target_cnt] = data;
|
||||
bg->target_cnt++;
|
||||
return bg->target_cnt-1;
|
||||
}
|
||||
|
||||
void bg_ClearTargetData(bg_t *bg)
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < bg->target_max; i++ )
|
||||
bg->target_data[i] = 0;
|
||||
bg->target_cnt = 0;
|
||||
bg->target_bit_pos = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Desc:
|
||||
Output a field to the target bitstream. The field size in bits is given by "cnt" and
|
||||
the value of the field is "val".
|
||||
Args:
|
||||
cnt: Fieldsize in bits, must be lower or equal to 8
|
||||
val: The value (content) of the field. Side condition: val < (1<<cnt) && val >= 0
|
||||
*/
|
||||
int bg_AddTargetBits(bg_t *bg, unsigned cnt, unsigned val)
|
||||
{
|
||||
|
||||
assert( val < (1<<cnt) );
|
||||
|
||||
while( bg->target_max <= bg->target_cnt+1 )
|
||||
if ( bg_extend_target_data(bg) == 0 )
|
||||
return 0;
|
||||
|
||||
bg->target_data[bg->target_cnt] |= (val << bg->target_bit_pos);
|
||||
|
||||
if ( bg->target_bit_pos+cnt >= 8 )
|
||||
{
|
||||
bg->target_cnt++;
|
||||
|
||||
val >>= 8-bg->target_bit_pos;
|
||||
bg->target_data[bg->target_cnt] = val;
|
||||
|
||||
bg->target_bit_pos+=cnt;
|
||||
bg->target_bit_pos-=8;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg->target_bit_pos+=cnt;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bg_FlushTargetBits(bg_t *bg)
|
||||
{
|
||||
while( bg->target_bit_pos != 0 )
|
||||
if ( bg_AddTargetBits(bg, 1, 0) == 0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int bg_SetBitmapSizeInBytes(bg_t *bg, size_t bytes)
|
||||
{
|
||||
if ( bg->bitmap_data != NULL )
|
||||
free(bg->bitmap_data);
|
||||
bg->bitmap_data = (uint8_t *)malloc(bytes);
|
||||
if ( bg->bitmap_data == NULL )
|
||||
return 0;
|
||||
memset(bg->bitmap_data, 0, bytes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bg_SetBitmapSize(bg_t *bg, int w, int h)
|
||||
{
|
||||
return bg_SetBitmapSizeInBytes(bg, w*h);
|
||||
}
|
||||
|
||||
void bg_SetBitmapPixel(bg_t *bg, int x, int y, int value)
|
||||
{
|
||||
static long last_encoding = 0xffffffff;
|
||||
static long biggest_x = -1;
|
||||
|
||||
if ( x >= bg->bitmap_width || y >= bg->bitmap_height )
|
||||
{
|
||||
if ( last_encoding != bg->encoding )
|
||||
{
|
||||
biggest_x = x;
|
||||
printf("Glyph size problem: ");
|
||||
printf("encoding=%ld/0x%lx, ", bg->encoding, bg->encoding);
|
||||
printf("width=%d, height=%d, ", bg->bitmap_width, bg->bitmap_height);
|
||||
printf("requested position x=%d, y=%d (use BBX %d ...?)\n", x, y, x+1);
|
||||
last_encoding = bg->encoding;
|
||||
}
|
||||
else if ( biggest_x < x )
|
||||
{
|
||||
biggest_x = x;
|
||||
printf("Glyph size problem: ");
|
||||
printf("encoding=%ld/0x%lx, ", bg->encoding, bg->encoding);
|
||||
printf("width=%d, height=%d, ", bg->bitmap_width, bg->bitmap_height);
|
||||
printf("requested position x=%d, y=%d (use BBX %d ...?)\n", x, y, x+1);
|
||||
}
|
||||
}
|
||||
|
||||
assert( x < ((bg->bitmap_width+7)/8)*8 );
|
||||
assert( y < bg->bitmap_height );
|
||||
assert( x >= 0 );
|
||||
assert( y >= 0 );
|
||||
bg->bitmap_data[y*bg->bitmap_width + x] = value;
|
||||
}
|
||||
|
||||
int bg_GetBitmapPixel(bg_t *bg, int x, int y)
|
||||
{
|
||||
if ( x >= bg->bitmap_width )
|
||||
return 0;
|
||||
|
||||
if ( y >= bg->bitmap_height )
|
||||
return 0;
|
||||
if ( x < 0 )
|
||||
return 0;
|
||||
if ( y < 0 )
|
||||
return 0;
|
||||
|
||||
return bg->bitmap_data[y*bg->bitmap_width + x];
|
||||
}
|
||||
|
||||
/*
|
||||
Return a pixel with the provided bbx
|
||||
Coordinates are within the bbx.
|
||||
*/
|
||||
int bg_GetBBXPixel(bg_t *bg, int x, int y)
|
||||
{
|
||||
/* glyph rectangle */
|
||||
long glyph_x0, glyph_x1, glyph_y0, glyph_y1;
|
||||
|
||||
/* local bitmap coordinates */
|
||||
long bitmap_x, bitmap_y;
|
||||
|
||||
/* perform x offset alignment (used in BDF_BBX_MODE_HEIGHT mode only)*/
|
||||
x += bg->shift_x;
|
||||
|
||||
/* calculate the rectangle for the glyph */
|
||||
glyph_x0 = bg->bbx.x;
|
||||
glyph_y0 = bg->bbx.y;
|
||||
glyph_x1 = bg->bbx.x+bg->bbx.w;
|
||||
glyph_y1 = bg->bbx.y+bg->bbx.h;
|
||||
|
||||
if ( x < glyph_x0 )
|
||||
return 0;
|
||||
if ( x >= glyph_x1 )
|
||||
return 0;
|
||||
|
||||
if ( y < glyph_y0 )
|
||||
return 0;
|
||||
if ( y >= glyph_y1 )
|
||||
return 0;
|
||||
|
||||
bitmap_x = x - glyph_x0;
|
||||
bitmap_y = bg->bbx.h - 1 - ( y - glyph_y0);
|
||||
|
||||
return bg_GetBitmapPixel( bg, bitmap_x, bitmap_y );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void bg_ShowBitmap(bg_t *bg, bbx_t *bbx)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if ( bbx == NULL )
|
||||
bbx = &(bg->bbx);
|
||||
|
||||
printf("Encoding %ld, mapped to %ld, w=%ld, h=%ld, x=%ld, y=%ld\n", bg->encoding, bg->map_to, bg->bbx.w, bg->bbx.h, bg->bbx.x, bg->bbx.y);
|
||||
for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
|
||||
{
|
||||
printf("%03d ", y);
|
||||
for( x = bbx->x; x < bbx->x + bbx->w; x++)
|
||||
{
|
||||
if ( bg_GetBBXPixel(bg, x, y) == 0 )
|
||||
{
|
||||
printf(" .");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" #");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int bg_IsColZero(bg_t *bg, int x)
|
||||
{
|
||||
int y;
|
||||
for( y = 0; y < bg->bitmap_height; y++ )
|
||||
{
|
||||
if ( bg_GetBitmapPixel(bg, x, y) != 0 )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bg_IsRowZero(bg_t *bg, int y)
|
||||
{
|
||||
int x;
|
||||
for( x = 0; x < bg->bitmap_width; x++ )
|
||||
{
|
||||
if ( bg_GetBitmapPixel(bg, x, y) != 0 )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void bg_DeleteFirstCol(bg_t *bg)
|
||||
{
|
||||
int x,y;
|
||||
for( y = 0; y < bg->bitmap_height; y++ )
|
||||
for( x = 0; x+1 < bg->bitmap_width; x++ )
|
||||
{
|
||||
bg_SetBitmapPixel(bg, x, y, bg_GetBitmapPixel(bg, x+1, y));
|
||||
}
|
||||
}
|
||||
|
||||
void bg_DeleteFirstRow(bg_t *bg)
|
||||
{
|
||||
int x,y;
|
||||
for( y = 0; y+1 < bg->bitmap_height; y++ )
|
||||
for( x = 0; x < bg->bitmap_width; x++ )
|
||||
{
|
||||
bg_SetBitmapPixel(bg, x, y, bg_GetBitmapPixel(bg, x, y+1));
|
||||
}
|
||||
}
|
||||
|
||||
void bg_ReduceGlyph(bg_t *bg)
|
||||
{
|
||||
//long w;
|
||||
/* assign bitmap dimension (should be done already) */
|
||||
|
||||
//bg->bbx.w = bg->bitmap_width;
|
||||
//bg->bbx.h = bg->bitmap_height;
|
||||
|
||||
/* do not assign x,y because they are already set correctly */
|
||||
|
||||
//w = bg->bbx.w;
|
||||
|
||||
while( bg->bbx.w > 0 )
|
||||
{
|
||||
if ( bg_IsColZero(bg, bg->bbx.w-1) == 0 )
|
||||
break;
|
||||
bg->bbx.w--;
|
||||
}
|
||||
|
||||
while( bg->bbx.h > 0 )
|
||||
{
|
||||
if ( bg_IsRowZero(bg, bg->bbx.h-1) == 0 )
|
||||
break;
|
||||
bg->bbx.y++;
|
||||
bg->bbx.h--;
|
||||
}
|
||||
|
||||
while( bg->bbx.w > 0)
|
||||
{
|
||||
if ( bg_IsColZero(bg, 0) == 0 )
|
||||
break;
|
||||
bg_DeleteFirstCol(bg);
|
||||
bg->bbx.x++;
|
||||
bg->bbx.w--;
|
||||
}
|
||||
|
||||
while( bg->bbx.h > 0 )
|
||||
{
|
||||
if ( bg_IsRowZero(bg, 0) == 0 )
|
||||
break;
|
||||
bg_DeleteFirstRow(bg);
|
||||
bg->bbx.h--;
|
||||
}
|
||||
|
||||
/*
|
||||
problem: pixel width calculation failes, because a blank at
|
||||
the end is not calculated correctly.
|
||||
analysis:
|
||||
- bbx.w is reduced to 0
|
||||
- original bbx.w is sometimes identical to dwidth_x (6x10.bdf)
|
||||
or is 1 (helvR10.bdf)
|
||||
-the bdf file for helvR10.bdf does not contain any other information then
|
||||
delta x, so this should be used as bbx.w
|
||||
solution:
|
||||
Nothing done on the converter side, but handle this as a special case in the
|
||||
pixel width calculation
|
||||
|
||||
*/
|
||||
//if ( bg->bbx.w == 0 && bg->bbx.h == 0 )
|
||||
//{
|
||||
//printf("enc=%ld, new bbx,w=%ld, original width=%ld, dx=%ld\n", bg->encoding, bg->bbx.w, w, bg->dwidth_x);
|
||||
//printf("enc=%ld, new bbx.w=%ld, original width=%ld, dx=%ld\n", bg->encoding, bg->bbx.w, w, bg->dwidth_x);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
maximize the provided bbx so that the bbxof the glyph completly is covered by the max bbx
|
||||
*/
|
||||
int bg_Max(bg_t *bg, bbx_t *max)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
/* glyph rectangle */
|
||||
long glyph_x0, glyph_x1, glyph_y0, glyph_y1;
|
||||
|
||||
/* max rectangle */
|
||||
long max_x0, max_x1, max_y0, max_y1;
|
||||
|
||||
// printf("Encoding %ld, mapped to %ld, w=%ld, h=%ld, x=%ld, y=%ld\n", bg->encoding, bg->map_to, bg->bbx.w, bg->bbx.h, bg->bbx.x, bg->bbx.y);
|
||||
|
||||
|
||||
/* calculate the rectangle for the glyph */
|
||||
glyph_x0 = bg->bbx.x;
|
||||
glyph_y0 = bg->bbx.y;
|
||||
glyph_x1 = bg->bbx.x+bg->bbx.w;
|
||||
glyph_y1 = bg->bbx.y+bg->bbx.h;
|
||||
|
||||
/* calculate the rectangle for the max bbx */
|
||||
max_x0 = max->x;
|
||||
max_y0 = max->y;
|
||||
max_x1 = max->x+max->w;
|
||||
max_y1 = max->y+max->h;
|
||||
|
||||
/* maximize the max rectrangle so that the glyph rectangle full fits inside */
|
||||
if ( max_x0 > glyph_x0 )
|
||||
{
|
||||
max_x0 = glyph_x0;
|
||||
r = 3;
|
||||
}
|
||||
/* 28 Mar dwidth_x and x0???? */
|
||||
if ( max_x0 > bg->dwidth_x ) /* include dwidth_x into the box */
|
||||
{
|
||||
max_x0 = bg->dwidth_x; /* is this correct??? */
|
||||
r = 3;
|
||||
}
|
||||
|
||||
|
||||
if ( max_x1 < glyph_x1 )
|
||||
{
|
||||
r = 1;
|
||||
max_x1 = glyph_x1;
|
||||
}
|
||||
|
||||
if ( max_y0 > glyph_y0 )
|
||||
{
|
||||
r = 4;
|
||||
max_y0 = glyph_y0;
|
||||
}
|
||||
if ( max_y1 < glyph_y1 )
|
||||
{
|
||||
r = 2;
|
||||
max_y1 = glyph_y1;
|
||||
}
|
||||
|
||||
/* reconstruct the max bbx from the max rectangle */
|
||||
max->x = max_x0;
|
||||
max->y = max_y0;
|
||||
max->w = max_x1 - max->x;
|
||||
max->h = max_y1 - max->y;
|
||||
|
||||
return r;
|
||||
}
|
85
font/bdfconv/bdf_glyph.h
Normal file
85
font/bdfconv/bdf_glyph.h
Normal file
@ -0,0 +1,85 @@
|
||||
|
||||
|
||||
#ifndef _BDF_GLYPH_H
|
||||
#define _BDF_GLYPH_H
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* forward def */
|
||||
typedef struct _bdf_font_struct bf_t;
|
||||
|
||||
|
||||
struct _bbx_struct
|
||||
{
|
||||
long w;
|
||||
long h;
|
||||
long x;
|
||||
long y;
|
||||
};
|
||||
typedef struct _bbx_struct bbx_t;
|
||||
|
||||
|
||||
struct _bdf_glyph_struct
|
||||
{
|
||||
bf_t *bf;
|
||||
|
||||
long encoding;
|
||||
long map_to;
|
||||
|
||||
long dwidth_x;
|
||||
long dwidth_y;
|
||||
|
||||
bbx_t bbx; /* x,y are delta x,y from glyph, w,h start wth bitmap dimension, but may be reduced */
|
||||
long shift_x; /* extra shift for BDF_BBX_MODE_HEIGHT alignment */
|
||||
int is_excluded_from_kerning;
|
||||
|
||||
uint8_t *bitmap_data;
|
||||
int bitmap_width; /* the physical width within "bitmap_data", will be larger than or equal to bbx.w */
|
||||
int bitmap_height;
|
||||
|
||||
//int actual_bitmap_width; /* identical to bbx.w, maybe replace actual_bitmap_width by bbx.w */
|
||||
//int actual_bitmap_height; /* identical to bbx.h, maybe replace actual_bitmap_height by bbx.h */
|
||||
|
||||
uint8_t *target_data; /* if this is not NULL, then there is a valid glyph */
|
||||
int target_max; /* 32 bit value */
|
||||
int target_cnt; /* 32 bit value */
|
||||
int target_bit_pos;
|
||||
|
||||
/* rle data */
|
||||
|
||||
unsigned rle_bits_per_0;
|
||||
unsigned rle_bits_per_1;
|
||||
|
||||
int rle_is_first;
|
||||
unsigned rle_bitcnt;
|
||||
unsigned rle_last_0;
|
||||
unsigned rle_last_1;
|
||||
|
||||
long width_deviation; /* filled by bf_copy_bbx_and_update_shift for statistics */
|
||||
|
||||
};
|
||||
typedef struct _bdf_glyph_struct bg_t;
|
||||
|
||||
bg_t *bg_Open(void);
|
||||
void bg_Close(bg_t *bg);
|
||||
int bg_AddTargetData(bg_t *bg, uint8_t data);
|
||||
void bg_ClearTargetData(bg_t *bg);
|
||||
int bg_AddTargetBits(bg_t *bg, unsigned cnt, unsigned val);
|
||||
int bg_FlushTargetBits(bg_t *bg);
|
||||
|
||||
int bg_SetBitmapSizeInBytes(bg_t *bg, size_t bytes);
|
||||
int bg_SetBitmapSize(bg_t *bg, int w, int h);
|
||||
void bg_SetBitmapPixel(bg_t *bg, int x, int y, int value);
|
||||
int bg_GetBitmapPixel(bg_t *bg, int x, int y);
|
||||
int bg_GetBBXPixel(bg_t *bg, int x, int y);
|
||||
|
||||
void bg_ShowBitmap(bg_t *bg, bbx_t *bbx);
|
||||
void bg_ReduceGlyph(bg_t *bg);
|
||||
int bg_Max(bg_t *bg, bbx_t *max); /* returns idx which describes glyph expansion */
|
||||
|
||||
/* bdf_rle.c */
|
||||
int bg_rle_compress(bg_t *bg, bbx_t *bbx, unsigned rle_bits_per_0, unsigned rle_bits_per_1, int is_output);
|
||||
|
||||
|
||||
#endif
|
||||
|
217
font/bdfconv/bdf_kern.c
Normal file
217
font/bdfconv/bdf_kern.c
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
|
||||
bdf_kern.c
|
||||
|
||||
*/
|
||||
|
||||
#include "bdf_font.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define BDF_KERNING_MAX (1024*60)
|
||||
|
||||
/* the following tables contain the first encodings if they do contain any kernings */
|
||||
uint16_t bdf_first_table_cnt;
|
||||
uint16_t bdf_first_encoding_table[BDF_KERNING_MAX];
|
||||
uint16_t bdf_index_to_second_table[BDF_KERNING_MAX];
|
||||
|
||||
/* the index from bdf_index_to_second_table can be used to jump into the following table */
|
||||
uint16_t bdf_second_table_cnt;
|
||||
uint16_t bdf_second_encoding_table[BDF_KERNING_MAX];
|
||||
uint8_t bdf_kerning_values[BDF_KERNING_MAX];
|
||||
|
||||
/*
|
||||
struct u8g2_kerning
|
||||
{
|
||||
uint16_t first_table_cnt;
|
||||
uint16_t second_table_cnt;
|
||||
uint16_t *first_encoding_table;
|
||||
uint16_t *index_to_second_table;
|
||||
uin16_t *second_encoding_table;
|
||||
uint8_t *kerning_values;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static void bdf_write_uint16_array(FILE *fp, const char *pre, const char *post, uint16_t cnt, const uint16_t *a)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
fprintf(fp, "static const uint16_t %s_%s[%u] = {\n ", pre, post, cnt);
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
fprintf(fp, "%u", a[i]);
|
||||
if ( i+1 < cnt )
|
||||
{
|
||||
fprintf(fp, ", ");
|
||||
if ( i % 16 == 0 && i > 0 )
|
||||
{
|
||||
fprintf(fp, "\n ");
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(fp, "};\n");
|
||||
}
|
||||
|
||||
static void bdf_write_uint8_array(FILE *fp, const char *pre, const char *post, uint16_t cnt, const uint8_t *a)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
fprintf(fp, "static const uint8_t %s_%s[%u] = {\n ", pre, post, cnt);
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
fprintf(fp, "%u", a[i]);
|
||||
if ( i+1 < cnt )
|
||||
{
|
||||
fprintf(fp, ", ");
|
||||
if ( i % 16 == 0 && i > 0 )
|
||||
{
|
||||
fprintf(fp, "\n ");
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(fp, "};\n");
|
||||
}
|
||||
|
||||
|
||||
void bdf_write_kerning_file(const char *kernfile, const char *name)
|
||||
{
|
||||
FILE *fp;
|
||||
fp = fopen(kernfile, "w");
|
||||
|
||||
fprintf(fp, "/* %s, Size: %u Bytes */\n", name, bdf_first_table_cnt*4 + bdf_second_table_cnt*3 + 4 + 8); // size calculation for 16 bit controller
|
||||
bdf_write_uint16_array(fp, name, "first_encoding_table", bdf_first_table_cnt, bdf_first_encoding_table);
|
||||
bdf_write_uint16_array(fp, name, "index_to_second_table", bdf_first_table_cnt, bdf_index_to_second_table);
|
||||
bdf_write_uint16_array(fp, name, "second_encoding_table", bdf_second_table_cnt, bdf_second_encoding_table);
|
||||
bdf_write_uint8_array(fp, name, "kerning_values", bdf_second_table_cnt, bdf_kerning_values);
|
||||
|
||||
|
||||
fprintf(fp, "u8g2_kerning_t %s_k = {\n", name);
|
||||
fprintf(fp, " %u, %u,\n", bdf_first_table_cnt, bdf_second_table_cnt);
|
||||
fprintf(fp, " %s_%s,\n", name, "first_encoding_table");
|
||||
fprintf(fp, " %s_%s,\n", name, "index_to_second_table");
|
||||
fprintf(fp, " %s_%s,\n", name, "second_encoding_table");
|
||||
fprintf(fp, " %s_%s};\n\n", name, "kerning_values");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
assumes
|
||||
tga_set_font(font);
|
||||
and
|
||||
tga_init((tga_get_char_width()+16)*3, ((tga_get_char_height()+8)*2));
|
||||
is called before
|
||||
*/
|
||||
static int bdf_is_glyph_overlap(uint8_t *font, uint16_t e1, uint16_t e2, uint8_t kerning_test, int is_save)
|
||||
{
|
||||
unsigned int x, y;
|
||||
tga_clear();
|
||||
|
||||
x = 8;
|
||||
y = tga_get_char_height();
|
||||
x += tga_draw_glyph(x, y, e1, 0);
|
||||
x -= kerning_test;
|
||||
tga_clear_pixel_intersection();
|
||||
x += tga_draw_glyph(x, y, e2, 0);
|
||||
|
||||
if ( is_save )
|
||||
{
|
||||
//char buf[64];
|
||||
//sprintf(buf, "glyph_intersection_%u_%u_%u.tga", e1, e2, kerning_test);
|
||||
//tga_save(buf);
|
||||
}
|
||||
|
||||
return tga_is_pixel_intersection();
|
||||
}
|
||||
|
||||
unsigned bdf_calculate_kerning(uint8_t *font, uint16_t e1, uint16_t e2, uint8_t min_distance_in_per_cent_of_char_width)
|
||||
{
|
||||
uint8_t upper_bound;
|
||||
uint8_t kerning;
|
||||
uint8_t min_distance_in_pixel;
|
||||
|
||||
|
||||
tga_set_font(font);
|
||||
tga_init((tga_get_char_width()+16)*3, ((tga_get_char_height()+8)*2));
|
||||
|
||||
min_distance_in_pixel = ((unsigned)tga_get_char_width()*(unsigned)min_distance_in_per_cent_of_char_width) / 100;
|
||||
upper_bound = tga_get_char_width();
|
||||
for( kerning = 0; kerning < upper_bound; kerning++ )
|
||||
{
|
||||
if ( bdf_is_glyph_overlap(font, e1, e2, kerning, 0) != 0 )
|
||||
break;
|
||||
}
|
||||
if ( kerning >= upper_bound )
|
||||
kerning = 0; /* maybe "." compared against "-" */
|
||||
if ( kerning < min_distance_in_pixel )
|
||||
kerning = 0;
|
||||
else
|
||||
kerning -= min_distance_in_pixel;
|
||||
|
||||
if ( kerning != 0 )
|
||||
{
|
||||
bdf_is_glyph_overlap(font, e1, e2, kerning, 1);
|
||||
//printf("bdf_calculate_kerning %u %u ", e1, e2);
|
||||
//printf("result: %d\n", kerning);
|
||||
}
|
||||
return kerning;
|
||||
}
|
||||
|
||||
void bdf_calculate_all_kerning(bf_t *bf, const char *filename, const char *fontname, uint8_t min_distance_in_per_cent_of_char_width)
|
||||
{
|
||||
int first, second;
|
||||
bg_t *bg_first;
|
||||
bg_t *bg_second;
|
||||
uint8_t kerning;
|
||||
int is_first_encoding_added;
|
||||
|
||||
|
||||
bdf_first_table_cnt = 0;
|
||||
bdf_second_table_cnt = 0;
|
||||
|
||||
for( first= 0; first < bf->glyph_cnt; first++ )
|
||||
{
|
||||
is_first_encoding_added = 0;
|
||||
bg_first = bf->glyph_list[first];
|
||||
if ( bg_first->target_data != NULL && bg_first->is_excluded_from_kerning == 0 )
|
||||
{
|
||||
for( second= 0; second < bf->glyph_cnt; second++ )
|
||||
{
|
||||
bg_second = bf->glyph_list[second];
|
||||
if ( bg_second->target_data != NULL && bg_second->is_excluded_from_kerning == 0 )
|
||||
{
|
||||
kerning = bdf_calculate_kerning(bf->target_data, bg_first->encoding, bg_second->encoding, min_distance_in_per_cent_of_char_width);
|
||||
if ( kerning > 1 )
|
||||
{
|
||||
if ( is_first_encoding_added == 0 )
|
||||
{
|
||||
bdf_first_encoding_table[bdf_first_table_cnt] = bg_first->encoding;
|
||||
bdf_index_to_second_table[bdf_first_table_cnt] = bdf_second_table_cnt;
|
||||
bdf_first_table_cnt++;
|
||||
if (bdf_first_table_cnt > BDF_KERNING_MAX)
|
||||
{
|
||||
fprintf(stderr, "Kerning calculation aborted: bdf_first_table_cnt > BDF_KERNING_MAX\n");
|
||||
return;
|
||||
}
|
||||
is_first_encoding_added = 1;
|
||||
}
|
||||
bdf_second_encoding_table[bdf_second_table_cnt] = bg_second->encoding;
|
||||
bdf_kerning_values[bdf_second_table_cnt] = kerning;
|
||||
bdf_second_table_cnt++;
|
||||
if (bdf_second_table_cnt > BDF_KERNING_MAX)
|
||||
{
|
||||
fprintf(stderr, "Kerning calculation aborted: bdf_second_table_cnt > BDF_KERNING_MAX\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* add a final entry for more easier calculation in u8g2 */
|
||||
bdf_first_encoding_table[bdf_first_table_cnt] = 0x0ffff;
|
||||
bdf_index_to_second_table[bdf_first_table_cnt] = bdf_second_table_cnt;
|
||||
bdf_first_table_cnt++;
|
||||
|
||||
bdf_write_kerning_file(filename, fontname);
|
||||
}
|
||||
|
323
font/bdfconv/bdf_map.c
Normal file
323
font/bdfconv/bdf_map.c
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
bdf_map.c
|
||||
|
||||
select and map glyphs
|
||||
|
||||
Syntax:
|
||||
maplist := <mapcmd> { "," <mapcmd> }
|
||||
mapcmd := <default> | <maprange> | <exclude>
|
||||
default := "*"
|
||||
maprange := <range> [ ">" <num> ]
|
||||
exclude := "~" <range>
|
||||
kern_exclude := "x" <range>
|
||||
range := <num> [ "-" <num> ]
|
||||
num := <hexnum> | <decnum>
|
||||
hexnum := "$" <hexdigit> { <hexdigit> }
|
||||
decnum := <decdigit> { <decdigit> }
|
||||
decdigit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
|
||||
hexdigit := "a" | "b" | "c" | "d" | "e" | "f" | "A" | "B" | "C" | "D" | "E" | "F" | <decdigit>
|
||||
|
||||
{ }: zero, one ore more
|
||||
[ ]: zero or once
|
||||
|: alternative
|
||||
|
||||
*/
|
||||
|
||||
#include "bdf_font.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static long range_from;
|
||||
static long range_to;
|
||||
static int is_exclude;
|
||||
static int is_kern_exclude;
|
||||
static long map_to;
|
||||
|
||||
static void skip_space(const char **s)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if ( **s == '\0' )
|
||||
break;
|
||||
if ( **s > ' ' )
|
||||
break;
|
||||
(*s)++;
|
||||
}
|
||||
}
|
||||
|
||||
static long get_dec(const char **s)
|
||||
{
|
||||
long v = 0;
|
||||
for(;;)
|
||||
{
|
||||
if ( (**s) >= '0' && (**s) <= '9' )
|
||||
{
|
||||
v*=10;
|
||||
v+= (**s)-'0';
|
||||
(*s)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
skip_space(s);
|
||||
return v;
|
||||
}
|
||||
|
||||
static long get_hex(const char **s)
|
||||
{
|
||||
long v = 0;
|
||||
for(;;)
|
||||
{
|
||||
if ( (**s) >= '0' && (**s) <= '9' )
|
||||
{
|
||||
v*=16;
|
||||
v+= (**s)-'0';
|
||||
(*s)++;
|
||||
}
|
||||
else if ( (**s) >= 'a' && (**s) <= 'f' )
|
||||
{
|
||||
v*=16;
|
||||
v+= (**s)-'a'+10;
|
||||
(*s)++;
|
||||
}
|
||||
else if ( (**s) >= 'A' && (**s) <= 'F' )
|
||||
{
|
||||
v*=16;
|
||||
v+= (**s)-'A'+10;
|
||||
(*s)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
skip_space(s);
|
||||
return v;
|
||||
}
|
||||
|
||||
static long get_num(const char **s)
|
||||
{
|
||||
if ( (**s) != '$' )
|
||||
return get_dec(s);
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
return get_hex(s);
|
||||
}
|
||||
|
||||
static long get_mul(const char **s)
|
||||
{
|
||||
long v;
|
||||
v = get_num(s);
|
||||
while ( (**s) == '*' )
|
||||
{
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
v *= get_num(s);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static long get_add(const char **s)
|
||||
{
|
||||
long v;
|
||||
v = get_mul(s);
|
||||
while ( (**s) == '+' )
|
||||
{
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
v += get_mul(s);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static long get_addsub(const char **s)
|
||||
{
|
||||
long v;
|
||||
int op;
|
||||
v = get_mul(s);
|
||||
while ( (**s) == '+' || (**s) == '-' )
|
||||
{
|
||||
op = **s;
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
if ( op == '+' )
|
||||
v += get_mul(s);
|
||||
else
|
||||
v -= get_mul(s);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static void get_range(const char **s)
|
||||
{
|
||||
range_from = get_add(s);
|
||||
if ( **s != '-' )
|
||||
{
|
||||
range_to = range_from;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
range_to = get_add(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void map_cmd(const char **s)
|
||||
{
|
||||
if ( **s == '*' )
|
||||
{
|
||||
range_from = 32;
|
||||
range_to = 255;
|
||||
map_to = 32;
|
||||
is_exclude = 0;
|
||||
is_kern_exclude = 0;
|
||||
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
}
|
||||
else if ( **s == '~' )
|
||||
{
|
||||
is_exclude = 1;
|
||||
map_to = 0; /*will be ignored */
|
||||
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
get_range(s);
|
||||
|
||||
}
|
||||
else if ( **s == 'x' )
|
||||
{
|
||||
is_kern_exclude = 1;
|
||||
map_to = 0; /*will be ignored */
|
||||
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
get_range(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
is_exclude = 0;
|
||||
get_range(s);
|
||||
map_to = range_from;
|
||||
if ( **s == '>')
|
||||
{
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
map_to = get_addsub(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bf_map_cmd(bf_t *bf, const char **s)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
static int is_log_disabled_for_single_glyphs = 0;
|
||||
|
||||
if ( **s == ',' || **s == '\0' )
|
||||
return;
|
||||
|
||||
map_cmd(s);
|
||||
|
||||
|
||||
if ( range_from != range_to )
|
||||
{
|
||||
bf_Log(bf, "Map: exclude=%d from=%ld/$%lx to=%ld/$%lx map=%ld/$%lx", is_exclude, range_from, range_from, range_to, range_to, map_to, map_to);
|
||||
}
|
||||
else if ( is_log_disabled_for_single_glyphs == 0 )
|
||||
{
|
||||
bf_Log(bf, "Map: exclude=%d from=%ld/$%lx to=%ld/$%lx map=%ld/$%lx (further single glyph logs disabled)", is_exclude, range_from, range_from, range_to, range_to, map_to, map_to);
|
||||
is_log_disabled_for_single_glyphs = 1;
|
||||
}
|
||||
|
||||
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->encoding >= range_from && bg->encoding <= range_to )
|
||||
{
|
||||
if ( is_kern_exclude != 0 )
|
||||
{
|
||||
bg->is_excluded_from_kerning = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( is_exclude != 0 )
|
||||
{
|
||||
bg->map_to = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg->map_to = bg->encoding - range_from + map_to;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void bf_map_list(bf_t *bf, const char **s)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
|
||||
/* exclude everything first */
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
bg->map_to = -1;
|
||||
}
|
||||
|
||||
/* process the mapping list list */
|
||||
skip_space(s);
|
||||
for(;;)
|
||||
{
|
||||
bf_map_cmd(bf, s);
|
||||
if ( **s != ',' )
|
||||
break;
|
||||
(*s)++;
|
||||
skip_space(s);
|
||||
}
|
||||
}
|
||||
|
||||
void bf_Map(bf_t *bf, const char *map_cmd_list)
|
||||
{
|
||||
if ( strlen(map_cmd_list) < 1024 )
|
||||
bf_Log(bf, "Map: map_cmd_list='%s'", map_cmd_list);
|
||||
bf_map_list(bf, &map_cmd_list);
|
||||
}
|
||||
|
||||
int bf_MapFile(bf_t *bf, const char *map_file_name)
|
||||
{
|
||||
struct stat buf;
|
||||
char *s;
|
||||
FILE *fp;
|
||||
if ( map_file_name == NULL )
|
||||
return 1;
|
||||
if ( map_file_name[0] == '\0' )
|
||||
return 1;
|
||||
|
||||
|
||||
if ( stat(map_file_name, &buf) != 0 )
|
||||
return 0;
|
||||
fp = fopen(map_file_name, "r");
|
||||
if ( fp == NULL )
|
||||
return 0;
|
||||
s = malloc(buf.st_size+1);
|
||||
if ( s == NULL )
|
||||
return 0;
|
||||
fread(s, buf.st_size, 1, fp);
|
||||
s[buf.st_size] = '\0';
|
||||
fclose(fp);
|
||||
bf_Map(bf, s);
|
||||
free(s);
|
||||
return 1;
|
||||
}
|
||||
|
478
font/bdfconv/bdf_parser.c
Normal file
478
font/bdfconv/bdf_parser.c
Normal file
@ -0,0 +1,478 @@
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bdf_font.h"
|
||||
|
||||
static int bf_curr(bf_t * bf)
|
||||
{
|
||||
if ( bf->line_pos >= BDF_LINE_LEN )
|
||||
return '\0';
|
||||
return bf->line_buf[bf->line_pos];
|
||||
}
|
||||
|
||||
static void bf_next(bf_t *bf)
|
||||
{
|
||||
if ( bf_curr(bf) == '\0' )
|
||||
return;
|
||||
if ( bf->line_pos >= BDF_LINE_LEN )
|
||||
return;
|
||||
bf->line_pos++;
|
||||
}
|
||||
|
||||
static void bf_skipspace(bf_t *bf)
|
||||
{
|
||||
int c;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
c = bf_curr(bf);
|
||||
if ( c == '\0' )
|
||||
return;
|
||||
if ( c > ' ' )
|
||||
return;
|
||||
bf_next(bf);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *bf_get_identifier(bf_t *bf)
|
||||
{
|
||||
static char buf[BDF_LINE_LEN];
|
||||
int c;
|
||||
int i = 0;
|
||||
buf[0] = '\0';
|
||||
for(;;)
|
||||
{
|
||||
c = bf_curr(bf);
|
||||
if ( c <= ' ' )
|
||||
break;
|
||||
if ( i >= BDF_LINE_LEN-2 )
|
||||
break;
|
||||
buf[i++] = c;
|
||||
buf[i] = '\0';
|
||||
bf_next(bf);
|
||||
}
|
||||
bf_skipspace(bf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char *bf_get_string(bf_t *bf)
|
||||
{
|
||||
static char buf[BDF_LINE_LEN];
|
||||
int i = 0;
|
||||
int c;
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
if ( bf_curr(bf) != '\"' )
|
||||
return bf_get_identifier(bf);
|
||||
|
||||
bf_next(bf);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
c = bf_curr(bf);
|
||||
if ( c == '\0' )
|
||||
break;
|
||||
if ( c == '\"' )
|
||||
break;
|
||||
if ( i >= BDF_LINE_LEN-2 )
|
||||
break;
|
||||
if ( c != '\r' && c != '\n' ) /* skip \r and \n, see https://github.com/olikraus/u8g2/pull/1361, https://github.com/olikraus/u8g2/issues/1379 */
|
||||
{
|
||||
buf[i++] = c;
|
||||
buf[i] = '\0';
|
||||
}
|
||||
bf_next(bf);
|
||||
}
|
||||
if ( bf_curr(bf) == '\"' )
|
||||
bf_next(bf);
|
||||
|
||||
bf_skipspace(bf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char *bf_get_eol_string(bf_t *bf)
|
||||
{
|
||||
static char buf[BDF_LINE_LEN];
|
||||
int i = 0;
|
||||
int c;
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
if ( bf_curr(bf) == '\"' )
|
||||
return bf_get_string(bf);
|
||||
//bf_next(bf);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
c = bf_curr(bf);
|
||||
if ( c == '\0' )
|
||||
break;
|
||||
if ( c == '\n' || c == '\r' )
|
||||
break;
|
||||
if ( i >= BDF_LINE_LEN-2 )
|
||||
break;
|
||||
buf[i++] = c;
|
||||
buf[i] = '\0';
|
||||
bf_next(bf);
|
||||
}
|
||||
|
||||
bf_skipspace(bf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static long bf_get_long(bf_t *bf)
|
||||
{
|
||||
int c;
|
||||
long v = 0;
|
||||
long sign = 1;
|
||||
|
||||
if ( bf_curr(bf) == '-' )
|
||||
{
|
||||
sign = -1;
|
||||
bf_next(bf);
|
||||
bf_skipspace(bf);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
c = bf_curr(bf);
|
||||
if ( c < '0' )
|
||||
break;
|
||||
if ( c > '9' )
|
||||
break;
|
||||
v *= 10L;
|
||||
v += (long)(c-'0');
|
||||
bf_next(bf);
|
||||
}
|
||||
bf_skipspace(bf);
|
||||
|
||||
return v*sign;
|
||||
}
|
||||
|
||||
/*
|
||||
static long bf_get_mul(bf_t *bf)
|
||||
{
|
||||
long v;
|
||||
v = bf_get_long(bf);
|
||||
if ( bf_curr(bf) == '*' )
|
||||
{
|
||||
bf_next(bf);
|
||||
bf_skipspace(bf);
|
||||
v *= bf_get_long(bf);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static long bf_get_add(bf_t *bf)
|
||||
{
|
||||
long v;
|
||||
v = bf_get_mul(bf);
|
||||
if ( bf_curr(bf) == '+' )
|
||||
{
|
||||
bf_next(bf);
|
||||
bf_skipspace(bf);
|
||||
v += bf_get_mul(bf);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static int bf_add_glyph_to_list(bf_t *bf)
|
||||
{
|
||||
bg_t *bg;
|
||||
bf->glyph_pos = bf_AddGlyph(bf);
|
||||
if ( bf->glyph_pos < 0 )
|
||||
{
|
||||
bf_Error(bf, "Can not add glyph (memory error?)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bg = bf->glyph_list[bf->glyph_pos];
|
||||
|
||||
/* copy the values from the parser to the glyph record */
|
||||
bg->encoding = bf->encoding;
|
||||
bg->dwidth_x = bf->dwidth_x;
|
||||
bg->dwidth_y = bf->dwidth_y;
|
||||
bg->bbx.w = bf->bbx_w;
|
||||
bg->bbx.h = bf->bbx_h;
|
||||
bg->bbx.x = bf->bbx_x;
|
||||
bg->bbx.y = bf->bbx_y;
|
||||
|
||||
if ( bg_SetBitmapSize(bg, bf->bbx_w, bf->bbx_h) == 0 )
|
||||
{
|
||||
bf_Error(bf, "Can not create bitmap (memory error?)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bg->bitmap_width = bf->bbx_w;
|
||||
bg->bitmap_height = bf->bbx_h;
|
||||
|
||||
// bg->actual_bitmap_width = bf->bbx_w;
|
||||
// bg->actual_bitmap_height = bf->bbx_h;
|
||||
|
||||
//bf_Log(bf, "BDF File: Create glyph glyph_pos=%d bbx_w=%d bbx_h=%d bbx_x=%d bbx_y=%d", bf->glyph_pos, bf->bbx_w, bf->bbx_h, bf->bbx_x, bf->bbx_y);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void bf_set_pixel_by_halfbyte(bf_t *bf, int halfbyte)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
|
||||
assert( bf->glyph_list != NULL );
|
||||
|
||||
bg = bf->glyph_list[bf->glyph_pos];
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( (halfbyte & 8) != 0 )
|
||||
{
|
||||
bg_SetBitmapPixel(bg, bf->bitmap_x, bf->bitmap_y, 1);
|
||||
}
|
||||
halfbyte<<=1;
|
||||
bf->bitmap_x++;
|
||||
}
|
||||
}
|
||||
|
||||
static void bf_set_pixel_by_hex_char(bf_t *bf, int hex)
|
||||
{
|
||||
if ( hex >= '0' && hex <= '9' )
|
||||
return bf_set_pixel_by_halfbyte(bf, hex-'0');
|
||||
if ( hex >= 'a' && hex <= 'f' )
|
||||
return bf_set_pixel_by_halfbyte(bf, hex-'a'+10);
|
||||
if ( hex >= 'A' && hex <= 'F' )
|
||||
return bf_set_pixel_by_halfbyte(bf, hex-'A'+10);
|
||||
return bf_set_pixel_by_halfbyte(bf, 0);
|
||||
}
|
||||
|
||||
static int bf_parse_line(bf_t *bf)
|
||||
{
|
||||
static char cmd[BDF_LINE_LEN];
|
||||
|
||||
bf->line_pos = 0;
|
||||
bf_skipspace(bf);
|
||||
|
||||
if ( bf->is_bitmap_parsing == 0 )
|
||||
{
|
||||
/* regular command */
|
||||
bf->bitmap_y = 0;
|
||||
strcpy(cmd, bf_get_string(bf));
|
||||
|
||||
if ( strcmp(cmd, "" ) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if ( strcmp(cmd, "STARTFONT" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "FONT" ) == 0 ) /* args: s */
|
||||
{
|
||||
if ( bf->str_font != NULL )
|
||||
free(bf->str_font);
|
||||
bf->str_font = strdup(bf_get_eol_string(bf));
|
||||
}
|
||||
else if ( strcmp(cmd, "SIZE" ) == 0 ) /* args: lll */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "FONTBOUNDINGBOX" ) == 0 ) /* args: llll */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "STARTPROPERTIES" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "FONTNAME_REGISTRY" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "FOUNDRY" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "FAMILY_NAME" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "WEIGHT_NAME" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "SLANT" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "SETWIDTH_NAME" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "ADD_STYLE_NAME" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "PIXEL_SIZE" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "POINT_SIZE" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "RESOLUTION_X" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "RESOLUTION_Y" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "SPACING" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "AVERAGE_WIDTH" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "CHARSET_REGISTRY" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "CHARSET_ENCODING" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "DESTINATION" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "COPYRIGHT" ) == 0 ) /* args: s */
|
||||
{
|
||||
if ( bf->str_copyright != NULL )
|
||||
free(bf->str_copyright);
|
||||
bf->str_copyright = strdup(bf_get_eol_string(bf));
|
||||
}
|
||||
else if ( strcmp(cmd, "_XMBDFED_INFO" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "CAP_HEIGHT" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "X_HEIGHT" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "WEIGHT" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "QUAD_WIDTH" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "DEFAULT_CHAR" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "FONT_DESCENT" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "FONT_ASCENT" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "ENDPROPERTIES" ) == 0 ) /* args: - */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "CHARS" ) == 0 ) /* args: l */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "STARTCHAR" ) == 0 ) /* args: s */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "ENCODING" ) == 0 ) /* args: l */
|
||||
{
|
||||
bf->encoding = bf_get_long(bf);
|
||||
//bf_Log(bf, "BDF File: ENCODING %d", bf->encoding);
|
||||
}
|
||||
else if ( strcmp(cmd, "SWIDTH" ) == 0 ) /* args: ll */
|
||||
{
|
||||
}
|
||||
else if ( strcmp(cmd, "DWIDTH" ) == 0 ) /* args: ll */
|
||||
{
|
||||
bf->dwidth_x = bf_get_long(bf);
|
||||
bf->dwidth_y = bf_get_long(bf);
|
||||
|
||||
}
|
||||
else if ( strcmp(cmd, "BBX" ) == 0 ) /* args: llll */
|
||||
{
|
||||
bf->bbx_w = bf_get_long(bf);
|
||||
bf->bbx_h = bf_get_long(bf);
|
||||
bf->bbx_x = bf_get_long(bf);
|
||||
bf->bbx_y = bf_get_long(bf);
|
||||
}
|
||||
else if ( strcmp(cmd, "BITMAP" ) == 0 ) /* args: - */
|
||||
{
|
||||
if ( bf_add_glyph_to_list(bf) == 0 )
|
||||
return 0;
|
||||
bf->is_bitmap_parsing = 1;
|
||||
}
|
||||
else if ( strcmp(cmd, "ENDCHAR" ) == 0 ) /* args: - */
|
||||
{
|
||||
bf_Error(bf, "Unexpected ENDCHAR found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* a line of the glyph bitmap */
|
||||
int c;
|
||||
strcpy(cmd, bf_get_string(bf));
|
||||
if ( cmd[0] != '\0' )
|
||||
{
|
||||
if ( strcmp(cmd, "ENDCHAR" ) == 0 ) /* args: - */
|
||||
{
|
||||
bf->is_bitmap_parsing = 0;
|
||||
/* bg_ShowBitmap(bf->glyph_list[bf->glyph_pos]); */
|
||||
}
|
||||
else
|
||||
{
|
||||
bf->line_pos = 0;
|
||||
bf_skipspace(bf);
|
||||
|
||||
|
||||
bf->bitmap_x = 0;
|
||||
|
||||
|
||||
for(;;)
|
||||
{
|
||||
c = bf_curr(bf);
|
||||
if ( c < '0' )
|
||||
break;
|
||||
bf_set_pixel_by_hex_char(bf, c);
|
||||
bf_next(bf);
|
||||
}
|
||||
|
||||
bf->bitmap_y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bf_parse_file(bf_t *bf)
|
||||
{
|
||||
long line_cnt = 0;
|
||||
bf->is_bitmap_parsing = 0;
|
||||
for(;;)
|
||||
{
|
||||
line_cnt++;
|
||||
if ( fgets(bf->line_buf, BDF_LINE_LEN, bf->fp) == NULL )
|
||||
break;
|
||||
if ( bf_parse_line(bf) == 0 )
|
||||
{
|
||||
bf_Error(bf, "perse error in line %ld", line_cnt);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bf_ParseFile(bf_t *bf, const char *name)
|
||||
{
|
||||
int r;
|
||||
bf->fp = fopen(name, "r");
|
||||
if ( bf->fp == NULL )
|
||||
{
|
||||
bf_Error(bf, "Can not open bdf file '%s'", name);
|
||||
return 0;
|
||||
}
|
||||
r = bf_parse_file(bf);
|
||||
fclose(bf->fp);
|
||||
bf_Log(bf, "Parse File %s: %d glyph(s) found", name, bf->glyph_cnt);
|
||||
return r;
|
||||
}
|
||||
|
932
font/bdfconv/bdf_rle.c
Normal file
932
font/bdfconv/bdf_rle.c
Normal file
@ -0,0 +1,932 @@
|
||||
/*
|
||||
|
||||
bdf_rle.c
|
||||
|
||||
run length glyph encoding
|
||||
|
||||
|
||||
size comparison with old and new font format
|
||||
4x6 1500 1469
|
||||
4x6r 734 726
|
||||
6x10 1866 2009
|
||||
6x10r 889 971
|
||||
7x13B 2172 2253
|
||||
7x13Br 1041 1017
|
||||
9x15 2959 2649
|
||||
9x15r 1427 1242
|
||||
10x20 3453 3053
|
||||
10x20r 1667 1417 85%
|
||||
courB12 3959 3312
|
||||
courB12r 1857 1538
|
||||
courB24 10502 6661
|
||||
courB24r 4775 3015 63%
|
||||
helvB24 10931 6904 63%
|
||||
helvB24r 4992 3166 63%
|
||||
logisoso50r 14375 5248 36%
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/* font information */
|
||||
/*
|
||||
glyph_cnt = *font++;
|
||||
bits_per_0 = *font++;
|
||||
bits_per_1 = *font++;
|
||||
bits_per_char_width = *font++;
|
||||
bits_per_char_height = *font++;
|
||||
bits_per_char_x = *font++;
|
||||
bits_per_char_y = *font++;
|
||||
bits_per_delta_x = *font++;
|
||||
|
||||
*/
|
||||
|
||||
/* apply glyph information */
|
||||
/*
|
||||
~ encoding unsigned, 1 or 2 byte (high byte first in two byte version)
|
||||
~ total size unsigned, 1 byte
|
||||
~ BBX width unsigned 5
|
||||
~ BBX height unsigned 5
|
||||
~ BBX xoffset signed 2
|
||||
~ BBX yoffset signed 5
|
||||
~ DWIDTH unsigned 3
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#define BDF_RLE_FONT_GLYPH_START 23
|
||||
|
||||
/* max glyphs count is around 7500, 7500/100 = 75 */
|
||||
/* changed 100 to 101 due to off by one error in the code and in order to keep the current binary data identical https://github.com/olikraus/u8g2/issues/1521 */
|
||||
#define UNICODE_GLYPHS_PER_LOOKUP_TABLE_ENTRY 101
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include "bdf_font.h"
|
||||
|
||||
#ifdef OLD_CODE
|
||||
|
||||
#define SCREEN_W 140
|
||||
#define SCREEN_H 140
|
||||
|
||||
uint8_t screen_buf[SCREEN_H][SCREEN_W];
|
||||
unsigned screen_max_y;
|
||||
|
||||
void screen_init(void)
|
||||
{
|
||||
unsigned x, y;
|
||||
screen_max_y = 0;
|
||||
for( y = 0; y < SCREEN_H; y++ )
|
||||
{
|
||||
for( x = 0; x < SCREEN_W; x++ )
|
||||
{
|
||||
screen_buf[y][x] = '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void screen_set_pixel(unsigned x, unsigned y, uint8_t c)
|
||||
{
|
||||
if ( screen_max_y < y)
|
||||
screen_max_y = y;
|
||||
screen_buf[y][x] = c;
|
||||
}
|
||||
|
||||
void screen_show(void)
|
||||
{
|
||||
unsigned x, y;
|
||||
printf("\n");
|
||||
for( y = 0; y <= screen_max_y; y++ )
|
||||
{
|
||||
for( x = 0; x < SCREEN_W; x++ )
|
||||
{
|
||||
printf("%c", screen_buf[y][x]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*===================================================*/
|
||||
|
||||
/* font decode */
|
||||
struct fd_struct
|
||||
{
|
||||
unsigned x; /* local coordinates, (0,0) is upper left */
|
||||
unsigned y;
|
||||
unsigned glyph_width;
|
||||
unsigned glyph_height;
|
||||
|
||||
|
||||
const uint8_t *decode_ptr; /* pointer to the compressed data */
|
||||
unsigned decode_bit_pos; /* bitpos inside a byte of the compressed data */
|
||||
|
||||
uint8_t bbx_x_max_bit_size;
|
||||
uint8_t bbx_y_max_bit_size;
|
||||
uint8_t bbx_w_max_bit_size;
|
||||
uint8_t bbx_h_max_bit_size;
|
||||
uint8_t dx_max_bit_size;
|
||||
|
||||
};
|
||||
typedef struct fd_struct fd_t;
|
||||
|
||||
/* increment x and consider line wrap (inc y)*/
|
||||
static void fd_inc(fd_t *f)
|
||||
{
|
||||
unsigned x = f->x;
|
||||
x++;
|
||||
if ( x == f->glyph_width )
|
||||
{
|
||||
x = 0;
|
||||
f->y++;
|
||||
}
|
||||
f->x = x;
|
||||
}
|
||||
|
||||
|
||||
static unsigned fd_get_unsigned_bits(fd_t *f, unsigned cnt)
|
||||
{
|
||||
unsigned val;
|
||||
unsigned bit_pos = f->decode_bit_pos;
|
||||
|
||||
val = *(f->decode_ptr);
|
||||
|
||||
val >>= bit_pos;
|
||||
if ( bit_pos + cnt >= 8 )
|
||||
{
|
||||
f->decode_ptr++;
|
||||
val |= *(f->decode_ptr) << (8-bit_pos);
|
||||
bit_pos -= 8;
|
||||
}
|
||||
val &= (1U<<cnt)-1;
|
||||
bit_pos += cnt;
|
||||
|
||||
f->decode_bit_pos = bit_pos;
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
2 bit --> cnt = 2
|
||||
-2,-1,0. 1
|
||||
|
||||
3 bit --> cnt = 3
|
||||
-2,-1,0. 1
|
||||
-4,-3,-2,-1,0,1,2,3
|
||||
|
||||
if ( x < 0 )
|
||||
r = bits(x-1)+1;
|
||||
else
|
||||
r = bits(x)+1;
|
||||
|
||||
*/
|
||||
static int fd_get_signed_bits(fd_t *t, int cnt)
|
||||
{
|
||||
return (int)fd_get_unsigned_bits(t, cnt) - ((1<<cnt)>>1);
|
||||
}
|
||||
|
||||
|
||||
static void fd_draw_pixel(fd_t *f)
|
||||
{
|
||||
screen_set_pixel(f->x, f->y, '#');
|
||||
}
|
||||
|
||||
static void fd_decode(bg_t *bg, bbx_t *bbx, fd_t *f, unsigned rle_bits_per_0, unsigned rle_bits_per_1)
|
||||
{
|
||||
unsigned a, b;
|
||||
unsigned i;
|
||||
|
||||
screen_init();
|
||||
|
||||
if ( bbx == NULL )
|
||||
bbx = &(bg->bbx);
|
||||
|
||||
/* init decode algorithm */
|
||||
f->decode_ptr = bg->target_data;
|
||||
f->decode_bit_pos = 0;
|
||||
f->glyph_width = bbx->w;
|
||||
f->glyph_height = bbx->h;
|
||||
|
||||
|
||||
/* read glyph info */
|
||||
f->decode_ptr += 2;
|
||||
|
||||
fd_get_unsigned_bits(f, f->bbx_w_max_bit_size);
|
||||
fd_get_unsigned_bits(f, f->bbx_h_max_bit_size);
|
||||
fd_get_signed_bits(f, f->bbx_x_max_bit_size);
|
||||
fd_get_signed_bits(f, f->bbx_y_max_bit_size);
|
||||
fd_get_signed_bits(f, f->dx_max_bit_size);
|
||||
|
||||
/* reset local x/y position */
|
||||
f->x = 0;
|
||||
f->y = 0;
|
||||
|
||||
//puts("");
|
||||
|
||||
/* decode glyph */
|
||||
for(;;)
|
||||
{
|
||||
a = fd_get_unsigned_bits(f, rle_bits_per_0);
|
||||
b = fd_get_unsigned_bits(f, rle_bits_per_1);
|
||||
//printf("[%u %u]", a, b);
|
||||
do
|
||||
{
|
||||
for( i = 0; i < a; i++ )
|
||||
{
|
||||
fd_inc(f);
|
||||
}
|
||||
|
||||
for( i = 0; i < b; i++ )
|
||||
{
|
||||
fd_draw_pixel(f);
|
||||
fd_inc(f);
|
||||
}
|
||||
|
||||
} while( fd_get_unsigned_bits(f, 1) != 0 );
|
||||
|
||||
if ( f->y >= f->glyph_height )
|
||||
break;
|
||||
}
|
||||
|
||||
screen_show();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*===================================================*/
|
||||
|
||||
|
||||
/*
|
||||
Desc:
|
||||
Output a and b to the stream.
|
||||
a and b must fit to the target size in bits.
|
||||
Additionally a repeat code r (one bit) is generated:
|
||||
It may look like this:
|
||||
r = 0: 0aaaabb
|
||||
or
|
||||
r = 1: 1
|
||||
If r is 0, then the number of zeros (a) and ones (b) will follow and both
|
||||
values must be stored as in the decoder.
|
||||
If r os 1, then the number of zeros and ones is repeated once
|
||||
Args:
|
||||
a: number of 0 bits, log2(a) must be smaller or equal to the fieldsize
|
||||
b: number of 1 bits, log2(b) must be smaller or equal to the fieldsize
|
||||
*/
|
||||
|
||||
static void bg_err(const char *s)
|
||||
{
|
||||
puts(s);
|
||||
}
|
||||
|
||||
static void bg_init_rle(bg_t *bg, unsigned rle_bits_per_0, unsigned rle_bits_per_1)
|
||||
{
|
||||
bg->rle_bitcnt = 0;
|
||||
bg->rle_is_first = 1;
|
||||
bg->rle_bits_per_0 = rle_bits_per_0;
|
||||
bg->rle_bits_per_1 = rle_bits_per_1;
|
||||
bg->rle_last_0 = 0;
|
||||
bg->rle_last_1 = 1;
|
||||
bg_ClearTargetData(bg);
|
||||
}
|
||||
|
||||
static int bg_01_rle(bg_t *bg, unsigned a, unsigned b)
|
||||
{
|
||||
if ( bg->rle_is_first == 0 && bg->rle_last_0 == a && bg->rle_last_1 == b )
|
||||
{
|
||||
bg->rle_bitcnt++;
|
||||
if ( bg_AddTargetBits(bg, 1, 1) == 0 )
|
||||
return bg_err("error in bg_01_rle 1 0"), 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bg->rle_is_first == 0 )
|
||||
{
|
||||
if ( bg_AddTargetBits(bg, 1, 0) == 0 )
|
||||
return bg_err("error in bg_01_rle 1 0"), 0;
|
||||
bg->rle_bitcnt++;
|
||||
}
|
||||
if ( bg_AddTargetBits(bg, bg->rle_bits_per_0, a) == 0 )
|
||||
return bg_err("error in bg_01_rle 1 a"), 0;
|
||||
if ( bg_AddTargetBits(bg, bg->rle_bits_per_1, b) == 0 )
|
||||
return bg_err("error in bg_01_rle 1 b"), 0;
|
||||
|
||||
|
||||
/*
|
||||
if ( bg->encoding == ' ' )
|
||||
{
|
||||
printf("[%u %u]", a, b);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
bg->rle_is_first = 0;
|
||||
bg->rle_bitcnt +=bg->rle_bits_per_0;
|
||||
bg->rle_bitcnt +=bg->rle_bits_per_1;
|
||||
bg->rle_last_0 = a;
|
||||
bg->rle_last_1 = b;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Desc:
|
||||
Write the number of zeros and ones to the bit stream.
|
||||
There is no restriction on the size of a and b.
|
||||
Args:
|
||||
a: number of 0 bits
|
||||
b: number of 1 bits
|
||||
|
||||
*/
|
||||
static int bg_prepare_01_rle(bg_t *bg, unsigned a, unsigned b)
|
||||
{
|
||||
//printf("[%u %u]", a, b);
|
||||
while( a > (1<<bg->rle_bits_per_0) -1 )
|
||||
{
|
||||
if ( bg_01_rle(bg, (1<<bg->rle_bits_per_0) -1, 0) == 0 )
|
||||
return 0;
|
||||
a -= (1<<bg->rle_bits_per_0) -1;
|
||||
}
|
||||
while( b > (1<<bg->rle_bits_per_1) -1 )
|
||||
{
|
||||
if ( bg_01_rle(bg, a, (1<<bg->rle_bits_per_1) -1) == 0 )
|
||||
return 0;
|
||||
a = 0;
|
||||
b -= (1<<bg->rle_bits_per_1) -1;
|
||||
}
|
||||
if ( a != 0 || b != 0 )
|
||||
if ( bg_01_rle(bg, a, b) == 0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int bg_rle_compress(bg_t *bg, bbx_t *bbx, unsigned rle_bits_per_0, unsigned rle_bits_per_1, int is_output)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int i;
|
||||
int bd_is_one; /* bit delta */
|
||||
int bd_curr_len;
|
||||
int bd_max_len;
|
||||
int bd_chg_cnt;
|
||||
|
||||
static int bd_list[1024*2];
|
||||
|
||||
if ( bbx == NULL )
|
||||
bbx = &(bg->bbx);
|
||||
|
||||
bg_init_rle(bg, rle_bits_per_0, rle_bits_per_1);
|
||||
|
||||
|
||||
/* step 0: output initial information */
|
||||
//printf("%ld %ld\n", (long)bg->encoding, (long)bg->map_to);
|
||||
if ( bg->map_to <= 255 )
|
||||
{
|
||||
if ( bg_AddTargetData(bg, bg->map_to) < 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bg_AddTargetData(bg, bg->map_to >> 8) < 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
if ( bg_AddTargetData(bg, bg->map_to & 255 ) < 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
}
|
||||
/* size, will be added later */
|
||||
if ( bg_AddTargetData(bg, 0) < 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
// if ( bbx->w == 0 && bbx->h == 0 )
|
||||
// {
|
||||
// printf("blank char: enc=%ld\n", bg->encoding);
|
||||
// }
|
||||
// w & h is 0 for the space glyphe (encoding 32)
|
||||
if ( bg_AddTargetBits(bg, bg->bf->bbx_w_max_bit_size, bbx->w) == 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
if ( bg_AddTargetBits(bg, bg->bf->bbx_h_max_bit_size, bbx->h) == 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
if ( bg_AddTargetBits(bg, bg->bf->bbx_x_max_bit_size, bbx->x + (1<<(bg->bf->bbx_x_max_bit_size-1))) == 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
if ( bg_AddTargetBits(bg, bg->bf->bbx_y_max_bit_size, bbx->y + (1<<(bg->bf->bbx_y_max_bit_size-1))) == 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
|
||||
if ( bg->bf->bbx_mode == BDF_BBX_MODE_MINIMAL )
|
||||
{
|
||||
if ( bg_AddTargetBits(bg, bg->bf->dx_max_bit_size, bg->dwidth_x + (1<<(bg->bf->dx_max_bit_size-1))) == 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
}
|
||||
else if ( bg->bf->bbx_mode == BDF_BBX_MODE_MAX )
|
||||
{
|
||||
if ( bg_AddTargetBits(bg, bg->bf->dx_max_bit_size, bbx->w+ (1<<(bg->bf->dx_max_bit_size-1))) == 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bg_AddTargetBits(bg, bg->bf->dx_max_bit_size, bbx->w+ (1<<(bg->bf->dx_max_bit_size-1))) == 0 )
|
||||
return bg_err("error in bg_rle_compress"), 0;
|
||||
}
|
||||
|
||||
bd_is_one = 0;
|
||||
bd_curr_len = 0;
|
||||
bd_max_len = 0;
|
||||
bd_chg_cnt = 0;
|
||||
|
||||
/* step 1: build array with pairs of a (number of zero bits) and b (number of one bits) */
|
||||
|
||||
for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
|
||||
{
|
||||
for( x = bbx->x; x < bbx->x + bbx->w; x++)
|
||||
{
|
||||
if ( bg_GetBBXPixel(bg, x, y) == 0 )
|
||||
{
|
||||
if ( bd_is_one != 0 )
|
||||
{
|
||||
bd_list[bd_chg_cnt] = bd_curr_len;
|
||||
bd_is_one = 0;
|
||||
bd_chg_cnt++;
|
||||
bd_curr_len = 0;
|
||||
}
|
||||
bd_curr_len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bd_is_one == 0 )
|
||||
{
|
||||
bd_list[bd_chg_cnt] = bd_curr_len;
|
||||
bd_is_one = 1;
|
||||
bd_chg_cnt++;
|
||||
bd_curr_len = 0;
|
||||
}
|
||||
bd_curr_len++;
|
||||
}
|
||||
|
||||
if ( bd_max_len < bd_curr_len )
|
||||
bd_max_len = bd_curr_len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bd_list[bd_chg_cnt] = bd_curr_len;
|
||||
bd_chg_cnt++;
|
||||
|
||||
if ( (bd_chg_cnt & 1) == 1 )
|
||||
{
|
||||
assert(bd_is_one == 0);
|
||||
bd_list[bd_chg_cnt] = 0;
|
||||
bd_chg_cnt++;
|
||||
}
|
||||
|
||||
//printf("01 pairs = %d\n", bd_chg_cnt/2);
|
||||
|
||||
/* step 2: convert the array into bit stream */
|
||||
|
||||
//if ( bg->encoding == ' ' )
|
||||
// printf("Encoding list, pairs = %d\n", bd_chg_cnt/2);
|
||||
|
||||
for( i = 0; i < bd_chg_cnt; i+=2 )
|
||||
{
|
||||
//if ( bg->encoding == ' ' )
|
||||
// printf("(%d %d)", bd_list[i], bd_list[i+1]);
|
||||
|
||||
if ( bg_prepare_01_rle(bg, bd_list[i], bd_list[i+1]) == 0 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//if ( bg->encoding == 'B' )
|
||||
// printf("\nEncoding list end\n");
|
||||
|
||||
if ( bg_AddTargetBits(bg, 1, 0) == 0 ) // ensure that there is a 0 bit at the end. This will simplify decoding loop
|
||||
return 0;
|
||||
|
||||
if ( bg_FlushTargetBits(bg) == 0 ) // finish the last byte and update bg->target_cnt
|
||||
return 0;
|
||||
|
||||
|
||||
if ( bg->map_to <= 255 )
|
||||
{
|
||||
bg->target_data[1] = bg->target_cnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
bg->target_data[2] = bg->target_cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
fd_t f;
|
||||
f.bbx_x_max_bit_size = bg->bf->bbx_x_max_bit_size;
|
||||
f.bbx_y_max_bit_size = bg->bf->bbx_y_max_bit_size;
|
||||
f.bbx_w_max_bit_size = bg->bf->bbx_w_max_bit_size;
|
||||
f.bbx_h_max_bit_size = bg->bf->bbx_h_max_bit_size;
|
||||
f.dx_max_bit_size = bg->bf->dx_max_bit_size;
|
||||
|
||||
fd_decode(bg, bbx, &f, rle_bits_per_0, rle_bits_per_1);
|
||||
}
|
||||
*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned long bf_RLECompressAllGlyphsWithFieldSize(bf_t *bf, int rle_0, int rle_1, int is_output)
|
||||
{
|
||||
int i;
|
||||
bg_t *bg;
|
||||
unsigned long total_bits = 0;
|
||||
bbx_t local_bbx;
|
||||
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 )
|
||||
{
|
||||
bf_copy_bbx_and_update_shift(bf, &local_bbx, bg);
|
||||
#ifdef OLD_CLODE
|
||||
/* modifing the following code requires update ind bdf_font.c also */
|
||||
|
||||
if ( bf->bbx_mode == BDF_BBX_MODE_MINIMAL )
|
||||
{
|
||||
local_bbx = bg->bbx;
|
||||
}
|
||||
else if ( bf->bbx_mode == BDF_BBX_MODE_MAX )
|
||||
{
|
||||
local_bbx = bf->max;
|
||||
local_bbx.x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
bg->shift_x = bg->bbx.x;
|
||||
if ( local_bbx.w < bg->dwidth_x )
|
||||
local_bbx.w = bg->dwidth_x;
|
||||
}
|
||||
else if ( bf->bbx_mode == BDF_BBX_MODE_M8 )
|
||||
{
|
||||
local_bbx.w = bf->max.w;
|
||||
if ( local_bbx.w < bg->dwidth_x )
|
||||
local_bbx.w = bg->dwidth_x;
|
||||
local_bbx.w = (local_bbx.w+7) & ~7;
|
||||
local_bbx.h = (bf->max.h+7) & ~7;
|
||||
local_bbx.x = bf->max.x;
|
||||
local_bbx.y = bf->max.y;
|
||||
local_bbx.x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
local_bbx = bf->max;
|
||||
local_bbx.w = bg->bbx.w;
|
||||
local_bbx.x = bg->bbx.x;
|
||||
|
||||
local_bbx.x = 0;
|
||||
if ( bg->bbx.x < 0 )
|
||||
{
|
||||
/* e.g. "j" */
|
||||
local_bbx.w -= bg->bbx.x;
|
||||
bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* e.g. "B" */
|
||||
local_bbx.w += bg->bbx.x;
|
||||
//bg->shift_x = bg->bbx.x;
|
||||
}
|
||||
if ( local_bbx.w < bg->dwidth_x )
|
||||
local_bbx.w = bg->dwidth_x;
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
bg_rle_compress(bg, &local_bbx, rle_0, rle_1, is_output);
|
||||
total_bits += bg->target_cnt*8+bg->target_bit_pos;
|
||||
if ( is_output != 0 )
|
||||
{
|
||||
bf_Log(bf, "RLE Compress: Encoding %ld bits %u/%u", bg->encoding, bg->rle_bitcnt, bg->target_cnt*8+bg->target_bit_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
//bf_Log(bf, "RLE Compress: zero bits %d, one bits %d, total bit size %lu", rle_0, rle_1, total_bits);
|
||||
return total_bits;
|
||||
}
|
||||
|
||||
|
||||
unsigned bf_RLE_get_glyph_data(bf_t *bf, uint8_t encoding)
|
||||
{
|
||||
uint8_t *font = bf->target_data;
|
||||
font += BDF_RLE_FONT_GLYPH_START;
|
||||
for(;;)
|
||||
{
|
||||
if ( font[1] == 0 )
|
||||
break;
|
||||
if ( font[0] == encoding )
|
||||
{
|
||||
return (font-bf->target_data)-BDF_RLE_FONT_GLYPH_START;
|
||||
}
|
||||
font += font[1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void bf_RLECompressAllGlyphs(bf_t *bf)
|
||||
{
|
||||
int i, j;
|
||||
bg_t *bg;
|
||||
|
||||
int rle_0, rle_1;
|
||||
int best_rle_0=0, best_rle_1= 0;
|
||||
unsigned long total_bits = 0;
|
||||
unsigned long min_total_bits = 0xffffffff;
|
||||
|
||||
int idx_cap_a;
|
||||
int idx_cap_a_ascent;
|
||||
int idx_1;
|
||||
int idx_1_ascent;
|
||||
int idx_g;
|
||||
int idx_g_descent;
|
||||
int idx_para;
|
||||
int idx_para_ascent;
|
||||
int idx_para_descent;
|
||||
|
||||
unsigned pos;
|
||||
unsigned ascii_glyphs;
|
||||
unsigned unicode_start_pos;
|
||||
unsigned unicode_lookup_table_len;
|
||||
uint32_t unicode_lookup_table_start;
|
||||
uint32_t unicode_last_delta;
|
||||
uint32_t unicode_last_target_cnt;
|
||||
unsigned unicode_lookup_table_pos;
|
||||
unsigned unicode_lookup_table_glyph_cnt;
|
||||
uint32_t unicode_glyph_cnt = 0;
|
||||
|
||||
idx_cap_a_ascent = 0;
|
||||
idx_cap_a = bf_GetIndexByEncoding(bf, 'A');
|
||||
if ( idx_cap_a >= 0 )
|
||||
{
|
||||
idx_cap_a_ascent = bf->glyph_list[idx_cap_a]->bbx.h+bf->glyph_list[idx_cap_a]->bbx.y;
|
||||
}
|
||||
|
||||
idx_1_ascent = 0;
|
||||
idx_1 = bf_GetIndexByEncoding(bf, '1');
|
||||
if ( idx_1 >= 0 )
|
||||
{
|
||||
idx_1_ascent = bf->glyph_list[idx_1]->bbx.h+bf->glyph_list[idx_1]->bbx.y;
|
||||
}
|
||||
|
||||
idx_g_descent = 0;
|
||||
idx_g = bf_GetIndexByEncoding(bf, 'g');
|
||||
if ( idx_g >= 0 )
|
||||
{
|
||||
idx_g_descent = bf->glyph_list[idx_g]->bbx.y;
|
||||
}
|
||||
|
||||
|
||||
idx_para_ascent = 0;
|
||||
idx_para = bf_GetIndexByEncoding(bf, '(');
|
||||
if ( idx_para >= 0 )
|
||||
{
|
||||
idx_para_ascent = bf->glyph_list[idx_para]->bbx.h+bf->glyph_list[idx_para]->bbx.y;
|
||||
idx_para_descent = bf->glyph_list[idx_para]->bbx.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
idx_para_ascent = idx_cap_a_ascent;
|
||||
if ( idx_para_ascent == 0 )
|
||||
idx_para_ascent = idx_1_ascent;
|
||||
|
||||
idx_para_descent = idx_g_descent;
|
||||
}
|
||||
|
||||
|
||||
for( rle_0 = 2; rle_0 < 9; rle_0++ )
|
||||
{
|
||||
for( rle_1 = 2; rle_1 < 7; rle_1++ )
|
||||
{
|
||||
total_bits = bf_RLECompressAllGlyphsWithFieldSize(bf, rle_0, rle_1, 0);
|
||||
if ( min_total_bits > total_bits )
|
||||
{
|
||||
min_total_bits = total_bits;
|
||||
best_rle_0 = rle_0;
|
||||
best_rle_1 = rle_1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
bf_Log(bf, "RLE Compress: best zero bits %d, one bits %d, total bit size %lu", best_rle_0, best_rle_1, min_total_bits);
|
||||
bf_RLECompressAllGlyphsWithFieldSize(bf, best_rle_0, best_rle_1, 0);
|
||||
|
||||
|
||||
bf_ClearTargetData(bf);
|
||||
|
||||
/*
|
||||
glyph_cnt = *font++;
|
||||
bits_per_0 = *font++;
|
||||
bits_per_1 = *font++;
|
||||
bits_per_char_width = *font++;
|
||||
bits_per_char_height = *font++;
|
||||
bits_per_char_x = *font++;
|
||||
bits_per_char_y = *font++;
|
||||
bits_per_delta_x = *font++;
|
||||
*/
|
||||
|
||||
bf_Log(bf, "RLE Compress: Font code generation, selected glyphs=%d, total glyphs=%d", bf->selected_glyphs, bf->glyph_cnt);
|
||||
|
||||
/* 0 */
|
||||
bf_AddTargetData(bf, bf->selected_glyphs);
|
||||
bf_AddTargetData(bf, bf->bbx_mode);
|
||||
bf_AddTargetData(bf, best_rle_0);
|
||||
bf_AddTargetData(bf, best_rle_1);
|
||||
|
||||
/* 4 */
|
||||
bf_AddTargetData(bf, bf->bbx_w_max_bit_size);
|
||||
bf_AddTargetData(bf, bf->bbx_h_max_bit_size);
|
||||
bf_AddTargetData(bf, bf->bbx_x_max_bit_size);
|
||||
bf_AddTargetData(bf, bf->bbx_y_max_bit_size);
|
||||
bf_AddTargetData(bf, bf->dx_max_bit_size);
|
||||
|
||||
/* 9 */
|
||||
bf_AddTargetData(bf, bf->max.w);
|
||||
bf_AddTargetData(bf, bf->max.h);
|
||||
bf_AddTargetData(bf, bf->max.x);
|
||||
bf_AddTargetData(bf, bf->max.y);
|
||||
|
||||
/* 13 */
|
||||
if ( idx_cap_a_ascent > 0 )
|
||||
bf_AddTargetData(bf, idx_cap_a_ascent);
|
||||
else
|
||||
bf_AddTargetData(bf, idx_1_ascent);
|
||||
bf_AddTargetData(bf, idx_g_descent);
|
||||
|
||||
/* 15 */
|
||||
bf_AddTargetData(bf, idx_para_ascent);
|
||||
bf_AddTargetData(bf, idx_para_descent);
|
||||
|
||||
/* 17 */
|
||||
bf_AddTargetData(bf, 0); /* start pos 'A', high/low */
|
||||
bf_AddTargetData(bf, 0);
|
||||
|
||||
/* 19 */
|
||||
bf_AddTargetData(bf, 0); /* start pos 'a', high/low */
|
||||
bf_AddTargetData(bf, 0);
|
||||
|
||||
/* 21 */
|
||||
bf_AddTargetData(bf, 0); /* start pos unicode, high/low */
|
||||
bf_AddTargetData(bf, 0);
|
||||
|
||||
/* assumes, that map_to is sorted */
|
||||
|
||||
ascii_glyphs = 0;
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 0 && bg->map_to <= 255L )
|
||||
{
|
||||
if ( bg->target_data != NULL )
|
||||
{
|
||||
|
||||
if ( bg->target_cnt >= 255 )
|
||||
{
|
||||
bf_Error(bf, "RLE Compress: Error, glyph too large, encoding=%ld cnt=%d", (long)bg->encoding, (int)bg->target_cnt);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for( j = 0; j < bg->target_cnt; j++ )
|
||||
{
|
||||
bf_AddTargetData(bf, bg->target_data[j]);
|
||||
}
|
||||
ascii_glyphs++; /* calculate the numner of ascii glyphs, this is required later for the unicode index table */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* add empty glyph as end of font marker for the ASCII part (chars from 0 to 255) */
|
||||
bf_AddTargetData(bf, 0);
|
||||
bf_AddTargetData(bf, 0);
|
||||
|
||||
unicode_start_pos = bf->target_cnt-BDF_RLE_FONT_GLYPH_START;
|
||||
/*
|
||||
1 May 2018: Unicode lookup table
|
||||
*/
|
||||
bf_Log(bf, "RLE Compress: ASCII gylphs=%d, Unicode glyphs=%d", ascii_glyphs, bf->selected_glyphs-ascii_glyphs);
|
||||
unicode_lookup_table_len = (bf->selected_glyphs-ascii_glyphs) / UNICODE_GLYPHS_PER_LOOKUP_TABLE_ENTRY;
|
||||
//if ( unicode_lookup_table_len > 1 )
|
||||
// unicode_lookup_table_len--;
|
||||
bf_Log(bf, "RLE Compress: Glyphs per unicode lookup table entry=%d", UNICODE_GLYPHS_PER_LOOKUP_TABLE_ENTRY);
|
||||
unicode_lookup_table_start = bf->target_cnt;
|
||||
|
||||
/* write n-1 entries */
|
||||
for( i = 1; i < unicode_lookup_table_len; i++ )
|
||||
{
|
||||
bf_AddTargetData(bf, 0); /* offset */
|
||||
bf_AddTargetData(bf, 0);
|
||||
bf_AddTargetData(bf, 0); /* encoding */
|
||||
bf_AddTargetData(bf, 0);
|
||||
}
|
||||
/* the last entry is special, it contains the encoding 0xffff */
|
||||
bf_AddTargetData(bf, 0); /* offset */
|
||||
bf_AddTargetData(bf, 4); /* default, if the table has only one entry, then just skip the table */
|
||||
bf_AddTargetData(bf, 0xff); /* encoding */
|
||||
bf_AddTargetData(bf, 0xff);
|
||||
|
||||
|
||||
|
||||
unicode_lookup_table_pos = 0;
|
||||
unicode_lookup_table_glyph_cnt = 0;
|
||||
unicode_last_delta = bf->target_cnt-unicode_lookup_table_start; /* should be 4 if unicode_lookup_table_len == 0 */
|
||||
unicode_last_target_cnt = bf->target_cnt;
|
||||
unicode_glyph_cnt = 0;
|
||||
/* now write chars with code >= 256 from the BMP */
|
||||
/* assumes, that map_to is sorted */
|
||||
for( i = 0; i < bf->glyph_cnt; i++ )
|
||||
{
|
||||
bg = bf->glyph_list[i];
|
||||
if ( bg->map_to >= 256 )
|
||||
{
|
||||
if ( bg->target_data != NULL )
|
||||
{
|
||||
|
||||
if ( bg->target_cnt >= 255 )
|
||||
{
|
||||
bf_Error(bf, "RLE Compress: Error, glyph too large, encoding=%ld", (long)bg->encoding);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for( j = 0; j < bg->target_cnt; j++ )
|
||||
{
|
||||
bf_AddTargetData(bf, bg->target_data[j]);
|
||||
}
|
||||
|
||||
// Debug output issue 1521
|
||||
//bf_Log(bf, "RLE Compress: Unicode glyph pos=%d, lookup table=%d, glyph within lut=%d", unicode_glyph_cnt, unicode_lookup_table_pos, unicode_lookup_table_glyph_cnt);
|
||||
|
||||
|
||||
/* update the unicode lookup table entry counter */
|
||||
unicode_lookup_table_glyph_cnt++;
|
||||
|
||||
if ( unicode_lookup_table_glyph_cnt >= UNICODE_GLYPHS_PER_LOOKUP_TABLE_ENTRY )
|
||||
{
|
||||
/* ensure, that there is a table entry available */
|
||||
if ( unicode_lookup_table_pos < unicode_lookup_table_len )
|
||||
{
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+0] = unicode_last_delta>>8;
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+1] = unicode_last_delta&255;
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+2] |= bg->encoding>>8; // ensure to keep the 0x0ffff encoding at the end
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+3] |= bg->encoding&255; // ensure to keep the 0x0ffff encoding at the end
|
||||
|
||||
unicode_lookup_table_pos++;
|
||||
unicode_lookup_table_glyph_cnt = 0;
|
||||
unicode_last_delta = bf->target_cnt - unicode_last_target_cnt;
|
||||
unicode_last_target_cnt = bf->target_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unicode_glyph_cnt++;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write pending block to the unicode lookup table, ensure, that there is a table entry available */
|
||||
if ( unicode_lookup_table_pos < unicode_lookup_table_len )
|
||||
{
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+0] = unicode_last_delta>>8;
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+1] = unicode_last_delta&255;
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+2] = 0xff;
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+3] = 0xff;
|
||||
unicode_lookup_table_pos++;
|
||||
}
|
||||
|
||||
/* add empty encoding as end of font marker (note: this differs from the ASCII section) */
|
||||
bf_AddTargetData(bf, 0);
|
||||
bf_AddTargetData(bf, 0);
|
||||
|
||||
bf_Log(bf, "RLE Compress: Unicode lookup table len=%d, written entries=%d", unicode_lookup_table_len, unicode_lookup_table_pos);
|
||||
bf_Log(bf, "RLE Compress: Unicode lookup table first entry: delta=%d, encoding=%d",
|
||||
bf->target_data[unicode_lookup_table_start+0]*256+bf->target_data[unicode_lookup_table_start+1],
|
||||
bf->target_data[unicode_lookup_table_start+2]*256+bf->target_data[unicode_lookup_table_start+3]);
|
||||
|
||||
bf_Log(bf, "RLE Compress: Unicode lookup table last entry: delta=%d, encoding=%d",
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4-4+0]*256+bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4-4+1],
|
||||
bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4-4+2]*256+bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4-4+3]);
|
||||
|
||||
bf_Log(bf, "RLE Compress: Unicode glyphs written=%d", unicode_glyph_cnt);
|
||||
|
||||
|
||||
assert(unicode_lookup_table_len == unicode_lookup_table_pos ); // ensure that all table entries are filled
|
||||
|
||||
pos = bf_RLE_get_glyph_data(bf, 'A');
|
||||
bf->target_data[17] = pos >> 8;
|
||||
bf->target_data[18] = pos & 255;
|
||||
|
||||
pos = bf_RLE_get_glyph_data(bf, 'a');
|
||||
bf->target_data[19] = pos >> 8;
|
||||
bf->target_data[20] = pos & 255;
|
||||
|
||||
bf->target_data[21] = unicode_start_pos >> 8;
|
||||
bf->target_data[22] = unicode_start_pos & 255;
|
||||
|
||||
bf_Log(bf, "RLE Compress: 'A' pos = %u, 'a' pos = %u", bf_RLE_get_glyph_data(bf, 'A'), bf_RLE_get_glyph_data(bf, 'a'));
|
||||
|
||||
bf_Log(bf, "RLE Compress: Font size %d", bf->target_cnt);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
523
font/bdfconv/bdf_tga.c
Normal file
523
font/bdfconv/bdf_tga.c
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
|
||||
bdf_tga.c
|
||||
|
||||
|
||||
|
||||
Modes:
|
||||
BDF_BBX_MODE_MINIMAL 0
|
||||
BDF_BBX_MODE_MAX 1
|
||||
BDF_BBX_MODE_HEIGHT 2
|
||||
|
||||
For all modes, default reference should be the baseline.
|
||||
This is required for mode 0, but may be optional for 1 and 2
|
||||
|
||||
If (x,y) is the user provided baseline point for the glyph, then
|
||||
the decoding mus tbe start at
|
||||
(x..., y-h-descent)
|
||||
|
||||
|
||||
BDF_BBX_MODE_MINIMAL
|
||||
- exact space as intended by the font author
|
||||
- glyphs my overlap ("mj" with osb18)
|
||||
|
||||
BDF_BBX_MODE_MAX
|
||||
- extra space may be added
|
||||
- glyphs do not overlap
|
||||
|
||||
BDF_BBX_MODE_HEIGHT
|
||||
- extra space may be added
|
||||
- glyphs do not overlap
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "fd.h"
|
||||
|
||||
|
||||
static uint16_t tga_width;
|
||||
static uint16_t tga_height;
|
||||
static uint16_t tga_used_height;
|
||||
static uint8_t *tga_data = NULL;
|
||||
|
||||
static uint8_t *tga_font;
|
||||
static int glyph_cnt;
|
||||
static int bits_per_0;
|
||||
static int bits_per_1;
|
||||
static int bits_per_char_width;
|
||||
static int bits_per_char_height;
|
||||
static int bits_per_char_x;
|
||||
static int bits_per_char_y;
|
||||
static int bits_per_delta_x;
|
||||
static int char_width;
|
||||
static int char_height;
|
||||
static int char_descent;
|
||||
static unsigned unicode_start_pos;
|
||||
static int tga_pixel_intersection;
|
||||
|
||||
|
||||
int tga_get_char_width(void)
|
||||
{
|
||||
return char_width;
|
||||
}
|
||||
|
||||
int tga_get_char_height(void)
|
||||
{
|
||||
return char_height;
|
||||
}
|
||||
|
||||
int tga_init(uint16_t w, uint16_t h)
|
||||
{
|
||||
tga_width = 0;
|
||||
tga_height = 0;
|
||||
tga_used_height = 0;
|
||||
tga_pixel_intersection = 0;
|
||||
if ( tga_data != NULL )
|
||||
free(tga_data);
|
||||
tga_data = (uint8_t *)malloc((size_t)w*(size_t)h*3);
|
||||
if ( tga_data == NULL )
|
||||
return 0;
|
||||
tga_width = w;
|
||||
tga_height = h;
|
||||
memset(tga_data, 255, tga_width*tga_height*3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void tga_clear(void)
|
||||
{
|
||||
memset(tga_data, 255, tga_width*tga_height*3);
|
||||
}
|
||||
|
||||
void tga_set_pixel(uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
uint8_t *p;
|
||||
if ( y>= tga_height)
|
||||
return;
|
||||
if ( x>= tga_width)
|
||||
return;
|
||||
if ( tga_used_height < y )
|
||||
tga_used_height = y;
|
||||
|
||||
p = tga_data + (tga_height-y-1)*(size_t)tga_width*3 + (size_t)x*3;
|
||||
|
||||
if ( p[0] != 255 || p[1] != 255 || p[2] != 255 )
|
||||
tga_pixel_intersection = 1;
|
||||
|
||||
//printf("tga_set_pixel %d %d\n", x, y);
|
||||
|
||||
*p++ = b;
|
||||
*p++ = g;
|
||||
*p++ = r;
|
||||
}
|
||||
|
||||
int tga_is_pixel_intersection(void)
|
||||
{
|
||||
return tga_pixel_intersection;
|
||||
}
|
||||
|
||||
void tga_clear_pixel_intersection(void)
|
||||
{
|
||||
tga_pixel_intersection = 0;
|
||||
}
|
||||
|
||||
void tga_write_byte(FILE *fp, uint8_t byte)
|
||||
{
|
||||
fputc(byte, fp);
|
||||
}
|
||||
|
||||
void tga_write_word(FILE *fp, uint16_t word)
|
||||
{
|
||||
tga_write_byte(fp, word&255);
|
||||
tga_write_byte(fp, word>>8);
|
||||
}
|
||||
|
||||
void tga_save(const char *name)
|
||||
{
|
||||
FILE *fp;
|
||||
fp = fopen(name, "wb");
|
||||
if ( fp != NULL )
|
||||
{
|
||||
tga_write_byte(fp, 0); /* no ID */
|
||||
tga_write_byte(fp, 0); /* no color map */
|
||||
tga_write_byte(fp, 2); /* uncompressed true color */
|
||||
tga_write_word(fp, 0);
|
||||
tga_write_word(fp, 0);
|
||||
tga_write_byte(fp, 0);
|
||||
tga_write_word(fp, 0); /* x origin */
|
||||
tga_write_word(fp, 0); /* y origin */
|
||||
tga_write_word(fp, tga_width); /* width */
|
||||
tga_write_word(fp, tga_used_height+1); /* height */
|
||||
tga_write_byte(fp, 24); /* color depth */
|
||||
tga_write_byte(fp, 0);
|
||||
fwrite(tga_data + (tga_height - (tga_used_height+1))*tga_width*3 , tga_width*3, tga_used_height+1, fp);
|
||||
tga_write_word(fp, 0);
|
||||
tga_write_word(fp, 0);
|
||||
tga_write_word(fp, 0);
|
||||
tga_write_word(fp, 0);
|
||||
fwrite("TRUEVISION-XFILE.", 18, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
font data:
|
||||
|
||||
offset bytes description
|
||||
0 1 glyph_cnt number of glyphs
|
||||
1 1 bbx_mode 0: proportional, 1: common height, 2: monospace, 3: multiple of 8
|
||||
2 1 bits_per_0 glyph rle parameter
|
||||
3 1 bits_per_1 glyph rle parameter
|
||||
|
||||
4 1 bits_per_char_width glyph rle parameter
|
||||
5 1 bits_per_char_height glyph rle parameter
|
||||
6 1 bits_per_char_x glyph rle parameter
|
||||
7 1 bits_per_char_y glyph rle parameter
|
||||
8 1 bits_per_delta_x glyph rle parameter
|
||||
|
||||
9 1 max_char_width
|
||||
10 1 max_char_height
|
||||
11 1 x offset
|
||||
12 1 y offset (descent)
|
||||
|
||||
13 1 ascent (capital A)
|
||||
14 1 descent (lower g)
|
||||
15 1 ascent '('
|
||||
16 1 descent ')'
|
||||
|
||||
17 1 start pos 'A' high byte
|
||||
18 1 start pos 'A' low byte
|
||||
|
||||
19 1 start pos 'a' high byte
|
||||
20 1 start pos 'a' low byte
|
||||
|
||||
21 1 start pos unicode high byte
|
||||
22 1 start pos unicode low byte
|
||||
|
||||
*/
|
||||
|
||||
void tga_set_font(uint8_t *font)
|
||||
{
|
||||
glyph_cnt = *font++;
|
||||
font++; /* bbx mode */
|
||||
bits_per_0 = *font++;
|
||||
bits_per_1 = *font++;
|
||||
bits_per_char_width = *font++;
|
||||
bits_per_char_height = *font++;
|
||||
bits_per_char_x = *font++;
|
||||
bits_per_char_y = *font++;
|
||||
bits_per_delta_x = *font++;
|
||||
char_width = *font++;
|
||||
char_height = *font++;
|
||||
font++; /* x offset */
|
||||
char_descent = *(int8_t *)font;
|
||||
font++;
|
||||
|
||||
font++;
|
||||
font++;
|
||||
font++;
|
||||
font++;
|
||||
|
||||
font++;
|
||||
font++;
|
||||
font++;
|
||||
font++;
|
||||
|
||||
unicode_start_pos = *font++;
|
||||
unicode_start_pos <<= 8;
|
||||
unicode_start_pos |= *font++;
|
||||
|
||||
tga_font = font;
|
||||
|
||||
}
|
||||
|
||||
uint8_t *tga_get_glyph_data(uint16_t encoding)
|
||||
{
|
||||
uint8_t *font = tga_font;
|
||||
if ( encoding <= 255 )
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if ( font[1] == 0 )
|
||||
break;
|
||||
if ( font[0] == encoding )
|
||||
{
|
||||
return font;
|
||||
}
|
||||
font += font[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t e;
|
||||
uint8_t *unicode_lookup_table;
|
||||
font += unicode_start_pos;
|
||||
unicode_lookup_table = font;
|
||||
|
||||
|
||||
/* search for the glyph start in the unicode lookup table */
|
||||
do
|
||||
{
|
||||
font += ((unicode_lookup_table[0]<<8)|unicode_lookup_table[1]);
|
||||
unicode_lookup_table+=2;
|
||||
e = (unicode_lookup_table[0]<<8)|unicode_lookup_table[1];
|
||||
unicode_lookup_table+=2;
|
||||
} while( e < encoding );
|
||||
|
||||
/* continue with the search in the font */
|
||||
for(;;)
|
||||
{
|
||||
e = ((font[0]<<8)|font[1]);
|
||||
if ( e == 0 )
|
||||
break;
|
||||
if ( e == encoding )
|
||||
{
|
||||
return font;
|
||||
}
|
||||
font += font[2];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* font decode */
|
||||
struct tga_fd_struct
|
||||
{
|
||||
unsigned target_x;
|
||||
unsigned target_y;
|
||||
unsigned is_transparent;
|
||||
|
||||
unsigned x; /* local coordinates, (0,0) is upper left */
|
||||
unsigned y;
|
||||
unsigned glyph_width;
|
||||
unsigned glyph_height;
|
||||
|
||||
|
||||
const uint8_t *decode_ptr; /* pointer to the compressed data */
|
||||
unsigned decode_bit_pos; /* bitpos inside a byte of the compressed data */
|
||||
|
||||
uint8_t bbx_x_max_bit_size;
|
||||
uint8_t bbx_y_max_bit_size;
|
||||
uint8_t bbx_w_max_bit_size;
|
||||
uint8_t bbx_h_max_bit_size;
|
||||
uint8_t dx_max_bit_size;
|
||||
|
||||
};
|
||||
typedef struct tga_fd_struct tga_fd_t;
|
||||
|
||||
/* increment x and consider line wrap (inc y)*/
|
||||
/* old procedure */
|
||||
void tga_fd_inc(tga_fd_t *f)
|
||||
{
|
||||
unsigned x = f->x;
|
||||
x++;
|
||||
if ( x == f->glyph_width )
|
||||
{
|
||||
x = 0;
|
||||
f->y++;
|
||||
}
|
||||
f->x = x;
|
||||
}
|
||||
|
||||
|
||||
unsigned tga_fd_get_unsigned_bits(tga_fd_t *f, unsigned cnt)
|
||||
{
|
||||
unsigned val;
|
||||
unsigned bit_pos = f->decode_bit_pos;
|
||||
|
||||
val = *(f->decode_ptr);
|
||||
|
||||
val >>= bit_pos;
|
||||
if ( bit_pos + cnt >= 8 )
|
||||
{
|
||||
f->decode_ptr++;
|
||||
val |= *(f->decode_ptr) << (8-bit_pos);
|
||||
bit_pos -= 8;
|
||||
}
|
||||
val &= (1U<<cnt)-1;
|
||||
bit_pos += cnt;
|
||||
|
||||
f->decode_bit_pos = bit_pos;
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
2 bit --> cnt = 2
|
||||
-2,-1,0. 1
|
||||
|
||||
3 bit --> cnt = 3
|
||||
-2,-1,0. 1
|
||||
-4,-3,-2,-1,0,1,2,3
|
||||
|
||||
if ( x < 0 )
|
||||
r = bits(x-1)+1;
|
||||
else
|
||||
r = bits(x)+1;
|
||||
|
||||
*/
|
||||
int tga_fd_get_signed_bits(tga_fd_t *t, int cnt)
|
||||
{
|
||||
return (int)tga_fd_get_unsigned_bits(t, cnt) - ((1<<cnt)>>1);
|
||||
}
|
||||
|
||||
|
||||
void tga_fd_draw_fg_pixel(tga_fd_t *f, unsigned cnt)
|
||||
{
|
||||
//printf("%d ", cnt);
|
||||
/* cnt can be zero */
|
||||
while( cnt > 0 )
|
||||
{
|
||||
cnt--;
|
||||
tga_set_pixel(f->target_x+f->x+cnt, f->target_y+f->y, 0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
void tga_fd_draw_bg_pixel(tga_fd_t *f, unsigned cnt)
|
||||
{
|
||||
//printf("%d ", cnt);
|
||||
/* cnt can be zero */
|
||||
while( cnt > 0 )
|
||||
{
|
||||
cnt--;
|
||||
if ( f->is_transparent == 0 )
|
||||
tga_set_pixel(f->target_x+f->x+cnt, f->target_y+f->y, 0x0e8,0x0e8,0x0e8);
|
||||
}
|
||||
}
|
||||
|
||||
void tga_draw_hline(unsigned x,unsigned y, unsigned cnt, unsigned is_foreground)
|
||||
{
|
||||
while( cnt > 0 )
|
||||
{
|
||||
cnt--;
|
||||
if ( is_foreground == 0 )
|
||||
tga_set_pixel(x+cnt, y, 0x0e8,0x0e8,0x0e8);
|
||||
else
|
||||
tga_set_pixel(x+cnt, y, 255,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tga_fd_draw_pixel(tga_fd_t *f, unsigned cnt, unsigned is_foreground)
|
||||
{
|
||||
if ( is_foreground )
|
||||
{
|
||||
tga_fd_draw_fg_pixel(f, cnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
tga_fd_draw_bg_pixel(f, cnt);
|
||||
}
|
||||
}
|
||||
|
||||
void tga_fd_decode_len(tga_fd_t *f, unsigned len, unsigned is_foreground)
|
||||
{
|
||||
unsigned cnt, rem;
|
||||
cnt = len;
|
||||
for(;;)
|
||||
{
|
||||
rem = f->glyph_width;
|
||||
rem -= f->x;
|
||||
if ( cnt < rem )
|
||||
break;
|
||||
tga_fd_draw_pixel(f,rem, is_foreground);
|
||||
cnt -= rem;
|
||||
f->x = 0;
|
||||
f->y++;
|
||||
}
|
||||
tga_fd_draw_pixel(f, cnt, is_foreground);
|
||||
f->x += cnt;
|
||||
}
|
||||
|
||||
unsigned tga_fd_decode(tga_fd_t *f, uint8_t *glyph_data, int is_unicode)
|
||||
{
|
||||
unsigned a, b;
|
||||
//unsigned cnt, rem;
|
||||
int x, y;
|
||||
unsigned d = 0;
|
||||
|
||||
f->decode_ptr = glyph_data;
|
||||
f->decode_bit_pos = 0;
|
||||
|
||||
f->decode_ptr += 1;
|
||||
f->decode_ptr += 1;
|
||||
if ( is_unicode != 0 )
|
||||
f->decode_ptr += 1;
|
||||
|
||||
|
||||
f->glyph_width = tga_fd_get_unsigned_bits(f, bits_per_char_width);
|
||||
f->glyph_height = tga_fd_get_unsigned_bits(f, bits_per_char_height);
|
||||
x = tga_fd_get_signed_bits(f, bits_per_char_x);
|
||||
y = tga_fd_get_signed_bits(f, bits_per_char_y);
|
||||
d = tga_fd_get_signed_bits(f, bits_per_delta_x);
|
||||
|
||||
if ( f->glyph_width > 0 )
|
||||
{
|
||||
|
||||
f->target_x += x;
|
||||
f->target_y -= f->glyph_height ;
|
||||
f->target_y -=y ;
|
||||
|
||||
/* reset local x/y position */
|
||||
f->x = 0;
|
||||
f->y = 0;
|
||||
|
||||
/* decode glyph */
|
||||
for(;;)
|
||||
{
|
||||
a = tga_fd_get_unsigned_bits(f, bits_per_0);
|
||||
b = tga_fd_get_unsigned_bits(f, bits_per_1);
|
||||
do
|
||||
{
|
||||
tga_fd_decode_len(f, a, 0);
|
||||
tga_fd_decode_len(f, b, 1);
|
||||
} while( tga_fd_get_unsigned_bits(f, 1) != 0 );
|
||||
|
||||
if ( f->y >= f->glyph_height )
|
||||
break;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
unsigned tga_draw_glyph(unsigned x, unsigned y, uint16_t encoding, int is_hints)
|
||||
{
|
||||
unsigned dx = 0;
|
||||
tga_fd_t f;
|
||||
f.target_x = x;
|
||||
f.target_y = y;
|
||||
f.is_transparent = !is_hints;
|
||||
uint8_t *glyph_data = tga_get_glyph_data(encoding); /* better skip the first 2 or 3 bytes */
|
||||
if ( glyph_data != NULL )
|
||||
{
|
||||
dx = tga_fd_decode(&f, glyph_data, encoding >= 255 ? 1 : 0);
|
||||
if ( is_hints )
|
||||
{
|
||||
tga_set_pixel(x+dx, y, 28,133,240); /* orange: reference point */
|
||||
tga_set_pixel(x, y, 255,164,0); /* blue: delta x (width) for this glyph */
|
||||
}
|
||||
}
|
||||
return dx;
|
||||
}
|
||||
|
||||
unsigned tga_draw_string(unsigned x, unsigned y, const char *s, int is_hints, unsigned max_dx)
|
||||
{
|
||||
unsigned dx = 0;
|
||||
while( *s != '\0' )
|
||||
{
|
||||
dx += tga_draw_glyph(x+dx,y,*s, is_hints);
|
||||
if ( max_dx > 0 )
|
||||
if ( dx > max_dx )
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
return dx;
|
||||
}
|
||||
|
||||
|
226
font/bdfconv/fd.c
Normal file
226
font/bdfconv/fd.c
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
|
||||
fd.c
|
||||
|
||||
font decode
|
||||
|
||||
(obsolete? does not support unicode)
|
||||
|
||||
*/
|
||||
|
||||
#include "fd.h"
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
void fd_init(fd_t *fd)
|
||||
{
|
||||
fd->is_transparent = 1;
|
||||
}
|
||||
|
||||
void fd_set_font(fd_t *fd, uint8_t *font)
|
||||
{
|
||||
fd->glyph_cnt = *font++;
|
||||
font++; /* bbx mode */
|
||||
fd->bits_per_0 = *font++;
|
||||
fd->bits_per_1 = *font++;
|
||||
fd->bits_per_char_width = *font++;
|
||||
fd->bits_per_char_height = *font++;
|
||||
fd->bits_per_char_x = *font++;
|
||||
fd->bits_per_char_y = *font++;
|
||||
fd->bits_per_delta_x = *font++;
|
||||
fd->char_width = *font++;
|
||||
fd->char_height = *font++;
|
||||
font++; /* x offset */
|
||||
fd->char_descent = *(int8_t *)font;
|
||||
font++;
|
||||
|
||||
font++;
|
||||
font++;
|
||||
font++;
|
||||
font++;
|
||||
|
||||
fd->capital_a_pos= *font++;
|
||||
fd->capital_a_pos <<= 8;
|
||||
fd->capital_a_pos |= *font++;
|
||||
fd->small_a_pos = *font++;
|
||||
fd->small_a_pos <<= 8;
|
||||
fd->small_a_pos |= *font++;
|
||||
|
||||
/* TODO: proper unicode update */
|
||||
font++;
|
||||
font++;
|
||||
|
||||
fd->font = font;
|
||||
}
|
||||
|
||||
uint8_t *fd_get_glyph_data(fd_t *fd, uint8_t encoding)
|
||||
{
|
||||
|
||||
uint8_t *font = fd->font;
|
||||
if ( encoding >= 'a' ) /* assumes 'a' > 'A' */
|
||||
{
|
||||
font += fd->small_a_pos;
|
||||
}
|
||||
else if ( encoding >= 'A' )
|
||||
{
|
||||
font += fd->capital_a_pos;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if ( font[1] == 0 )
|
||||
break;
|
||||
if ( font[0] == encoding )
|
||||
{
|
||||
return font;
|
||||
}
|
||||
font += font[1];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__attribute__((noinline)) unsigned fd_get_unsigned_bits(fd_t *f, unsigned cnt)
|
||||
{
|
||||
unsigned val;
|
||||
unsigned bit_pos = f->decode_bit_pos;
|
||||
unsigned rem_bits;
|
||||
|
||||
val = f->decode_byte;
|
||||
rem_bits = 8;
|
||||
rem_bits -= bit_pos;
|
||||
|
||||
bit_pos += cnt;
|
||||
if ( cnt >= rem_bits )
|
||||
{
|
||||
f->decode_ptr++;
|
||||
f->decode_byte = *(f->decode_ptr);
|
||||
|
||||
val |= f->decode_byte << (rem_bits);
|
||||
|
||||
bit_pos -= 8;
|
||||
f->decode_byte >>= bit_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
f->decode_byte >>= cnt;
|
||||
}
|
||||
val &= (1U<<cnt)-1;
|
||||
f->decode_bit_pos = bit_pos;
|
||||
return val;
|
||||
}
|
||||
|
||||
int fd_get_signed_bits(fd_t *fd, int cnt)
|
||||
{
|
||||
return (int)fd_get_unsigned_bits(fd, cnt) - ((1<<cnt)>>1);
|
||||
}
|
||||
|
||||
void tga_draw_hline(unsigned x,unsigned y, unsigned cnt, unsigned is_foreground);
|
||||
|
||||
|
||||
void fd_draw_pixel(fd_t *f, unsigned cnt, unsigned is_foreground)
|
||||
{
|
||||
if ( f->is_transparent != 0 && is_foreground == 0 )
|
||||
return;
|
||||
tga_draw_hline(f->target_x+f->x, f->target_y+f->y, cnt, is_foreground);
|
||||
}
|
||||
|
||||
void fd_decode_len(fd_t *fd, unsigned len, unsigned is_foreground)
|
||||
{
|
||||
unsigned cnt, rem;
|
||||
cnt = len;
|
||||
for(;;)
|
||||
{
|
||||
rem = fd->glyph_width;
|
||||
rem -= fd->x;
|
||||
if ( cnt < rem )
|
||||
break;
|
||||
fd_draw_pixel(fd,rem, is_foreground);
|
||||
cnt -= rem;
|
||||
fd->x = 0;
|
||||
fd->y++;
|
||||
}
|
||||
fd_draw_pixel(fd, cnt, is_foreground);
|
||||
fd->x += cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
expects:
|
||||
unsigned target_x;
|
||||
unsigned target_y;
|
||||
unsigned is_transparent;
|
||||
const uint8_t *decode_ptr;
|
||||
*/
|
||||
unsigned fd_decode(fd_t *f)
|
||||
{
|
||||
unsigned a, b;
|
||||
int x, y;
|
||||
unsigned d = 0;
|
||||
|
||||
f->decode_bit_pos = 0;
|
||||
|
||||
f->decode_ptr += 1;
|
||||
f->decode_ptr += 1;
|
||||
|
||||
f->decode_byte = *(f->decode_ptr); /* init decoder */
|
||||
|
||||
f->glyph_width = fd_get_unsigned_bits(f, f->bits_per_char_width);
|
||||
f->glyph_height = fd_get_unsigned_bits(f, f->bits_per_char_height);
|
||||
x = fd_get_signed_bits(f, f->bits_per_char_x);
|
||||
y = fd_get_signed_bits(f, f->bits_per_char_y);
|
||||
d = fd_get_signed_bits(f, f->bits_per_delta_x);
|
||||
|
||||
if ( f->glyph_width > 0 )
|
||||
{
|
||||
|
||||
f->target_x += x;
|
||||
f->target_y -= f->glyph_height ;
|
||||
f->target_y -=y ;
|
||||
|
||||
f->x = 0;
|
||||
f->y = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
a = fd_get_unsigned_bits(f, f->bits_per_0);
|
||||
b = fd_get_unsigned_bits(f, f->bits_per_1);
|
||||
do
|
||||
{
|
||||
fd_decode_len(f, a, 0);
|
||||
fd_decode_len(f, b, 1);
|
||||
} while( fd_get_unsigned_bits(f, 1) != 0 );
|
||||
|
||||
if ( f->y >= f->glyph_height )
|
||||
break;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
unsigned fd_draw_glyph(fd_t *fd, unsigned x, unsigned y, uint8_t encoding)
|
||||
{
|
||||
unsigned dx = 0;
|
||||
fd->target_x = x;
|
||||
fd->target_y = y;
|
||||
fd->decode_ptr = fd_get_glyph_data(fd, encoding);
|
||||
if ( fd->decode_ptr != NULL )
|
||||
{
|
||||
dx = fd_decode(fd);
|
||||
}
|
||||
return dx;
|
||||
}
|
||||
|
||||
unsigned fd_draw_string(fd_t *fd, unsigned x, unsigned y, const char *s)
|
||||
{
|
||||
unsigned dx = 0;
|
||||
while( *s != '\0' )
|
||||
{
|
||||
dx += fd_draw_glyph(fd, x+dx,y,*s);
|
||||
s++;
|
||||
}
|
||||
return dx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
49
font/bdfconv/fd.h
Normal file
49
font/bdfconv/fd.h
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
#ifndef _FD_H
|
||||
#define _FD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* font decode */
|
||||
struct fd_struct
|
||||
{
|
||||
unsigned target_x;
|
||||
unsigned target_y;
|
||||
unsigned is_transparent;
|
||||
|
||||
unsigned x; /* local coordinates, (0,0) is upper left */
|
||||
unsigned y;
|
||||
unsigned glyph_width;
|
||||
unsigned glyph_height;
|
||||
|
||||
const uint8_t *decode_ptr; /* pointer to the compressed data */
|
||||
unsigned decode_bit_pos; /* bitpos inside a byte of the compressed data */
|
||||
unsigned decode_byte;
|
||||
|
||||
uint8_t glyph_cnt;
|
||||
uint8_t bits_per_0;
|
||||
uint8_t bits_per_1;
|
||||
uint8_t bits_per_char_width;
|
||||
uint8_t bits_per_char_height;
|
||||
uint8_t bits_per_char_x;
|
||||
uint8_t bits_per_char_y;
|
||||
uint8_t bits_per_delta_x;
|
||||
uint8_t char_width;
|
||||
uint8_t char_height;
|
||||
uint8_t char_descent;
|
||||
unsigned capital_a_pos;
|
||||
unsigned small_a_pos;
|
||||
|
||||
uint8_t *font;
|
||||
|
||||
};
|
||||
typedef struct fd_struct fd_t;
|
||||
|
||||
void fd_init(fd_t *fd);
|
||||
void fd_set_font(fd_t *fd, uint8_t *font);
|
||||
unsigned fd_draw_glyph(fd_t *fd, unsigned x, unsigned y, uint8_t encoding);
|
||||
unsigned fd_draw_string(fd_t *fd, unsigned x, unsigned y, const char *s);
|
||||
|
||||
|
||||
|
||||
#endif /* _FD_H */
|
529
font/bdfconv/main.c
Normal file
529
font/bdfconv/main.c
Normal file
@ -0,0 +1,529 @@
|
||||
/*
|
||||
|
||||
main.c (bdfconv)
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, olikraus@gmail.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "bdf_font.h"
|
||||
#include "fd.h"
|
||||
|
||||
/*================================================*/
|
||||
|
||||
int get_str_arg(char ***argv, int c, char **result)
|
||||
{
|
||||
if ( (**argv)[0] == '-' )
|
||||
{
|
||||
if ( (**argv)[1] == c )
|
||||
{
|
||||
if ( (**argv)[2] == '\0' )
|
||||
{
|
||||
(*argv)++;
|
||||
*result = **argv;
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = (**argv)+2;
|
||||
}
|
||||
(*argv)++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int get_num_arg(char ***argv, int c, unsigned long *result)
|
||||
{
|
||||
if ( (**argv)[0] == '-' )
|
||||
{
|
||||
if ( (**argv)[1] == c )
|
||||
{
|
||||
|
||||
if ( (**argv)[2] == '\0' )
|
||||
{
|
||||
if ( *((*argv)+1) != NULL )
|
||||
{
|
||||
(*argv)++;
|
||||
*result = strtoul((**argv), NULL, 10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = strtoul((**argv)+2, NULL, 10);
|
||||
}
|
||||
(*argv)++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_num_strarg(char ***argv, const char *s, unsigned long *result)
|
||||
{
|
||||
if ( (**argv)[0] == '-' )
|
||||
{
|
||||
//printf("get_num_strarg %s: match %s\n", **argv, s);
|
||||
if ( strcmp( (**argv)+1, s ) == 0 )
|
||||
{
|
||||
//printf("get_num_strarg %s: match %s found\n", **argv, s);
|
||||
if ( *((*argv)+1) != NULL )
|
||||
{
|
||||
(*argv)++;
|
||||
*result = strtoul((**argv), NULL, 10);
|
||||
}
|
||||
(*argv)++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_arg(char ***argv, int c)
|
||||
{
|
||||
if ( (**argv)[0] == '-' )
|
||||
{
|
||||
if ( (**argv)[1] == c )
|
||||
{
|
||||
(*argv)++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
void help(void)
|
||||
{
|
||||
printf("bdfconv [options] filename\n");
|
||||
printf("-h Display this help\n");
|
||||
printf("-v Print log messages\n");
|
||||
printf("-b <n> Font build mode, 0: proportional, 1: common height, 2: monospace, 3: multiple of 8, 4: 5x7 mode\n");
|
||||
printf("-f <n> Font format, 0: ucglib font, 1: u8g2 font, 2: u8g2 uncompressed 8x8 font (enforces -b 3)\n");
|
||||
printf("-m 'map' Unicode ASCII mapping\n");
|
||||
printf("-M 'mapfile' Read Unicode ASCII mapping from file 'mapname'\n");
|
||||
printf("-o <file> C output font file\n");
|
||||
printf("-k <file> C output file with kerning information\n");
|
||||
printf("-p <%%> Minimum distance for kerning in percent of the global char width (lower values: Smaller gaps, more data)\n");
|
||||
printf("-x <n> X-Offset for 8x8 font sub-glyph extraction (requires -f 2, default 0)\n");
|
||||
printf("-y <n> Y-Offset for 8x8 font sub-glyph extraction (requires -f 2, default 0)\n");
|
||||
printf("-th <n> Horizontal size of the 8x8 glyphs (requires -f 2, default 1)\n");
|
||||
printf("-tv <n> Vertical size of the 8x8 glyphs (requires -f 2, default 1)\n");
|
||||
|
||||
printf("-n <name> C indentifier (font name)\n");
|
||||
printf("-d <file> Overview picture: Enable generation of bdf.tga and assign BDF font <file> for description\n");
|
||||
printf("-l <margin> Overview picture: Set left margin\n");
|
||||
printf("-g <glyphs> Overview picture: Set glyphs per line (default: 16)\n");
|
||||
printf("-a Overview picture: Additional font information (background, orange&blue dot)\n");
|
||||
printf("-t Overview picture: Test string (Woven silk pyjamas exchanged for blue quartz.)\n");
|
||||
printf("-r Runtime test\n");
|
||||
printf("\n");
|
||||
|
||||
printf("map := <mapcmd> { \",\" <mapcmd> }\n");
|
||||
printf("mapcmd := <default> | <maprange> | <exclude> | <exclude-kerning>\n");
|
||||
printf("default := \"*\"\n");
|
||||
printf("maprange := <range> [ \">\" <addexpr> ] Move specified glyph <range> to target code <num>\n");
|
||||
printf("exclude := \"~\" <range> \n");
|
||||
printf("exclude-kerning:= \"x\" <range> \n");
|
||||
printf("range := <addexpr> [ \"-\" <addexpr> ] Select glyphs within specified range\n");
|
||||
printf("addexpr := <mulexpr> [ \"+\" <mulexpr> ]\n");
|
||||
printf("mulexpr := <num> [ \"*\" <num> ]\n");
|
||||
printf("num := <hexnum> | <decnum>\n");
|
||||
printf("hexnum := \"$\" <hexdigit> { <hexdigit> }\n");
|
||||
printf("decnum := <decdigit> { <decdigit> }\n");
|
||||
printf("decdigit := \"0\" | \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\"\n");
|
||||
printf("hexdigit := \"a\" | \"b\" | \"c\" | \"d\" | \"e\" | \"f\" | \"A\" | \"B\" | \"C\" | \"D\" | \"E\" | \"F\" | <decdigit>\n");
|
||||
|
||||
printf("{ } zero, one ore more, [ ] zero or once, | alternative\n");
|
||||
|
||||
printf("example:\n");
|
||||
printf(" -m '32-255' select gylphs from encoding 32 to 255\n");
|
||||
printf(" -m '32-255,~64' select gylphs from encoding 32 to 255, exclude '@'\n");
|
||||
printf(" -m '32,48-57' select space, '1', '2', ... '9'\n");
|
||||
printf("build modes:\n");
|
||||
printf(" -b 0: Most compact, glyph bitmap is minimal\n");
|
||||
printf(" -b 1: Like -b 0, but glyph bitmap is extended to the height of the largest glyph within the selected glyph list.\n");
|
||||
printf(" Also the width of the gylphs is extended to cover the delta x advance.\n");
|
||||
printf(" -b 2: Like -b 1, but glyph width is set to the width of the largest glyph within the selected gylph list.\n");
|
||||
printf(" -b 3: Like -b 2, but width and height are forced to be a multiple of 8.\n");
|
||||
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
|
||||
unsigned long left_margin = 1;
|
||||
unsigned long build_bbx_mode = 0;
|
||||
unsigned long font_format = 0;
|
||||
unsigned long min_distance_in_per_cent_of_char_width = 25;
|
||||
unsigned long cmdline_glyphs_per_line = 16;
|
||||
unsigned long xoffset = 0;
|
||||
unsigned long yoffset = 0;
|
||||
unsigned long tile_h_size = 1;
|
||||
unsigned long tile_v_size = 1;
|
||||
int font_picture_extra_info = 0;
|
||||
int font_picture_test_string = 0;
|
||||
int runtime_test = 0;
|
||||
char *c_filename = NULL;
|
||||
char *k_filename = NULL;
|
||||
char *target_fontname = "bdf_font";
|
||||
|
||||
/*================================================*/
|
||||
|
||||
unsigned tga_get_line_height(bf_t *bf_desc_font, bf_t *bf)
|
||||
{
|
||||
unsigned h;
|
||||
tga_set_font(bf_desc_font->target_data);
|
||||
h = tga_get_char_height();
|
||||
tga_set_font(bf->target_data);
|
||||
if ( h < tga_get_char_height() )
|
||||
return tga_get_char_height();
|
||||
return h;
|
||||
}
|
||||
|
||||
unsigned tga_draw_font_line(unsigned y, long enc_start, bf_t *bf_desc_font, bf_t *bf, long glyphs_per_line)
|
||||
{
|
||||
long i;
|
||||
unsigned x;
|
||||
int is_empty;
|
||||
char pre[32];
|
||||
|
||||
is_empty = 1;
|
||||
for( i = 0; i< 16 && is_empty != 0; i++ )
|
||||
{
|
||||
if ( tga_get_glyph_data(i+enc_start) != NULL )
|
||||
is_empty = 0;
|
||||
}
|
||||
|
||||
if ( is_empty != 0 )
|
||||
return 0;
|
||||
|
||||
sprintf(pre, "%5ld/0x%04lx", enc_start, enc_start);
|
||||
|
||||
x = left_margin;
|
||||
if ( bf_desc_font != NULL )
|
||||
{
|
||||
if ( bf_desc_font->target_data != NULL )
|
||||
{
|
||||
tga_set_font(bf_desc_font->target_data);
|
||||
x += tga_draw_string(x, y, pre, 0, 0);
|
||||
}
|
||||
}
|
||||
x += 4;
|
||||
|
||||
tga_set_font(bf->target_data);
|
||||
for( i = 0; i< glyphs_per_line; i++ )
|
||||
{
|
||||
tga_draw_glyph(x + (tga_get_char_width()+2)*i,y,enc_start+i, font_picture_extra_info);
|
||||
}
|
||||
|
||||
return left_margin + x + (tga_get_char_width()+2)*glyphs_per_line;
|
||||
}
|
||||
|
||||
unsigned tga_draw_font_info(unsigned y, const char *fontname, bf_t *bf_desc_font, bf_t *bf)
|
||||
{
|
||||
unsigned x;
|
||||
int cap_a, cap_a_height;
|
||||
static char s[256];
|
||||
|
||||
cap_a_height = 0;
|
||||
cap_a = bf_GetIndexByEncoding(bf, 'A');
|
||||
if ( cap_a >= 0 )
|
||||
{
|
||||
cap_a_height = bf->glyph_list[cap_a]->bbx.h+bf->glyph_list[cap_a]->bbx.y;
|
||||
}
|
||||
|
||||
if ( bf_desc_font != NULL )
|
||||
{
|
||||
if ( bf_desc_font->target_data != NULL )
|
||||
{
|
||||
|
||||
tga_set_font(bf_desc_font->target_data);
|
||||
|
||||
y += tga_get_char_height()+1;
|
||||
x = left_margin;
|
||||
x += tga_draw_string(x, y, fontname, 0, 0);
|
||||
|
||||
y += tga_get_char_height()+1;
|
||||
sprintf(s, "Max width %u, max height %u", tga_get_char_width(), tga_get_char_height());
|
||||
x = left_margin;
|
||||
x += tga_draw_string(x, y, s, 0, 0);
|
||||
|
||||
y += tga_get_char_height()+1;
|
||||
sprintf(s, "'A' height %d, font size %d ", cap_a_height, bf->target_cnt);
|
||||
x = left_margin;
|
||||
x += tga_draw_string(x, y, s, 0, 0);
|
||||
return (tga_get_char_height()+1)*3;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned tga_draw_font(unsigned y, const char *fontname, bf_t *bf_desc_font, bf_t *bf, long glyphs_per_line)
|
||||
{
|
||||
long i;
|
||||
unsigned x, xmax;
|
||||
xmax = 0;
|
||||
|
||||
bf_Log(bf, "Draw TGA, line height %d", tga_get_line_height(bf_desc_font, bf));
|
||||
|
||||
y += tga_draw_font_info( y, fontname, bf_desc_font, bf);
|
||||
|
||||
y += tga_get_line_height(bf_desc_font, bf)+1;
|
||||
|
||||
|
||||
|
||||
for( i = 0; i <= 0x0ffff; i+=glyphs_per_line )
|
||||
{
|
||||
x = tga_draw_font_line(y, i, bf_desc_font, bf, glyphs_per_line);
|
||||
if ( x > 0 )
|
||||
{
|
||||
if ( xmax < x )
|
||||
xmax = x;
|
||||
y += tga_get_line_height(bf_desc_font, bf)+1;
|
||||
//bf_Log(bf, "Draw TGA, encoding %04x, y %d", i, y);
|
||||
}
|
||||
}
|
||||
|
||||
bf_Log(bf, "Draw TGA, xmax %d", xmax);
|
||||
|
||||
tga_set_font(bf->target_data);
|
||||
|
||||
//tga_draw_string(0, y, "Woven silk pyjamas exchanged for blue quartz", 1, xmax);
|
||||
//y += tga_get_char_height()+1;
|
||||
if ( font_picture_test_string != 0 )
|
||||
{
|
||||
tga_draw_string(left_margin, y, "Woven silk pyjamas exchanged for blue quartz.", 0, xmax);
|
||||
y += tga_get_line_height(bf_desc_font, bf)+1;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* main */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bf_t *bf_desc_font;
|
||||
bf_t *bf;
|
||||
char *bdf_filename = NULL;
|
||||
int is_verbose = 0;
|
||||
char *map_str ="*";
|
||||
char *map_filename ="";
|
||||
char *desc_font_str = "";
|
||||
unsigned y;
|
||||
|
||||
argv++;
|
||||
/*
|
||||
if ( *argv == NULL )
|
||||
{
|
||||
help();
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
for(;;)
|
||||
{
|
||||
if ( *argv == NULL )
|
||||
break;
|
||||
if ( is_arg(&argv, 'h') != 0 )
|
||||
{
|
||||
help();
|
||||
exit(1);
|
||||
}
|
||||
else if ( is_arg(&argv, 'v') != 0 )
|
||||
{
|
||||
is_verbose = 1;
|
||||
}
|
||||
else if ( is_arg(&argv, 'a') != 0 )
|
||||
{
|
||||
font_picture_extra_info = 1;
|
||||
}
|
||||
else if ( get_num_strarg(&argv, "th", &tile_h_size) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_num_strarg(&argv, "tv", &tile_v_size) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( is_arg(&argv, 't') != 0 )
|
||||
{
|
||||
font_picture_test_string = 1;
|
||||
}
|
||||
else if ( is_arg(&argv, 'r') != 0 )
|
||||
{
|
||||
runtime_test = 1;
|
||||
}
|
||||
else if ( get_num_arg(&argv, 'g', &cmdline_glyphs_per_line) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_num_arg(&argv, 'b', &build_bbx_mode) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_num_arg(&argv, 'f', &font_format) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_num_arg(&argv, 'x', &xoffset) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_num_arg(&argv, 'y', &yoffset) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_num_arg(&argv, 'l', &left_margin) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_num_arg(&argv, 'p', &min_distance_in_per_cent_of_char_width) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_str_arg(&argv, 'd', &desc_font_str) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_str_arg(&argv, 'o', &c_filename) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_str_arg(&argv, 'n', &target_fontname) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_str_arg(&argv, 'm', &map_str) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_str_arg(&argv, 'k', &k_filename) != 0 )
|
||||
{
|
||||
}
|
||||
else if ( get_str_arg(&argv, 'M', &map_filename) != 0 )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
bdf_filename = *argv;
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bdf_filename == NULL )
|
||||
{
|
||||
help();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bf_desc_font = NULL;
|
||||
if ( desc_font_str[0] != '\0' )
|
||||
{
|
||||
bf_desc_font = bf_OpenFromFile(desc_font_str, 0, BDF_BBX_MODE_MINIMAL, "*", "", 0, 0, 0, 1, 1); /* assume format 0 for description */
|
||||
if ( bf_desc_font == NULL )
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( font_format == 2 )
|
||||
{
|
||||
build_bbx_mode = BDF_BBX_MODE_M8;
|
||||
/* issue the following log message later, when there is a valid bf object */
|
||||
/* bf_Log(bf, "Font mode 1: BBX mode set to 3"); */
|
||||
}
|
||||
|
||||
/* render the complete font */
|
||||
bf = bf_OpenFromFile(bdf_filename, is_verbose, build_bbx_mode, map_str, map_filename, font_format, xoffset, yoffset, tile_h_size, tile_v_size);
|
||||
|
||||
if ( bf == NULL )
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( font_format == 2 )
|
||||
{
|
||||
/* now generate the log message */
|
||||
bf_Log(bf, "Note: For font format 2 BBX mode has been set to 3");
|
||||
}
|
||||
|
||||
if ( bf_desc_font != NULL )
|
||||
{
|
||||
if ( font_format == 2 )
|
||||
{
|
||||
bf_Log(bf, "Note: Overview Picture not possible for font format 2, option -d ignored.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tga_init(1024, 1024*12);
|
||||
if ( target_fontname[0] != '\0' )
|
||||
y = tga_draw_font(0, target_fontname, bf_desc_font, bf, cmdline_glyphs_per_line);
|
||||
else
|
||||
y = tga_draw_font(0, bdf_filename, bf_desc_font, bf, cmdline_glyphs_per_line);
|
||||
|
||||
if ( runtime_test != 0 )
|
||||
{
|
||||
long i;
|
||||
clock_t c = clock();
|
||||
fd_t fd;
|
||||
fd_init(&fd);
|
||||
fd_set_font(&fd, bf->target_data);
|
||||
for( i = 0; i < 10000; i++ )
|
||||
fd_draw_string(&fd, left_margin, y, "Woven silk pyjamas exchanged for blue quartz.");
|
||||
bf_Log(bf, "Runtime test: %.2lf sec", (double)(clock()-c)/(double)CLOCKS_PER_SEC);
|
||||
}
|
||||
|
||||
tga_set_pixel(1, 1, 0, 0, 0);
|
||||
|
||||
tga_save("bdf.tga");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( c_filename != NULL )
|
||||
{
|
||||
/* write the encoded data in bf->target_data */
|
||||
if ( font_format == 0 )
|
||||
{
|
||||
bf_WriteUCGCByFilename(bf, c_filename, target_fontname, " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* font format >= 1 are for u8g2, the following procedure just writes the content to the file */
|
||||
bf_WriteU8G2CByFilename(bf, c_filename, target_fontname, " "); /* bdf_font.c */
|
||||
}
|
||||
}
|
||||
|
||||
if ( k_filename != NULL )
|
||||
{
|
||||
bdf_calculate_all_kerning(bf, k_filename, target_fontname, min_distance_in_per_cent_of_char_width);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bf_Close(bf);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user