First jameswitzema.net commit
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
<!-- Accept terminus font -->
|
||||
<selectfont>
|
||||
<acceptfont>
|
||||
<pattern>
|
||||
<patelt name="family"><string>Terminus</string></patelt>
|
||||
</pattern>
|
||||
</acceptfont>
|
||||
</selectfont>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1 @@
|
||||
Dimitar Zhekov <dimitar.zhekov@gmail.com>
|
||||
@@ -0,0 +1,112 @@
|
||||
Version 4.49.1:
|
||||
* Fixed install-otb and uninstall-otb to use otbdir instead of x11dir.
|
||||
|
||||
Version 4.49:
|
||||
* Added Open Type Bitmap support.
|
||||
* Altered ascii grave in some sizes to be more useful as a back quote.
|
||||
* Fixed 21B5, added 21B2 and 21B3.
|
||||
|
||||
Version 4.48:
|
||||
|
||||
* Added the basic 27 hebrew letters and sheqel, with uppercase height.
|
||||
* Some improvements in the font build scripts.
|
||||
|
||||
Version 4.47:
|
||||
|
||||
* Added 35 new characters (33 glyphs).
|
||||
* Replaced ao2-variant "ae" with ao1 "ae", it was too similar to "oe".
|
||||
* Some fixes and improvements (17 characters in various sizes/styles).
|
||||
* Significantly improved the font conversion tools. Python 3.5.0 or
|
||||
Node 6.9.0 are now required to build the font.
|
||||
|
||||
Version 4.46:
|
||||
|
||||
* The X11 8-bit code pages are not installed by default.
|
||||
* Added IBM-437 8-bit code page for X11.
|
||||
* The CRT VGA weight for Linux console is not installed by default.
|
||||
* Removed the Linux console mapping files.
|
||||
They should be provided by the console packages.
|
||||
* Removed the BSD console installation.
|
||||
The recent BSD-s have a new console subsystem.
|
||||
* Added 50 new characters. Mostly math, but also Buglarian yat and yus.
|
||||
* Rewritten the font conversion tools in python and javascript.
|
||||
The full unicode range (17x64K) is now supported.
|
||||
* The Windows installer can be built from sources.
|
||||
* Small fixes and improvements (7 characters in various sizes).
|
||||
* Renamed (un)install-ref to (un)install-psf-ref.
|
||||
|
||||
Version 4.40:
|
||||
|
||||
* Added 6 combining accents as separate characters.
|
||||
* Added 14 letters with dot above / dot below.
|
||||
* Added partial subscript and superscript: all digits and 11 letters.
|
||||
* Added 30+ math characters, notably large braces, brackets and parens.
|
||||
* Added unicode range 2800-28FF in two variants (br1 and br2).
|
||||
* A few small character fixes.
|
||||
* Altered configure to be a bit more POSIX compliant.
|
||||
* Replaced some obscure (un)install Makefile targets with variables.
|
||||
|
||||
Version 4.39:
|
||||
|
||||
* Added ballot, checkmark, heavy ballot and heavy checkmark.
|
||||
* Changed HT, LF etc. in sizes 14 and 18-hi2 to be proportional to the
|
||||
letter height, not the matrix height.
|
||||
* Added the powerline characters E0A0..E0A2 and E0B0..E0B3.
|
||||
* Added diameter (2300) - same gluph as empty set (2205).
|
||||
* Small improvements in size 32.
|
||||
|
||||
Version 4.38:
|
||||
|
||||
* Added 23 pseudographic characters, most notably rounded frames.
|
||||
* Added new td1 variant with centered ascii tidle.
|
||||
* Fixed Y acute in sizes 22 and 28, internal optimizations (invisible).
|
||||
|
||||
Version 4.36:
|
||||
|
||||
* Removed the rarely used cm2 variant.
|
||||
* Added new ll2 variant with more distinctive l.
|
||||
* Added quotereversed (201B), quotedblreversed (201F), I/i/U/u dotbelow
|
||||
(1ECA, 1ECB, 1EE4, 1EE5).
|
||||
* Moved all quotes and alike in size 32 one line down.
|
||||
* Small fixes and improvements (t commaaccent, quotes alignment etc. in
|
||||
some sizes).
|
||||
* Windows installation: creates the relevant registry key.
|
||||
|
||||
Version 4.35:
|
||||
|
||||
* Added hi2 variant for size 18.
|
||||
* Fixes in size 18: normal V, normal W, bold X, H stroke, some
|
||||
pseudographic characters and the *NIX installation.
|
||||
|
||||
Version 4.34:
|
||||
|
||||
* Added size 10x18.
|
||||
* Small fixes and improvements in section, multiply, Eng/eng, Dje,
|
||||
dje, house, male, zeta and various characters in the different sizes.
|
||||
* The default cyrillic ghe is now ge1, with ge2 available as an option.
|
||||
|
||||
Version 4.32:
|
||||
|
||||
* Slightly more distintive normal M and W.
|
||||
* Rounded 28-bold, 32-normal, 32-bold.
|
||||
Also removed the 32-normal kx2 style.
|
||||
* Small changes: Che/che stroke, phi, Zhe/zhe etc.
|
||||
* Linux console: the default bold is now framebuffer.
|
||||
* Smaller Makefile, GNU make required.
|
||||
* Changed the font license to SIL OFL 1.1.
|
||||
It's FSF approved, no need to worry.
|
||||
* And, as you can see, Terminus Font is now on sourceforge.
|
||||
|
||||
Version 4.30:
|
||||
|
||||
* Added size 22 (not very good).
|
||||
* Added another 25 characters.
|
||||
* Various small fixes and improvements.
|
||||
* Changed the default prefix and x11dir.
|
||||
|
||||
Version 4.28:
|
||||
|
||||
* Heavy frames (written mostly by Tim Allen) and a few more letters.
|
||||
* Altered trianges and arrows, small bugfixes.
|
||||
* Reorganized the 512-character console font to include more letters
|
||||
instead of the IBM-437 specific pseudographics.
|
||||
@@ -0,0 +1 @@
|
||||
See OFL.TXT
|
||||
@@ -0,0 +1 @@
|
||||
See README
|
||||
@@ -0,0 +1,315 @@
|
||||
INT = python3
|
||||
EXT = py
|
||||
BIN = ./bin
|
||||
|
||||
UCS2ANY = $(INT) $(BIN)/ucstoany.$(EXT)
|
||||
BDF2PSF = $(INT) $(BIN)/bdftopsf.$(EXT)
|
||||
UCS2X11 = $(INT) $(BIN)/ucstoany.$(EXT) -f
|
||||
BDF2PCF = bdftopcf
|
||||
#BDF2OTB = fontforge -lang=ff -c 'Open($$3); ScaleToEm(1024); Generate($$2)'
|
||||
BDF2OTB = $(INT) $(BIN)/otb1cli.$(EXT)
|
||||
|
||||
REG_8859_1 = ISO8859 1
|
||||
REG_8859_2 = ISO8859 2
|
||||
REG_8859_5 = ISO8859 5
|
||||
REG_8859_7 = ISO8859 7
|
||||
REG_8859_9 = ISO8859 9
|
||||
REG_MS_1251 = Microsoft CP1251
|
||||
REG_8859_13 = ISO8859 13
|
||||
REG_8859_15 = ISO8859 15
|
||||
REG_8859_16 = ISO8859 16
|
||||
REG_MS_1255 = Microsoft CP1255
|
||||
REG_IBM_437 = IBM CP437
|
||||
REG_KOI8_R = KOI8 R
|
||||
REG_KOI8_U = KOI8 U
|
||||
REG_BG_MIK = Bulgarian MIK
|
||||
REG_PT_154 = Paratype PT154
|
||||
REG_XOS4_2 = XOS4 2
|
||||
REG_10646_1 = ISO10646 1
|
||||
|
||||
PSF_8859_1 = ter-112n.psf ter-114n.psf ter-114b.psf ter-116n.psf ter-116b.psf ter-118n.psf ter-118b.psf ter-120n.psf ter-120b.psf ter-122n.psf ter-122b.psf ter-124n.psf ter-124b.psf ter-128n.psf ter-128b.psf ter-132n.psf ter-132b.psf
|
||||
PSF_8859_2 = ter-212n.psf ter-214n.psf ter-214b.psf ter-216n.psf ter-216b.psf ter-218n.psf ter-218b.psf ter-220n.psf ter-220b.psf ter-222n.psf ter-222b.psf ter-224n.psf ter-224b.psf ter-228n.psf ter-228b.psf ter-232n.psf ter-232b.psf
|
||||
PSF_8859_7 = ter-712n.psf ter-714n.psf ter-714b.psf ter-716n.psf ter-716b.psf ter-718n.psf ter-718b.psf ter-720n.psf ter-720b.psf ter-722n.psf ter-722b.psf ter-724n.psf ter-724b.psf ter-728n.psf ter-728b.psf ter-732n.psf ter-732b.psf
|
||||
PSF_8859_9 = ter-912n.psf ter-914n.psf ter-914b.psf ter-916n.psf ter-916b.psf ter-918n.psf ter-918b.psf ter-920n.psf ter-920b.psf ter-922n.psf ter-922b.psf ter-924n.psf ter-924b.psf ter-928n.psf ter-928b.psf ter-932n.psf ter-932b.psf
|
||||
PSF_MS_1251 = ter-c12n.psf ter-c14n.psf ter-c14b.psf ter-c16n.psf ter-c16b.psf ter-c18n.psf ter-c18b.psf ter-c20n.psf ter-c20b.psf ter-c22n.psf ter-c22b.psf ter-c24n.psf ter-c24b.psf ter-c28n.psf ter-c28b.psf ter-c32n.psf ter-c32b.psf
|
||||
PSF_8859_13 = ter-d12n.psf ter-d14n.psf ter-d14b.psf ter-d16n.psf ter-d16b.psf ter-d18n.psf ter-d18b.psf ter-d20n.psf ter-d20b.psf ter-d22n.psf ter-d22b.psf ter-d24n.psf ter-d24b.psf ter-d28n.psf ter-d28b.psf ter-d32n.psf ter-d32b.psf
|
||||
PSF_8859_16 = ter-g12n.psf ter-g14n.psf ter-g14b.psf ter-g16n.psf ter-g16b.psf ter-g18n.psf ter-g18b.psf ter-g20n.psf ter-g20b.psf ter-g22n.psf ter-g22b.psf ter-g24n.psf ter-g24b.psf ter-g28n.psf ter-g28b.psf ter-g32n.psf ter-g32b.psf
|
||||
PSF_MS_1255 = ter-h12n.psf ter-h14n.psf ter-h14b.psf ter-h16n.psf ter-h16b.psf ter-h18n.psf ter-h18b.psf ter-h20n.psf ter-h20b.psf ter-h22n.psf ter-h22b.psf ter-h24n.psf ter-h24b.psf ter-h28n.psf ter-h28b.psf ter-h32n.psf ter-h32b.psf
|
||||
PSF_IBM_437 = ter-i12n.psf ter-i14n.psf ter-i14b.psf ter-i16n.psf ter-i16b.psf ter-i18n.psf ter-i18b.psf ter-i20n.psf ter-i20b.psf ter-i22n.psf ter-i22b.psf ter-i24n.psf ter-i24b.psf ter-i28n.psf ter-i28b.psf ter-i32n.psf ter-i32b.psf
|
||||
PSF_KOI8_RV = ter-k14n.psf ter-k14b.psf ter-k16n.psf ter-k16b.psf
|
||||
PSF_KOI8_R = ter-k12n.psf ter-k18n.psf ter-k18b.psf ter-k20n.psf ter-k20b.psf ter-k22n.psf ter-k22b.psf ter-k24n.psf ter-k24b.psf ter-k28n.psf ter-k28b.psf ter-k32n.psf ter-k32b.psf
|
||||
PSF_BG_MIK = ter-m12n.psf ter-m14n.psf ter-m14b.psf ter-m16n.psf ter-m16b.psf ter-m18n.psf ter-m18b.psf ter-m20n.psf ter-m20b.psf ter-m22n.psf ter-m22b.psf ter-m24n.psf ter-m24b.psf ter-m28n.psf ter-m28b.psf ter-m32n.psf ter-m32b.psf
|
||||
PSF_PT_154 = ter-p12n.psf ter-p14n.psf ter-p14b.psf ter-p16n.psf ter-p16b.psf ter-p18n.psf ter-p18b.psf ter-p20n.psf ter-p20b.psf ter-p22n.psf ter-p22b.psf ter-p24n.psf ter-p24b.psf ter-p28n.psf ter-p28b.psf ter-p32n.psf ter-p32b.psf
|
||||
PSF_KOI8_UV = ter-u14n.psf ter-u14b.psf ter-u16n.psf ter-u16b.psf
|
||||
PSF_KOI8_U = ter-u12n.psf ter-u18n.psf ter-u18b.psf ter-u20n.psf ter-u20b.psf ter-u22n.psf ter-u22b.psf ter-u24n.psf ter-u24b.psf ter-u28n.psf ter-u28b.psf ter-u32n.psf ter-u32b.psf
|
||||
PSF_XOS4_2 = ter-v12n.psf ter-v14n.psf ter-v14b.psf ter-v16n.psf ter-v16b.psf ter-v18n.psf ter-v18b.psf ter-v20n.psf ter-v20b.psf ter-v22n.psf ter-v22b.psf ter-v24n.psf ter-v24b.psf ter-v28n.psf ter-v28b.psf ter-v32n.psf ter-v32b.psf
|
||||
PSF = $(PSF_8859_1) $(PSF_8859_2) $(PSF_8859_7) $(PSF_8859_9) $(PSF_MS_1251) $(PSF_8859_13) $(PSF_8859_16) $(PSF_MS_1255) $(PSF_IBM_437) $(PSF_KOI8_RV) $(PSF_KOI8_R) $(PSF_BG_MIK) $(PSF_PT_154) $(PSF_KOI8_UV) $(PSF_KOI8_U) $(PSF_XOS4_2)
|
||||
|
||||
PSF_VGAW_8859_1 = ter-114v.psf ter-116v.psf
|
||||
PSF_VGAW_8859_2 = ter-214v.psf ter-216v.psf
|
||||
PSF_VGAW_8859_7 = ter-714v.psf ter-716v.psf
|
||||
PSF_VGAW_8859_9 = ter-914v.psf ter-916v.psf
|
||||
PSF_VGAW_MS_1251 = ter-c14v.psf ter-c16v.psf
|
||||
PSF_VGAW_8859_13 = ter-d14v.psf ter-d16v.psf
|
||||
PSF_VGAW_8859_16 = ter-g14v.psf ter-g16v.psf
|
||||
PSF_VGAW_MS_1255 = ter-h14v.psf ter-h16v.psf
|
||||
PSF_VGAW_IBM_437 = ter-i14v.psf ter-i16v.psf
|
||||
PSF_VGAW_KOI8_RV = ter-k14v.psf ter-k16v.psf
|
||||
PSF_VGAW_BG_MIK = ter-m14v.psf ter-m16v.psf
|
||||
PSF_VGAW_PT_154 = ter-p14v.psf ter-p16v.psf
|
||||
PSF_VGAW_KOI8_UV = ter-u14v.psf ter-u16v.psf
|
||||
PSF_VGAW_XOS4_2 = ter-v14v.psf ter-v16v.psf
|
||||
PSF_VGAW = $(PSF_VGAW_8859_1) $(PSF_VGAW_8859_2) $(PSF_VGAW_8859_7) $(PSF_VGAW_8859_9) $(PSF_VGAW_MS_1251) $(PSF_VGAW_8859_13) $(PSF_VGAW_8859_16) $(PSF_VGAW_MS_1255) $(PSF_VGAW_IBM_437) $(PSF_VGAW_KOI8_RV) $(PSF_VGAW_BG_MIK) $(PSF_VGAW_PT_154) $(PSF_VGAW_KOI8_UV) $(PSF_VGAW_XOS4_2)
|
||||
|
||||
PCF_8859_1 = ter-112n.pcf ter-112b.pcf ter-114n.pcf ter-114b.pcf ter-116n.pcf ter-116b.pcf ter-118n.pcf ter-118b.pcf ter-120n.pcf ter-120b.pcf ter-122n.pcf ter-122b.pcf ter-124n.pcf ter-124b.pcf ter-128n.pcf ter-128b.pcf ter-132n.pcf ter-132b.pcf
|
||||
PCF_8859_2 = ter-212n.pcf ter-212b.pcf ter-214n.pcf ter-214b.pcf ter-216n.pcf ter-216b.pcf ter-218n.pcf ter-218b.pcf ter-220n.pcf ter-220b.pcf ter-222n.pcf ter-222b.pcf ter-224n.pcf ter-224b.pcf ter-228n.pcf ter-228b.pcf ter-232n.pcf ter-232b.pcf
|
||||
PCF_8859_5 = ter-512n.pcf ter-512b.pcf ter-514n.pcf ter-514b.pcf ter-516n.pcf ter-516b.pcf ter-518n.pcf ter-518b.pcf ter-520n.pcf ter-520b.pcf ter-522n.pcf ter-522b.pcf ter-524n.pcf ter-524b.pcf ter-528n.pcf ter-528b.pcf ter-532n.pcf ter-532b.pcf
|
||||
PCF_8859_7 = ter-712n.pcf ter-712b.pcf ter-714n.pcf ter-714b.pcf ter-716n.pcf ter-716b.pcf ter-718n.pcf ter-718b.pcf ter-720n.pcf ter-720b.pcf ter-722n.pcf ter-722b.pcf ter-724n.pcf ter-724b.pcf ter-728n.pcf ter-728b.pcf ter-732n.pcf ter-732b.pcf
|
||||
PCF_8859_9 = ter-912n.pcf ter-912b.pcf ter-914n.pcf ter-914b.pcf ter-916n.pcf ter-916b.pcf ter-918n.pcf ter-918b.pcf ter-920n.pcf ter-920b.pcf ter-922n.pcf ter-922b.pcf ter-924n.pcf ter-924b.pcf ter-928n.pcf ter-928b.pcf ter-932n.pcf ter-932b.pcf
|
||||
PCF_MS_1251 = ter-c12n.pcf ter-c12b.pcf ter-c14n.pcf ter-c14b.pcf ter-c16n.pcf ter-c16b.pcf ter-c18n.pcf ter-c18b.pcf ter-c20n.pcf ter-c20b.pcf ter-c22n.pcf ter-c22b.pcf ter-c24n.pcf ter-c24b.pcf ter-c28n.pcf ter-c28b.pcf ter-c32n.pcf ter-c32b.pcf
|
||||
PCF_8859_13 = ter-d12n.pcf ter-d12b.pcf ter-d14n.pcf ter-d14b.pcf ter-d16n.pcf ter-d16b.pcf ter-d18n.pcf ter-d18b.pcf ter-d20n.pcf ter-d20b.pcf ter-d22n.pcf ter-d22b.pcf ter-d24n.pcf ter-d24b.pcf ter-d28n.pcf ter-d28b.pcf ter-d32n.pcf ter-d32b.pcf
|
||||
PCF_8859_15 = ter-f12n.pcf ter-f12b.pcf ter-f14n.pcf ter-f14b.pcf ter-f16n.pcf ter-f16b.pcf ter-f18n.pcf ter-f18b.pcf ter-f20n.pcf ter-f20b.pcf ter-f22n.pcf ter-f22b.pcf ter-f24n.pcf ter-f24b.pcf ter-f28n.pcf ter-f28b.pcf ter-f32n.pcf ter-f32b.pcf
|
||||
PCF_8859_16 = ter-g12n.pcf ter-g12b.pcf ter-g14n.pcf ter-g14b.pcf ter-g16n.pcf ter-g16b.pcf ter-g18n.pcf ter-g18b.pcf ter-g20n.pcf ter-g20b.pcf ter-g22n.pcf ter-g22b.pcf ter-g24n.pcf ter-g24b.pcf ter-g28n.pcf ter-g28b.pcf ter-g32n.pcf ter-g32b.pcf
|
||||
PCF_IBM_437 = ter-i12n.pcf ter-i12b.pcf ter-i14n.pcf ter-i14b.pcf ter-i16n.pcf ter-i16b.pcf ter-i18n.pcf ter-i18b.pcf ter-i20n.pcf ter-i20b.pcf ter-i22n.pcf ter-i22b.pcf ter-i24n.pcf ter-i24b.pcf ter-i28n.pcf ter-i28b.pcf ter-i32n.pcf ter-i32b.pcf
|
||||
PCF_KOI8_R = ter-k12n.pcf ter-k12b.pcf ter-k14n.pcf ter-k14b.pcf ter-k16n.pcf ter-k16b.pcf ter-k18n.pcf ter-k18b.pcf ter-k20n.pcf ter-k20b.pcf ter-k22n.pcf ter-k22b.pcf ter-k24n.pcf ter-k24b.pcf ter-k28n.pcf ter-k28b.pcf ter-k32n.pcf ter-k32b.pcf
|
||||
PCF_PT_154 = ter-p12n.pcf ter-p12b.pcf ter-p14n.pcf ter-p14b.pcf ter-p16n.pcf ter-p16b.pcf ter-p18n.pcf ter-p18b.pcf ter-p20n.pcf ter-p20b.pcf ter-p22n.pcf ter-p22b.pcf ter-p24n.pcf ter-p24b.pcf ter-p28n.pcf ter-p28b.pcf ter-p32n.pcf ter-p32b.pcf
|
||||
PCF_KOI8_U = ter-u12n.pcf ter-u12b.pcf ter-u14n.pcf ter-u14b.pcf ter-u16n.pcf ter-u16b.pcf ter-u18n.pcf ter-u18b.pcf ter-u20n.pcf ter-u20b.pcf ter-u22n.pcf ter-u22b.pcf ter-u24n.pcf ter-u24b.pcf ter-u28n.pcf ter-u28b.pcf ter-u32n.pcf ter-u32b.pcf
|
||||
PCF_10646_1 = ter-x12n.pcf ter-x12b.pcf ter-x14n.pcf ter-x14b.pcf ter-x16n.pcf ter-x16b.pcf ter-x18n.pcf ter-x18b.pcf ter-x20n.pcf ter-x20b.pcf ter-x22n.pcf ter-x22b.pcf ter-x24n.pcf ter-x24b.pcf ter-x28n.pcf ter-x28b.pcf ter-x32n.pcf ter-x32b.pcf
|
||||
PCF_8BIT = $(PCF_8859_1) $(PCF_8859_2) $(PCF_8859_5) $(PCF_8859_7) $(PCF_8859_9) $(PCF_MS_1251) $(PCF_8859_13) $(PCF_8859_15) $(PCF_8859_16) $(PCF_IBM_437) $(PCF_KOI8_R) $(PCF_PT_154) $(PCF_KOI8_U)
|
||||
PCF = $(PCF_10646_1)
|
||||
|
||||
OTB = ter-u12n.otb ter-u12b.otb ter-u14n.otb ter-u14b.otb ter-u16n.otb ter-u16b.otb ter-u18n.otb ter-u18b.otb ter-u20n.otb ter-u20b.otb ter-u22n.otb ter-u22b.otb ter-u24n.otb ter-u24b.otb ter-u28n.otb ter-u28b.otb ter-u32n.otb ter-u32b.otb
|
||||
|
||||
# Default
|
||||
|
||||
all: $(PSF) $(PCF)
|
||||
|
||||
DESTDIR =
|
||||
prefix = /usr/local
|
||||
psfdir = $(prefix)/share/consolefonts
|
||||
x11dir = $(prefix)/share/fonts/terminus
|
||||
otbdir = $(prefix)/share/fonts/terminus
|
||||
|
||||
install: $(PSF) $(PCF)
|
||||
mkdir -p $(DESTDIR)$(psfdir)
|
||||
for i in $(PSF) ; do gzip -c $$i > $(DESTDIR)$(psfdir)/$$i.gz ; done
|
||||
mkdir -p $(DESTDIR)$(x11dir)
|
||||
for i in $(PCF) ; do gzip -c $$i > $(DESTDIR)$(x11dir)/$$i.gz ; done
|
||||
|
||||
uninstall:
|
||||
for i in $(PSF) ; do rm -f $(DESTDIR)$(psfdir)/$$i.gz ; done
|
||||
for i in $(PCF) ; do rm -f $(DESTDIR)$(x11dir)/$$i.gz ; done
|
||||
|
||||
fontdir:
|
||||
mkfontscale $(DESTDIR)$(x11dir)
|
||||
mkfontdir $(DESTDIR)$(x11dir)
|
||||
fc-cache -f $(DESTDIR)$(x11dir)
|
||||
|
||||
# Linux Console
|
||||
|
||||
VGA_8859_1 = uni/vgagr.uni uni/ascii-h.uni uni/win-1252.uni
|
||||
VGA_8859_2 = uni/vgagr.uni uni/ascii-h.uni uni/vga-1250.uni uni/8859-2.uni
|
||||
VGA_8859_7 = uni/vgagr.uni uni/ascii-h.uni uni/vga-1253.uni uni/8859-7.uni
|
||||
VGA_8859_9 = uni/vgagr.uni uni/ascii-h.uni uni/win-1254.uni
|
||||
VGA_MS_1251 = uni/vgagr.uni uni/ascii-h.uni uni/vga-1251.uni uni/win-1251.uni
|
||||
VGA_8859_13 = uni/vgagr.uni uni/ascii-h.uni uni/vga-1257.uni uni/8859-13.uni
|
||||
VGA_8859_16 = uni/vgagr.uni uni/ascii-h.uni uni/nls-1250.uni uni/8859-16.uni
|
||||
VGA_MS_1255 = uni/vgagr.uni uni/ascii-h.uni uni/win-1255.uni
|
||||
VGA_IBM_437 = uni/cntrl.uni uni/ascii-h.uni uni/ibm-437.uni
|
||||
VGA_KOI8_RV = uni/cntrl.uni uni/ascii-h.uni uni/koibm8-r.uni
|
||||
VGA_KOI8_R = uni/cntrl.uni uni/ascii-h.uni uni/koi8-r.uni
|
||||
VGA_BG_MIK = uni/cntrl.uni uni/ascii-h.uni uni/bg-mik.uni
|
||||
VGA_PT_154 = uni/vgagr.uni uni/ascii-h.uni uni/pt-154.uni
|
||||
VGA_KOI8_UV = uni/cntrl.uni uni/ascii-h.uni uni/koibm8-u.uni
|
||||
VGA_KOI8_U = uni/cntrl.uni uni/ascii-h.uni uni/koi8-u.uni
|
||||
VGA_XOS4_2 = uni/xos4-2.uni
|
||||
|
||||
DUP_8859_1 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_8859_2 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_8859_7 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_8859_9 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_MS_1251 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_8859_13 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_8859_16 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_MS_1255 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_IBM_437 = dup/cntrl.dup dup/ascii-h.dup dup/ibm-437.dup
|
||||
DUP_KOI8_RV = dup/cntrl.dup dup/ascii-h.dup dup/koi8.dup
|
||||
DUP_KOI8_R = dup/cntrl.dup dup/ascii-h.dup dup/koi8.dup
|
||||
DUP_BG_MIK = dup/cntrl.dup dup/ascii-h.dup dup/ibm-437.dup
|
||||
DUP_PT_154 = dup/vgagr.dup dup/ascii-h.dup
|
||||
DUP_KOI8_UV = dup/cntrl.dup dup/ascii-h.dup dup/koi8.dup
|
||||
DUP_KOI8_U = dup/cntrl.dup dup/ascii-h.dup dup/koi8.dup
|
||||
DUP_XOS4_2 = dup/vgagr.dup dup/xos4-2.dup
|
||||
|
||||
$(PSF_8859_1) $(PSF_VGAW_8859_1): ter-1%.psf : ter-u%.bdf $(VGA_8859_1) $(DUP_8859_1)
|
||||
$(UCS2ANY) $< $(REG_8859_1) $(VGA_8859_1) | $(BDF2PSF) -o $@ $(DUP_8859_1)
|
||||
|
||||
$(PSF_8859_2) $(PSF_VGAW_8859_2): ter-2%.psf : ter-u%.bdf $(VGA_8859_2) $(DUP_8859_2)
|
||||
$(UCS2ANY) $< $(REG_8859_2) $(VGA_8859_2) | $(BDF2PSF) -o $@ $(DUP_8859_2)
|
||||
|
||||
$(PSF_8859_7) $(PSF_VGAW_8859_7): ter-7%.psf : ter-u%.bdf $(VGA_8859_7) $(DUP_8859_7)
|
||||
$(UCS2ANY) $< $(REG_8859_7) $(VGA_8859_7) | $(BDF2PSF) -o $@ $(DUP_8859_7)
|
||||
|
||||
$(PSF_8859_9) $(PSF_VGAW_8859_9): ter-9%.psf : ter-u%.bdf $(VGA_8859_9) $(DUP_8859_9)
|
||||
$(UCS2ANY) $< $(REG_8859_9) $(VGA_8859_9) | $(BDF2PSF) -o $@ $(DUP_8859_9)
|
||||
|
||||
$(PSF_MS_1251) $(PSF_VGAW_MS_1251): ter-c%.psf : ter-u%.bdf $(VGA_MS_1251) $(DUP_MS_1251)
|
||||
$(UCS2ANY) $< $(REG_MS_1251) $(VGA_MS_1251) | $(BDF2PSF) -o $@ $(DUP_MS_1251)
|
||||
|
||||
$(PSF_8859_13) $(PSF_VGAW_8859_13): ter-d%.psf : ter-u%.bdf $(VGA_8859_13) $(DUP_8859_13)
|
||||
$(UCS2ANY) $< $(REG_8859_13) $(VGA_8859_13) | $(BDF2PSF) -o $@ $(DUP_8859_13)
|
||||
|
||||
$(PSF_8859_16) $(PSF_VGAW_8859_16): ter-g%.psf : ter-u%.bdf $(VGA_8859_16) $(DUP_8859_16)
|
||||
$(UCS2ANY) $< $(REG_8859_16) $(VGA_8859_16) | $(BDF2PSF) -o $@ $(DUP_8859_16)
|
||||
|
||||
$(PSF_MS_1255) $(PSF_VGAW_MS_1255): ter-h%.psf : ter-u%.bdf $(VGA_MS_1255) $(DUP_MS_1255)
|
||||
$(UCS2ANY) $< $(REG_MS_1255) $(VGA_MS_1255) | $(BDF2PSF) -o $@ $(DUP_MS_1255)
|
||||
|
||||
$(PSF_IBM_437) $(PSF_VGAW_IBM_437): ter-i%.psf : ter-u%.bdf $(VGA_IBM_437) $(DUP_IBM_437)
|
||||
$(UCS2ANY) $< $(REG_IBM_437) $(VGA_IBM_437) | $(BDF2PSF) -o $@ $(DUP_IBM_437)
|
||||
|
||||
$(PSF_KOI8_RV) $(PSF_VGAW_KOI8_RV): ter-k%.psf : ter-u%.bdf $(VGA_KOI8_RV) $(DUP_KOI8_RV)
|
||||
$(UCS2ANY) $< $(REG_KOI8_R) $(VGA_KOI8_RV) | $(BDF2PSF) -o $@ $(DUP_KOI8_RV)
|
||||
|
||||
$(PSF_KOI8_R): ter-k%.psf : ter-u%.bdf $(VGA_KOI8_R) $(DUP_KOI8_R)
|
||||
$(UCS2ANY) $< $(REG_KOI8_R) $(VGA_KOI8_R) | $(BDF2PSF) -o $@ $(DUP_KOI8_R)
|
||||
|
||||
$(PSF_BG_MIK) $(PSF_VGAW_BG_MIK): ter-m%.psf : ter-u%.bdf $(VGA_BG_MIK) $(DUP_BG_MIK)
|
||||
$(UCS2ANY) $< $(REG_BG_MIK) $(VGA_BG_MIK) | $(BDF2PSF) -o $@ $(DUP_BG_MIK)
|
||||
|
||||
$(PSF_PT_154) $(PSF_VGAW_PT_154): ter-p%.psf : ter-u%.bdf $(VGA_PT_154) $(DUP_PT_154)
|
||||
$(UCS2ANY) $< $(REG_PT_154) $(VGA_PT_154) | $(BDF2PSF) -o $@ $(DUP_PT_154)
|
||||
|
||||
$(PSF_KOI8_UV) $(PSF_VGAW_KOI8_UV): ter-u%.psf : ter-u%.bdf $(VGA_KOI8_UV) $(DUP_KOI8_UV)
|
||||
$(UCS2ANY) $< $(REG_KOI8_R) $(VGA_KOI8_UV) | $(BDF2PSF) -o $@ $(DUP_KOI8_UV)
|
||||
|
||||
$(PSF_KOI8_U): ter-u%.psf : ter-u%.bdf $(VGA_KOI8_U) $(DUP_KOI8_U)
|
||||
$(UCS2ANY) $< $(REG_KOI8_U) $(VGA_KOI8_U) | $(BDF2PSF) -o $@ $(DUP_KOI8_U)
|
||||
|
||||
$(PSF_XOS4_2) $(PSF_VGAW_XOS4_2): ter-v%.psf : ter-u%.bdf $(VGA_XOS4_2) $(DUP_XOS4_2)
|
||||
$(UCS2ANY) $< $(REG_XOS4_2) $(VGA_XOS4_2) | $(BDF2PSF) -o $@ $(DUP_XOS4_2)
|
||||
|
||||
psf: $(PSF)
|
||||
|
||||
install-psf: $(PSF)
|
||||
mkdir -p $(DESTDIR)$(psfdir)
|
||||
for i in $(PSF) ; do gzip -c $$i > $(DESTDIR)$(psfdir)/$$i.gz ; done
|
||||
|
||||
uninstall-psf:
|
||||
for i in $(PSF) ; do rm -f $(DESTDIR)$(psfdir)/$$i.gz ; done
|
||||
|
||||
psf-vgaw: $(PSF_VGAW)
|
||||
|
||||
install-psf-vgaw: $(PSF_VGAW)
|
||||
mkdir -p $(DESTDIR)$(psfdir)
|
||||
for i in $(PSF_VGAW) ; do gzip -c $$i > $(DESTDIR)$(psfdir)/$$i.gz ; done
|
||||
|
||||
uninstall-psf-vgaw:
|
||||
for i in $(PSF_VGAW) ; do rm -f $(DESTDIR)$(psfdir)/$$i.gz ; done
|
||||
|
||||
psfref = $(psfdir)/README.terminus
|
||||
|
||||
install-psf-ref: README
|
||||
mkdir -p $(DESTDIR)$(psfdir)
|
||||
sed -e"/^2\.4/,/^2\.5/p" -n README | grep -v "^2\." > $(DESTDIR)$(psfref)
|
||||
|
||||
uninstall-psf-ref:
|
||||
rm -f $(DESTDIR)$(psfref)
|
||||
|
||||
# X11 Window System
|
||||
|
||||
X11_8859_1 = uni/x11gr.uni uni/ascii-h.uni uni/win-1252.uni
|
||||
X11_8859_2 = uni/x11gr.uni uni/ascii-h.uni uni/empty.uni uni/8859-2.uni
|
||||
X11_8859_5 = uni/x11gr.uni uni/ascii-h.uni uni/empty.uni uni/8859-5.uni
|
||||
X11_8859_7 = uni/x11gr.uni uni/ascii-h.uni uni/empty.uni uni/8859-7.uni
|
||||
X11_8859_9 = uni/x11gr.uni uni/ascii-h.uni uni/win-1254.uni
|
||||
X11_MS_1251 = uni/x11gr.uni uni/ascii-h.uni uni/x11-1251.uni uni/win-1251.uni
|
||||
X11_8859_13 = uni/x11gr.uni uni/ascii-h.uni uni/x11-1257.uni uni/8859-13.uni
|
||||
X11_8859_15 = uni/x11gr.uni uni/ascii-h.uni uni/empty.uni uni/8859-15.uni
|
||||
X11_8859_16 = uni/x11gr.uni uni/ascii-h.uni uni/empty.uni uni/8859-16.uni
|
||||
X11_IBM_437 = uni/cntrl.uni uni/ascii-h.uni uni/ibm-437.uni
|
||||
X11_KOI8_R = uni/x11gr.uni uni/ascii-h.uni uni/koi8-r.uni
|
||||
X11_PT_154 = uni/x11gr.uni uni/ascii-h.uni uni/pt-154.uni
|
||||
X11_KOI8_U = uni/x11gr.uni uni/ascii-h.uni uni/koi8-u.uni
|
||||
X11_10646_1 = uni/x11gr.uni uni/10646-1.uni
|
||||
|
||||
$(PCF_8859_1): ter-1%.pcf : ter-u%.bdf $(X11_8859_1)
|
||||
$(UCS2X11) $< $(REG_8859_1) $(X11_8859_1) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_8859_2): ter-2%.pcf : ter-u%.bdf $(X11_8859_2)
|
||||
$(UCS2X11) $< $(REG_8859_2) $(X11_8859_2) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_8859_5): ter-5%.pcf : ter-u%.bdf $(X11_8859_5)
|
||||
$(UCS2X11) $< $(REG_8859_5) $(X11_8859_5) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_8859_7): ter-7%.pcf : ter-u%.bdf $(X11_8859_7)
|
||||
$(UCS2X11) $< $(REG_8859_7) $(X11_8859_7) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_8859_9): ter-9%.pcf : ter-u%.bdf $(X11_8859_9)
|
||||
$(UCS2X11) $< $(REG_8859_9) $(X11_8859_9) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_MS_1251): ter-c%.pcf : ter-u%.bdf $(X11_MS_1251)
|
||||
$(UCS2X11) $< $(REG_MS_1251) $(X11_MS_1251) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_8859_13): ter-d%.pcf : ter-u%.bdf $(X11_8859_13)
|
||||
$(UCS2X11) $< $(REG_8859_13) $(X11_8859_13) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_8859_15): ter-f%.pcf : ter-u%.bdf $(X11_8859_15)
|
||||
$(UCS2X11) $< $(REG_8859_15) $(X11_8859_15) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_8859_16): ter-g%.pcf : ter-u%.bdf $(X11_8859_16)
|
||||
$(UCS2X11) $< $(REG_8859_16) $(X11_8859_16) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_IBM_437): ter-i%.pcf : ter-u%.bdf $(X11_IBM_437)
|
||||
$(UCS2X11) $< $(REG_IBM_437) $(X11_IBM_437) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_KOI8_R): ter-k%.pcf : ter-u%.bdf $(X11_KOI8_R)
|
||||
$(UCS2X11) $< $(REG_KOI8_R) $(X11_KOI8_R) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_PT_154): ter-p%.pcf : ter-u%.bdf $(X11_PT_154)
|
||||
$(UCS2X11) $< $(REG_PT_154) $(X11_PT_154) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_KOI8_U): ter-u%.pcf : ter-u%.bdf $(X11_KOI8_U)
|
||||
$(UCS2X11) $< $(REG_KOI8_U) $(X11_KOI8_U) | $(BDF2PCF) -o $@
|
||||
|
||||
$(PCF_10646_1): ter-x%.pcf : ter-u%.bdf $(X11_10646_1)
|
||||
$(UCS2X11) $< $(REG_10646_1) $(X11_10646_1) | $(BDF2PCF) -o $@
|
||||
|
||||
pcf: $(PCF)
|
||||
|
||||
install-pcf: $(PCF)
|
||||
mkdir -p $(DESTDIR)$(x11dir)
|
||||
for i in $(PCF) ; do gzip -c $$i > $(DESTDIR)$(x11dir)/$$i.gz ; done
|
||||
|
||||
uninstall-pcf:
|
||||
for i in $(PCF) ; do rm -f $(DESTDIR)$(x11dir)/$$i.gz ; done
|
||||
|
||||
pcf-8bit: $(PCF_8BIT)
|
||||
|
||||
install-pcf-8bit: $(PCF_8BIT)
|
||||
mkdir -p $(DESTDIR)$(x11dir)
|
||||
for i in $(PCF_8BIT) ; do gzip -c $$i > $(DESTDIR)$(x11dir)/$$i.gz ; done
|
||||
|
||||
uninstall-pcf-8bit:
|
||||
for i in $(PCF_8BIT) ; do rm -f $(DESTDIR)$(x11dir)/$$i.gz ; done
|
||||
|
||||
# Open Type Bitmap
|
||||
|
||||
$(OTB): ter-u%.otb : ter-u%.bdf
|
||||
$(BDF2OTB) -o $@ $<
|
||||
|
||||
otb: $(OTB)
|
||||
|
||||
install-otb: $(OTB)
|
||||
mkdir -p $(DESTDIR)$(otbdir)
|
||||
cp -f $(OTB) $(DESTDIR)$(otbdir)
|
||||
|
||||
uninstall-otb:
|
||||
for i in $(OTB) ; do rm -f $(DESTDIR)$(otbdir)/$$i ; done
|
||||
|
||||
# Cleanup
|
||||
|
||||
clean:
|
||||
rm -f $(PSF) $(PSF_VGAW) $(PCF) $(PCF_8BIT) $(OTB)
|
||||
|
||||
.PHONY: all install uninstall fontdir psf install-psf uninstall-psf psf-vgaw install-psf-vgaw uninstall-psf-vgaw install-psf-ref uninstall-psf-ref pcf install-pcf uninstall-pcf pcf-8bit install-pcf-8bit uninstall-pcf-8bit otb install-otb uninstall-otb clean
|
||||
@@ -0,0 +1 @@
|
||||
See CHANGES
|
||||
@@ -0,0 +1,94 @@
|
||||
Copyright (C) 2020 Dimitar Toshkov Zhekov,
|
||||
with Reserved Font Name "Terminus Font".
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -0,0 +1,395 @@
|
||||
Contents:
|
||||
|
||||
1. About.
|
||||
1.1. Build requitements.
|
||||
1.2. Quick installation.
|
||||
1.3. Legend.
|
||||
1.4. Variants.
|
||||
1.5. Notes.
|
||||
1.6. Alternative tools.
|
||||
|
||||
2. Linux console.
|
||||
2.1. Installation.
|
||||
2.2. Usage.
|
||||
2.3. Quick reference.
|
||||
2.4. Legend.
|
||||
2.5. Notes.
|
||||
|
||||
3. X11 Window System.
|
||||
3.1. Installation.
|
||||
3.2. Notes.
|
||||
|
||||
4. Open Type Bitmap.
|
||||
4.1. Installation.
|
||||
4.2. Notes.
|
||||
|
||||
5. Microsoft Windows.
|
||||
5.1. Installation package.
|
||||
5.2. Font file only.
|
||||
5.3. Notes.
|
||||
|
||||
6. Frequently Asked Questions.
|
||||
|
||||
7. Legal information.
|
||||
7.1. Licenses.
|
||||
7.2. Copyright.
|
||||
|
||||
--
|
||||
|
||||
1. About.
|
||||
|
||||
This archive contains source code for generating and installing Terminus
|
||||
Font for Linux console, X11 Window System, Microsoft Windows and Open Type
|
||||
Bitmap capable systems.
|
||||
|
||||
- version 4.49.1
|
||||
- sizes 6x12, 8x14, 8x16, 10x18, 10x20, 11x22, 12x24, 14x28, 16x32
|
||||
- weights normal, bold, CRT VGA bold
|
||||
- characters 1356
|
||||
- format Bitmap Distribution Format (BDF) version 2.1
|
||||
|
||||
The character set covers about 120 language sets and supports ISO8859-1/2/5/
|
||||
7/9/13/15/16, Paratype-PT154/PT254, KOI8-R/U/E/F, Esperanto and many IBM,
|
||||
Windows and Macintosh code pages, as well as the IBM VGA, vt100 and xterm
|
||||
pseudographic characters.
|
||||
|
||||
|
||||
1.1. Build requirements.
|
||||
|
||||
- GNU make
|
||||
- Python 3.5.0+ (or node.js 6.9.0+ as alternative)
|
||||
- for X11 only: bdftopcf
|
||||
- for Windows only: GCC for Win32/i686
|
||||
- for the Windows installer only: NSIS and patch(1).
|
||||
|
||||
|
||||
1.2. Quick installation.
|
||||
|
||||
The commands:
|
||||
|
||||
$ ./configure [--prefix=PREFIX]
|
||||
$ make -j8
|
||||
# make install fontdir
|
||||
|
||||
compile and install the Linux console and X11 Window System fonts.
|
||||
The default PREFIX is /usr/local.
|
||||
|
||||
|
||||
1.3. Legend.
|
||||
|
||||
The file names are structured as follows:
|
||||
|
||||
ter-u<SIZE><STYLE>.bdf
|
||||
|
||||
<SIZE> is the font height. <STYLE> is n for normal (all sizes), b for bold
|
||||
(all sizes except 6x12), and v for CRT VGA bold (8x14 and 8x16 only, uses
|
||||
the eight character matrix column).
|
||||
|
||||
|
||||
1.4. Variants.
|
||||
|
||||
Some characters are implemented in two variants. To use the alternate
|
||||
variant, execute:
|
||||
|
||||
$ patch -p1 -i alt/<NAME>.diff
|
||||
|
||||
before making the font. See the font WEB page for examples. If you want to
|
||||
combine hi2 with dv1 and/or ka2, apply hi2 and then hi2-dv1 and/or hi2-ka2.
|
||||
The default variant for unicode range 2800-28FF is oriented towards
|
||||
pseudographics.
|
||||
|
||||
|
||||
1.5. Notes.
|
||||
|
||||
The commands marked with $ can be executed by a regular user.
|
||||
The configure commands are optional.
|
||||
"make -j8" runs 8 jobs in parallel.
|
||||
|
||||
Sizes 6x12, 11x22, 14x28-bold and 16x32-normal are worse than the others.
|
||||
Avoid them.
|
||||
|
||||
210E and 210F are not italic.
|
||||
|
||||
226A, 226B and the double struck letters are not very good.
|
||||
|
||||
2135 may be wrong.
|
||||
|
||||
The hebrew letters and sheqel are uppercase height, which is an attempt to
|
||||
compensate for the missing width.
|
||||
|
||||
|
||||
1.6. Alternative tools.
|
||||
|
||||
If your Python 3 executable is named python instead if python3:
|
||||
|
||||
$ ./configure INT=python
|
||||
|
||||
To use node.js instead of python:
|
||||
|
||||
$ ./configure INT=node EXT=js
|
||||
|
||||
--
|
||||
|
||||
2. Linux console.
|
||||
|
||||
- weights normal, bold, CRT VGA-bold
|
||||
- code pages ISO8859-1/ISO8859-15/Windows-1252, ISO8859-2/Windows-1250,
|
||||
Windows-1251/ISO8859-5, ISO8859-9/Windows-1254, ISO8859-16,
|
||||
ISO8859-7/Windows-1253, ISO8859-13/Windows-1257, IBM-437,
|
||||
Bulgarian-MIK, KOI8-R, KOI8-U, Paratype-PT154, combined
|
||||
- format PC Screen Font (PSF) with unicode data
|
||||
|
||||
|
||||
2.1. Installation.
|
||||
|
||||
$ ./configure [--prefix=PREFIX | --psfdir=DIRECTORY]
|
||||
$ make -j8 psf
|
||||
# make install-psf
|
||||
|
||||
The files are compressed with gzip and installed in DIRECTORY. The default
|
||||
DIRECTORY is PREFIX/share/consolefonts. For kbd, you may need to change it
|
||||
to PREFIX/lib/kbd/consolefonts or PREFIX/share/kbd/consolefonts, depending
|
||||
on the kbd version.
|
||||
|
||||
The CRT VGA bold weight fonts, suitable for real CRT text modes only, are
|
||||
not installed by default. To install them, execute:
|
||||
|
||||
$ make -j8 psf-vgaw
|
||||
# make install-psf-vgaw
|
||||
|
||||
|
||||
2.2. Usage.
|
||||
|
||||
To load a cont in consoletools:
|
||||
|
||||
$ consolechars [-m MAPPING] -f ter-<X><SIZE><STYLE>
|
||||
|
||||
To load a font in kbd:
|
||||
|
||||
$ setfont [-m MAPPING] ter-<X><SIZE><STYLE>
|
||||
|
||||
where <X> is a character identifying the code page as listed in p.2.4.
|
||||
|
||||
|
||||
2.3. Quick reference.
|
||||
|
||||
The commands:
|
||||
|
||||
$ ./configure [--prefix=PREFIX | --psfdir=DIRECTORY | --psfref=FILENAME]
|
||||
# make install-psf-ref
|
||||
|
||||
install the text from p.2.4 as FILENAME (the default is README.terminus)
|
||||
in DIRECTORY.
|
||||
|
||||
|
||||
2.4. Legend.
|
||||
|
||||
names mappings covered codepage(s)
|
||||
|
||||
ter-1* iso01, iso15, cp1252 ISO8859-1, ISO8859-15, Windows-1252
|
||||
ter-2* iso02, cp1250 ISO8859-2, Windows-1250
|
||||
ter-7* iso07, cp1253 ISO8859-7, Windows-1253
|
||||
ter-9* iso09, cp1254 ISO8859-9, Windows-1254
|
||||
ter-c* cp1251, iso05 Windows-1251, ISO8859-5
|
||||
ter-d* iso13, cp1257 ISO8859-13, Windows-1257
|
||||
ter-g* iso16 ISO8859-16
|
||||
ter-h* cp1255, iso08 Windows-1258, ISO8859-8
|
||||
ter-i* cp437 IBM-437
|
||||
ter-k* koi8r KOI8-R
|
||||
ter-m* mik Bulgarian-MIK
|
||||
ter-p* pt154 Paratype-PT154
|
||||
ter-u* koi8u KOI8-U
|
||||
|
||||
ter-v* all mappings / code pages listed above and many others, about 110
|
||||
language sets, 8 or 16 foreground colors depending on the kernel and
|
||||
console driver versions
|
||||
|
||||
names weight
|
||||
|
||||
ter-*n normal
|
||||
ter-*b bold
|
||||
ter-*v CRT VGA bold
|
||||
|
||||
|
||||
2.5. Notes.
|
||||
|
||||
The combined code page is based on IBM-437 (character 0xFF is ogonek).
|
||||
The ISO8859-16 font also includes all letters and accents from Windows-1250.
|
||||
|
||||
--
|
||||
|
||||
3. X11 Window System.
|
||||
|
||||
- weights normal, bold
|
||||
- code pages ISO8859-1/Windows-1252, ISO8859-2, ISO8859-5, ISO8859-7,
|
||||
ISO8859-9/Windows-1254, ISO8859-13, ISO8859-15, ISO8859-16,
|
||||
Windows-1251, IBM-437, KOI8-R, KOI8-U, Paratype-PT154 and
|
||||
ISO10646-1 (unicode)
|
||||
- format Portable Compiled Font (PCF)
|
||||
|
||||
|
||||
3.1. Installation.
|
||||
|
||||
$ ./configure [--prefix=PREFIX | --x11dir=DIRECTORY]
|
||||
$ make -j8 pcf
|
||||
# make install-pcf
|
||||
|
||||
The files are compressed with gzip and installed in DIRECTORY. The default
|
||||
DIRECTORY is PREFIX/share/fonts/terminus. Requires bdftopcf.
|
||||
|
||||
A copy of the normal 6x12 font is installed as "bold", because some X11
|
||||
libraries and applications substitute the missing bold fonts by shifting the
|
||||
normal fonts, and others do not recognize the bold weight at all if the
|
||||
lowest font size lacks it.
|
||||
|
||||
To update the font cache in DIRECTORY after (un)installation, run:
|
||||
|
||||
# make fontdir
|
||||
|
||||
The configuration file which lists the font directories must contain
|
||||
DIRECTORY. The X11 server may need to be restarted so the font list can be
|
||||
updated.
|
||||
|
||||
By default, only the unicode (ISO10646-1) font is installed. To install the
|
||||
other code pages:
|
||||
|
||||
$ make -j8 pcf-8bit
|
||||
# make install-pcf-8bit
|
||||
|
||||
|
||||
3.2. Notes.
|
||||
|
||||
The ISO8859-1 and ISO8859-9 fonts contain the Windows Western characters and
|
||||
can be used as Windows-1252 and Windows-1254 respectively.
|
||||
|
||||
--
|
||||
|
||||
4. Open Type Bitmap.
|
||||
|
||||
- weights normal, bold
|
||||
- code pages ISO10646-1 (unicode)
|
||||
- format Linux/UNIX bitmap-only TrueType
|
||||
|
||||
|
||||
4.1. Installation.
|
||||
|
||||
$ ./configure [--prefix=PREFIX | --otbdir=DIRECTORY]
|
||||
$ make otb
|
||||
# make install-otb
|
||||
|
||||
The files are installed in DIRECTORY.
|
||||
The default DIRECTORY is PREFIX/share/fonts/terminus.
|
||||
|
||||
|
||||
4.2. Notes
|
||||
|
||||
An OTB file is generated for each BDF file, instead of combining sizes by
|
||||
weight, for the following reasons:
|
||||
|
||||
- KDE compatibility. With combined files, only the first size is available.
|
||||
|
||||
- Correct global font metrics. For example, the base line and character
|
||||
width for 8x14 and 8x16 (relative to height) may never be identical.
|
||||
|
||||
otb1cli is NOT a full-featured BDF to sfnt convertor. It expands the bitmaps
|
||||
first, uses the expanded widths, does not support overlapping characters,
|
||||
and targets Linux/UNIX only.
|
||||
|
||||
--
|
||||
|
||||
5. Microsoft Windows.
|
||||
|
||||
- weights normal, bold
|
||||
- code pages Windows-1252, 1250, 1253, 1254, 1251 and 1257
|
||||
- format Font File Format version 2.0, compiled into FON
|
||||
|
||||
|
||||
5.1. Installation package.
|
||||
|
||||
Make sure that no variant patches are applied to the font (p.1.4).
|
||||
|
||||
> cd win32
|
||||
> build
|
||||
|
||||
Be patient, the process may take several minutes.
|
||||
After that, open terminus.nsi and compile it.
|
||||
|
||||
|
||||
5.2. Font file only.
|
||||
|
||||
> copy *.bdf win32
|
||||
> cd win32
|
||||
> make -j8
|
||||
|
||||
You can install terminus.fon via the regular means.
|
||||
|
||||
|
||||
5.3. Notes.
|
||||
|
||||
The Windows code pages contain a total of 384 characters. All other
|
||||
characters (math, pseudographics etc.) are not currently available.
|
||||
|
||||
--
|
||||
|
||||
6. Frequently Asked Questions.
|
||||
|
||||
Q. Italic version?
|
||||
|
||||
A. No. The quality is significantly lower, and preserving the font width
|
||||
requires overlapping characters, which are not handled very well by X11/Xft.
|
||||
You can try mkitalic from FreeBSD or bdfslant from Debian.
|
||||
|
||||
Q. Scalable version?
|
||||
|
||||
A. Probably not. The font uses a lot of straight horizontal and vertical
|
||||
lines, which is good for a bitmap, but not so much for a vector font. A
|
||||
bitmap font packaged as TTF seems possible.
|
||||
|
||||
Q. How about some new characters?
|
||||
|
||||
A. Contact me and be ready to help.
|
||||
|
||||
Q. The bold 6x12 font...
|
||||
|
||||
A. ...does not exist, there is no space for a bold font in a 6x12 matrix.
|
||||
However, the "normal" font is somewhere between.
|
||||
|
||||
Q. The font works in X11/Motif, but not in GNOME/KDE/Xfce.
|
||||
|
||||
A. Try adding 75-yes-terminus.conf to the Fontconfig configuration files.
|
||||
For some Fontconfig versions, you may need to replace the text "Terminus"
|
||||
in 75-yes-terminus.conf with "xos4 Terminus", though that is unlikely.
|
||||
See also mkfontscale(1), mkfontdir(1), fc-cache(1), xorg.conf(5), xfs(1),
|
||||
xlsfonts(1), fonts-conf(5) etc.
|
||||
|
||||
Q. My terminal emulator does not display cyrillic/pseudographics/...
|
||||
A. If you have the 8-bit X11 code pages installed, and your emulator uses
|
||||
"XLFD" font names, make sure that the font name ends with "-10616-1" instead
|
||||
of "-*-*".
|
||||
|
||||
--
|
||||
|
||||
7. Legal information.
|
||||
|
||||
|
||||
7.1. Licenses.
|
||||
|
||||
Terminus Font is licensed under the SIL Open Font License, Version 1.1.
|
||||
The license is included as OFL.TXT, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
The font includes two variants of unicode range 2800-28FF, but does not
|
||||
support Braille in any way.
|
||||
|
||||
The configure files, python and javascript sources are distributed under
|
||||
the GNU General Public License version 2.0 or (at your choice) any later
|
||||
version.
|
||||
|
||||
|
||||
7.2. Copyright.
|
||||
|
||||
Terminus Font 4.49.1, Copyright (C) 2020 Dimitar Toshkov Zhekov.
|
||||
Report bugs to <dimitar.zhekov@gmail.com>
|
||||
|
||||
Thanks to Anton Zinoviev, Tim Allen, Kir Koliushkin, Antonios Galanopoulos
|
||||
and everyone else who helped.
|
||||
@@ -0,0 +1,395 @@
|
||||
Съдържание:
|
||||
|
||||
1. Обща информация.
|
||||
1.1. Изисквания за компилация.
|
||||
1.2. Бърза инсталация.
|
||||
1.3. Легенда.
|
||||
1.4. Варианти.
|
||||
1.5. Забележки.
|
||||
1.6. Алтернативни средства.
|
||||
|
||||
2. Линукс конзола.
|
||||
2.1. Инсталация.
|
||||
2.2. Използване.
|
||||
2.3. Кратко описание.
|
||||
2.4. Легенда.
|
||||
2.5. Забележки.
|
||||
|
||||
3. X11 Window System.
|
||||
3.1. Инсталация.
|
||||
3.2. Забележки.
|
||||
|
||||
4. Open Type Bitmap.
|
||||
4.1. Инсталация.
|
||||
4.2. Забележки.
|
||||
|
||||
5. Microsoft Windows.
|
||||
5.1. Инсталационен пакет.
|
||||
5.2. Само файл с шрифта.
|
||||
5.3. Забележки.
|
||||
|
||||
6. Често задавани въпроси.
|
||||
|
||||
7. Правна информация.
|
||||
7.1. Лицензи.
|
||||
7.2. Авторство.
|
||||
|
||||
--
|
||||
|
||||
1. Обща информация.
|
||||
|
||||
Този архив съдържа изходен код за генериране и инсталиране на шрифта
|
||||
Терминус за Линукс конзола, X11 Window System, Microsoft Windows и системи
|
||||
поддържащи Open Type Bitmap.
|
||||
|
||||
- версия 4.49.1
|
||||
- размери 6x12, 8x14, 8x16, 10x18, 10x20, 11x22, 12x24, 14x28, 16x32
|
||||
- тежести нормален, удебелен, CRT VGA-удебелен
|
||||
- символи 1356
|
||||
- формат Bitmap Distribution Format (BDF) версия 2.1
|
||||
|
||||
Набора символи покрива около 120 езикови набора и поддържа ISO8859-1/2/5/7/
|
||||
9/13/15/16, Paratype-PT154/PT254, KOI8-R/U/E/F, Есперанто, много кодови
|
||||
страници на IBM, Windows и Macintosh, а също и превдографичните символи на
|
||||
VGA, vt100 и xterm.
|
||||
|
||||
|
||||
1.1. Изисквания за компилация.
|
||||
|
||||
- GNU make
|
||||
- Python 3.5.0+ (или node.js 6.9.0+ като алтернатива)
|
||||
- само за X11: bdftopcf
|
||||
- само за Windows: GCC за Win32/i686
|
||||
- само за Windows инсталатора: NSIS и patch(1).
|
||||
|
||||
|
||||
1.2. Бърза инсталация.
|
||||
|
||||
Командите:
|
||||
|
||||
$ ./configure [--prefix=PREFIX]
|
||||
$ make -j8
|
||||
# make install fontdir
|
||||
|
||||
компилират и инсталират шрифтовете за Линукс конзола и X11 Window System.
|
||||
Подразбиращият се префикс е /usr/local.
|
||||
|
||||
|
||||
1.3. Легенда.
|
||||
|
||||
Имената на файловете са структурирани както следва:
|
||||
|
||||
ter-u<РАЗМЕР><СТИЛ>.bdf
|
||||
|
||||
където <РАЗМЕР> е височината в точки, а <СТИЛ> е n за нормален (всички
|
||||
размери), b за удебелен (всички размери освен 6x12), и v за CRT VGA удебелен
|
||||
(само за 8x14 и 8x16, използва 8 колона на символната матрица).
|
||||
|
||||
|
||||
1.4. Варианти.
|
||||
|
||||
Някои символи са реализирани в два варианта. За да използвате алтернативния
|
||||
вариант, преди инсталация изпълнете:
|
||||
|
||||
$ patch -p1 -i alt/<ИМЕ>.diff
|
||||
|
||||
Примери за разликите межда вариантите са дадени на страницата на шрифта.
|
||||
Ако желаете да комбинирате hi2 с dv1 и/или ka2, приложете първо hi2, и след
|
||||
това hi2-dv1 и/или hi2-ka2. Подразбиращия се вариант на юникод обхвата
|
||||
2800-28FF е ориентиран към псевдографика.
|
||||
|
||||
|
||||
1.5. Забележки.
|
||||
|
||||
Командите отбелязани с $ могат да се изпълняват от обикновен потребител.
|
||||
Командите за конфигуриране не са задължителни.
|
||||
"make -j8" изпълнява паралелно 8 задачи.
|
||||
|
||||
Размери 6x12, 11x22, 14x28-удебелен и 16x32-нормален са с по-лошо качество
|
||||
от останалите. Избягвайте ги.
|
||||
|
||||
210E и 210F не са наклонени.
|
||||
|
||||
226A, 226B и двойно начертаните букви не са много добри.
|
||||
|
||||
2135 може би е грешен.
|
||||
|
||||
В опит да се компенсира липсващата ширина, буквите от иврит и знака шекел са
|
||||
с височина на главни букви.
|
||||
|
||||
|
||||
1.6. Алтернативни средства.
|
||||
|
||||
Ако изпълнимия файл на Python 3 интерпретатора е python вместо python3:
|
||||
|
||||
$ ./configure INT=python
|
||||
|
||||
За използване на node.js вместо python:
|
||||
|
||||
$ ./configure INT=node EXT=js
|
||||
|
||||
--
|
||||
|
||||
2. Линукс конзола.
|
||||
|
||||
- тежести нормален, удебелен, CRT VGA-удебелен
|
||||
- кодировки ISO8859-1/ISO8859-15/Windows-1252, ISO8859-2/Windows-1250,
|
||||
Windows-1251/ISO8859-5, ISO8859-9/Windows-1254, ISO8859-16,
|
||||
ISO8859-7/Windows-1253, ISO8859-13/Windows-1257, IBM-437,
|
||||
Bulgarian-MIK, KOI8-R, KOI8-U, Paratype-PT154, комбинирана
|
||||
- формат PC Screen Font (PSF) с unicode данни
|
||||
|
||||
|
||||
2.1. Инсталация.
|
||||
|
||||
$ ./configure [--prefix=ПРЕФИКС | --psfdir=ДИРЕКТОРИЯ]
|
||||
$ make -j8 psf
|
||||
# make install-psf
|
||||
|
||||
Файловете се компресират с gzip и инсталират в ДИРЕКТОРИЯ. Подразбиращата се
|
||||
ДИРЕКТОРИЯ е ПРЕФИКС/share/consolefonts. За kbd може да се наложи да смените
|
||||
директорията на PREFIX/lib/kbd/consolefonts или
|
||||
PREFIX/share/kbd/consolefonts, в зависимост от версията на kbd.
|
||||
|
||||
CRT VGA-удебелените шрифтове, подходящи за само истински CRT текстови
|
||||
режими, не се инсталират по подразбиране. За инсталирането им изпълнете:
|
||||
|
||||
$ make -j8 psf-vgaw
|
||||
# make install-psf-vgaw
|
||||
|
||||
|
||||
2.2. Използване.
|
||||
|
||||
За зареждане на шрифт с consoletools:
|
||||
|
||||
$ consolechars [-m КОДИРОВКА] -f ter-<X><РАЗМЕР><СТИЛ>
|
||||
|
||||
За зареждане на шрифт с kbd:
|
||||
|
||||
$ setfont [-m MAPPING] ter-<X><SIZE><STYLE>
|
||||
|
||||
където <X> е символ идентифициращ кодовата страница по списъка от т.2.4.
|
||||
|
||||
|
||||
2.3. Кратко описание.
|
||||
|
||||
Командите:
|
||||
|
||||
$ ./configure [--prefix=ПРЕФИКС | --psfdir=ДИРЕКТОРИЯ | --psfref=ИМЕНАФАЙЛ]
|
||||
# make install-psf-ref
|
||||
|
||||
инсталират текста от т.2.4 (на английски) под името ИМЕНАФАЙЛ (подразбира
|
||||
се README.terminus) в ДИРЕКТОРИЯ.
|
||||
|
||||
|
||||
2.4. Легенда.
|
||||
|
||||
имена кодировки кодови страници
|
||||
|
||||
ter-1* iso01, iso15, cp1252 ISO8859-1, ISO8859-15, Windows-1252
|
||||
ter-2* iso02, cp1250 ISO8859-2, Windows-1250
|
||||
ter-7* iso07, cp1253 ISO8859-7, Windows-1253
|
||||
ter-9* iso09, cp1254 ISO8859-9, Windows-1254
|
||||
ter-c* cp1251, iso05 Windows-1251, ISO8859-5
|
||||
ter-d* iso13, cp1257 ISO8859-13, Windows-1257
|
||||
ter-g* iso16 ISO8859-16
|
||||
ter-h* cp1255, iso08 Windows-1255, ISO8859-8
|
||||
ter-i* cp437 IBM-437
|
||||
ter-k* koi8r KOI8-R
|
||||
ter-m* mik Bulgarian-MIK
|
||||
ter-p* pt154 Paratype-PT154
|
||||
ter-k* koi8u KOI8-U
|
||||
|
||||
ter-v* всички изброени по-горе кодировки / страници и много други, около
|
||||
110 езикови набора, 8 или 16 цвята за текст в зависимост от ядрото и
|
||||
конзолния драйвер
|
||||
|
||||
имена тежест
|
||||
|
||||
ter-*n нормален
|
||||
ter-*b удебелен
|
||||
ter-*v CRT VGA-удебелен
|
||||
|
||||
|
||||
2.5. Забележки.
|
||||
|
||||
Комбинираната кодова страница е базирана IBM-437 (символ 0xFF е ogonek).
|
||||
ISO8859-16 шрифта включва също всички букви и акценти от Windows-1250.
|
||||
|
||||
--
|
||||
|
||||
3. X11 Window System.
|
||||
|
||||
- тежести нормален, удебелен
|
||||
- кодировки ISO8859-1/Windows-1252, ISO8859-2, ISO8859-5, ISO8859-7,
|
||||
ISO8859-9/Windows-1254, ISO8859-13, ISO8859-15, ISO8859-16,
|
||||
Windows-1251, IBM-437, KOI8-R, KOI8-U, Paratype-PT154 и
|
||||
ISO10646-1 (уникод)
|
||||
- формат Portable Compiled Font (PCF)
|
||||
|
||||
|
||||
3.1. Инсталация.
|
||||
|
||||
$ ./configure [--prefix=ПРЕФИКС | --x11dir=ДИРЕКТОРИЯ]
|
||||
$ make pcf
|
||||
# make install-pcf
|
||||
|
||||
Файловете се компресират с gzip и инсталират в ДИРЕКТОРИЯ. Подразбиращата се
|
||||
ДИРЕКТОРИЯ е ПРЕФИКС/share/fonts/terminus. Изисква се bdftopcf.
|
||||
|
||||
Копие на нормалния 6x12 шрифт се инсталира като "удебелен", защото някои
|
||||
X11 библиотеки и програми заменят липсващите удебелени шрифтове чрез
|
||||
отместване на нормалните, а други изобщо не разпознават удебелена тежест,
|
||||
ако такава липсва в най-малкия размер на шрифта.
|
||||
|
||||
За да актуализирате fonts.dir в ДИРЕКТОРИЯ след (де)инсталация, изпълнете:
|
||||
|
||||
# make fontdir
|
||||
|
||||
Конфигурационния файл, изброяващ директориите за шрифтове, трябва да включва
|
||||
ДИРЕКТОРИЯ. За да се обнови списъка от шрифтове може да се наложи рестарт на
|
||||
X11 сървъра.
|
||||
|
||||
По подразбиране се инсталира само уникод (ISO10646-1) шрифта. За инсталиране
|
||||
на останалите кодови страници:
|
||||
|
||||
$ make -j8 pcf-8bit
|
||||
# make install-pcf-8bit
|
||||
|
||||
|
||||
3.2. Забележки.
|
||||
|
||||
ISO8859-1 и ISO8859-9 шрифтовете съдържат Windows Western символите и могат
|
||||
да бъдат използвани съответно като Windows-1252 и Windows-1254.
|
||||
|
||||
--
|
||||
|
||||
4. Open Type Bitmap.
|
||||
|
||||
- тежести нормален, удебелен
|
||||
- кодировки ISO10646-1 (уникод)
|
||||
- формат растерен TrueType за Linux/UNIX
|
||||
|
||||
|
||||
4.1. Инсталация.
|
||||
|
||||
$ ./configure [--prefix=ПРЕФИКС | --otbdir=ДИРЕКТОРИЯ]
|
||||
$ make otb
|
||||
# make install-otb
|
||||
|
||||
Файловете се инсталират в ДИРЕКТОРИЯ.
|
||||
Подразбиращата се ДИРЕКТОРИЯ е ПРЕФИКС/share/fonts/terminus.
|
||||
|
||||
|
||||
4.2. Забележки.
|
||||
|
||||
За всеки BDF файл се генерира отделен OTB файл, вместо да се комбинират
|
||||
по тежест, по следните причини:
|
||||
|
||||
- Съвместимост с КДЕ. При комбинирани файлове е достъпен само първия размер.
|
||||
|
||||
- Коректни глобални размери. Например базовата линия и ширината на символите
|
||||
(измервани по височината) не могат да бъдат еднакви за 8x14 и 8x16.
|
||||
|
||||
otb1cli НЕ Е пълноценен конвертор от BDF към TTF. Символите предварително
|
||||
се растеризират, използват се растеризизираните ширини, не се поддържат
|
||||
застъпващи се символи, и резултата е предназначен само за Linux/UNIX.
|
||||
|
||||
--
|
||||
|
||||
5. Microsoft Windows.
|
||||
|
||||
- тежести нормален, удебелен
|
||||
- кодировки Windows-1252, 1250, 1253, 1254, 1251 and 1257
|
||||
- формат Font File Format версия 2.0, компилиран във FON
|
||||
|
||||
|
||||
5.1. Инстанационен пакет.
|
||||
|
||||
Уверете се, че към шрифта не са прилагани корекции за варианти (т.1.4).
|
||||
|
||||
> cd win32
|
||||
> build
|
||||
|
||||
Бъдете търпеливи, процеса може да отнеме няколко минути.
|
||||
След това отворете terminus.nsi и го компилирайте.
|
||||
|
||||
|
||||
5.2. Само файл с шрифта.
|
||||
|
||||
> copy *.bdf win32
|
||||
> cd win32
|
||||
> make -j8
|
||||
|
||||
Можете са инсталирате terminus.fon по стандартните начини.
|
||||
|
||||
|
||||
5.3. Забележки.
|
||||
|
||||
Кодовите страници за Windows съдържат общо 384 символа. Всички останали
|
||||
символи (математика, превдографика и т.н.) засега не са достъпни.
|
||||
|
||||
--
|
||||
|
||||
6. Често задавани въпроси.
|
||||
|
||||
В. Наклонена версия?
|
||||
|
||||
О. Не. Качеството е доста по-ниско, а и запазването ширината на символите
|
||||
изисква припокриване, което не се обработва много добре от X11/Xft. Ако Ви
|
||||
е много необходима, пробвайте mkitalic от FreeBSD или bdfslant от Debian.
|
||||
|
||||
В. Мащабируема версия?
|
||||
|
||||
О. Вероятно не. Шрифта използва мого хоризонтални и вертикални линии, които
|
||||
са подходящш ра растерна графика, но не толкова за векторна. Може би
|
||||
растерен шрифт, комплектован като TrueType.
|
||||
|
||||
В. Какво ще кажете за някои нови символи?
|
||||
|
||||
О. Пишете ми и имайте готовност да помогнете.
|
||||
|
||||
В. Удебеленият 6x12 шрифт...
|
||||
|
||||
О. ...не съществува, в матрица 6x12 няма достатъчно място за добър удебелен
|
||||
шрифт. Всъщност "нормалният" шрифт е някъде по средата.
|
||||
|
||||
В. Шрифтът работи с X11/Motif, но не и с GNOME/KDE/Xfce.
|
||||
|
||||
О. Опитайте да добавите 75-yes-terminus.conf към конфигурационните файлове
|
||||
на Fontconfig. За някои версии на Fontconfig, може да се наложи да замените
|
||||
текста "Terminus" във файла с "xos4 Terminus", макар че е слабо вероятно.
|
||||
Вижте също mkfontscale(1), mkfontdir(1), fc-cache(1), xorg.conf(5), xfs(1),
|
||||
xlsfonts(1), fonts-conf(5) и т.н.
|
||||
|
||||
В. Моя терминален емулатор не извежда кирилица/псевдографика/...
|
||||
О. Ако имате инсталирани 8-битовите кодови страници за X11, и емулатора
|
||||
използва "XLFD" имена на шрифтовете, уверете се че името на шрифта завършва
|
||||
на "-10616-1" вместо "-*-*".
|
||||
|
||||
--
|
||||
|
||||
7. Правна информация.
|
||||
|
||||
|
||||
7.1. Лицензи.
|
||||
|
||||
Terminus Font е лицензизан под SIL Open Font License, версия 1.1.
|
||||
Лицензът е включен като OFL.TXT, и е достъпен заедно с FAQ на адрес:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
Шрифтът включва два варианта на юникод обхвата 2800-28FF, но по никакъв
|
||||
начин не поддържа Брайловата азбука.
|
||||
|
||||
Конфигурационните файлове, както и изходния код на python и javascript, се
|
||||
разпространяват под GNU General Public License версия 2.0 или (по Ваше
|
||||
усмотрение) която и да е по-късна версия.
|
||||
|
||||
|
||||
7.2. Авторство.
|
||||
|
||||
Terminus Font 4.49.1, Copyright (C) 2020 Димитър Тошков Жеков.
|
||||
Адрес за кореспонденция <dimitar.zhekov@gmail.com>
|
||||
|
||||
Благодаря на Антон Зиновиев, Тим Алън, Кир Колышкин, Антониос Галанопулос и
|
||||
всички останали, които помогнаха.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,860 @@
|
||||
--- ./ter-u12b.bdf.orig 2020-12-28 20:34:18.635118400 +0200
|
||||
+++ ./ter-u12b.bdf 2020-12-28 20:34:21.775122800 +0200
|
||||
@@ -10030,3 +10030,2 @@
|
||||
-E0
|
||||
-90
|
||||
-90
|
||||
+00
|
||||
+00
|
||||
@@ -10034,0 +10034 @@
|
||||
+F0
|
||||
@@ -10070,8 +10070,8 @@
|
||||
-78
|
||||
-88
|
||||
-88
|
||||
-88
|
||||
-88
|
||||
-78
|
||||
-08
|
||||
-70
|
||||
+38
|
||||
+48
|
||||
+48
|
||||
+48
|
||||
+48
|
||||
+FC
|
||||
+84
|
||||
+00
|
||||
--- ./ter-u12n.bdf.orig 2020-12-28 20:34:18.605118300 +0200
|
||||
+++ ./ter-u12n.bdf 2020-12-28 20:34:21.775122800 +0200
|
||||
@@ -10030,3 +10030,2 @@
|
||||
-E0
|
||||
-90
|
||||
-90
|
||||
+00
|
||||
+00
|
||||
@@ -10034,0 +10034 @@
|
||||
+F0
|
||||
@@ -10070,8 +10070,8 @@
|
||||
-78
|
||||
-88
|
||||
-88
|
||||
-88
|
||||
-88
|
||||
-78
|
||||
-08
|
||||
-70
|
||||
+38
|
||||
+48
|
||||
+48
|
||||
+48
|
||||
+48
|
||||
+FC
|
||||
+84
|
||||
+00
|
||||
--- ./ter-u14b.bdf.orig 2020-12-28 20:34:18.655118400 +0200
|
||||
+++ ./ter-u14b.bdf 2020-12-28 20:34:21.815122800 +0200
|
||||
@@ -11082,4 +11082,3 @@
|
||||
-78
|
||||
-CC
|
||||
-CC
|
||||
-C8
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -11088,0 +11088 @@
|
||||
+FC
|
||||
@@ -11127,9 +11127,9 @@
|
||||
-7E
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-7E
|
||||
-06
|
||||
-7C
|
||||
+3E
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+FF
|
||||
+C3
|
||||
+00
|
||||
--- ./ter-u14n.bdf.orig 2020-12-28 20:34:18.645118400 +0200
|
||||
+++ ./ter-u14n.bdf 2020-12-28 20:34:21.785122800 +0200
|
||||
@@ -11082,4 +11082,3 @@
|
||||
-38
|
||||
-44
|
||||
-44
|
||||
-48
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -11088,0 +11088 @@
|
||||
+7C
|
||||
@@ -11127,8 +11126,0 @@
|
||||
-3E
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-3E
|
||||
-02
|
||||
@@ -11135,0 +11128,8 @@
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+FE
|
||||
+82
|
||||
+00
|
||||
--- ./ter-u14v.bdf.orig 2020-12-28 20:34:18.675118400 +0200
|
||||
+++ ./ter-u14v.bdf 2020-12-28 20:34:21.815122800 +0200
|
||||
@@ -11082,4 +11082,3 @@
|
||||
-78
|
||||
-CC
|
||||
-CC
|
||||
-C8
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -11088,0 +11088 @@
|
||||
+FC
|
||||
@@ -11127,9 +11127,9 @@
|
||||
-7E
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-7E
|
||||
-06
|
||||
-7C
|
||||
+3E
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+FF
|
||||
+C3
|
||||
+00
|
||||
--- ./ter-u16b.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16b.bdf 2020-12-28 20:34:21.825122800 +0200
|
||||
@@ -12134,4 +12134,3 @@
|
||||
-78
|
||||
-CC
|
||||
-CC
|
||||
-C8
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -12140,0 +12140 @@
|
||||
+FC
|
||||
@@ -12183,10 +12183,10 @@
|
||||
-7E
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-7E
|
||||
-06
|
||||
-06
|
||||
-7C
|
||||
+3E
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+FF
|
||||
+C3
|
||||
+00
|
||||
+00
|
||||
--- ./ter-u16n.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16n.bdf 2020-12-28 20:34:21.825122800 +0200
|
||||
@@ -12134,4 +12134,3 @@
|
||||
-38
|
||||
-44
|
||||
-44
|
||||
-48
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -12140,0 +12140 @@
|
||||
+7C
|
||||
@@ -12183,9 +12182,0 @@
|
||||
-3E
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-3E
|
||||
-02
|
||||
-02
|
||||
@@ -12192,0 +12184,9 @@
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+FE
|
||||
+82
|
||||
+00
|
||||
+00
|
||||
--- ./ter-u16v.bdf.orig 2020-12-28 20:34:18.695118400 +0200
|
||||
+++ ./ter-u16v.bdf 2020-12-28 20:34:21.855122900 +0200
|
||||
@@ -12134,4 +12134,3 @@
|
||||
-78
|
||||
-CC
|
||||
-CC
|
||||
-C8
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -12140,0 +12140 @@
|
||||
+FC
|
||||
@@ -12183,10 +12183,10 @@
|
||||
-7E
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-7E
|
||||
-06
|
||||
-06
|
||||
-7C
|
||||
+3E
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+FF
|
||||
+C3
|
||||
+00
|
||||
+00
|
||||
--- ./ter-u18b.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18b.bdf 2020-12-28 20:34:21.865122900 +0200
|
||||
@@ -13187,5 +13187,3 @@
|
||||
-3E00
|
||||
-6300
|
||||
-6300
|
||||
-6300
|
||||
-6200
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -13195,0 +13194,2 @@
|
||||
+7F00
|
||||
+6180
|
||||
@@ -13240,12 +13240,12 @@
|
||||
-3F80
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-3F80
|
||||
-0180
|
||||
-0180
|
||||
-3F00
|
||||
+1F00
|
||||
+3300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+FF80
|
||||
+C180
|
||||
+C180
|
||||
+0000
|
||||
--- ./ter-u18n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18n.bdf 2020-12-28 20:34:21.865122900 +0200
|
||||
@@ -13187,5 +13187,3 @@
|
||||
-3C00
|
||||
-4200
|
||||
-4200
|
||||
-4200
|
||||
-4400
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -13195,0 +13194,2 @@
|
||||
+7E00
|
||||
+4100
|
||||
@@ -13240,12 +13240,12 @@
|
||||
-3F00
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-3F00
|
||||
-0100
|
||||
-0100
|
||||
-3E00
|
||||
+0F00
|
||||
+1100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+7F80
|
||||
+4080
|
||||
+4080
|
||||
+0000
|
||||
--- ./ter-u20b.bdf.orig 2020-12-28 20:34:18.735118500 +0200
|
||||
+++ ./ter-u20b.bdf 2020-12-28 20:34:21.905122900 +0200
|
||||
@@ -14239,5 +14239,4 @@
|
||||
-3E00
|
||||
-6300
|
||||
-6300
|
||||
-6300
|
||||
-6200
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -14247,0 +14247 @@
|
||||
+7F00
|
||||
@@ -14297,12 +14297,12 @@
|
||||
-3F80
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-3F80
|
||||
-0180
|
||||
-0180
|
||||
-3F00
|
||||
+1F00
|
||||
+3300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+FF80
|
||||
+C180
|
||||
+C180
|
||||
+0000
|
||||
--- ./ter-u20n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u20n.bdf 2020-12-28 20:34:21.865122900 +0200
|
||||
@@ -14239,5 +14239,4 @@
|
||||
-3C00
|
||||
-4200
|
||||
-4200
|
||||
-4200
|
||||
-4400
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -14247,0 +14247 @@
|
||||
+7E00
|
||||
@@ -14297,12 +14297,12 @@
|
||||
-3F00
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-3F00
|
||||
-0100
|
||||
-0100
|
||||
-3E00
|
||||
+0F00
|
||||
+1100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+7F80
|
||||
+4080
|
||||
+4080
|
||||
+0000
|
||||
--- ./ter-u22b.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22b.bdf 2020-12-28 20:34:21.905122900 +0200
|
||||
@@ -15291,8 +15291,5 @@
|
||||
-3E00
|
||||
-6300
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6300
|
||||
-7F00
|
||||
-6180
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F80
|
||||
@@ -15301,0 +15299 @@
|
||||
+7F80
|
||||
@@ -15303,2 +15301,4 @@
|
||||
-6180
|
||||
-7F00
|
||||
+60C0
|
||||
+60C0
|
||||
+60C0
|
||||
+7F80
|
||||
@@ -15353,14 +15353,14 @@
|
||||
-1FC0
|
||||
-30C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-30C0
|
||||
-1FC0
|
||||
-00C0
|
||||
-00C0
|
||||
-0180
|
||||
-3F00
|
||||
+1F80
|
||||
+3180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+FFC0
|
||||
+C0C0
|
||||
+C0C0
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u22n.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22n.bdf 2020-12-28 20:34:21.915123000 +0200
|
||||
@@ -15291,8 +15291,6 @@
|
||||
-3C00
|
||||
-4200
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4200
|
||||
-7E00
|
||||
-4100
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F00
|
||||
+4080
|
||||
@@ -15300,0 +15299 @@
|
||||
+7F00
|
||||
@@ -15303,2 +15302,3 @@
|
||||
-4100
|
||||
-7E00
|
||||
+4080
|
||||
+4080
|
||||
+7F00
|
||||
@@ -15353 +15353,4 @@
|
||||
-1F80
|
||||
+0F80
|
||||
+1080
|
||||
+2080
|
||||
+2080
|
||||
@@ -15355,6 +15357,0 @@
|
||||
-4080
|
||||
-4080
|
||||
-4080
|
||||
-4080
|
||||
-4080
|
||||
-4080
|
||||
@@ -15362,5 +15359,8 @@
|
||||
-1F80
|
||||
-0080
|
||||
-0080
|
||||
-0100
|
||||
-3E00
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+7FC0
|
||||
+4040
|
||||
+4040
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u24b.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24b.bdf 2020-12-28 20:34:21.955123000 +0200
|
||||
@@ -16344,2 +16344,5 @@
|
||||
-3F00
|
||||
-6180
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F80
|
||||
@@ -16349,2 +16351,0 @@
|
||||
-6180
|
||||
-7F80
|
||||
@@ -16351,0 +16353 @@
|
||||
+7FC0
|
||||
@@ -16356,3 +16358 @@
|
||||
-6060
|
||||
-60C0
|
||||
-7F80
|
||||
+7FC0
|
||||
@@ -16410,7 +16410,11 @@
|
||||
-1FE0
|
||||
-3060
|
||||
-6060
|
||||
-6060
|
||||
-6060
|
||||
-6060
|
||||
-6060
|
||||
+0FC0
|
||||
+18C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+7FE0
|
||||
@@ -16419,6 +16423,2 @@
|
||||
-30E0
|
||||
-1FE0
|
||||
-0060
|
||||
-0060
|
||||
-00C0
|
||||
-3F80
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u24n.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24n.bdf 2020-12-28 20:34:21.915123000 +0200
|
||||
@@ -16344,2 +16344,5 @@
|
||||
-3E00
|
||||
-4100
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F00
|
||||
@@ -16349,2 +16351,0 @@
|
||||
-4100
|
||||
-7F00
|
||||
@@ -16351,0 +16353 @@
|
||||
+7F80
|
||||
@@ -16356,3 +16358 @@
|
||||
-4040
|
||||
-4080
|
||||
-7F00
|
||||
+7F80
|
||||
@@ -16410,7 +16410,11 @@
|
||||
-1FC0
|
||||
-2040
|
||||
-4040
|
||||
-4040
|
||||
-4040
|
||||
-4040
|
||||
-4040
|
||||
+0F80
|
||||
+1080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+7FC0
|
||||
@@ -16419,6 +16423,2 @@
|
||||
-20C0
|
||||
-1F40
|
||||
-0040
|
||||
-0040
|
||||
-0080
|
||||
-3F00
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u28b.bdf.orig 2020-12-28 20:34:18.845118700 +0200
|
||||
+++ ./ter-u28b.bdf 2020-12-28 20:34:21.975123000 +0200
|
||||
@@ -18448 +18448,5 @@
|
||||
-3F00
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -18450,5 +18453,0 @@
|
||||
-61C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-6180
|
||||
@@ -18456,4 +18455,6 @@
|
||||
-7FE0
|
||||
-6070
|
||||
-6030
|
||||
-6030
|
||||
+6060
|
||||
+6060
|
||||
+6060
|
||||
+7FC0
|
||||
+7FC0
|
||||
+6060
|
||||
@@ -18463 +18463,0 @@
|
||||
-6070
|
||||
@@ -18523 +18523,11 @@
|
||||
-1FF0
|
||||
+07F0
|
||||
+0FF0
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
@@ -18525,16 +18535,6 @@
|
||||
-7030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-7030
|
||||
-3FF0
|
||||
-1FF0
|
||||
-0030
|
||||
-0030
|
||||
-0070
|
||||
-3FE0
|
||||
-3FC0
|
||||
+7FF8
|
||||
+6018
|
||||
+6018
|
||||
+6018
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u28n.bdf.orig 2020-12-28 20:34:18.835118600 +0200
|
||||
+++ ./ter-u28n.bdf 2020-12-28 20:34:21.965123000 +0200
|
||||
@@ -18448,4 +18448,6 @@
|
||||
-3F00
|
||||
-6180
|
||||
-60C0
|
||||
-60C0
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F80
|
||||
@@ -18452,0 +18455,3 @@
|
||||
+6060
|
||||
+6060
|
||||
+6060
|
||||
@@ -18454 +18458,0 @@
|
||||
-6180
|
||||
@@ -18460,4 +18463,0 @@
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
@@ -18523,18 +18523,18 @@
|
||||
-1FF0
|
||||
-3030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-3030
|
||||
-1FF0
|
||||
-0030
|
||||
-0030
|
||||
-0030
|
||||
-0060
|
||||
-3FC0
|
||||
+07F0
|
||||
+0C30
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+7FF8
|
||||
+6018
|
||||
+6018
|
||||
+6018
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u32b.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32b.bdf 2020-12-28 20:34:22.025123100 +0200
|
||||
@@ -20554,8 +20554,6 @@
|
||||
-3FC0
|
||||
-7FE0
|
||||
-70F0
|
||||
-7070
|
||||
-7070
|
||||
-7070
|
||||
-7070
|
||||
-70E0
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -20563,0 +20562 @@
|
||||
+7078
|
||||
@@ -20565,4 +20564,5 @@
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
+7038
|
||||
+7038
|
||||
+7FF0
|
||||
+7FF8
|
||||
+703C
|
||||
@@ -20638 +20638,12 @@
|
||||
-1FFC
|
||||
+07FC
|
||||
+0FFC
|
||||
+1E1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
@@ -20640,17 +20651,6 @@
|
||||
-781C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-781C
|
||||
-3FFC
|
||||
-1FFC
|
||||
-001C
|
||||
-001C
|
||||
-003C
|
||||
-3FF8
|
||||
-3FF0
|
||||
+7FFE
|
||||
+700E
|
||||
+700E
|
||||
+700E
|
||||
+700E
|
||||
+0000
|
||||
--- ./ter-u32n.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32n.bdf 2020-12-28 20:34:21.985123000 +0200
|
||||
@@ -20554,8 +20554,6 @@
|
||||
-1FC0
|
||||
-3FE0
|
||||
-3070
|
||||
-3030
|
||||
-3030
|
||||
-3030
|
||||
-3030
|
||||
-3070
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -20564,0 +20563,5 @@
|
||||
+3018
|
||||
+3018
|
||||
+3038
|
||||
+3FF0
|
||||
+3FF8
|
||||
@@ -20568,3 +20570,0 @@
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
@@ -20638,19 +20638,19 @@
|
||||
-0FFC
|
||||
-1FFC
|
||||
-380C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-380C
|
||||
-1FFC
|
||||
-0FFC
|
||||
-000C
|
||||
-000C
|
||||
-001C
|
||||
-1FF8
|
||||
-1FF0
|
||||
+07F8
|
||||
+0FF8
|
||||
+1C18
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+3FF8
|
||||
+7FFC
|
||||
+600C
|
||||
+600C
|
||||
+600C
|
||||
+600C
|
||||
+0000
|
||||
@@ -0,0 +1,992 @@
|
||||
--- ./ter-u12b.bdf.orig 2020-12-28 20:34:18.635118400 +0200
|
||||
+++ ./ter-u12b.bdf 2020-12-28 20:34:22.635124000 +0200
|
||||
@@ -10051,4 +10051,3 @@
|
||||
-F8
|
||||
-80
|
||||
-80
|
||||
-80
|
||||
+70
|
||||
+08
|
||||
+70
|
||||
@@ -10056,0 +10056 @@
|
||||
+70
|
||||
@@ -10659,4 +10659,3 @@
|
||||
-F8
|
||||
-80
|
||||
-80
|
||||
-80
|
||||
+70
|
||||
+08
|
||||
+70
|
||||
@@ -10664,0 +10664 @@
|
||||
+70
|
||||
@@ -10998,0 +10999,3 @@
|
||||
+40
|
||||
+40
|
||||
+70
|
||||
@@ -11000,5 +11003 @@
|
||||
-08
|
||||
-F8
|
||||
-80
|
||||
-80
|
||||
-80
|
||||
+70
|
||||
@@ -11006,0 +11006 @@
|
||||
+70
|
||||
--- ./ter-u12n.bdf.orig 2020-12-28 20:34:18.605118300 +0200
|
||||
+++ ./ter-u12n.bdf 2020-12-28 20:34:22.625123900 +0200
|
||||
@@ -10051,4 +10051,3 @@
|
||||
-F8
|
||||
-80
|
||||
-80
|
||||
-80
|
||||
+70
|
||||
+08
|
||||
+70
|
||||
@@ -10056,0 +10056 @@
|
||||
+70
|
||||
@@ -10659,4 +10659,3 @@
|
||||
-F8
|
||||
-80
|
||||
-80
|
||||
-80
|
||||
+70
|
||||
+08
|
||||
+70
|
||||
@@ -10664,0 +10664 @@
|
||||
+70
|
||||
@@ -10998,0 +10999,3 @@
|
||||
+40
|
||||
+40
|
||||
+70
|
||||
@@ -11000,5 +11003 @@
|
||||
-08
|
||||
-F8
|
||||
-80
|
||||
-80
|
||||
-80
|
||||
+70
|
||||
@@ -11006,0 +11006 @@
|
||||
+70
|
||||
--- ./ter-u14b.bdf.orig 2020-12-28 20:34:18.655118400 +0200
|
||||
+++ ./ter-u14b.bdf 2020-12-28 20:34:22.675124000 +0200
|
||||
@@ -11106,5 +11106,4 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
+06
|
||||
+06
|
||||
+7C
|
||||
@@ -11112,0 +11112 @@
|
||||
+7C
|
||||
@@ -11778,5 +11778,4 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
+06
|
||||
+06
|
||||
+7C
|
||||
@@ -11784,0 +11784 @@
|
||||
+7C
|
||||
@@ -12153,0 +12154,3 @@
|
||||
+60
|
||||
+60
|
||||
+7C
|
||||
@@ -12156,5 +12159 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
@@ -12162,0 +12162 @@
|
||||
+7C
|
||||
--- ./ter-u14n.bdf.orig 2020-12-28 20:34:18.645118400 +0200
|
||||
+++ ./ter-u14n.bdf 2020-12-28 20:34:22.655124000 +0200
|
||||
@@ -11106,5 +11106,4 @@
|
||||
-7E
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
+3C
|
||||
+02
|
||||
+02
|
||||
+3C
|
||||
@@ -11112,0 +11112 @@
|
||||
+3C
|
||||
@@ -11778,5 +11778,4 @@
|
||||
-7E
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
+3C
|
||||
+02
|
||||
+02
|
||||
+3C
|
||||
@@ -11784,0 +11784 @@
|
||||
+3C
|
||||
@@ -12153,0 +12154,3 @@
|
||||
+20
|
||||
+20
|
||||
+3C
|
||||
@@ -12156,5 +12159 @@
|
||||
-7E
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
+3C
|
||||
@@ -12162,0 +12162 @@
|
||||
+3C
|
||||
--- ./ter-u14v.bdf.orig 2020-12-28 20:34:18.675118400 +0200
|
||||
+++ ./ter-u14v.bdf 2020-12-28 20:34:22.665124000 +0200
|
||||
@@ -11106,5 +11106,4 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
+06
|
||||
+06
|
||||
+7C
|
||||
@@ -11112,0 +11112 @@
|
||||
+7C
|
||||
@@ -11778,5 +11778,4 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
+06
|
||||
+06
|
||||
+7C
|
||||
@@ -11784,0 +11784 @@
|
||||
+7C
|
||||
@@ -12153,0 +12154,3 @@
|
||||
+60
|
||||
+60
|
||||
+7C
|
||||
@@ -12156,5 +12159 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
@@ -12162,0 +12162 @@
|
||||
+7C
|
||||
--- ./ter-u16b.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16b.bdf 2020-12-28 20:34:22.695124000 +0200
|
||||
@@ -12160,5 +12160,4 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
+06
|
||||
+06
|
||||
+7C
|
||||
@@ -12166,0 +12166 @@
|
||||
+7C
|
||||
@@ -12896,5 +12896,4 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
+06
|
||||
+06
|
||||
+7C
|
||||
@@ -12902,0 +12902 @@
|
||||
+7C
|
||||
@@ -13307,0 +13308,3 @@
|
||||
+60
|
||||
+60
|
||||
+7C
|
||||
@@ -13310,5 +13313 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
@@ -13316,0 +13316 @@
|
||||
+7C
|
||||
--- ./ter-u16n.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16n.bdf 2020-12-28 20:34:22.685124000 +0200
|
||||
@@ -12160,5 +12160,4 @@
|
||||
-7E
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
+3C
|
||||
+02
|
||||
+02
|
||||
+3C
|
||||
@@ -12166,0 +12166 @@
|
||||
+3C
|
||||
@@ -12896,5 +12896,4 @@
|
||||
-7E
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
+3C
|
||||
+02
|
||||
+02
|
||||
+3C
|
||||
@@ -12902,0 +12902 @@
|
||||
+3C
|
||||
@@ -13307,0 +13308,3 @@
|
||||
+20
|
||||
+20
|
||||
+3C
|
||||
@@ -13310,5 +13313 @@
|
||||
-7E
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
+3C
|
||||
@@ -13316,0 +13316 @@
|
||||
+3C
|
||||
--- ./ter-u16v.bdf.orig 2020-12-28 20:34:18.695118400 +0200
|
||||
+++ ./ter-u16v.bdf 2020-12-28 20:34:22.715124100 +0200
|
||||
@@ -12160,5 +12160,4 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
+06
|
||||
+06
|
||||
+7C
|
||||
@@ -12166,0 +12166 @@
|
||||
+7C
|
||||
@@ -12896,5 +12896,4 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
+06
|
||||
+06
|
||||
+7C
|
||||
@@ -12902,0 +12902 @@
|
||||
+7C
|
||||
@@ -13307,0 +13308,3 @@
|
||||
+60
|
||||
+60
|
||||
+7C
|
||||
@@ -13310,5 +13313 @@
|
||||
-FE
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
-C0
|
||||
+7C
|
||||
@@ -13316,0 +13316 @@
|
||||
+7C
|
||||
--- ./ter-u18b.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18b.bdf 2020-12-28 20:34:22.725124100 +0200
|
||||
@@ -13215,6 +13215,5 @@
|
||||
-7F80
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3F00
|
||||
+0180
|
||||
+0180
|
||||
+0180
|
||||
+3F00
|
||||
@@ -13223,0 +13223 @@
|
||||
+3F00
|
||||
@@ -14015,6 +14015,5 @@
|
||||
-7F80
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3F00
|
||||
+0180
|
||||
+0180
|
||||
+0180
|
||||
+3F00
|
||||
@@ -14023,0 +14023 @@
|
||||
+3F00
|
||||
@@ -14462,0 +14463,3 @@
|
||||
+3000
|
||||
+3000
|
||||
+3F00
|
||||
@@ -14465,6 +14468,2 @@
|
||||
-7F80
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+0180
|
||||
+3F00
|
||||
@@ -14473,0 +14473 @@
|
||||
+3F00
|
||||
--- ./ter-u18n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18n.bdf 2020-12-28 20:34:22.715124100 +0200
|
||||
@@ -13215,6 +13215,5 @@
|
||||
-7F00
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3E00
|
||||
+0100
|
||||
+0100
|
||||
+0100
|
||||
+3E00
|
||||
@@ -13223,0 +13223 @@
|
||||
+3E00
|
||||
@@ -14015,6 +14015,5 @@
|
||||
-7F00
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3E00
|
||||
+0100
|
||||
+0100
|
||||
+0100
|
||||
+3E00
|
||||
@@ -14023,0 +14023 @@
|
||||
+3E00
|
||||
@@ -14462,0 +14463,3 @@
|
||||
+2000
|
||||
+2000
|
||||
+3E00
|
||||
@@ -14465,6 +14468,2 @@
|
||||
-7F00
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+0100
|
||||
+3E00
|
||||
@@ -14473,0 +14473 @@
|
||||
+3E00
|
||||
--- ./ter-u20b.bdf.orig 2020-12-28 20:34:18.735118500 +0200
|
||||
+++ ./ter-u20b.bdf 2020-12-28 20:34:22.775124200 +0200
|
||||
@@ -14270,6 +14270,5 @@
|
||||
-7F80
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3F00
|
||||
+0180
|
||||
+0180
|
||||
+0180
|
||||
+3F00
|
||||
@@ -14278,0 +14278 @@
|
||||
+3F00
|
||||
@@ -15134,6 +15134,5 @@
|
||||
-7F80
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3F00
|
||||
+0180
|
||||
+0180
|
||||
+0180
|
||||
+3F00
|
||||
@@ -15142,0 +15142 @@
|
||||
+3F00
|
||||
@@ -15617,0 +15618,3 @@
|
||||
+3000
|
||||
+3000
|
||||
+3F00
|
||||
@@ -15620,6 +15623,2 @@
|
||||
-7F80
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+0180
|
||||
+3F00
|
||||
@@ -15628,0 +15628 @@
|
||||
+3F00
|
||||
--- ./ter-u20n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u20n.bdf 2020-12-28 20:34:22.735124100 +0200
|
||||
@@ -14270,6 +14270,5 @@
|
||||
-7F00
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3E00
|
||||
+0100
|
||||
+0100
|
||||
+0100
|
||||
+3E00
|
||||
@@ -14278,0 +14278 @@
|
||||
+3E00
|
||||
@@ -15134,6 +15134,5 @@
|
||||
-7F00
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3E00
|
||||
+0100
|
||||
+0100
|
||||
+0100
|
||||
+3E00
|
||||
@@ -15142,0 +15142 @@
|
||||
+3E00
|
||||
@@ -15617,0 +15618,3 @@
|
||||
+2000
|
||||
+2000
|
||||
+3E00
|
||||
@@ -15620,6 +15623,2 @@
|
||||
-7F00
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+0100
|
||||
+3E00
|
||||
@@ -15628,0 +15628 @@
|
||||
+3E00
|
||||
--- ./ter-u22b.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22b.bdf 2020-12-28 20:34:22.775124200 +0200
|
||||
@@ -15324,6 +15324,5 @@
|
||||
-7FC0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3F80
|
||||
+00C0
|
||||
+00C0
|
||||
+00C0
|
||||
+3F80
|
||||
@@ -15333,0 +15333 @@
|
||||
+3F80
|
||||
@@ -16252,6 +16252,5 @@
|
||||
-7FC0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3F80
|
||||
+00C0
|
||||
+00C0
|
||||
+00C0
|
||||
+3F80
|
||||
@@ -16261,0 +16261 @@
|
||||
+3F80
|
||||
@@ -16770,0 +16771,4 @@
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3F80
|
||||
@@ -16774,6 +16778 @@
|
||||
-7FC0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3F80
|
||||
@@ -16783,0 +16783 @@
|
||||
+3F80
|
||||
--- ./ter-u22n.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22n.bdf 2020-12-28 20:34:22.775124200 +0200
|
||||
@@ -15324,6 +15324,5 @@
|
||||
-7F80
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3F00
|
||||
+0080
|
||||
+0080
|
||||
+0080
|
||||
+3F00
|
||||
@@ -15333,0 +15333 @@
|
||||
+3F00
|
||||
@@ -16252,6 +16252,5 @@
|
||||
-7F80
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3F00
|
||||
+0080
|
||||
+0080
|
||||
+0080
|
||||
+3F00
|
||||
@@ -16261,0 +16261 @@
|
||||
+3F00
|
||||
@@ -16770,0 +16771,4 @@
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+3F00
|
||||
@@ -16774,6 +16778 @@
|
||||
-7F80
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3F00
|
||||
@@ -16783,0 +16783 @@
|
||||
+3F00
|
||||
--- ./ter-u24b.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24b.bdf 2020-12-28 20:34:22.825124200 +0200
|
||||
@@ -16379,7 +16379,6 @@
|
||||
-7FE0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3FC0
|
||||
+0060
|
||||
+0060
|
||||
+0060
|
||||
+0060
|
||||
+3FC0
|
||||
@@ -16389,0 +16389 @@
|
||||
+3FC0
|
||||
@@ -17371,7 +17371,6 @@
|
||||
-7FE0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3FC0
|
||||
+0060
|
||||
+0060
|
||||
+0060
|
||||
+0060
|
||||
+3FC0
|
||||
@@ -17381,0 +17381 @@
|
||||
+3FC0
|
||||
@@ -17925,0 +17926,4 @@
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3FC0
|
||||
@@ -17929,7 +17933,2 @@
|
||||
-7FE0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+0060
|
||||
+3FC0
|
||||
@@ -17939,0 +17939 @@
|
||||
+3FC0
|
||||
--- ./ter-u24n.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24n.bdf 2020-12-28 20:34:22.775124200 +0200
|
||||
@@ -16379,7 +16379,6 @@
|
||||
-7FC0
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3F80
|
||||
+0040
|
||||
+0040
|
||||
+0040
|
||||
+0040
|
||||
+3F80
|
||||
@@ -16389,0 +16389 @@
|
||||
+3F80
|
||||
@@ -17371,7 +17371,6 @@
|
||||
-7FC0
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+3F80
|
||||
+0040
|
||||
+0040
|
||||
+0040
|
||||
+0040
|
||||
+3F80
|
||||
@@ -17381,0 +17381 @@
|
||||
+3F80
|
||||
@@ -17925,0 +17926,4 @@
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+3F80
|
||||
@@ -17929,7 +17933,2 @@
|
||||
-7FC0
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
-4000
|
||||
+0040
|
||||
+3F80
|
||||
@@ -17939,0 +17939 @@
|
||||
+3F80
|
||||
--- ./ter-u28b.bdf.orig 2020-12-28 20:34:18.845118700 +0200
|
||||
+++ ./ter-u28b.bdf 2020-12-28 20:34:22.845124300 +0200
|
||||
@@ -18488,11 +18488,8 @@
|
||||
-7FF0
|
||||
-7FF0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3FC0
|
||||
+3FE0
|
||||
+0070
|
||||
+0030
|
||||
+0030
|
||||
+1FE0
|
||||
+3FC0
|
||||
+7000
|
||||
@@ -18500,0 +18498,3 @@
|
||||
+7000
|
||||
+3FE0
|
||||
+1FE0
|
||||
@@ -19608,11 +19608,8 @@
|
||||
-7FF0
|
||||
-7FF0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3FC0
|
||||
+3FE0
|
||||
+0070
|
||||
+0030
|
||||
+0030
|
||||
+1FE0
|
||||
+3FC0
|
||||
+7000
|
||||
@@ -19620,0 +19618,3 @@
|
||||
+7000
|
||||
+3FE0
|
||||
+1FE0
|
||||
@@ -20234,0 +20235,6 @@
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3FC0
|
||||
+3FE0
|
||||
+0070
|
||||
@@ -20237,12 +20243,3 @@
|
||||
-0030
|
||||
-7FF0
|
||||
-7FF0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+1FE0
|
||||
+3FC0
|
||||
+7000
|
||||
@@ -20250,0 +20248,3 @@
|
||||
+7000
|
||||
+3FE0
|
||||
+1FE0
|
||||
--- ./ter-u28n.bdf.orig 2020-12-28 20:34:18.835118600 +0200
|
||||
+++ ./ter-u28n.bdf 2020-12-28 20:34:22.835124200 +0200
|
||||
@@ -18488,10 +18488,8 @@
|
||||
-7FF0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3FC0
|
||||
+0060
|
||||
+0030
|
||||
+0030
|
||||
+0030
|
||||
+0060
|
||||
+1FC0
|
||||
+3000
|
||||
@@ -18500,0 +18499,2 @@
|
||||
+3000
|
||||
+1FE0
|
||||
@@ -19608,10 +19608,8 @@
|
||||
-7FF0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+3FC0
|
||||
+0060
|
||||
+0030
|
||||
+0030
|
||||
+0030
|
||||
+0060
|
||||
+1FC0
|
||||
+3000
|
||||
@@ -19620,0 +19619,2 @@
|
||||
+3000
|
||||
+1FE0
|
||||
@@ -20234,0 +20235,5 @@
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3FC0
|
||||
+0060
|
||||
@@ -20238,10 +20243,3 @@
|
||||
-7FF0
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
-6000
|
||||
+0060
|
||||
+1FC0
|
||||
+3000
|
||||
@@ -20250,0 +20249,2 @@
|
||||
+3000
|
||||
+1FE0
|
||||
--- ./ter-u32b.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32b.bdf 2020-12-28 20:34:22.905124300 +0200
|
||||
@@ -20599,12 +20599,9 @@
|
||||
-7FFC
|
||||
-7FFC
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
+3FF0
|
||||
+3FF8
|
||||
+003C
|
||||
+001C
|
||||
+001C
|
||||
+003C
|
||||
+1FF8
|
||||
+3FF0
|
||||
+7800
|
||||
@@ -20612,0 +20610,3 @@
|
||||
+7800
|
||||
+3FF8
|
||||
+1FF8
|
||||
@@ -21847,12 +21847,9 @@
|
||||
-7FFC
|
||||
-7FFC
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
+3FF0
|
||||
+3FF8
|
||||
+003C
|
||||
+001C
|
||||
+001C
|
||||
+003C
|
||||
+1FF8
|
||||
+3FF0
|
||||
+7800
|
||||
@@ -21860,0 +21858,3 @@
|
||||
+7800
|
||||
+3FF8
|
||||
+1FF8
|
||||
@@ -22544,0 +22545,7 @@
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3FF0
|
||||
+3FF8
|
||||
+003C
|
||||
@@ -22547,14 +22554,4 @@
|
||||
-001C
|
||||
-001C
|
||||
-7FFC
|
||||
-7FFC
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
-7000
|
||||
+003C
|
||||
+1FF8
|
||||
+3FF0
|
||||
+7800
|
||||
@@ -22562,0 +22560,3 @@
|
||||
+7800
|
||||
+3FF8
|
||||
+1FF8
|
||||
--- ./ter-u32n.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32n.bdf 2020-12-28 20:34:22.855124300 +0200
|
||||
@@ -20599,12 +20599,9 @@
|
||||
-3FFC
|
||||
-3FFC
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
+1FF0
|
||||
+1FF8
|
||||
+001C
|
||||
+000C
|
||||
+000C
|
||||
+001C
|
||||
+0FF8
|
||||
+1FF0
|
||||
+3800
|
||||
@@ -20612,0 +20610,3 @@
|
||||
+3800
|
||||
+1FF8
|
||||
+0FF8
|
||||
@@ -21847,12 +21847,9 @@
|
||||
-3FFC
|
||||
-3FFC
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
+1FF0
|
||||
+1FF8
|
||||
+001C
|
||||
+000C
|
||||
+000C
|
||||
+001C
|
||||
+0FF8
|
||||
+1FF0
|
||||
+3800
|
||||
@@ -21860,0 +21858,3 @@
|
||||
+3800
|
||||
+1FF8
|
||||
+0FF8
|
||||
@@ -22544,0 +22545,7 @@
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1FF0
|
||||
+1FF8
|
||||
+001C
|
||||
@@ -22547,14 +22554,4 @@
|
||||
-000C
|
||||
-000C
|
||||
-3FFC
|
||||
-3FFC
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
-3000
|
||||
+001C
|
||||
+0FF8
|
||||
+1FF0
|
||||
+3800
|
||||
@@ -22562,0 +22560,3 @@
|
||||
+3800
|
||||
+1FF8
|
||||
+0FF8
|
||||
@@ -0,0 +1,304 @@
|
||||
--- ./ter-u12b.bdf.orig 2020-12-28 20:34:18.635118400 +0200
|
||||
+++ ./ter-u12b.bdf 2020-12-28 20:34:23.545125200 +0200
|
||||
@@ -189 +189 @@
|
||||
-20
|
||||
+40
|
||||
@@ -1269,3 +1268,0 @@
|
||||
-40
|
||||
-20
|
||||
-00
|
||||
@@ -1272,0 +1270,3 @@
|
||||
+20
|
||||
+20
|
||||
+10
|
||||
--- ./ter-u12n.bdf.orig 2020-12-28 20:34:18.605118300 +0200
|
||||
+++ ./ter-u12n.bdf 2020-12-28 20:34:23.535125200 +0200
|
||||
@@ -189 +189 @@
|
||||
-20
|
||||
+40
|
||||
@@ -1269,3 +1268,0 @@
|
||||
-40
|
||||
-20
|
||||
-00
|
||||
@@ -1272,0 +1270,3 @@
|
||||
+20
|
||||
+20
|
||||
+10
|
||||
--- ./ter-u14b.bdf.orig 2020-12-28 20:34:18.655118400 +0200
|
||||
+++ ./ter-u14b.bdf 2020-12-28 20:34:23.575125300 +0200
|
||||
@@ -205 +205 @@
|
||||
-18
|
||||
+30
|
||||
@@ -1398,0 +1399,2 @@
|
||||
+00
|
||||
+30
|
||||
@@ -1401,2 +1402,0 @@
|
||||
-00
|
||||
-00
|
||||
--- ./ter-u14n.bdf.orig 2020-12-28 20:34:18.645118400 +0200
|
||||
+++ ./ter-u14n.bdf 2020-12-28 20:34:23.555125200 +0200
|
||||
@@ -203,2 +203,2 @@
|
||||
-10
|
||||
-10
|
||||
+08
|
||||
+08
|
||||
@@ -1398,0 +1399,2 @@
|
||||
+00
|
||||
+10
|
||||
@@ -1401,2 +1402,0 @@
|
||||
-00
|
||||
-00
|
||||
--- ./ter-u14v.bdf.orig 2020-12-28 20:34:18.675118400 +0200
|
||||
+++ ./ter-u14v.bdf 2020-12-28 20:34:23.575125300 +0200
|
||||
@@ -205 +205 @@
|
||||
-18
|
||||
+30
|
||||
@@ -1398,0 +1399,2 @@
|
||||
+00
|
||||
+30
|
||||
@@ -1401,2 +1402,0 @@
|
||||
-00
|
||||
-00
|
||||
--- ./ter-u16b.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16b.bdf 2020-12-28 20:34:23.595125300 +0200
|
||||
@@ -221 +221 @@
|
||||
-18
|
||||
+30
|
||||
@@ -1528,0 +1529,2 @@
|
||||
+00
|
||||
+30
|
||||
@@ -1531,2 +1532,0 @@
|
||||
-00
|
||||
-00
|
||||
--- ./ter-u16n.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16n.bdf 2020-12-28 20:34:23.585125300 +0200
|
||||
@@ -219,2 +219,2 @@
|
||||
-10
|
||||
-10
|
||||
+08
|
||||
+08
|
||||
@@ -1528,0 +1529,2 @@
|
||||
+00
|
||||
+10
|
||||
@@ -1531,2 +1532,0 @@
|
||||
-00
|
||||
-00
|
||||
--- ./ter-u16v.bdf.orig 2020-12-28 20:34:18.695118400 +0200
|
||||
+++ ./ter-u16v.bdf 2020-12-28 20:34:23.615125300 +0200
|
||||
@@ -221 +221 @@
|
||||
-18
|
||||
+30
|
||||
@@ -1528,0 +1529,2 @@
|
||||
+00
|
||||
+30
|
||||
@@ -1531,2 +1532,0 @@
|
||||
-00
|
||||
-00
|
||||
--- ./ter-u18b.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18b.bdf 2020-12-28 20:34:23.635125400 +0200
|
||||
@@ -238 +238 @@
|
||||
-0C00
|
||||
+1800
|
||||
@@ -1659 +1659,3 @@
|
||||
-3000
|
||||
+0000
|
||||
+1800
|
||||
+1800
|
||||
@@ -1662,2 +1663,0 @@
|
||||
-0000
|
||||
-0000
|
||||
--- ./ter-u18n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18n.bdf 2020-12-28 20:34:23.625125300 +0200
|
||||
@@ -238 +238 @@
|
||||
-0800
|
||||
+1000
|
||||
@@ -1659 +1659,3 @@
|
||||
-2000
|
||||
+0000
|
||||
+1000
|
||||
+1000
|
||||
@@ -1662,2 +1663,0 @@
|
||||
-0000
|
||||
-0000
|
||||
--- ./ter-u20b.bdf.orig 2020-12-28 20:34:18.735118500 +0200
|
||||
+++ ./ter-u20b.bdf 2020-12-28 20:34:23.665125400 +0200
|
||||
@@ -254 +254 @@
|
||||
-0C00
|
||||
+1800
|
||||
@@ -1789 +1789,3 @@
|
||||
-3000
|
||||
+0000
|
||||
+1800
|
||||
+1800
|
||||
@@ -1792,2 +1793,0 @@
|
||||
-0000
|
||||
-0000
|
||||
--- ./ter-u20n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u20n.bdf 2020-12-28 20:34:23.635125400 +0200
|
||||
@@ -254 +254 @@
|
||||
-0800
|
||||
+1000
|
||||
@@ -1789 +1789,3 @@
|
||||
-2000
|
||||
+0000
|
||||
+1000
|
||||
+1000
|
||||
@@ -1792,2 +1793,0 @@
|
||||
-0000
|
||||
-0000
|
||||
--- ./ter-u22b.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22b.bdf 2020-12-28 20:34:23.675125400 +0200
|
||||
@@ -267,4 +267,4 @@
|
||||
-0C00
|
||||
-0C00
|
||||
-0C00
|
||||
-0C00
|
||||
+0600
|
||||
+0600
|
||||
+0600
|
||||
+0600
|
||||
@@ -1919 +1919,4 @@
|
||||
-1800
|
||||
+0000
|
||||
+0C00
|
||||
+0C00
|
||||
+0C00
|
||||
@@ -1922,3 +1924,0 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
--- ./ter-u22n.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22n.bdf 2020-12-28 20:34:23.675125400 +0200
|
||||
@@ -271 +271 @@
|
||||
-0400
|
||||
+0800
|
||||
@@ -1919,5 +1918,0 @@
|
||||
-1000
|
||||
-0800
|
||||
-0400
|
||||
-0000
|
||||
-0000
|
||||
@@ -1924,0 +1920,5 @@
|
||||
+0400
|
||||
+0400
|
||||
+0400
|
||||
+0400
|
||||
+0200
|
||||
--- ./ter-u24b.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24b.bdf 2020-12-28 20:34:23.715125500 +0200
|
||||
@@ -288 +288 @@
|
||||
-0600
|
||||
+0C00
|
||||
@@ -2050,5 +2049,0 @@
|
||||
-1800
|
||||
-0C00
|
||||
-0600
|
||||
-0000
|
||||
-0000
|
||||
@@ -2055,0 +2051,5 @@
|
||||
+0600
|
||||
+0600
|
||||
+0600
|
||||
+0600
|
||||
+0300
|
||||
--- ./ter-u24n.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24n.bdf 2020-12-28 20:34:23.685125400 +0200
|
||||
@@ -288 +288 @@
|
||||
-0400
|
||||
+0800
|
||||
@@ -2050,5 +2049,0 @@
|
||||
-1000
|
||||
-0800
|
||||
-0400
|
||||
-0000
|
||||
-0000
|
||||
@@ -2055,0 +2051,5 @@
|
||||
+0400
|
||||
+0400
|
||||
+0400
|
||||
+0400
|
||||
+0200
|
||||
--- ./ter-u28b.bdf.orig 2020-12-28 20:34:18.845118700 +0200
|
||||
+++ ./ter-u28b.bdf 2020-12-28 20:34:23.735125500 +0200
|
||||
@@ -320,2 +320,2 @@
|
||||
-0300
|
||||
-0300
|
||||
+0600
|
||||
+0600
|
||||
@@ -2309,6 +2308,0 @@
|
||||
-3800
|
||||
-1C00
|
||||
-0E00
|
||||
-0700
|
||||
-0000
|
||||
-0000
|
||||
@@ -2316,0 +2311,6 @@
|
||||
+0600
|
||||
+0600
|
||||
+0600
|
||||
+0600
|
||||
+0300
|
||||
+0300
|
||||
--- ./ter-u28n.bdf.orig 2020-12-28 20:34:18.835118600 +0200
|
||||
+++ ./ter-u28n.bdf 2020-12-28 20:34:23.735125500 +0200
|
||||
@@ -320,2 +320,2 @@
|
||||
-0300
|
||||
-0300
|
||||
+0600
|
||||
+0600
|
||||
@@ -2309,6 +2308,0 @@
|
||||
-1800
|
||||
-0C00
|
||||
-0600
|
||||
-0300
|
||||
-0000
|
||||
-0000
|
||||
@@ -2316,0 +2311,6 @@
|
||||
+0600
|
||||
+0600
|
||||
+0600
|
||||
+0600
|
||||
+0300
|
||||
+0300
|
||||
--- ./ter-u32b.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32b.bdf 2020-12-28 20:34:23.775125600 +0200
|
||||
@@ -354,2 +354,2 @@
|
||||
-0380
|
||||
-0380
|
||||
+0700
|
||||
+0700
|
||||
@@ -2571,6 +2570,0 @@
|
||||
-1C00
|
||||
-0E00
|
||||
-0700
|
||||
-0380
|
||||
-0000
|
||||
-0000
|
||||
@@ -2578,0 +2573,6 @@
|
||||
+0380
|
||||
+0380
|
||||
+0380
|
||||
+0380
|
||||
+01C0
|
||||
+01C0
|
||||
--- ./ter-u32n.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32n.bdf 2020-12-28 20:34:23.765125500 +0200
|
||||
@@ -354,2 +354,2 @@
|
||||
-0180
|
||||
-0180
|
||||
+0300
|
||||
+0300
|
||||
@@ -2571,6 +2570,0 @@
|
||||
-0E00
|
||||
-0700
|
||||
-0380
|
||||
-01C0
|
||||
-0000
|
||||
-0000
|
||||
@@ -2578,0 +2573,6 @@
|
||||
+0180
|
||||
+0180
|
||||
+0180
|
||||
+0180
|
||||
+00C0
|
||||
+00C0
|
||||
@@ -0,0 +1,860 @@
|
||||
--- ./ter-u12b.bdf.orig 2020-12-28 20:34:27.995131500 +0200
|
||||
+++ ./ter-u12b.bdf 2020-12-28 20:34:29.445133500 +0200
|
||||
@@ -10030,3 +10030,2 @@
|
||||
-E0
|
||||
-90
|
||||
-90
|
||||
+00
|
||||
+00
|
||||
@@ -10034,0 +10034 @@
|
||||
+F0
|
||||
@@ -10070,8 +10070,8 @@
|
||||
-78
|
||||
-88
|
||||
-88
|
||||
-88
|
||||
-88
|
||||
-78
|
||||
-08
|
||||
-70
|
||||
+38
|
||||
+48
|
||||
+48
|
||||
+48
|
||||
+48
|
||||
+FC
|
||||
+84
|
||||
+00
|
||||
--- ./ter-u12n.bdf.orig 2020-12-28 20:34:27.975131400 +0200
|
||||
+++ ./ter-u12n.bdf 2020-12-28 20:34:29.425133500 +0200
|
||||
@@ -10030,3 +10030,2 @@
|
||||
-E0
|
||||
-90
|
||||
-90
|
||||
+00
|
||||
+00
|
||||
@@ -10034,0 +10034 @@
|
||||
+F0
|
||||
@@ -10070,8 +10070,8 @@
|
||||
-78
|
||||
-88
|
||||
-88
|
||||
-88
|
||||
-88
|
||||
-78
|
||||
-08
|
||||
-70
|
||||
+38
|
||||
+48
|
||||
+48
|
||||
+48
|
||||
+48
|
||||
+FC
|
||||
+84
|
||||
+00
|
||||
--- ./ter-u14b.bdf.orig 2020-12-28 20:34:28.025131500 +0200
|
||||
+++ ./ter-u14b.bdf 2020-12-28 20:34:29.465133500 +0200
|
||||
@@ -11082,4 +11082,3 @@
|
||||
-78
|
||||
-CC
|
||||
-CC
|
||||
-C8
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -11088,0 +11088 @@
|
||||
+FC
|
||||
@@ -11127,9 +11127,9 @@
|
||||
-7E
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-7E
|
||||
-06
|
||||
-7C
|
||||
+3E
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+FF
|
||||
+C3
|
||||
+00
|
||||
--- ./ter-u14n.bdf.orig 2020-12-28 20:34:27.995131500 +0200
|
||||
+++ ./ter-u14n.bdf 2020-12-28 20:34:29.465133500 +0200
|
||||
@@ -11082,4 +11082,3 @@
|
||||
-38
|
||||
-44
|
||||
-44
|
||||
-48
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -11088,0 +11088 @@
|
||||
+7C
|
||||
@@ -11127,8 +11126,0 @@
|
||||
-3E
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-3E
|
||||
-02
|
||||
@@ -11135,0 +11128,8 @@
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+FE
|
||||
+82
|
||||
+00
|
||||
--- ./ter-u14v.bdf.orig 2020-12-28 20:34:28.025131500 +0200
|
||||
+++ ./ter-u14v.bdf 2020-12-28 20:34:29.475133500 +0200
|
||||
@@ -11082,4 +11082,3 @@
|
||||
-78
|
||||
-CC
|
||||
-CC
|
||||
-C8
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -11088,0 +11088 @@
|
||||
+FC
|
||||
@@ -11127,9 +11127,9 @@
|
||||
-7E
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-7E
|
||||
-06
|
||||
-7C
|
||||
+3E
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+FF
|
||||
+C3
|
||||
+00
|
||||
--- ./ter-u16b.bdf.orig 2020-12-28 20:34:28.035131500 +0200
|
||||
+++ ./ter-u16b.bdf 2020-12-28 20:34:29.515133600 +0200
|
||||
@@ -12134,4 +12134,3 @@
|
||||
-78
|
||||
-CC
|
||||
-CC
|
||||
-C8
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -12140,0 +12140 @@
|
||||
+FC
|
||||
@@ -12183,10 +12183,10 @@
|
||||
-7E
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-7E
|
||||
-06
|
||||
-06
|
||||
-7C
|
||||
+3E
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+FF
|
||||
+C3
|
||||
+00
|
||||
+00
|
||||
--- ./ter-u16n.bdf.orig 2020-12-28 20:34:28.035131500 +0200
|
||||
+++ ./ter-u16n.bdf 2020-12-28 20:34:29.485133500 +0200
|
||||
@@ -12134,4 +12134,3 @@
|
||||
-38
|
||||
-44
|
||||
-44
|
||||
-48
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -12140,0 +12140 @@
|
||||
+7C
|
||||
@@ -12183,9 +12182,0 @@
|
||||
-3E
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-42
|
||||
-3E
|
||||
-02
|
||||
-02
|
||||
@@ -12192,0 +12184,9 @@
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+44
|
||||
+FE
|
||||
+82
|
||||
+00
|
||||
+00
|
||||
--- ./ter-u16v.bdf.orig 2020-12-28 20:34:28.065131600 +0200
|
||||
+++ ./ter-u16v.bdf 2020-12-28 20:34:29.515133600 +0200
|
||||
@@ -12134,4 +12134,3 @@
|
||||
-78
|
||||
-CC
|
||||
-CC
|
||||
-C8
|
||||
+00
|
||||
+00
|
||||
+00
|
||||
@@ -12140,0 +12140 @@
|
||||
+FC
|
||||
@@ -12183,10 +12183,10 @@
|
||||
-7E
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-C6
|
||||
-7E
|
||||
-06
|
||||
-06
|
||||
-7C
|
||||
+3E
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+66
|
||||
+FF
|
||||
+C3
|
||||
+00
|
||||
+00
|
||||
--- ./ter-u18b.bdf.orig 2020-12-28 20:34:28.085131600 +0200
|
||||
+++ ./ter-u18b.bdf 2020-12-28 20:34:29.535133600 +0200
|
||||
@@ -13186,5 +13186,4 @@
|
||||
-3E00
|
||||
-6300
|
||||
-6300
|
||||
-6300
|
||||
-6200
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -13194,0 +13194 @@
|
||||
+7F00
|
||||
@@ -13240,12 +13240,12 @@
|
||||
-3F80
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-3F80
|
||||
-0180
|
||||
-0180
|
||||
-3F00
|
||||
+1F00
|
||||
+3300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+FF80
|
||||
+C180
|
||||
+C180
|
||||
+0000
|
||||
--- ./ter-u18n.bdf.orig 2020-12-28 20:34:28.065131600 +0200
|
||||
+++ ./ter-u18n.bdf 2020-12-28 20:34:29.515133600 +0200
|
||||
@@ -13186,5 +13186,4 @@
|
||||
-3C00
|
||||
-4200
|
||||
-4200
|
||||
-4200
|
||||
-4400
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -13194,0 +13194 @@
|
||||
+7E00
|
||||
@@ -13240,12 +13240,12 @@
|
||||
-3F00
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-3F00
|
||||
-0100
|
||||
-0100
|
||||
-3E00
|
||||
+0F00
|
||||
+1100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+7F80
|
||||
+4080
|
||||
+4080
|
||||
+0000
|
||||
--- ./ter-u20b.bdf.orig 2020-12-28 20:34:28.115131600 +0200
|
||||
+++ ./ter-u20b.bdf 2020-12-28 20:34:29.575133700 +0200
|
||||
@@ -14239,5 +14239,4 @@
|
||||
-3E00
|
||||
-6300
|
||||
-6300
|
||||
-6300
|
||||
-6200
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -14247,0 +14247 @@
|
||||
+7F00
|
||||
@@ -14297,12 +14297,12 @@
|
||||
-3F80
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-3F80
|
||||
-0180
|
||||
-0180
|
||||
-3F00
|
||||
+1F00
|
||||
+3300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+6300
|
||||
+FF80
|
||||
+C180
|
||||
+C180
|
||||
+0000
|
||||
--- ./ter-u20n.bdf.orig 2020-12-28 20:34:28.085131600 +0200
|
||||
+++ ./ter-u20n.bdf 2020-12-28 20:34:29.565133700 +0200
|
||||
@@ -14239,5 +14239,4 @@
|
||||
-3C00
|
||||
-4200
|
||||
-4200
|
||||
-4200
|
||||
-4400
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -14247,0 +14247 @@
|
||||
+7E00
|
||||
@@ -14297,12 +14297,12 @@
|
||||
-3F00
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-3F00
|
||||
-0100
|
||||
-0100
|
||||
-3E00
|
||||
+0F00
|
||||
+1100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+2100
|
||||
+7F80
|
||||
+4080
|
||||
+4080
|
||||
+0000
|
||||
--- ./ter-u22b.bdf.orig 2020-12-28 20:34:28.135131700 +0200
|
||||
+++ ./ter-u22b.bdf 2020-12-28 20:34:29.605133700 +0200
|
||||
@@ -15291,8 +15291,5 @@
|
||||
-3E00
|
||||
-6300
|
||||
-6180
|
||||
-6180
|
||||
-6180
|
||||
-6300
|
||||
-7F00
|
||||
-6180
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F80
|
||||
@@ -15301,0 +15299 @@
|
||||
+7F80
|
||||
@@ -15303,2 +15301,4 @@
|
||||
-6180
|
||||
-7F00
|
||||
+60C0
|
||||
+60C0
|
||||
+60C0
|
||||
+7F80
|
||||
@@ -15353,14 +15353,14 @@
|
||||
-1FC0
|
||||
-30C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-30C0
|
||||
-1FC0
|
||||
-00C0
|
||||
-00C0
|
||||
-0180
|
||||
-3F00
|
||||
+1F80
|
||||
+3180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+6180
|
||||
+FFC0
|
||||
+C0C0
|
||||
+C0C0
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u22n.bdf.orig 2020-12-28 20:34:28.115131600 +0200
|
||||
+++ ./ter-u22n.bdf 2020-12-28 20:34:29.575133700 +0200
|
||||
@@ -15291,8 +15291,6 @@
|
||||
-3C00
|
||||
-4200
|
||||
-4100
|
||||
-4100
|
||||
-4100
|
||||
-4200
|
||||
-7E00
|
||||
-4100
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F00
|
||||
+4080
|
||||
@@ -15300,0 +15299 @@
|
||||
+7F00
|
||||
@@ -15303,2 +15302,3 @@
|
||||
-4100
|
||||
-7E00
|
||||
+4080
|
||||
+4080
|
||||
+7F00
|
||||
@@ -15353 +15353,4 @@
|
||||
-1F80
|
||||
+0F80
|
||||
+1080
|
||||
+2080
|
||||
+2080
|
||||
@@ -15355,6 +15357,0 @@
|
||||
-4080
|
||||
-4080
|
||||
-4080
|
||||
-4080
|
||||
-4080
|
||||
-4080
|
||||
@@ -15362,5 +15359,8 @@
|
||||
-1F80
|
||||
-0080
|
||||
-0080
|
||||
-0100
|
||||
-3E00
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+7FC0
|
||||
+4040
|
||||
+4040
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u24b.bdf.orig 2020-12-28 20:34:28.165131700 +0200
|
||||
+++ ./ter-u24b.bdf 2020-12-28 20:34:29.615133700 +0200
|
||||
@@ -16344,2 +16344,5 @@
|
||||
-3F00
|
||||
-6180
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F80
|
||||
@@ -16349,2 +16351,0 @@
|
||||
-6180
|
||||
-7F80
|
||||
@@ -16351,0 +16353 @@
|
||||
+7FC0
|
||||
@@ -16356,3 +16358 @@
|
||||
-6060
|
||||
-60C0
|
||||
-7F80
|
||||
+7FC0
|
||||
@@ -16410,7 +16410,11 @@
|
||||
-1FE0
|
||||
-3060
|
||||
-6060
|
||||
-6060
|
||||
-6060
|
||||
-6060
|
||||
-6060
|
||||
+0FC0
|
||||
+18C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+30C0
|
||||
+7FE0
|
||||
@@ -16419,6 +16423,2 @@
|
||||
-30E0
|
||||
-1FE0
|
||||
-0060
|
||||
-0060
|
||||
-00C0
|
||||
-3F80
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u24n.bdf.orig 2020-12-28 20:34:28.135131700 +0200
|
||||
+++ ./ter-u24n.bdf 2020-12-28 20:34:29.625133700 +0200
|
||||
@@ -16344,2 +16344,5 @@
|
||||
-3E00
|
||||
-4100
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F00
|
||||
@@ -16349,2 +16351,0 @@
|
||||
-4100
|
||||
-7F00
|
||||
@@ -16351,0 +16353 @@
|
||||
+7F80
|
||||
@@ -16356,3 +16358 @@
|
||||
-4040
|
||||
-4080
|
||||
-7F00
|
||||
+7F80
|
||||
@@ -16410,7 +16410,11 @@
|
||||
-1FC0
|
||||
-2040
|
||||
-4040
|
||||
-4040
|
||||
-4040
|
||||
-4040
|
||||
-4040
|
||||
+0F80
|
||||
+1080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+2080
|
||||
+7FC0
|
||||
@@ -16419,6 +16423,2 @@
|
||||
-20C0
|
||||
-1F40
|
||||
-0040
|
||||
-0040
|
||||
-0080
|
||||
-3F00
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u28b.bdf.orig 2020-12-28 20:34:28.185131700 +0200
|
||||
+++ ./ter-u28b.bdf 2020-12-28 20:34:29.665133800 +0200
|
||||
@@ -18448 +18448,5 @@
|
||||
-3F00
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -18450,5 +18453,0 @@
|
||||
-61C0
|
||||
-60C0
|
||||
-60C0
|
||||
-60C0
|
||||
-6180
|
||||
@@ -18456,4 +18455,6 @@
|
||||
-7FE0
|
||||
-6070
|
||||
-6030
|
||||
-6030
|
||||
+6060
|
||||
+6060
|
||||
+6060
|
||||
+7FC0
|
||||
+7FC0
|
||||
+6060
|
||||
@@ -18463 +18463,0 @@
|
||||
-6070
|
||||
@@ -18523 +18523,11 @@
|
||||
-1FF0
|
||||
+07F0
|
||||
+0FF0
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
@@ -18525,16 +18535,6 @@
|
||||
-7030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-7030
|
||||
-3FF0
|
||||
-1FF0
|
||||
-0030
|
||||
-0030
|
||||
-0070
|
||||
-3FE0
|
||||
-3FC0
|
||||
+7FF8
|
||||
+6018
|
||||
+6018
|
||||
+6018
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u28n.bdf.orig 2020-12-28 20:34:28.175131700 +0200
|
||||
+++ ./ter-u28n.bdf 2020-12-28 20:34:29.635133800 +0200
|
||||
@@ -18448,4 +18448,6 @@
|
||||
-3F00
|
||||
-6180
|
||||
-60C0
|
||||
-60C0
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+7F80
|
||||
@@ -18452,0 +18455,3 @@
|
||||
+6060
|
||||
+6060
|
||||
+6060
|
||||
@@ -18454 +18458,0 @@
|
||||
-6180
|
||||
@@ -18460,4 +18463,0 @@
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
@@ -18523,18 +18523,18 @@
|
||||
-1FF0
|
||||
-3030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-6030
|
||||
-3030
|
||||
-1FF0
|
||||
-0030
|
||||
-0030
|
||||
-0030
|
||||
-0060
|
||||
-3FC0
|
||||
+07F0
|
||||
+0C30
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+1830
|
||||
+7FF8
|
||||
+6018
|
||||
+6018
|
||||
+6018
|
||||
+0000
|
||||
+0000
|
||||
--- ./ter-u32b.bdf.orig 2020-12-28 20:34:28.225131800 +0200
|
||||
+++ ./ter-u32b.bdf 2020-12-28 20:34:29.675133800 +0200
|
||||
@@ -20554,8 +20554,6 @@
|
||||
-3FC0
|
||||
-7FE0
|
||||
-70F0
|
||||
-7070
|
||||
-7070
|
||||
-7070
|
||||
-7070
|
||||
-70E0
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -20563,0 +20562 @@
|
||||
+7078
|
||||
@@ -20565,4 +20564,5 @@
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
+7038
|
||||
+7038
|
||||
+7FF0
|
||||
+7FF8
|
||||
+703C
|
||||
@@ -20638 +20638,12 @@
|
||||
-1FFC
|
||||
+07FC
|
||||
+0FFC
|
||||
+1E1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
+1C1C
|
||||
@@ -20640,17 +20651,6 @@
|
||||
-781C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-701C
|
||||
-781C
|
||||
-3FFC
|
||||
-1FFC
|
||||
-001C
|
||||
-001C
|
||||
-003C
|
||||
-3FF8
|
||||
-3FF0
|
||||
+7FFE
|
||||
+700E
|
||||
+700E
|
||||
+700E
|
||||
+700E
|
||||
+0000
|
||||
--- ./ter-u32n.bdf.orig 2020-12-28 20:34:28.205131800 +0200
|
||||
+++ ./ter-u32n.bdf 2020-12-28 20:34:29.675133800 +0200
|
||||
@@ -20554,8 +20554,6 @@
|
||||
-1FC0
|
||||
-3FE0
|
||||
-3070
|
||||
-3030
|
||||
-3030
|
||||
-3030
|
||||
-3030
|
||||
-3070
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
+0000
|
||||
@@ -20564,0 +20563,5 @@
|
||||
+3018
|
||||
+3018
|
||||
+3038
|
||||
+3FF0
|
||||
+3FF8
|
||||
@@ -20568,3 +20570,0 @@
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
@@ -20638,19 +20638,19 @@
|
||||
-0FFC
|
||||
-1FFC
|
||||
-380C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-300C
|
||||
-380C
|
||||
-1FFC
|
||||
-0FFC
|
||||
-000C
|
||||
-000C
|
||||
-001C
|
||||
-1FF8
|
||||
-1FF0
|
||||
+07F8
|
||||
+0FF8
|
||||
+1C18
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+1818
|
||||
+3FF8
|
||||
+7FFC
|
||||
+600C
|
||||
+600C
|
||||
+600C
|
||||
+600C
|
||||
+0000
|
||||
@@ -0,0 +1,945 @@
|
||||
--- ./ter-u12b.bdf.orig 2020-12-28 20:34:27.995131500 +0200
|
||||
+++ ./ter-u12b.bdf 2020-12-28 20:34:30.355134800 +0200
|
||||
@@ -10182,2 +10182,2 @@
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
@@ -10828,2 +10828,2 @@
|
||||
-08
|
||||
-10
|
||||
+48
|
||||
+50
|
||||
@@ -11189,2 +11189,2 @@
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
@@ -11227,2 +11227,2 @@
|
||||
-00
|
||||
-00
|
||||
+80
|
||||
+80
|
||||
@@ -11265,3 +11265,3 @@
|
||||
-00
|
||||
-00
|
||||
-C8
|
||||
+C0
|
||||
+40
|
||||
+48
|
||||
--- ./ter-u12n.bdf.orig 2020-12-28 20:34:27.975131400 +0200
|
||||
+++ ./ter-u12n.bdf 2020-12-28 20:34:30.315134700 +0200
|
||||
@@ -10182,2 +10182,2 @@
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
@@ -10828,2 +10828,2 @@
|
||||
-08
|
||||
-10
|
||||
+48
|
||||
+50
|
||||
@@ -11189,2 +11189,2 @@
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
@@ -11227,2 +11227,2 @@
|
||||
-00
|
||||
-00
|
||||
+80
|
||||
+80
|
||||
@@ -11265,3 +11265,3 @@
|
||||
-00
|
||||
-00
|
||||
-C8
|
||||
+C0
|
||||
+40
|
||||
+48
|
||||
--- ./ter-u14b.bdf.orig 2020-12-28 20:34:28.025131500 +0200
|
||||
+++ ./ter-u14b.bdf 2020-12-28 20:34:30.365134800 +0200
|
||||
@@ -11250,3 +11250,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -11964,3 +11964,3 @@
|
||||
-18
|
||||
-30
|
||||
-00
|
||||
+D8
|
||||
+F0
|
||||
+C0
|
||||
@@ -12363,3 +12363,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -12405,3 +12405,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -12447,4 +12447,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-E3
|
||||
+E0
|
||||
+60
|
||||
+60
|
||||
+63
|
||||
--- ./ter-u14n.bdf.orig 2020-12-28 20:34:27.995131500 +0200
|
||||
+++ ./ter-u14n.bdf 2020-12-28 20:34:30.365134800 +0200
|
||||
@@ -11250,3 +11250,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -11964,3 +11964,3 @@
|
||||
-08
|
||||
-10
|
||||
-00
|
||||
+48
|
||||
+50
|
||||
+40
|
||||
@@ -12363,3 +12363,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -12405,3 +12405,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -12447,4 +12447,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-C2
|
||||
+C0
|
||||
+40
|
||||
+40
|
||||
+42
|
||||
--- ./ter-u14v.bdf.orig 2020-12-28 20:34:28.025131500 +0200
|
||||
+++ ./ter-u14v.bdf 2020-12-28 20:34:30.385134800 +0200
|
||||
@@ -11250,3 +11250,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -11964,3 +11964,3 @@
|
||||
-18
|
||||
-30
|
||||
-00
|
||||
+D8
|
||||
+F0
|
||||
+C0
|
||||
@@ -12363,3 +12363,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -12405,3 +12405,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -12447,4 +12447,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-E3
|
||||
+E0
|
||||
+60
|
||||
+60
|
||||
+63
|
||||
--- ./ter-u16b.bdf.orig 2020-12-28 20:34:28.035131500 +0200
|
||||
+++ ./ter-u16b.bdf 2020-12-28 20:34:30.405134800 +0200
|
||||
@@ -12318,3 +12318,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13100,3 +13100,3 @@
|
||||
-18
|
||||
-30
|
||||
-00
|
||||
+D8
|
||||
+F0
|
||||
+C0
|
||||
@@ -13537,3 +13537,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13583,3 +13583,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13629,4 +13629,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-E3
|
||||
+E0
|
||||
+60
|
||||
+60
|
||||
+63
|
||||
--- ./ter-u16n.bdf.orig 2020-12-28 20:34:28.035131500 +0200
|
||||
+++ ./ter-u16n.bdf 2020-12-28 20:34:30.395134800 +0200
|
||||
@@ -12318,3 +12318,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -13100,3 +13100,3 @@
|
||||
-08
|
||||
-10
|
||||
-00
|
||||
+48
|
||||
+50
|
||||
+40
|
||||
@@ -13537,3 +13537,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -13583,3 +13583,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -13629,4 +13629,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-C2
|
||||
+C0
|
||||
+40
|
||||
+40
|
||||
+42
|
||||
--- ./ter-u16v.bdf.orig 2020-12-28 20:34:28.065131600 +0200
|
||||
+++ ./ter-u16v.bdf 2020-12-28 20:34:30.405134800 +0200
|
||||
@@ -12318,3 +12318,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13100,3 +13100,3 @@
|
||||
-18
|
||||
-30
|
||||
-00
|
||||
+D8
|
||||
+F0
|
||||
+C0
|
||||
@@ -13537,3 +13537,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13583,3 +13583,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13629,4 +13629,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-E3
|
||||
+E0
|
||||
+60
|
||||
+60
|
||||
+63
|
||||
--- ./ter-u18b.bdf.orig 2020-12-28 20:34:28.085131600 +0200
|
||||
+++ ./ter-u18b.bdf 2020-12-28 20:34:30.445134900 +0200
|
||||
@@ -13386,4 +13386,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -14237,3 +14237,3 @@
|
||||
-0600
|
||||
-0C00
|
||||
-0000
|
||||
+6600
|
||||
+6C00
|
||||
+6000
|
||||
@@ -14712,3 +14712,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -14762,3 +14762,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -14811,5 +14811,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-E180
|
||||
+8000
|
||||
+E000
|
||||
+6000
|
||||
+6000
|
||||
+6180
|
||||
--- ./ter-u18n.bdf.orig 2020-12-28 20:34:28.065131600 +0200
|
||||
+++ ./ter-u18n.bdf 2020-12-28 20:34:30.445134900 +0200
|
||||
@@ -13386,4 +13386,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -14237,3 +14237,3 @@
|
||||
-0400
|
||||
-0800
|
||||
-0000
|
||||
+4400
|
||||
+4800
|
||||
+4000
|
||||
@@ -14712,3 +14712,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -14762,3 +14762,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -14811,5 +14811,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-C100
|
||||
+8000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4100
|
||||
--- ./ter-u20b.bdf.orig 2020-12-28 20:34:28.115131600 +0200
|
||||
+++ ./ter-u20b.bdf 2020-12-28 20:34:30.455134900 +0200
|
||||
@@ -14455,4 +14455,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -15373,4 +15373,4 @@
|
||||
-0000
|
||||
-0600
|
||||
-0C00
|
||||
-0000
|
||||
+6000
|
||||
+6600
|
||||
+6C00
|
||||
+6000
|
||||
@@ -15886,4 +15886,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -15940,4 +15940,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -15994,5 +15994,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-E180
|
||||
+E000
|
||||
+E000
|
||||
+6000
|
||||
+6000
|
||||
+6180
|
||||
--- ./ter-u20n.bdf.orig 2020-12-28 20:34:28.085131600 +0200
|
||||
+++ ./ter-u20n.bdf 2020-12-28 20:34:30.445134900 +0200
|
||||
@@ -14455,4 +14455,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -15373,4 +15373,4 @@
|
||||
-0000
|
||||
-0400
|
||||
-0800
|
||||
-0000
|
||||
+4000
|
||||
+4400
|
||||
+4800
|
||||
+4000
|
||||
@@ -15886,4 +15886,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -15940,4 +15940,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -15994,5 +15994,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-C100
|
||||
+C000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4100
|
||||
--- ./ter-u22b.bdf.orig 2020-12-28 20:34:28.135131700 +0200
|
||||
+++ ./ter-u22b.bdf 2020-12-28 20:34:30.505135000 +0200
|
||||
@@ -15523,4 +15523,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -16509,4 +16509,4 @@
|
||||
-0180
|
||||
-0300
|
||||
-0600
|
||||
-0000
|
||||
+3180
|
||||
+3300
|
||||
+3600
|
||||
+3000
|
||||
@@ -17060,4 +17060,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -17118,4 +17118,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -17176,6 +17176,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-70C0
|
||||
-7180
|
||||
+7000
|
||||
+7000
|
||||
+3000
|
||||
+3000
|
||||
+30C0
|
||||
+3180
|
||||
--- ./ter-u22n.bdf.orig 2020-12-28 20:34:28.115131600 +0200
|
||||
+++ ./ter-u22n.bdf 2020-12-28 20:34:30.485134900 +0200
|
||||
@@ -15523,4 +15523,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -16509,4 +16509,4 @@
|
||||
-0100
|
||||
-0200
|
||||
-0400
|
||||
-0000
|
||||
+2100
|
||||
+2200
|
||||
+2400
|
||||
+2000
|
||||
@@ -17060,4 +17060,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -17118,4 +17118,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -17176,5 +17176,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-E080
|
||||
+E000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2080
|
||||
--- ./ter-u24b.bdf.orig 2020-12-28 20:34:28.165131700 +0200
|
||||
+++ ./ter-u24b.bdf 2020-12-28 20:34:30.515135000 +0200
|
||||
@@ -16592,4 +16592,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -17646,4 +17646,4 @@
|
||||
-0180
|
||||
-0300
|
||||
-0600
|
||||
-0000
|
||||
+3180
|
||||
+3300
|
||||
+3600
|
||||
+3000
|
||||
@@ -18235,4 +18235,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -18297,4 +18297,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -18359,6 +18359,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-7060
|
||||
-70C0
|
||||
+7000
|
||||
+7000
|
||||
+3000
|
||||
+3000
|
||||
+3060
|
||||
+30C0
|
||||
--- ./ter-u24n.bdf.orig 2020-12-28 20:34:28.135131700 +0200
|
||||
+++ ./ter-u24n.bdf 2020-12-28 20:34:30.505135000 +0200
|
||||
@@ -16592,4 +16592,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -17646,4 +17646,4 @@
|
||||
-0100
|
||||
-0200
|
||||
-0400
|
||||
-0000
|
||||
+2100
|
||||
+2200
|
||||
+2400
|
||||
+2000
|
||||
@@ -18235,4 +18235,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -18297,4 +18297,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -18359,5 +18359,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-E040
|
||||
+6000
|
||||
+6000
|
||||
+2000
|
||||
+2000
|
||||
+2040
|
||||
--- ./ter-u28b.bdf.orig 2020-12-28 20:34:28.185131700 +0200
|
||||
+++ ./ter-u28b.bdf 2020-12-28 20:34:30.555135000 +0200
|
||||
@@ -18728,5 +18728,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -19918,5 +19918,5 @@
|
||||
-0000
|
||||
-01C0
|
||||
-0380
|
||||
-0700
|
||||
-0000
|
||||
+3000
|
||||
+31C0
|
||||
+3380
|
||||
+3700
|
||||
+3000
|
||||
@@ -20583,5 +20583,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -20653,5 +20653,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -20723,7 +20723,7 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-F070
|
||||
-F0E0
|
||||
+F000
|
||||
+F000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3070
|
||||
+30E0
|
||||
--- ./ter-u28n.bdf.orig 2020-12-28 20:34:28.175131700 +0200
|
||||
+++ ./ter-u28n.bdf 2020-12-28 20:34:30.535135000 +0200
|
||||
@@ -18728,5 +18728,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -19918,5 +19918,5 @@
|
||||
-0000
|
||||
-00C0
|
||||
-0180
|
||||
-0300
|
||||
-0000
|
||||
+3000
|
||||
+30C0
|
||||
+3180
|
||||
+3300
|
||||
+3000
|
||||
@@ -20583,5 +20583,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -20653,5 +20653,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -20723,7 +20723,7 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-F030
|
||||
-F060
|
||||
+F000
|
||||
+F000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3030
|
||||
+3060
|
||||
--- ./ter-u32b.bdf.orig 2020-12-28 20:34:28.225131800 +0200
|
||||
+++ ./ter-u32b.bdf 2020-12-28 20:34:30.585135100 +0200
|
||||
@@ -20866,6 +20866,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
@@ -22192,6 +22192,6 @@
|
||||
-0070
|
||||
-00E0
|
||||
-01C0
|
||||
-0380
|
||||
-0000
|
||||
-0000
|
||||
+3838
|
||||
+3870
|
||||
+38E0
|
||||
+39C0
|
||||
+3800
|
||||
+3800
|
||||
@@ -22933,6 +22933,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
@@ -23011,6 +23011,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+7000
|
||||
+7000
|
||||
+7000
|
||||
+7000
|
||||
+7000
|
||||
+7000
|
||||
@@ -23089,8 +23089,8 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-F81C
|
||||
-F838
|
||||
+F800
|
||||
+F800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+381C
|
||||
+3838
|
||||
--- ./ter-u32n.bdf.orig 2020-12-28 20:34:28.205131800 +0200
|
||||
+++ ./ter-u32n.bdf 2020-12-28 20:34:30.585135100 +0200
|
||||
@@ -20866,6 +20866,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
@@ -22192,6 +22192,6 @@
|
||||
-0070
|
||||
-00E0
|
||||
-01C0
|
||||
-0380
|
||||
-0000
|
||||
-0000
|
||||
+1838
|
||||
+1870
|
||||
+18E0
|
||||
+19C0
|
||||
+1800
|
||||
+1800
|
||||
@@ -22933,6 +22933,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
@@ -23011,6 +23011,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -23089,8 +23089,8 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-781C
|
||||
-7838
|
||||
+7800
|
||||
+7800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+181C
|
||||
+1838
|
||||
--- ./dup/xos4-2.dup.orig 2019-03-13 21:55:47.071547500 +0200
|
||||
+++ ./dup/xos4-2.dup 2020-12-28 20:34:27.655131000 +0200
|
||||
@@ -107 +107 @@
|
||||
-0138 043A
|
||||
+006B 043A
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,937 @@
|
||||
--- ./ter-u12b.bdf.orig 2020-12-28 20:34:18.635118400 +0200
|
||||
+++ ./ter-u12b.bdf 2020-12-28 20:34:27.095130200 +0200
|
||||
@@ -10182,2 +10182,2 @@
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
@@ -10828,2 +10828,2 @@
|
||||
-08
|
||||
-10
|
||||
+48
|
||||
+50
|
||||
@@ -11189,2 +11189,2 @@
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
@@ -11227,2 +11227,2 @@
|
||||
-00
|
||||
-00
|
||||
+80
|
||||
+80
|
||||
@@ -11265,3 +11265,3 @@
|
||||
-00
|
||||
-00
|
||||
-C8
|
||||
+C0
|
||||
+40
|
||||
+48
|
||||
--- ./ter-u12n.bdf.orig 2020-12-28 20:34:18.605118300 +0200
|
||||
+++ ./ter-u12n.bdf 2020-12-28 20:34:27.065130200 +0200
|
||||
@@ -10182,2 +10182,2 @@
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
@@ -10828,2 +10828,2 @@
|
||||
-08
|
||||
-10
|
||||
+48
|
||||
+50
|
||||
@@ -11189,2 +11189,2 @@
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
@@ -11227,2 +11227,2 @@
|
||||
-00
|
||||
-00
|
||||
+80
|
||||
+80
|
||||
@@ -11265,3 +11265,3 @@
|
||||
-00
|
||||
-00
|
||||
-C8
|
||||
+C0
|
||||
+40
|
||||
+48
|
||||
--- ./ter-u14b.bdf.orig 2020-12-28 20:34:18.655118400 +0200
|
||||
+++ ./ter-u14b.bdf 2020-12-28 20:34:27.105130200 +0200
|
||||
@@ -11250,3 +11250,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -11964,3 +11964,3 @@
|
||||
-18
|
||||
-30
|
||||
-00
|
||||
+D8
|
||||
+F0
|
||||
+C0
|
||||
@@ -12363,3 +12363,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -12405,3 +12405,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -12447,4 +12447,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-E3
|
||||
+E0
|
||||
+60
|
||||
+60
|
||||
+63
|
||||
--- ./ter-u14n.bdf.orig 2020-12-28 20:34:18.645118400 +0200
|
||||
+++ ./ter-u14n.bdf 2020-12-28 20:34:27.095130200 +0200
|
||||
@@ -11250,3 +11250,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -11964,3 +11964,3 @@
|
||||
-08
|
||||
-10
|
||||
-00
|
||||
+48
|
||||
+50
|
||||
+40
|
||||
@@ -12363,3 +12363,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -12405,3 +12405,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -12447,4 +12447,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-C2
|
||||
+C0
|
||||
+40
|
||||
+40
|
||||
+42
|
||||
--- ./ter-u14v.bdf.orig 2020-12-28 20:34:18.675118400 +0200
|
||||
+++ ./ter-u14v.bdf 2020-12-28 20:34:27.125130200 +0200
|
||||
@@ -11250,3 +11250,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -11964,3 +11964,3 @@
|
||||
-18
|
||||
-30
|
||||
-00
|
||||
+D8
|
||||
+F0
|
||||
+C0
|
||||
@@ -12363,3 +12363,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -12405,3 +12405,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -12447,4 +12447,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-E3
|
||||
+E0
|
||||
+60
|
||||
+60
|
||||
+63
|
||||
--- ./ter-u16b.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16b.bdf 2020-12-28 20:34:27.135130300 +0200
|
||||
@@ -12318,3 +12318,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13100,3 +13100,3 @@
|
||||
-18
|
||||
-30
|
||||
-00
|
||||
+D8
|
||||
+F0
|
||||
+C0
|
||||
@@ -13537,3 +13537,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13583,3 +13583,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13629,4 +13629,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-E3
|
||||
+E0
|
||||
+60
|
||||
+60
|
||||
+63
|
||||
--- ./ter-u16n.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16n.bdf 2020-12-28 20:34:27.135130300 +0200
|
||||
@@ -12318,3 +12318,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -13100,3 +13100,3 @@
|
||||
-08
|
||||
-10
|
||||
-00
|
||||
+48
|
||||
+50
|
||||
+40
|
||||
@@ -13537,3 +13537,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -13583,3 +13583,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+40
|
||||
+40
|
||||
+40
|
||||
@@ -13629,4 +13629,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-C2
|
||||
+C0
|
||||
+40
|
||||
+40
|
||||
+42
|
||||
--- ./ter-u16v.bdf.orig 2020-12-28 20:34:18.695118400 +0200
|
||||
+++ ./ter-u16v.bdf 2020-12-28 20:34:27.135130300 +0200
|
||||
@@ -12318,3 +12318,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13100,3 +13100,3 @@
|
||||
-18
|
||||
-30
|
||||
-00
|
||||
+D8
|
||||
+F0
|
||||
+C0
|
||||
@@ -13537,3 +13537,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13583,3 +13583,3 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
+C0
|
||||
+C0
|
||||
+C0
|
||||
@@ -13629,4 +13629,4 @@
|
||||
-00
|
||||
-00
|
||||
-00
|
||||
-E3
|
||||
+E0
|
||||
+60
|
||||
+60
|
||||
+63
|
||||
--- ./ter-u18b.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18b.bdf 2020-12-28 20:34:27.185130300 +0200
|
||||
@@ -13387,3 +13387,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -14237,3 +14237,3 @@
|
||||
-0600
|
||||
-0C00
|
||||
-0000
|
||||
+6600
|
||||
+6C00
|
||||
+6000
|
||||
@@ -14712,3 +14712,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -14762,3 +14762,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -14812,4 +14812,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-E180
|
||||
+E000
|
||||
+E000
|
||||
+6000
|
||||
+6180
|
||||
--- ./ter-u18n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18n.bdf 2020-12-28 20:34:27.175130300 +0200
|
||||
@@ -13387,3 +13387,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -14237,3 +14237,3 @@
|
||||
-0400
|
||||
-0800
|
||||
-0000
|
||||
+4400
|
||||
+4800
|
||||
+4000
|
||||
@@ -14712,3 +14712,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -14762,3 +14762,3 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -14812,4 +14812,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-C100
|
||||
+C000
|
||||
+4000
|
||||
+4000
|
||||
+4100
|
||||
--- ./ter-u20b.bdf.orig 2020-12-28 20:34:18.735118500 +0200
|
||||
+++ ./ter-u20b.bdf 2020-12-28 20:34:27.195130300 +0200
|
||||
@@ -14455,4 +14455,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -15373,4 +15373,4 @@
|
||||
-0000
|
||||
-0600
|
||||
-0C00
|
||||
-0000
|
||||
+6000
|
||||
+6600
|
||||
+6C00
|
||||
+6000
|
||||
@@ -15886,4 +15886,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -15940,4 +15940,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -15994,5 +15994,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-E180
|
||||
+E000
|
||||
+E000
|
||||
+6000
|
||||
+6000
|
||||
+6180
|
||||
--- ./ter-u20n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u20n.bdf 2020-12-28 20:34:27.185130300 +0200
|
||||
@@ -14455,4 +14455,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -15373,4 +15373,4 @@
|
||||
-0000
|
||||
-0400
|
||||
-0800
|
||||
-0000
|
||||
+4000
|
||||
+4400
|
||||
+4800
|
||||
+4000
|
||||
@@ -15886,4 +15886,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -15940,4 +15940,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -15994,5 +15994,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-C100
|
||||
+C000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4100
|
||||
--- ./ter-u22b.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22b.bdf 2020-12-28 20:34:27.235130400 +0200
|
||||
@@ -15523,4 +15523,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -16509,4 +16509,4 @@
|
||||
-0180
|
||||
-0300
|
||||
-0600
|
||||
-0000
|
||||
+3180
|
||||
+3300
|
||||
+3600
|
||||
+3000
|
||||
@@ -17060,4 +17060,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -17118,4 +17118,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -17176,6 +17176,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-70C0
|
||||
-7180
|
||||
+7000
|
||||
+7000
|
||||
+3000
|
||||
+3000
|
||||
+30C0
|
||||
+3180
|
||||
--- ./ter-u22n.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22n.bdf 2020-12-28 20:34:27.225130400 +0200
|
||||
@@ -15523,4 +15523,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -16509,4 +16509,4 @@
|
||||
-0100
|
||||
-0200
|
||||
-0400
|
||||
-0000
|
||||
+2100
|
||||
+2200
|
||||
+2400
|
||||
+2000
|
||||
@@ -17060,4 +17060,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -17118,4 +17118,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -17176,5 +17176,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-E080
|
||||
+E000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2080
|
||||
--- ./ter-u24b.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24b.bdf 2020-12-28 20:34:27.245130400 +0200
|
||||
@@ -16592,4 +16592,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -17646,4 +17646,4 @@
|
||||
-0180
|
||||
-0300
|
||||
-0600
|
||||
-0000
|
||||
+3180
|
||||
+3300
|
||||
+3600
|
||||
+3000
|
||||
@@ -18235,4 +18235,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -18297,4 +18297,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -18359,6 +18359,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-7060
|
||||
-70C0
|
||||
+7000
|
||||
+7000
|
||||
+3000
|
||||
+3000
|
||||
+3060
|
||||
+30C0
|
||||
--- ./ter-u24n.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24n.bdf 2020-12-28 20:34:27.245130400 +0200
|
||||
@@ -16592,4 +16592,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -17646,4 +17646,4 @@
|
||||
-0100
|
||||
-0200
|
||||
-0400
|
||||
-0000
|
||||
+2100
|
||||
+2200
|
||||
+2400
|
||||
+2000
|
||||
@@ -18235,4 +18235,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
+2000
|
||||
@@ -18297,4 +18297,4 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
+4000
|
||||
@@ -18359,5 +18359,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-E040
|
||||
+6000
|
||||
+6000
|
||||
+2000
|
||||
+2000
|
||||
+2040
|
||||
--- ./ter-u28b.bdf.orig 2020-12-28 20:34:18.845118700 +0200
|
||||
+++ ./ter-u28b.bdf 2020-12-28 20:34:27.295130500 +0200
|
||||
@@ -18728,5 +18728,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -19918,5 +19918,5 @@
|
||||
-0000
|
||||
-01C0
|
||||
-0380
|
||||
-0700
|
||||
-0000
|
||||
+3000
|
||||
+31C0
|
||||
+3380
|
||||
+3700
|
||||
+3000
|
||||
@@ -20583,5 +20583,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -20653,5 +20653,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -20723,7 +20723,7 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-F070
|
||||
-F0E0
|
||||
+F000
|
||||
+F000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3070
|
||||
+30E0
|
||||
--- ./ter-u28n.bdf.orig 2020-12-28 20:34:18.835118600 +0200
|
||||
+++ ./ter-u28n.bdf 2020-12-28 20:34:27.285130500 +0200
|
||||
@@ -18728,5 +18728,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -19918,5 +19918,5 @@
|
||||
-0000
|
||||
-00C0
|
||||
-0180
|
||||
-0300
|
||||
-0000
|
||||
+3000
|
||||
+30C0
|
||||
+3180
|
||||
+3300
|
||||
+3000
|
||||
@@ -20583,5 +20583,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -20653,5 +20653,5 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
+6000
|
||||
@@ -20723,7 +20723,7 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-F030
|
||||
-F060
|
||||
+F000
|
||||
+F000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3030
|
||||
+3060
|
||||
--- ./ter-u32b.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32b.bdf 2020-12-28 20:34:27.305130500 +0200
|
||||
@@ -20866,6 +20866,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
@@ -22192,6 +22192,6 @@
|
||||
-0070
|
||||
-00E0
|
||||
-01C0
|
||||
-0380
|
||||
-0000
|
||||
-0000
|
||||
+3838
|
||||
+3870
|
||||
+38E0
|
||||
+39C0
|
||||
+3800
|
||||
+3800
|
||||
@@ -22933,6 +22933,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
@@ -23011,6 +23011,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+7000
|
||||
+7000
|
||||
+7000
|
||||
+7000
|
||||
+7000
|
||||
+7000
|
||||
@@ -23089,8 +23089,8 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-F81C
|
||||
-F838
|
||||
+F800
|
||||
+F800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+3800
|
||||
+381C
|
||||
+3838
|
||||
--- ./ter-u32n.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32n.bdf 2020-12-28 20:34:27.305130500 +0200
|
||||
@@ -20866,6 +20866,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
@@ -22192,6 +22192,6 @@
|
||||
-0070
|
||||
-00E0
|
||||
-01C0
|
||||
-0380
|
||||
-0000
|
||||
-0000
|
||||
+1838
|
||||
+1870
|
||||
+18E0
|
||||
+19C0
|
||||
+1800
|
||||
+1800
|
||||
@@ -22933,6 +22933,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
@@ -23011,6 +23011,6 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
+3000
|
||||
@@ -23089,8 +23089,8 @@
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-0000
|
||||
-781C
|
||||
-7838
|
||||
+7800
|
||||
+7800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+1800
|
||||
+181C
|
||||
+1838
|
||||
--- ./dup/xos4-2.dup.orig 2019-03-13 21:55:47.071547500 +0200
|
||||
+++ ./dup/xos4-2.dup 2020-12-28 20:34:27.655131000 +0200
|
||||
@@ -107 +107 @@
|
||||
-0138 043A
|
||||
+006B 043A
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,236 @@
|
||||
--- ./ter-u12b.bdf.orig 2020-12-28 20:34:18.635118400 +0200
|
||||
+++ ./ter-u12b.bdf 2020-12-28 20:34:26.185128900 +0200
|
||||
@@ -1840,3 +1839,0 @@
|
||||
-48
|
||||
-A8
|
||||
-90
|
||||
@@ -1846,0 +1844,3 @@
|
||||
+48
|
||||
+A8
|
||||
+90
|
||||
--- ./ter-u12n.bdf.orig 2020-12-28 20:34:18.605118300 +0200
|
||||
+++ ./ter-u12n.bdf 2020-12-28 20:34:26.185128900 +0200
|
||||
@@ -1840,3 +1839,0 @@
|
||||
-48
|
||||
-A8
|
||||
-90
|
||||
@@ -1846,0 +1844,3 @@
|
||||
+48
|
||||
+A8
|
||||
+90
|
||||
--- ./ter-u14b.bdf.orig 2020-12-28 20:34:18.655118400 +0200
|
||||
+++ ./ter-u14b.bdf 2020-12-28 20:34:26.225129000 +0200
|
||||
@@ -2030,3 +2029,0 @@
|
||||
-73
|
||||
-DB
|
||||
-CE
|
||||
@@ -2037,0 +2035,3 @@
|
||||
+73
|
||||
+DB
|
||||
+CE
|
||||
--- ./ter-u14n.bdf.orig 2020-12-28 20:34:18.645118400 +0200
|
||||
+++ ./ter-u14n.bdf 2020-12-28 20:34:26.205129000 +0200
|
||||
@@ -2030,3 +2029,0 @@
|
||||
-62
|
||||
-92
|
||||
-8C
|
||||
@@ -2037,0 +2035,3 @@
|
||||
+62
|
||||
+92
|
||||
+8C
|
||||
--- ./ter-u14v.bdf.orig 2020-12-28 20:34:18.675118400 +0200
|
||||
+++ ./ter-u14v.bdf 2020-12-28 20:34:26.225129000 +0200
|
||||
@@ -2030,3 +2029,0 @@
|
||||
-73
|
||||
-DB
|
||||
-CE
|
||||
@@ -2037,0 +2035,3 @@
|
||||
+73
|
||||
+DB
|
||||
+CE
|
||||
--- ./ter-u16b.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16b.bdf 2020-12-28 20:34:26.235129000 +0200
|
||||
@@ -2220,3 +2219,0 @@
|
||||
-73
|
||||
-DB
|
||||
-CE
|
||||
@@ -2227,0 +2225,3 @@
|
||||
+73
|
||||
+DB
|
||||
+CE
|
||||
--- ./ter-u16n.bdf.orig 2020-12-28 20:34:18.685118400 +0200
|
||||
+++ ./ter-u16n.bdf 2020-12-28 20:34:26.245129000 +0200
|
||||
@@ -2220,3 +2219,0 @@
|
||||
-62
|
||||
-92
|
||||
-8C
|
||||
@@ -2227,0 +2225,3 @@
|
||||
+62
|
||||
+92
|
||||
+8C
|
||||
--- ./ter-u16v.bdf.orig 2020-12-28 20:34:18.695118400 +0200
|
||||
+++ ./ter-u16v.bdf 2020-12-28 20:34:26.265129000 +0200
|
||||
@@ -2220,3 +2219,0 @@
|
||||
-73
|
||||
-DB
|
||||
-CE
|
||||
@@ -2227,0 +2225,3 @@
|
||||
+73
|
||||
+DB
|
||||
+CE
|
||||
--- ./ter-u18b.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18b.bdf 2020-12-28 20:34:26.275129100 +0200
|
||||
@@ -2410,4 +2409,0 @@
|
||||
-3980
|
||||
-6D80
|
||||
-6D80
|
||||
-6700
|
||||
@@ -2419,0 +2416,4 @@
|
||||
+3980
|
||||
+6D80
|
||||
+6D80
|
||||
+6700
|
||||
--- ./ter-u18n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u18n.bdf 2020-12-28 20:34:26.275129100 +0200
|
||||
@@ -2410,4 +2409,0 @@
|
||||
-3100
|
||||
-4900
|
||||
-4900
|
||||
-4600
|
||||
@@ -2419,0 +2416,4 @@
|
||||
+3100
|
||||
+4900
|
||||
+4900
|
||||
+4600
|
||||
--- ./ter-u20b.bdf.orig 2020-12-28 20:34:18.735118500 +0200
|
||||
+++ ./ter-u20b.bdf 2020-12-28 20:34:26.305129100 +0200
|
||||
@@ -2600,4 +2599,0 @@
|
||||
-3980
|
||||
-6D80
|
||||
-6D80
|
||||
-6700
|
||||
@@ -2610,0 +2607,4 @@
|
||||
+3980
|
||||
+6D80
|
||||
+6D80
|
||||
+6700
|
||||
--- ./ter-u20n.bdf.orig 2020-12-28 20:34:18.725118500 +0200
|
||||
+++ ./ter-u20n.bdf 2020-12-28 20:34:26.295129100 +0200
|
||||
@@ -2600,4 +2599,0 @@
|
||||
-3100
|
||||
-4900
|
||||
-4900
|
||||
-4600
|
||||
@@ -2610,0 +2607,4 @@
|
||||
+3100
|
||||
+4900
|
||||
+4900
|
||||
+4600
|
||||
--- ./ter-u22b.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22b.bdf 2020-12-28 20:34:26.325129100 +0200
|
||||
@@ -2790,4 +2789,0 @@
|
||||
-38C0
|
||||
-6CC0
|
||||
-66C0
|
||||
-6380
|
||||
@@ -2800,0 +2797,4 @@
|
||||
+38C0
|
||||
+6CC0
|
||||
+66C0
|
||||
+6380
|
||||
--- ./ter-u22n.bdf.orig 2020-12-28 20:34:18.775118600 +0200
|
||||
+++ ./ter-u22n.bdf 2020-12-28 20:34:26.325129100 +0200
|
||||
@@ -2790,4 +2789,0 @@
|
||||
-3080
|
||||
-4880
|
||||
-4480
|
||||
-4300
|
||||
@@ -2800,0 +2797,4 @@
|
||||
+3080
|
||||
+4880
|
||||
+4480
|
||||
+4300
|
||||
--- ./ter-u24b.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24b.bdf 2020-12-28 20:34:26.355129200 +0200
|
||||
@@ -2981,4 +2980,0 @@
|
||||
-3C60
|
||||
-6660
|
||||
-6660
|
||||
-63C0
|
||||
@@ -2992,0 +2989,4 @@
|
||||
+3C60
|
||||
+6660
|
||||
+6660
|
||||
+63C0
|
||||
--- ./ter-u24n.bdf.orig 2020-12-28 20:34:18.795118600 +0200
|
||||
+++ ./ter-u24n.bdf 2020-12-28 20:34:26.365129200 +0200
|
||||
@@ -2981,4 +2980,0 @@
|
||||
-3840
|
||||
-4440
|
||||
-4440
|
||||
-4380
|
||||
@@ -2992,0 +2989,4 @@
|
||||
+3840
|
||||
+4440
|
||||
+4440
|
||||
+4380
|
||||
--- ./ter-u28b.bdf.orig 2020-12-28 20:34:18.845118700 +0200
|
||||
+++ ./ter-u28b.bdf 2020-12-28 20:34:26.385129200 +0200
|
||||
@@ -3361,5 +3360,0 @@
|
||||
-3C30
|
||||
-7E30
|
||||
-6730
|
||||
-63F0
|
||||
-61E0
|
||||
@@ -3374,0 +3370,5 @@
|
||||
+3C30
|
||||
+7E30
|
||||
+6730
|
||||
+63F0
|
||||
+61E0
|
||||
--- ./ter-u28n.bdf.orig 2020-12-28 20:34:18.835118600 +0200
|
||||
+++ ./ter-u28n.bdf 2020-12-28 20:34:26.385129200 +0200
|
||||
@@ -3361,5 +3360,0 @@
|
||||
-3C30
|
||||
-6630
|
||||
-6330
|
||||
-6330
|
||||
-61E0
|
||||
@@ -3374,0 +3370,5 @@
|
||||
+3C30
|
||||
+6630
|
||||
+6330
|
||||
+6330
|
||||
+61E0
|
||||
--- ./ter-u32b.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32b.bdf 2020-12-28 20:34:26.435129300 +0200
|
||||
@@ -3743,6 +3742,0 @@
|
||||
-1E1C
|
||||
-3F1C
|
||||
-779C
|
||||
-73DC
|
||||
-71F8
|
||||
-70F0
|
||||
@@ -3757,0 +3752,6 @@
|
||||
+1E1C
|
||||
+3F1C
|
||||
+779C
|
||||
+73DC
|
||||
+71F8
|
||||
+70F0
|
||||
--- ./ter-u32n.bdf.orig 2020-12-28 20:34:18.865118700 +0200
|
||||
+++ ./ter-u32n.bdf 2020-12-28 20:34:26.425129300 +0200
|
||||
@@ -3743,6 +3742,0 @@
|
||||
-0E0C
|
||||
-1F0C
|
||||
-3B8C
|
||||
-31DC
|
||||
-30F8
|
||||
-3070
|
||||
@@ -3757,0 +3752,6 @@
|
||||
+0E0C
|
||||
+1F0C
|
||||
+3B8C
|
||||
+31DC
|
||||
+30F8
|
||||
+3070
|
||||
@@ -0,0 +1,135 @@
|
||||
module.exports = {
|
||||
'env': {
|
||||
'es6': true,
|
||||
'node': true,
|
||||
'browser': false
|
||||
},
|
||||
'extends': 'eslint:recommended',
|
||||
'parserOptions': {
|
||||
'sourceType': 'module'
|
||||
},
|
||||
'rules': {
|
||||
'indent': [
|
||||
'error',
|
||||
'tab'
|
||||
],
|
||||
'linebreak-style': [
|
||||
'error',
|
||||
'unix'
|
||||
],
|
||||
'quotes': [
|
||||
'warn',
|
||||
'single'
|
||||
],
|
||||
'semi': [
|
||||
'error',
|
||||
'always'
|
||||
],
|
||||
'curly': [
|
||||
'error',
|
||||
'all'
|
||||
],
|
||||
'brace-style': [
|
||||
'error',
|
||||
'1tbs'
|
||||
],
|
||||
'no-empty' : 'warn',
|
||||
'no-unused-vars' : 'warn',
|
||||
'no-console': 'warn',
|
||||
'consistent-return': 'error',
|
||||
'class-methods-use-this': 'warn',
|
||||
'eqeqeq': [
|
||||
'error',
|
||||
'always', {
|
||||
'null': 'ignore'
|
||||
}
|
||||
],
|
||||
'no-alert': 'warn',
|
||||
'no-caller': 'error',
|
||||
'no-eval': 'error',
|
||||
'no-extend-native': 'warn',
|
||||
'no-implicit-coercion': 'error',
|
||||
'no-implied-eval': 'error',
|
||||
'no-invalid-this': 'error',
|
||||
'no-loop-func': 'error',
|
||||
'no-new-func': 'warn',
|
||||
'no-new-wrappers': 'error',
|
||||
'no-proto': 'error',
|
||||
'no-return-assign': 'warn',
|
||||
'no-return-await': 'warn',
|
||||
'no-script-url': 'error',
|
||||
'no-self-compare': 'error',
|
||||
'no-sequences': 'error',
|
||||
'no-throw-literal': 'error',
|
||||
'no-unmodified-loop-condition': 'warn',
|
||||
'no-unused-expressions': 'warn',
|
||||
'no-useless-return': 'warn',
|
||||
'no-warning-comments': 'warn',
|
||||
'prefer-promise-reject-errors': 'warn',
|
||||
'no-label-var': 'error',
|
||||
'no-shadow': [
|
||||
'warn', {
|
||||
'builtinGlobals': true,
|
||||
'hoist': 'all'
|
||||
}
|
||||
],
|
||||
'no-shadow-restricted-names': 'error',
|
||||
'no-undefined': 'error',
|
||||
'no-use-before-define': 'error',
|
||||
'no-new-require': 'error',
|
||||
'no-path-concat': 'error',
|
||||
'camelcase': 'error',
|
||||
'comma-dangle': [
|
||||
'error',
|
||||
'never'
|
||||
],
|
||||
'eol-last': [
|
||||
'error',
|
||||
'always'
|
||||
],
|
||||
'func-call-spacing': 'warn',
|
||||
'lines-around-directive': [
|
||||
'warn',
|
||||
'always'
|
||||
],
|
||||
'max-params': [
|
||||
'warn', {
|
||||
'max': 7
|
||||
}
|
||||
],
|
||||
'max-statements-per-line': [
|
||||
'warn', {
|
||||
'max': 1
|
||||
}
|
||||
],
|
||||
'new-cap': [
|
||||
'error'
|
||||
],
|
||||
'no-array-constructor': 'warn',
|
||||
'no-mixed-operators': [
|
||||
'error', {
|
||||
'groups': [
|
||||
[ '&', '|', '^', '~', '<<', '>>', '>>>' ],
|
||||
[ '==', '!=', '===', '!==', '>', '>=', '<', '<=' ],
|
||||
[ '&&', '||' ],
|
||||
[ 'in', 'instanceof' ]
|
||||
],
|
||||
'allowSamePrecedence': false
|
||||
}
|
||||
],
|
||||
'no-trailing-spaces': 'warn',
|
||||
'no-unneeded-ternary': 'warn',
|
||||
'no-whitespace-before-property': 'error',
|
||||
'operator-linebreak': 'warn',
|
||||
'semi-spacing': 'warn',
|
||||
'no-confusing-arrow': [
|
||||
'error', {
|
||||
'allowParens': true
|
||||
}
|
||||
],
|
||||
'no-duplicate-imports': 'warn',
|
||||
'prefer-rest-params': 'warn',
|
||||
'prefer-spread': 'warn',
|
||||
'no-unsafe-negation': 'warn'
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,425 @@
|
||||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code
|
||||
extension-pkg-whitelist=
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
jobs=4
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once).You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,bad-continuation,missing-docstring,redefined-builtin,unnecessary-lambda,too-few-public-methods,too-many-locals,too-many-branches,too-many-statements,broad-except,consider-using-ternary
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
enable=
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectively contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details
|
||||
#msg-template=
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio).You can also give a reporter class, eg
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=no
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=8
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming hint for argument names
|
||||
argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct argument names
|
||||
argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Naming hint for attribute names
|
||||
attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct attribute names
|
||||
attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,bar,baz,toto,tutu,tata
|
||||
|
||||
# Naming hint for class attribute names
|
||||
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Regular expression matching correct class attribute names
|
||||
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Naming hint for class names
|
||||
class-name-hint=[A-Z_][a-zA-Z0-9]+$
|
||||
|
||||
# Regular expression matching correct class names
|
||||
class-rgx=[A-Z_][a-zA-Z0-9]+$
|
||||
|
||||
# Naming hint for constant names
|
||||
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Regular expression matching correct constant names
|
||||
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming hint for function names
|
||||
function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct function names
|
||||
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
good-names=i,j,k,ex,Run,_,s,e,x,y,n
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming hint for inline iteration names
|
||||
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Regular expression matching correct inline iteration names
|
||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Naming hint for method names
|
||||
method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct method names
|
||||
method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Naming hint for module names
|
||||
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Regular expression matching correct module names
|
||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming hint for variable names
|
||||
variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct variable names
|
||||
variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=LF
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string='\t'
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=120
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,dict-separator
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,XXX,TODO
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
||||
# install python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to indicated private dictionary in
|
||||
# --spelling-private-dict-file option instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
||||
# not used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,future.builtins
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,__new__,setUp
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,_fields,_replace,_source,_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=mcs
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=10
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=optparse,tkinter.tix
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "Exception"
|
||||
overgeneral-exceptions=Exception
|
||||
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
|
||||
// -- Width --
|
||||
const DPARSE_LIMIT = 512;
|
||||
const SPARSE_LIMIT = 32000;
|
||||
|
||||
class Width {
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
static parse(name, value, limit) {
|
||||
const words = fnutil.splitWords(name, value, 2);
|
||||
|
||||
return new Width(fnutil.parseDec(name + '.x', words[0], -limit, limit),
|
||||
fnutil.parseDec(name + '.y', words[1], -limit, limit));
|
||||
}
|
||||
|
||||
static parseS(name, value) {
|
||||
return Width.parse(name, value, SPARSE_LIMIT);
|
||||
}
|
||||
|
||||
static parseD(name, value) {
|
||||
return Width.parse(name, value, DPARSE_LIMIT);
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `${this.x} ${this.y}`;
|
||||
}
|
||||
}
|
||||
|
||||
// -- BBX --
|
||||
class BBX {
|
||||
constructor(width, height, xoff, yoff) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.xoff = xoff;
|
||||
this.yoff = yoff;
|
||||
}
|
||||
|
||||
static parse(name, value) {
|
||||
const words = fnutil.splitWords(name, value, 4);
|
||||
|
||||
return new BBX(fnutil.parseDec(name + '.width', words[0], 1, DPARSE_LIMIT),
|
||||
fnutil.parseDec(name + '.height', words[1], 1, DPARSE_LIMIT),
|
||||
fnutil.parseDec(name + '.xoff', words[2], -DPARSE_LIMIT, DPARSE_LIMIT),
|
||||
fnutil.parseDec(name + '.yoff', words[3], -DPARSE_LIMIT, DPARSE_LIMIT));
|
||||
}
|
||||
|
||||
rowSize() {
|
||||
return (this.width + 7) >> 3;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `${this.width} ${this.height} ${this.xoff} ${this.yoff}`;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Props --
|
||||
function skipComments(line) {
|
||||
return line.startsWith('COMMENT') ? null : line;
|
||||
}
|
||||
|
||||
class Props extends Map {
|
||||
forEach(callback) {
|
||||
super.forEach((value, name) => callback(name, value));
|
||||
}
|
||||
|
||||
read(input, name, callback) {
|
||||
return this.parse(input.readLines(skipComments), name, callback);
|
||||
}
|
||||
|
||||
parse(line, name, callback) {
|
||||
if (line == null || !line.startsWith(name)) {
|
||||
throw new Error(name + ' expected');
|
||||
}
|
||||
|
||||
const value = line.substring(name.length).trimLeft();
|
||||
|
||||
this.set(name, value);
|
||||
return callback == null ? value : callback(name, value);
|
||||
}
|
||||
|
||||
set(name, value) {
|
||||
super.set(name, value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// -- Base --
|
||||
class Base {
|
||||
constructor() {
|
||||
this.props = new Props();
|
||||
this.bbx = null;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Char --
|
||||
class Char extends Base {
|
||||
constructor() {
|
||||
super();
|
||||
this.code = -1;
|
||||
this.swidth = null;
|
||||
this.dwidth = null;
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
bitmap() {
|
||||
const bitmap = this.data.toString('hex').toUpperCase();
|
||||
const regex = new RegExp(`.{${this.bbx.rowSize() << 1}}`, 'g');
|
||||
return bitmap.replace(regex, '$&\n');
|
||||
}
|
||||
|
||||
_read(input) {
|
||||
// HEADER
|
||||
this.props.read(input, 'STARTCHAR');
|
||||
this.code = this.props.read(input, 'ENCODING', fnutil.parseDec);
|
||||
this.swidth = this.props.read(input, 'SWIDTH', Width.parseS);
|
||||
this.dwidth = this.props.read(input, 'DWIDTH', Width.parseD);
|
||||
this.bbx = this.props.read(input, 'BBX', BBX.parse);
|
||||
|
||||
let line = input.readLines(skipComments);
|
||||
|
||||
if (line != null && line.startsWith('ATTRIBUTES')) {
|
||||
this.props.parse(line, 'ATTRIBUTES');
|
||||
line = input.readLines(skipComments);
|
||||
}
|
||||
|
||||
// BITMAP
|
||||
if (this.props.parse(line, 'BITMAP') !== '') {
|
||||
throw new Error('BITMAP expected');
|
||||
}
|
||||
|
||||
const rowLen = this.bbx.rowSize() * 2;
|
||||
let bitmap = '';
|
||||
|
||||
for (let y = 0; y < this.bbx.height; y++) {
|
||||
line = input.readLines(skipComments);
|
||||
|
||||
if (line == null) {
|
||||
throw new Error('bitmap data expected');
|
||||
}
|
||||
if (line.match(/^[\dA-Fa-f]+$/) == null) {
|
||||
throw new Error('invalid bitmap character(s)');
|
||||
}
|
||||
if (line.length === rowLen) {
|
||||
bitmap += line;
|
||||
} else {
|
||||
throw new Error('invalid bitmap line length');
|
||||
}
|
||||
}
|
||||
|
||||
this.data = Buffer.from(bitmap, 'hex');
|
||||
|
||||
// FINAL
|
||||
if (input.readLines(skipComments) !== 'ENDCHAR') {
|
||||
throw new Error('ENDCHAR expected');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static read(input) {
|
||||
return (new Char())._read(input);
|
||||
}
|
||||
|
||||
write(output) {
|
||||
let header = '';
|
||||
|
||||
this.props.forEach((name, value) => {
|
||||
header += (name + ' ' + value).trim() + '\n';
|
||||
});
|
||||
output.writeLine(header + this.bitmap() + 'ENDCHAR');
|
||||
}
|
||||
}
|
||||
|
||||
// -- Font --
|
||||
const XLFD = {
|
||||
FOUNDRY: 1,
|
||||
FAMILY_NAME: 2,
|
||||
WEIGHT_NAME: 3,
|
||||
SLANT: 4,
|
||||
SETWIDTH_NAME: 5,
|
||||
ADD_STYLE_NAME: 6,
|
||||
PIXEL_SIZE: 7,
|
||||
POINT_SIZE: 8,
|
||||
RESOLUTION_X: 9,
|
||||
RESOLUTION_Y: 10,
|
||||
SPACING: 11,
|
||||
AVERAGE_WIDTH: 12,
|
||||
CHARSET_REGISTRY: 13,
|
||||
CHARSET_ENCODING: 14
|
||||
};
|
||||
|
||||
const CHARS_MAX = 65535;
|
||||
|
||||
class Font extends Base {
|
||||
constructor() {
|
||||
super();
|
||||
this.chars = [];
|
||||
this.defaultCode = -1;
|
||||
}
|
||||
|
||||
get bold() {
|
||||
return this.xlfd[XLFD.WEIGHT_NAME].toLowerCase().includes('bold');
|
||||
}
|
||||
|
||||
get italic() {
|
||||
return ['I', 'O'].indexOf(this.xlfd[XLFD.SLANT]) !== -1;
|
||||
}
|
||||
|
||||
get proportional() {
|
||||
return this.xlfd[XLFD.SPACING] === 'P';
|
||||
}
|
||||
|
||||
_read(input) {
|
||||
// HEADER
|
||||
let line = input.readLine();
|
||||
|
||||
if (this.props.parse(line, 'STARTFONT') !== '2.1') {
|
||||
throw new Error('STARTFONT 2.1 expected');
|
||||
}
|
||||
this.xlfd = this.props.read(input, 'FONT', (name, value) => value.split('-', 16));
|
||||
|
||||
if (this.xlfd.length !== 15 || this.xlfd[0] !== '') {
|
||||
throw new Error('non-XLFD font names are not supported');
|
||||
}
|
||||
this.props.read(input, 'SIZE');
|
||||
this.bbx = this.props.read(input, 'FONTBOUNDINGBOX', BBX.parse);
|
||||
line = input.readLines(skipComments);
|
||||
|
||||
if (line != null && line.startsWith('STARTPROPERTIES')) {
|
||||
const numProps = this.props.parse(line, 'STARTPROPERTIES', fnutil.parseDec);
|
||||
|
||||
for (let i = 0; i < numProps; i++) {
|
||||
line = input.readLines(skipComments);
|
||||
|
||||
if (line == null) {
|
||||
throw new Error('property expected');
|
||||
}
|
||||
|
||||
const match = line.match(/^(\w+)\s+([-\d"].*)$/);
|
||||
|
||||
if (match == null) {
|
||||
throw new Error('invalid property format');
|
||||
}
|
||||
|
||||
const name = match[1];
|
||||
const value = match[2];
|
||||
|
||||
if (this.props.get(name) != null) {
|
||||
throw new Error('duplicate property');
|
||||
}
|
||||
if (name === 'DEFAULT_CHAR') {
|
||||
this.defaultCode = fnutil.parseDec(name, value);
|
||||
}
|
||||
this.props.set(name, value);
|
||||
}
|
||||
|
||||
if (this.props.read(input, 'ENDPROPERTIES') !== '') {
|
||||
throw new Error('ENDPROPERTIES expected');
|
||||
}
|
||||
line = input.readLines(skipComments);
|
||||
}
|
||||
|
||||
// GLYPHS
|
||||
const numChars = fnutil.parseDec('CHARS', this.props.parse(line, 'CHARS'), 1, CHARS_MAX);
|
||||
|
||||
for (let i = 0; i < numChars; i++) {
|
||||
this.chars.push(Char.read(input));
|
||||
}
|
||||
|
||||
if (this.defaultCode !== -1 && this.chars.find(char => char.code === this.defaultCode) === -1) {
|
||||
throw new Error('invalid DEFAULT_CHAR');
|
||||
}
|
||||
|
||||
// FINAL
|
||||
if (input.readLines(skipComments) !== 'ENDFONT') {
|
||||
throw new Error('ENDFONT expected');
|
||||
}
|
||||
if (input.readLine() != null) {
|
||||
throw new Error('garbage after ENDFONT');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static read(input) {
|
||||
return (new Font())._read(input, false);
|
||||
}
|
||||
|
||||
write(output) {
|
||||
this.props.forEach((name, value) => output.writeProp(name, value));
|
||||
this.chars.forEach(char => char.write(output));
|
||||
output.writeLine('ENDFONT');
|
||||
}
|
||||
}
|
||||
|
||||
// -- Export --
|
||||
module.exports = Object.freeze({
|
||||
DPARSE_LIMIT,
|
||||
SPARSE_LIMIT,
|
||||
Width,
|
||||
BBX,
|
||||
skipComments,
|
||||
Props,
|
||||
Base,
|
||||
Char,
|
||||
XLFD,
|
||||
CHARS_MAX,
|
||||
Font
|
||||
});
|
||||
@@ -0,0 +1,309 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import re
|
||||
import codecs
|
||||
from collections import OrderedDict
|
||||
from enum import IntEnum, unique
|
||||
|
||||
import fnutil
|
||||
|
||||
# -- Width --
|
||||
DPARSE_LIMIT = 512
|
||||
SPARSE_LIMIT = 32000
|
||||
|
||||
class Width:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
|
||||
@staticmethod
|
||||
def parse(name, value, limit):
|
||||
words = fnutil.split_words(name, value, 2)
|
||||
return Width(fnutil.parse_dec(name + '.x', words[0], -limit, limit),
|
||||
fnutil.parse_dec(name + '.y', words[1], -limit, limit))
|
||||
|
||||
|
||||
@staticmethod
|
||||
def parse_s(name, value):
|
||||
return Width.parse(name, value, SPARSE_LIMIT)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def parse_d(name, value):
|
||||
return Width.parse(name, value, DPARSE_LIMIT)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return '%d %d' % (self.x, self.y)
|
||||
|
||||
|
||||
# -- BXX --
|
||||
class BBX:
|
||||
def __init__(self, width, height, xoff, yoff):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.xoff = xoff
|
||||
self.yoff = yoff
|
||||
|
||||
|
||||
@staticmethod
|
||||
def parse(name, value):
|
||||
words = fnutil.split_words(name, value, 4)
|
||||
return BBX(fnutil.parse_dec('width', words[0], 1, DPARSE_LIMIT),
|
||||
fnutil.parse_dec('height', words[1], 1, DPARSE_LIMIT),
|
||||
fnutil.parse_dec('bbxoff', words[2], -DPARSE_LIMIT, DPARSE_LIMIT),
|
||||
fnutil.parse_dec('bbyoff', words[3], -DPARSE_LIMIT, DPARSE_LIMIT))
|
||||
|
||||
|
||||
def row_size(self):
|
||||
return (self.width + 7) >> 3
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return '%d %d %d %d' % (self.width, self.height, self.xoff, self.yoff)
|
||||
|
||||
|
||||
# -- Props --
|
||||
def skip_comments(line):
|
||||
return None if line[:7] == b'COMMENT' else line
|
||||
|
||||
|
||||
class Props(OrderedDict):
|
||||
def __iter__(self):
|
||||
return self.items().__iter__()
|
||||
|
||||
|
||||
def read(self, input, name, callback=None):
|
||||
return self.parse(input.read_lines(skip_comments), name, callback)
|
||||
|
||||
|
||||
def parse(self, line, name, callback=None):
|
||||
if not line or not line.startswith(bytes(name, 'ascii')):
|
||||
raise Exception(name + ' expected')
|
||||
|
||||
value = line[len(name):].lstrip()
|
||||
self[name] = value
|
||||
return value if callback is None else callback(name, value)
|
||||
|
||||
|
||||
def set(self, name, value):
|
||||
self[name] = value if isinstance(value, (bytes, bytearray)) else bytes(str(value), 'ascii')
|
||||
|
||||
|
||||
# -- Base --
|
||||
class Base:
|
||||
def __init__(self):
|
||||
self.props = Props()
|
||||
self.bbx = None
|
||||
|
||||
|
||||
# -- Char
|
||||
HEX_BYTES = (48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70)
|
||||
|
||||
class Char(Base):
|
||||
def __init__(self):
|
||||
Base.__init__(self)
|
||||
self.code = -1
|
||||
self.swidth = None
|
||||
self.dwidth = None
|
||||
self.data = None
|
||||
|
||||
|
||||
def bitmap(self):
|
||||
bitmap = ''
|
||||
row_size = self.bbx.row_size()
|
||||
|
||||
for index in range(0, len(self.data), row_size):
|
||||
bitmap += self.data[index : index + row_size].hex() + '\n'
|
||||
|
||||
return bytes(bitmap, 'ascii').upper()
|
||||
|
||||
|
||||
def _read(self, input):
|
||||
# HEADER
|
||||
self.props.read(input, 'STARTCHAR')
|
||||
self.code = self.props.read(input, 'ENCODING', fnutil.parse_dec)
|
||||
self.swidth = self.props.read(input, 'SWIDTH', Width.parse_s)
|
||||
self.dwidth = self.props.read(input, 'DWIDTH', Width.parse_d)
|
||||
self.bbx = self.props.read(input, 'BBX', BBX.parse)
|
||||
line = input.read_lines(skip_comments)
|
||||
|
||||
if line and line.startswith(b'ATTRIBUTES'):
|
||||
self.props.parse(line, 'ATTRIBUTES')
|
||||
line = input.read_lines(skip_comments)
|
||||
|
||||
# BITMAP
|
||||
if self.props.parse(line, 'BITMAP'):
|
||||
raise Exception('BITMAP expected')
|
||||
|
||||
row_len = self.bbx.row_size() * 2
|
||||
self.data = bytearray()
|
||||
|
||||
for _ in range(0, self.bbx.height):
|
||||
line = input.read_lines(skip_comments)
|
||||
|
||||
if not line:
|
||||
raise Exception('bitmap data expected')
|
||||
|
||||
if len(line) == row_len:
|
||||
self.data += codecs.decode(line, 'hex')
|
||||
else:
|
||||
raise Exception('invalid bitmap length')
|
||||
|
||||
# FINAL
|
||||
if input.read_lines(skip_comments) != b'ENDCHAR':
|
||||
raise Exception('ENDCHAR expected')
|
||||
|
||||
return self
|
||||
|
||||
|
||||
@staticmethod
|
||||
def read(input):
|
||||
return Char()._read(input) # pylint: disable=protected-access
|
||||
|
||||
|
||||
def write(self, output):
|
||||
for [name, value] in self.props:
|
||||
output.write_prop(name, value)
|
||||
|
||||
output.write_line(self.bitmap() + b'ENDCHAR')
|
||||
|
||||
|
||||
# -- Font --
|
||||
@unique
|
||||
class XLFD(IntEnum):
|
||||
FOUNDRY = 1
|
||||
FAMILY_NAME = 2
|
||||
WEIGHT_NAME = 3
|
||||
SLANT = 4
|
||||
SETWIDTH_NAME = 5
|
||||
ADD_STYLE_NAME = 6
|
||||
PIXEL_SIZE = 7
|
||||
POINT_SIZE = 8
|
||||
RESOLUTION_X = 9
|
||||
RESOLUTION_Y = 10
|
||||
SPACING = 11
|
||||
AVERAGE_WIDTH = 12
|
||||
CHARSET_REGISTRY = 13
|
||||
CHARSET_ENCODING = 14
|
||||
|
||||
CHARS_MAX = 65535
|
||||
|
||||
class Font(Base):
|
||||
def __init__(self):
|
||||
Base.__init__(self)
|
||||
self.xlfd = []
|
||||
self.chars = []
|
||||
self.default_code = -1
|
||||
|
||||
|
||||
@property
|
||||
def bold(self):
|
||||
return b'bold' in self.xlfd[XLFD.WEIGHT_NAME].lower()
|
||||
|
||||
|
||||
@property
|
||||
def italic(self):
|
||||
return self.xlfd[XLFD.SLANT] in [b'I', b'O']
|
||||
|
||||
|
||||
@property
|
||||
def proportional(self):
|
||||
return self.xlfd[XLFD.SPACING] == b'P'
|
||||
|
||||
|
||||
def _read(self, input):
|
||||
# HEADER
|
||||
line = input.read_line()
|
||||
|
||||
if self.props.parse(line, 'STARTFONT') != b'2.1':
|
||||
raise Exception('STARTFONT 2.1 expected')
|
||||
|
||||
self.xlfd = self.props.read(input, 'FONT', lambda name, value: value.split(b'-', 15))
|
||||
|
||||
if len(self.xlfd) != 15 or self.xlfd[0] != b'':
|
||||
raise Exception('non-XLFD font names are not supported')
|
||||
|
||||
self.props.read(input, 'SIZE')
|
||||
self.bbx = self.props.read(input, 'FONTBOUNDINGBOX', BBX.parse)
|
||||
line = input.read_lines(skip_comments)
|
||||
|
||||
if line and line.startswith(b'STARTPROPERTIES'):
|
||||
num_props = self.props.parse(line, 'STARTPROPERTIES', fnutil.parse_dec)
|
||||
|
||||
for _ in range(0, num_props):
|
||||
line = input.read_lines(skip_comments)
|
||||
|
||||
if line is None:
|
||||
raise Exception('property expected')
|
||||
|
||||
match = re.fullmatch(br'(\w+)\s+([-\d"].*)', line)
|
||||
|
||||
if not match:
|
||||
raise Exception('invalid property format')
|
||||
|
||||
name = str(match.group(1), 'ascii')
|
||||
value = match.group(2)
|
||||
|
||||
if self.props.get(name) is not None:
|
||||
raise Exception('duplicate property')
|
||||
|
||||
if name == 'DEFAULT_CHAR':
|
||||
self.default_code = fnutil.parse_dec(name, value)
|
||||
|
||||
self.props[name] = value
|
||||
|
||||
if self.props.read(input, 'ENDPROPERTIES') != b'':
|
||||
raise Exception('ENDPROPERTIES expected')
|
||||
|
||||
line = input.read_lines(skip_comments)
|
||||
|
||||
# GLYPHS
|
||||
num_chars = fnutil.parse_dec('CHARS', self.props.parse(line, 'CHARS'), 1, CHARS_MAX)
|
||||
|
||||
for _ in range(0, num_chars):
|
||||
self.chars.append(Char.read(input))
|
||||
|
||||
if next((char.code for char in self.chars if char.code == self.default_code), -1) != self.default_code:
|
||||
raise Exception('invalid DEFAULT_CHAR')
|
||||
|
||||
# FINAL
|
||||
if input.read_lines(skip_comments) != b'ENDFONT':
|
||||
raise Exception('ENDFONT expected')
|
||||
|
||||
if input.read_line() is not None:
|
||||
raise Exception('garbage after ENDFONT')
|
||||
|
||||
return self
|
||||
|
||||
|
||||
@staticmethod
|
||||
def read(input):
|
||||
return Font()._read(input) # pylint: disable=protected-access
|
||||
|
||||
|
||||
def write(self, output):
|
||||
for [name, value] in self.props:
|
||||
output.write_prop(name, value)
|
||||
|
||||
for char in self.chars:
|
||||
char.write(output)
|
||||
|
||||
output.write_line(b'ENDFONT')
|
||||
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
const fncli = require('./fncli.js');
|
||||
const fnio = require('./fnio.js');
|
||||
const bdf = require('./bdf.js');
|
||||
|
||||
// -- Params --
|
||||
class Params extends fncli.Params {
|
||||
constructor() {
|
||||
super();
|
||||
this.asciiChars = true;
|
||||
this.bbxExceeds = true;
|
||||
this.duplCodes = -1;
|
||||
this.extraBits = true;
|
||||
this.attributes = true;
|
||||
this.duplNames = -1;
|
||||
this.duplProps = true;
|
||||
this.commonSlant = true;
|
||||
this.commonWeight = true;
|
||||
this.xlfdFontNm = true;
|
||||
this.yWidthZero = true;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Options --
|
||||
const HELP = ('' +
|
||||
'usage: bdfcheck [options] [INPUT...]\n' +
|
||||
'Check BDF font(s) for various problems\n' +
|
||||
'\n' +
|
||||
' -A disable non-ascii characters check\n' +
|
||||
' -B disable BBX exceeding FONTBOUNDINGBOX checks\n' +
|
||||
' -c/-C enable/disable duplicate character codes check\n' +
|
||||
' (default = enabled for registry ISO10646)\n' +
|
||||
' -E disable extra bits check\n' +
|
||||
' -I disable ATTRIBUTES check\n' +
|
||||
' -n/-N enable duplicate character names check\n' +
|
||||
' (default = enabled for registry ISO10646)\n' +
|
||||
' -P disable duplicate properties check\n' +
|
||||
' -S disable common slant check\n' +
|
||||
' -W disable common weight check\n' +
|
||||
' -X disable XLFD font name check\n' +
|
||||
' -Y disable zero WIDTH Y check\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'File directives: COMMENT bdfcheck --enable|disable-<check-name>\n' +
|
||||
' (also available as long command line options)\n' +
|
||||
'\n' +
|
||||
'Check names: ascii-chars, bbx-exceeds, duplicate-codes, extra-bits,\n' +
|
||||
' attributes, duplicate-names, duplicate-properties, common-slant,\n' +
|
||||
' common-weight, xlfd-font, ywidth-zero\n' +
|
||||
'\n' +
|
||||
'The input BDF(s) must be v2.1 with unicode encoding.\n');
|
||||
|
||||
const VERSION = 'bdfcheck 1.61, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE;
|
||||
|
||||
class Options extends fncli.Options {
|
||||
constructor() {
|
||||
super([], HELP, VERSION);
|
||||
}
|
||||
|
||||
parse(name, directive, params) {
|
||||
const value = name.startsWith('--enable') || name[1].match('[a-z]');
|
||||
|
||||
switch (name) {
|
||||
case '-A':
|
||||
case '--enable-ascii-chars':
|
||||
case '--disable-ascii-chars':
|
||||
params.asciiChars = value;
|
||||
break;
|
||||
case '-B':
|
||||
case '--enable-bbx-exceeds':
|
||||
case '--disable-bbx-exceeds':
|
||||
params.bbxExceeds = value;
|
||||
break;
|
||||
case '-c':
|
||||
case '-C':
|
||||
case '--enable-duplicate-codes':
|
||||
case '--disable-duplicate-codes':
|
||||
params.duplCodes = value;
|
||||
break;
|
||||
case '-E':
|
||||
case '--enable-extra-bits':
|
||||
case '--disable-extra-bits':
|
||||
params.extraBits = value;
|
||||
break;
|
||||
case '-I':
|
||||
case '--enable-attributes':
|
||||
case '--disable-attributes':
|
||||
params.attributes = value;
|
||||
break;
|
||||
case '-n':
|
||||
case '-N':
|
||||
case '--enable-duplicate-names':
|
||||
case '--disable-duplicate-names':
|
||||
params.duplNames = value;
|
||||
break;
|
||||
case '-P':
|
||||
case '--enable-duplicate-properties':
|
||||
case '--disable-duplicate-properties':
|
||||
params.duplProps = value;
|
||||
break;
|
||||
case '-S':
|
||||
case '--enable-common-slant':
|
||||
case '--disable-common-slant':
|
||||
params.commonSlant = value;
|
||||
break;
|
||||
case '-W':
|
||||
case '--enable-common-weight':
|
||||
case '--disable-common-weight':
|
||||
params.commonWeight = value;
|
||||
break;
|
||||
case '-X':
|
||||
case '--enable-xlfd-font':
|
||||
case '--disable-xlfd-font':
|
||||
params.xlfdFontNm = value;
|
||||
break;
|
||||
case '-Y':
|
||||
case '--enable-ywidth-zero':
|
||||
case '--disable-ywidth-zero':
|
||||
params.yWidthZero = value;
|
||||
break;
|
||||
default:
|
||||
return directive !== true && this.fallback(name, params);
|
||||
}
|
||||
|
||||
return directive !== true || name.startsWith('--');
|
||||
}
|
||||
}
|
||||
|
||||
// -- DupMap --
|
||||
class DupMap extends Map {
|
||||
constructor(prefix, descript, severity) {
|
||||
super();
|
||||
this.prefix = prefix;
|
||||
this.descript = descript;
|
||||
this.severity = severity;
|
||||
}
|
||||
|
||||
check() {
|
||||
this.forEach((lines, value) => {
|
||||
if (lines.length > 1) {
|
||||
let text = `duplicate ${this.descript} ${value} at lines`;
|
||||
|
||||
for (let index = 0; index < lines.length; index++) {
|
||||
text += (index === 0 ? ' ' : index === lines.length - 1 ? ' and ' : ', ');
|
||||
text += lines[index];
|
||||
}
|
||||
fnutil.message(this.prefix, this.severity, text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
push(value, lineNo) {
|
||||
let lines = this.get(value);
|
||||
|
||||
if (lines != null) {
|
||||
lines.push(lineNo);
|
||||
} else {
|
||||
this.set(value, [lineNo]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- InputFileStream --
|
||||
const MODE = Object.freeze({
|
||||
META: 0,
|
||||
PROPS: 1,
|
||||
BITMAP: 2
|
||||
});
|
||||
|
||||
class InputFileStream extends fnio.InputFileStream {
|
||||
constructor(fileName, parsed) {
|
||||
super(fileName);
|
||||
this.parsed = parsed;
|
||||
this.mode = MODE.META;
|
||||
this.proplocs = new DupMap(this.location(), 'property');
|
||||
this.namelocs = new DupMap(this.location(), 'character name', 'warning');
|
||||
this.codelocs = new DupMap(this.location(), 'encoding', 'warning');
|
||||
this.HANDLERS = [
|
||||
[ 'STARTCHAR', value => this.appendName(value) ],
|
||||
[ 'ENCODING', value => this.appendCode(value) ],
|
||||
[ 'SWIDTH', value => this.checkWidth('SWIDTH', value, bdf.Width.parseS) ],
|
||||
[ 'DWIDTH', value => this.checkWidth('DWIDTH', value, bdf.Width.parseD) ],
|
||||
[ 'BBX', value => this.setLastBox(value) ],
|
||||
[ 'BITMAP', () => this.setMode(MODE.BITMAP) ],
|
||||
[ 'SIZE', InputFileStream.checkSize ],
|
||||
[ 'ATTRIBUTES', value => this.checkAttr(value) ],
|
||||
[ 'STARTPROPERTIES', () => this.setMode(MODE.PROPS) ],
|
||||
[ 'FONTBOUNDINGBOX', value => this.setFontBox(value) ]
|
||||
];
|
||||
this.xlfdName = false;
|
||||
this.lastBox = null;
|
||||
this.fontBox = null;
|
||||
this.options = new Options();
|
||||
}
|
||||
|
||||
append(option, valocs, value) {
|
||||
if (option) {
|
||||
valocs.push(value, this.lineNo);
|
||||
}
|
||||
}
|
||||
|
||||
appendCode(value) {
|
||||
fnutil.parseDec('encoding', value);
|
||||
this.append(this.parsed.duplCodes, this.codelocs, value);
|
||||
}
|
||||
|
||||
appendName(value) {
|
||||
this.append(this.parsed.duplNames, this.namelocs, `"${value}"`);
|
||||
}
|
||||
|
||||
checkWidth(name, value, parse) {
|
||||
if (this.parsed.yWidthZero && parse(name, value).y !== 0) {
|
||||
fnutil.warning(this.location(), `non-zero ${name} Y`);
|
||||
}
|
||||
}
|
||||
|
||||
setFontBox(value) {
|
||||
this.fontBox = bdf.BBX.parse('FONTBOUNDINGBOX', value);
|
||||
}
|
||||
|
||||
setLastBox(value) {
|
||||
const bbx = bdf.BBX.parse('BBX', value);
|
||||
|
||||
if (this.parsed.bbxExceeds) {
|
||||
let exceeds = [];
|
||||
|
||||
if (bbx.xoff < this.fontBox.xoff) {
|
||||
exceeds.push('xoff < FONTBOUNDINGBOX xoff');
|
||||
}
|
||||
if (bbx.yoff < this.fontBox.yoff) {
|
||||
exceeds.push('yoff < FONTBOUNDINGBOX yoff');
|
||||
}
|
||||
if (bbx.width > this.fontBox.width) {
|
||||
exceeds.push('width > FONTBOUNDINGBOX width');
|
||||
}
|
||||
if (bbx.height > this.fontBox.height) {
|
||||
exceeds.push('height > FONTBOUNDINGBOX height');
|
||||
}
|
||||
exceeds.forEach(exceed => {
|
||||
fnutil.message(this.location(), '', exceed);
|
||||
});
|
||||
}
|
||||
this.lastBox = bbx;
|
||||
}
|
||||
|
||||
setMode(newMode) {
|
||||
this.mode = newMode;
|
||||
}
|
||||
|
||||
static checkSize(value) {
|
||||
const words = fnutil.splitWords('SIZE', value, 3);
|
||||
|
||||
fnutil.parseDec('point size', words[0], 1, null);
|
||||
fnutil.parseDec('x resolution', words[1], 1, null);
|
||||
fnutil.parseDec('y resolution', words[2], 1, null);
|
||||
}
|
||||
|
||||
checkAttr(value) {
|
||||
if (!value.match(/^[\dA-Fa-f]{4}$/)) {
|
||||
throw new Error('ATTRIBUTES must be 4 hex-encoded characters');
|
||||
}
|
||||
if (this.parsed.attributes) {
|
||||
fnutil.warning(this.location(), 'ATTRIBUTES may cause problems with freetype');
|
||||
}
|
||||
}
|
||||
|
||||
checkFont(value) {
|
||||
const xlfd = value.substring(4).trimLeft().split('-', 16);
|
||||
|
||||
if (xlfd.length === 15 && xlfd[0] === '') {
|
||||
let unicode = (xlfd[bdf.XLFD.CHARSET_REGISTRY].toUpperCase() === 'ISO10646');
|
||||
|
||||
if (this.parsed.duplCodes === -1) {
|
||||
this.parsed.duplCodes = unicode;
|
||||
}
|
||||
if (this.parsed.duplNames === -1) {
|
||||
this.parsed.duplNames = unicode;
|
||||
}
|
||||
|
||||
if (this.parsed.commonWeight) {
|
||||
let weight = xlfd[bdf.XLFD.WEIGHT_NAME];
|
||||
let compare = weight.toLowerCase();
|
||||
let consider = compare.includes('bold') ? 'Bold' : 'Normal';
|
||||
|
||||
if (compare === 'medium' || compare === 'regular') {
|
||||
compare = 'normal';
|
||||
}
|
||||
if (compare !== consider.toLowerCase()) {
|
||||
fnutil.warning(this.location(), `weight "${weight}" may be considered ${consider}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.parsed.commonSlant) {
|
||||
let slant = xlfd[bdf.XLFD.SLANT];
|
||||
let consider = slant.match(/^[IO]/) ? 'Italic' : 'Regular';
|
||||
|
||||
if (slant.match(/^[IOR]$/) == null) {
|
||||
fnutil.warning(this.location(), `slant "${slant}" may be considered ${consider}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.parsed.xlfdFontNm) {
|
||||
fnutil.warning(this.location(), 'non-XLFD font name');
|
||||
}
|
||||
value = 'FONT --------------';
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
checkProp(line) {
|
||||
const match = line.match(/^(\w+)\s+([-\d"].*)$/);
|
||||
|
||||
if (match == null) {
|
||||
throw new Error('invalid property format');
|
||||
}
|
||||
|
||||
const name = match[1];
|
||||
const value = match[2];
|
||||
|
||||
if (value.startsWith('"')) {
|
||||
if (value.length < 2 || !value.endsWith('"')) {
|
||||
throw new Error('no closing double quote');
|
||||
}
|
||||
if (value.substring(1, value.length - 1).match(/[^"]"[^"]/)) {
|
||||
throw new Error('unescaped double quote');
|
||||
}
|
||||
} else {
|
||||
fnutil.parseDec('value', value, null, null);
|
||||
}
|
||||
|
||||
this.append(this.parsed.duplProps, this.proplocs, name);
|
||||
return `P${this.lineNo} 1`;
|
||||
}
|
||||
|
||||
checkBitmap(line) {
|
||||
if (line.length !== this.lastBox.rowSize() * 2) {
|
||||
throw new Error('invalid bitmap length');
|
||||
} else if (line.match(/^[\dA-Fa-f]+$/) == null) {
|
||||
throw new Error('invalid bitmap data');
|
||||
} else if (this.parsed.extraBits) {
|
||||
const data = Buffer.from(line, 'hex');
|
||||
const checkX = (this.lastBox.width - 1) | 7;
|
||||
const lastByte = data[data.length - 1];
|
||||
let bitNo = 7 - (this.lastBox.Width & 7);
|
||||
|
||||
for (let x = this.lastBox.Width; x <= checkX; x++) {
|
||||
if (lastByte & (1 << bitNo)) {
|
||||
fnutil.warning(this.location(), `extra bit(s) starting with x=${x}`);
|
||||
break;
|
||||
}
|
||||
bitNo--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkLine(line) {
|
||||
if (line.match(/[^\t\f\v\u0020-\u00ff]/)) {
|
||||
throw new Error('control character(s)');
|
||||
}
|
||||
if (this.parsed.asciiChars && line.match(/[\u007f-\u00ff]/)) {
|
||||
fnutil.warning(this.location(), 'non-ascii character(s)');
|
||||
}
|
||||
|
||||
switch (this.mode) {
|
||||
case MODE.META:
|
||||
if (!this.xlfdName && line.startsWith('FONT')) {
|
||||
line = this.checkFont(line);
|
||||
this.xlfdName = true;
|
||||
} else {
|
||||
this.HANDLERS.findIndex(function(handler) {
|
||||
if (line.startsWith(handler[0])) {
|
||||
handler[1](line.substring(handler[0].length).trimLeft());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
break;
|
||||
case MODE.PROPS:
|
||||
if (line.startsWith('ENDPROPERTIES')) {
|
||||
this.mode = MODE.META;
|
||||
} else {
|
||||
line = this.checkProp(line);
|
||||
}
|
||||
break;
|
||||
default: // MODE.BITMAP
|
||||
if (line.startsWith('ENDCHAR')) {
|
||||
this.mode = MODE.META;
|
||||
} else {
|
||||
this.checkBitmap(line);
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
readCheck(line, callback) {
|
||||
const match = line.match(/^COMMENT\s*bdfcheck\s+(-.*)$/);
|
||||
|
||||
if (match && !this.options.parse(match[1], true, this.parsed)) {
|
||||
throw new Error('invalid bdfcheck directive');
|
||||
}
|
||||
|
||||
line = callback(line);
|
||||
return line != null ? this.checkLine(line) : null;
|
||||
}
|
||||
|
||||
readLines(callback) {
|
||||
return super.readLines(line => this.readCheck(line, callback));
|
||||
}
|
||||
}
|
||||
|
||||
// -- Main --
|
||||
function mainProgram(nonopt, parsed) {
|
||||
(nonopt.length >= 1 ? nonopt : [null]).forEach(input => {
|
||||
let ifs = new InputFileStream(input, parsed);
|
||||
|
||||
try {
|
||||
bdf.Font.read(ifs);
|
||||
ifs.close();
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
ifs.proplocs.check();
|
||||
ifs.namelocs.check();
|
||||
ifs.codelocs.check();
|
||||
});
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
fncli.start('bdfcheck.js', new Options(), new Params(), mainProgram);
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import re
|
||||
import codecs
|
||||
from collections import OrderedDict
|
||||
from enum import IntEnum, unique
|
||||
|
||||
import fnutil
|
||||
import fncli
|
||||
import fnio
|
||||
import bdf
|
||||
|
||||
# -- Params --
|
||||
class Params(fncli.Params): # pylint: disable=too-many-instance-attributes
|
||||
def __init__(self):
|
||||
fncli.Params.__init__(self)
|
||||
self.ascii_chars = True
|
||||
self.bbx_exceeds = True
|
||||
self.dupl_codes = -1
|
||||
self.extra_bits = True
|
||||
self.attributes = True
|
||||
self.dupl_names = -1
|
||||
self.dupl_props = True
|
||||
self.common_slant = True
|
||||
self.common_weight = True
|
||||
self.xlfd_fontnm = True
|
||||
self.ywidth_zero = True
|
||||
|
||||
|
||||
# -- Options --
|
||||
HELP = ('' +
|
||||
'usage: bdfcheck [options] [INPUT...]\n' +
|
||||
'Check BDF font(s) for various problems\n' +
|
||||
'\n' +
|
||||
' -A disable non-ascii characters check\n' +
|
||||
' -B disable BBX exceeding FONTBOUNDINGBOX checks\n' +
|
||||
' -c/-C enable/disable duplicate character codes check\n' +
|
||||
' (default = enabled for registry ISO10646)\n' +
|
||||
' -E disable extra bits check\n' +
|
||||
' -I disable ATTRIBUTES check\n' +
|
||||
' -n/-N enable duplicate character names check\n' +
|
||||
' (default = enabled for registry ISO10646)\n' +
|
||||
' -P disable duplicate properties check\n' +
|
||||
' -S disable common slant check\n' +
|
||||
' -W disable common weight check\n' +
|
||||
' -X disable XLFD font name check\n' +
|
||||
' -Y disable zero WIDTH Y check\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'File directives: COMMENT bdfcheck --enable|disable-<check-name>\n' +
|
||||
' (also available as long command line options)\n' +
|
||||
'\n' +
|
||||
'Check names: ascii-chars, bbx-exceeds, duplicate-codes, extra-bits,\n' +
|
||||
' attributes, duplicate-names, duplicate-properties, common-slant,\n' +
|
||||
' common-weight, xlfd-font, ywidth-zero\n' +
|
||||
'\n' +
|
||||
'The input BDF(s) must be v2.1 with unicode encoding.\n')
|
||||
|
||||
VERSION = 'bdfcheck 1.62, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE
|
||||
|
||||
class Options(fncli.Options):
|
||||
def __init__(self):
|
||||
fncli.Options.__init__(self, [], HELP, VERSION)
|
||||
|
||||
|
||||
def parse(self, name, directive, params):
|
||||
value = name.startswith('--enable') or name[1].islower()
|
||||
|
||||
if name in ['-A', '--enable-ascii-chars', '--disable-ascii-chars']:
|
||||
params.ascii_chars = value
|
||||
elif name in ['-B', '--enable-bbx-exceeds', '--disable-bbx-exceeds']:
|
||||
params.bbx_exceeds = value
|
||||
elif name in ['-c', '-C', '--enable-duplicate-codes', '--disable-duplicate-codes']:
|
||||
params.dupl_codes = value
|
||||
elif name in ['-E', '--enable-extra-bits', '--disable-extra-bits']:
|
||||
params.extra_bits = value
|
||||
elif name in ['-I', '--enable-attributes', '--disable-attributes']:
|
||||
params.attributes = value
|
||||
elif name in ['-n', '-N', '--enable-duplicate-names', '--disable-duplicate-names']:
|
||||
params.dupl_names = value
|
||||
elif name in ['-P', '--enable-duplicate-properties', '--disable-duplicate-properties']:
|
||||
params.dupl_props = value
|
||||
elif name in ['-S', '--enable-common-slant', '--disable-common-slant']:
|
||||
params.common_slant = value
|
||||
elif name in ['-W', '--enable-common-weight', '--disable-common-weight']:
|
||||
params.common_weight = value
|
||||
elif name in ['-X', '--enable-xlfd-font', '--disable-xlfd-font']:
|
||||
params.xlfd_fontnm = value
|
||||
elif name in ['-Y', '--enable-ywidth-zero', '--disable-ywidth-zero']:
|
||||
params.ywidth_zero = value
|
||||
else:
|
||||
return directive is not True and self.fallback(name, params)
|
||||
|
||||
return directive is not True or name.startswith('--')
|
||||
|
||||
|
||||
# -- DupMap --
|
||||
class DupMap(OrderedDict):
|
||||
def __init__(self, prefix, severity, descript, quote):
|
||||
OrderedDict.__init__(self)
|
||||
self.prefix = prefix
|
||||
self.descript = descript
|
||||
self.severity = severity
|
||||
self.quote = quote
|
||||
|
||||
|
||||
def check(self):
|
||||
for value, lines in self.items():
|
||||
if len(lines) > 1:
|
||||
text = 'duplicate %s %s at lines' % (self.descript, str(value))
|
||||
|
||||
for index, line in enumerate(lines):
|
||||
text += ' ' if index == 0 else ' and ' if index == len(lines) - 1 else ', '
|
||||
text += str(line)
|
||||
|
||||
fnutil.message(self.prefix, self.severity, text)
|
||||
|
||||
|
||||
def push(self, value, line_no):
|
||||
try:
|
||||
self[value].append(line_no)
|
||||
except KeyError:
|
||||
self[value] = [line_no]
|
||||
|
||||
|
||||
# -- InputFileStream --
|
||||
@unique
|
||||
class MODE(IntEnum):
|
||||
META = 0
|
||||
PROPS = 1
|
||||
BITMAP = 2
|
||||
|
||||
class InputFileStream(fnio.InputFileStream):
|
||||
def __init__(self, file_name, parsed):
|
||||
fnio.InputFileStream.__init__(self, file_name)
|
||||
self.parsed = parsed
|
||||
self.mode = MODE.META
|
||||
self.proplocs = DupMap(self.location(), 'error', 'property', '')
|
||||
self.namelocs = DupMap(self.location(), 'warning', 'character name', '"')
|
||||
self.codelocs = DupMap(self.location(), 'warning', 'encoding', '')
|
||||
self.handlers = [
|
||||
(b'STARTCHAR', lambda value: self.append_name(value)),
|
||||
(b'ENCODING', lambda value: self.append_code(value)),
|
||||
(b'SWIDTH', lambda value: self.check_width('SWIDTH', value, bdf.Width.parse_s)),
|
||||
(b'DWIDTH', lambda value: self.check_width('DWIDTH', value, bdf.Width.parse_d)),
|
||||
(b'BBX', lambda value: self.set_last_box(value)),
|
||||
(b'BITMAP', lambda _: self.set_mode(MODE.BITMAP)),
|
||||
(b'SIZE', InputFileStream.check_size),
|
||||
(b'ATTRIBUTES', lambda value: self.check_attr(value)),
|
||||
(b'STARTPROPERTIES', lambda _: self.set_mode(MODE.PROPS)),
|
||||
(b'FONTBOUNDINGBOX', lambda value: self.set_font_box(value)),
|
||||
]
|
||||
self.xlfd_name = False
|
||||
self.last_box = None
|
||||
self.font_box = None
|
||||
self.options = Options()
|
||||
|
||||
|
||||
def append(self, option, valocs, value):
|
||||
if option:
|
||||
valocs.push(str(value, 'ascii'), self.line_no)
|
||||
|
||||
|
||||
def append_code(self, value):
|
||||
fnutil.parse_dec('encoding', value)
|
||||
self.append(self.parsed.dupl_codes, self.codelocs, value)
|
||||
|
||||
|
||||
def append_name(self, value):
|
||||
self.append(self.parsed.dupl_names, self.namelocs, b'"%s"' % value)
|
||||
|
||||
|
||||
def check_width(self, name, value, parse):
|
||||
if self.parsed.ywidth_zero and parse(name, value).y != 0:
|
||||
fnutil.warning(self.location(), 'non-zero %s Y' % name)
|
||||
|
||||
|
||||
def set_font_box(self, value):
|
||||
self.font_box = bdf.BBX.parse('FONTBOUNDINGBOX', value)
|
||||
|
||||
|
||||
def set_last_box(self, value):
|
||||
bbx = bdf.BBX.parse('BBX', value)
|
||||
|
||||
if self.parsed.bbx_exceeds:
|
||||
exceeds = []
|
||||
|
||||
if bbx.xoff < self.font_box.xoff:
|
||||
exceeds.append('xoff < FONTBOUNDINGBOX xoff')
|
||||
|
||||
if bbx.yoff < self.font_box.yoff:
|
||||
exceeds.append('yoff < FONTBOUNDINGBOX yoff')
|
||||
|
||||
if bbx.width > self.font_box.width:
|
||||
exceeds.append('width > FONTBOUNDINGBOX width')
|
||||
|
||||
if bbx.height > self.font_box.height:
|
||||
exceeds.append('height > FONTBOUNDINGBOX height')
|
||||
|
||||
for exceed in exceeds:
|
||||
fnutil.message(self.location(), '', exceed)
|
||||
|
||||
self.last_box = bbx
|
||||
|
||||
|
||||
def set_mode(self, new_mode):
|
||||
self.mode = new_mode
|
||||
|
||||
|
||||
def check(self):
|
||||
self.process(bdf.Font.read)
|
||||
self.proplocs.check()
|
||||
self.namelocs.check()
|
||||
self.codelocs.check()
|
||||
|
||||
|
||||
@staticmethod
|
||||
def check_size(value):
|
||||
words = fnutil.split_words('SIZE', value, 3)
|
||||
fnutil.parse_dec('point size', words[0], 1, None)
|
||||
fnutil.parse_dec('x resolution', words[1], 1, None)
|
||||
fnutil.parse_dec('y resolution', words[2], 1, None)
|
||||
|
||||
|
||||
def check_attr(self, value):
|
||||
if not re.fullmatch(br'[\dA-Fa-f]{4}', value):
|
||||
raise Exception('ATTRIBUTES must be 4 hex-encoded characters')
|
||||
|
||||
if self.parsed.attributes:
|
||||
fnutil.warning(self.location(), 'ATTRIBUTES may cause problems with freetype')
|
||||
|
||||
|
||||
def check_font(self, value):
|
||||
xlfd = value[4:].lstrip().split(b'-', 15)
|
||||
|
||||
if len(xlfd) == 15 and xlfd[0] == b'':
|
||||
unicode = (xlfd[bdf.XLFD.CHARSET_REGISTRY].upper() == b'ISO10646')
|
||||
|
||||
if self.parsed.dupl_codes == -1:
|
||||
self.parsed.dupl_codes = unicode
|
||||
|
||||
if self.parsed.dupl_names == -1:
|
||||
self.parsed.dupl_names = unicode
|
||||
|
||||
if self.parsed.common_weight:
|
||||
weight = str(xlfd[bdf.XLFD.WEIGHT_NAME], 'ascii')
|
||||
compare = weight.lower()
|
||||
consider = 'Bold' if 'bold' in compare else 'Normal'
|
||||
|
||||
if compare in ['medium', 'regular']:
|
||||
compare = 'normal'
|
||||
|
||||
if compare != consider.lower():
|
||||
fnutil.warning(self.location(), 'weight "%s" may be considered %s' % (weight, consider))
|
||||
|
||||
if self.parsed.common_slant:
|
||||
slant = str(xlfd[bdf.XLFD.SLANT], 'ascii')
|
||||
consider = 'Italic' if re.search('^[IO]', slant) else 'Regular'
|
||||
|
||||
if not re.fullmatch('[IOR]', slant):
|
||||
fnutil.warning(self.location(), 'slant "%s" may be considered %s' % (slant, consider))
|
||||
|
||||
else:
|
||||
if self.parsed.xlfd_fontnm:
|
||||
fnutil.warning(self.location(), 'non-XLFD font name')
|
||||
|
||||
value = b'FONT --------------'
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def check_prop(self, line):
|
||||
match = re.fullmatch(br'(\w+)\s+([-\d"].*)', line)
|
||||
|
||||
if not match:
|
||||
raise Exception('invalid property format')
|
||||
|
||||
name = match.group(1)
|
||||
value = match.group(2)
|
||||
|
||||
if value.startswith(b'"'):
|
||||
if len(value) < 2 or not value.endswith(b'"'):
|
||||
raise Exception('no closing double quote')
|
||||
if re.search(b'[^"]"[^"]', value[1 : len(value) - 1]):
|
||||
raise Exception('unescaped double quote')
|
||||
else:
|
||||
fnutil.parse_dec('value', value, None, None)
|
||||
|
||||
self.append(self.parsed.dupl_props, self.proplocs, name)
|
||||
return b'P%d 1' % self.line_no
|
||||
|
||||
|
||||
def check_bitmap(self, line):
|
||||
if len(line) != self.last_box.row_size() * 2:
|
||||
raise Exception('invalid bitmap length')
|
||||
|
||||
data = codecs.decode(line, 'hex')
|
||||
|
||||
if self.parsed.extra_bits:
|
||||
check_x = (self.last_box.width - 1) | 7
|
||||
last_byte = data[len(data) - 1]
|
||||
bit_no = 7 - (self.last_box.width & 7)
|
||||
|
||||
for x in range(self.last_box.width, check_x + 1):
|
||||
if last_byte & (1 << bit_no):
|
||||
fnutil.warning(self.location(), 'extra bit(s) starting with x=%d' % x)
|
||||
break
|
||||
bit_no -= 1
|
||||
|
||||
|
||||
def check_line(self, line):
|
||||
if re.search(b'[^\t\f\v\x20-\xff]', line):
|
||||
raise Exception('control character(s)')
|
||||
|
||||
if self.parsed.ascii_chars and re.search(b'[\x7f-\xff]', line):
|
||||
fnutil.warning(self.location(), 'non-ascii character(s)')
|
||||
|
||||
if self.mode == MODE.META:
|
||||
if not self.xlfd_name and line.startswith(b'FONT'):
|
||||
line = self.check_font(line)
|
||||
self.xlfd_name = True
|
||||
else:
|
||||
for handler in self.handlers:
|
||||
if line.startswith(handler[0]):
|
||||
handler[1](line[len(handler[0]):].lstrip())
|
||||
break
|
||||
elif self.mode == MODE.PROPS:
|
||||
if line.startswith(b'ENDPROPERTIES'):
|
||||
self.mode = MODE.META
|
||||
else:
|
||||
line = self.check_prop(line)
|
||||
else: # MODE.BITMAP
|
||||
if line.startswith(b'ENDCHAR'):
|
||||
self.mode = MODE.META
|
||||
else:
|
||||
self.check_bitmap(line)
|
||||
|
||||
return line
|
||||
|
||||
|
||||
def read_check(self, line, callback):
|
||||
match = re.search(br'^COMMENT\s*bdfcheck\s+(-.*)$', line)
|
||||
|
||||
if match and not self.options.parse(str(match[1], 'ascii'), True, self.parsed):
|
||||
raise Exception('invalid bdfcheck directive')
|
||||
|
||||
line = callback(line)
|
||||
return self.check_line(line) if line is not None else None
|
||||
|
||||
|
||||
def read_lines(self, callback):
|
||||
return fnio.InputFileStream.read_lines(self, lambda line: self.read_check(line, callback))
|
||||
|
||||
|
||||
# -- Main --
|
||||
def main_program(nonopt, parsed):
|
||||
for input_name in nonopt or [None]:
|
||||
InputFileStream(input_name, parsed).check()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fncli.start('bdfcheck.py', Options(), Params(), main_program)
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
const fncli = require('./fncli.js');
|
||||
const fnio = require('./fnio.js');
|
||||
const bdf = require('./bdf.js');
|
||||
|
||||
// -- Font --
|
||||
class Font extends bdf.Font {
|
||||
constructor() {
|
||||
super();
|
||||
this.minWidth = 0; // used in proportional()
|
||||
this.avgWidth = 0;
|
||||
}
|
||||
|
||||
_expand(char) {
|
||||
if (char.dwidth.x >= 0) {
|
||||
if (char.bbx.xoff >= 0) {
|
||||
var width = Math.max(char.bbx.xoff + char.bbx.width, char.dwidth.x);
|
||||
var dstXOff = char.bbx.xoff;
|
||||
var expXOff = 0;
|
||||
} else {
|
||||
width = Math.max(char.bbx.width, char.dwidth.x - char.bbx.xoff);
|
||||
dstXOff = 0;
|
||||
expXOff = char.bbx.xoff;
|
||||
}
|
||||
} else {
|
||||
const revXOff = char.bbx.xoff + char.bbx.width;
|
||||
|
||||
if (revXOff <= 0) {
|
||||
width = -Math.min(char.dwidth.x, char.bbx.xoff);
|
||||
dstXOff = width + char.bbx.xoff;
|
||||
expXOff = -width;
|
||||
} else {
|
||||
width = Math.max(char.bbx.width, revXOff - char.dwidth.x);
|
||||
dstXOff = width - char.bbx.width;
|
||||
expXOff = revXOff - width;
|
||||
}
|
||||
}
|
||||
|
||||
const height = this.bbx.height;
|
||||
|
||||
if (width === char.bbx.width && height === char.bbx.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
const srcRowSize = char.bbx.rowSize();
|
||||
const dstRowSize = (width + 7) >> 3;
|
||||
const dstYMax = this.pxAscender - char.bbx.yoff;
|
||||
const dstYMin = dstYMax - char.bbx.height;
|
||||
const copyRow = (dstXOff & 7) === 0;
|
||||
const dstData = Buffer.alloc(dstRowSize * height);
|
||||
|
||||
for (let dstY = dstYMin; dstY < dstYMax; dstY++) {
|
||||
let srcByteNo = (dstY - dstYMin) * srcRowSize;
|
||||
let dstByteNo = dstY * dstRowSize + (dstXOff >> 3);
|
||||
|
||||
if (copyRow) {
|
||||
char.data.copy(dstData, dstByteNo, srcByteNo, srcByteNo + srcRowSize);
|
||||
} else {
|
||||
let srcBitNo = 7;
|
||||
let dstBitNo = 7 - (dstXOff & 7);
|
||||
|
||||
for (let x = 0; x < char.bbx.width; x++) {
|
||||
if (char.data[srcByteNo] & (1 << srcBitNo)) {
|
||||
dstData[dstByteNo] |= (1 << dstBitNo);
|
||||
}
|
||||
if (--srcBitNo < 0) {
|
||||
srcBitNo = 7;
|
||||
srcByteNo++;
|
||||
}
|
||||
if (--dstBitNo < 0) {
|
||||
dstBitNo = 7;
|
||||
dstByteNo++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char.bbx = new bdf.BBX(width, height, expXOff, this.bbx.yoff);
|
||||
char.props.set('BBX', char.bbx);
|
||||
char.data = dstData;
|
||||
}
|
||||
|
||||
expand() {
|
||||
// PREXPAND / VERTICAL
|
||||
const ascent = this.props.get('FONT_ASCENT');
|
||||
const descent = this.props.get('FONT_DESCENT');
|
||||
let pxAscent = (ascent == null ? 0 : fnutil.parseDec('FONT_ASCENT', ascent, 0, bdf.DPARSE_LIMIT));
|
||||
let pxDescent = (descent == null ? 0 : fnutil.parseDec('FONT_DESCENT', descent, 0, bdf.DPARSE_LIMIT));
|
||||
|
||||
this.chars.forEach(char => {
|
||||
pxAscent = Math.max(pxAscent, char.bbx.height + char.bbx.yoff);
|
||||
pxDescent = Math.max(pxDescent, -char.bbx.yoff);
|
||||
});
|
||||
this.bbx.height = pxAscent + pxDescent;
|
||||
this.bbx.yoff = -pxDescent;
|
||||
|
||||
// EXPAND / HORIZONTAL
|
||||
let totalWidth = 0;
|
||||
|
||||
this.minWidth = this.chars[0].bbx.width;
|
||||
this.chars.forEach(char => {
|
||||
this._expand(char);
|
||||
this.minWidth = Math.min(this.minWidth, char.bbx.width);
|
||||
this.bbx.width = Math.max(this.bbx.width, char.bbx.width);
|
||||
this.bbx.xoff = Math.min(this.bbx.xoff, char.bbx.xoff);
|
||||
totalWidth += char.bbx.width;
|
||||
});
|
||||
this.avgWidth = fnutil.round(totalWidth / this.chars.length);
|
||||
this.props.set('FONTBOUNDINGBOX', this.bbx);
|
||||
}
|
||||
|
||||
expandX() {
|
||||
this.chars.forEach(char => {
|
||||
if (char.dwidth.x !== char.bbx.width) { // preserve SWIDTH if possible
|
||||
char.swidth.x = fnutil.round(char.bbx.width * 1000 / this.bbx.height);
|
||||
char.props.set('SWIDTH', char.swidth);
|
||||
char.dwidth.x = char.bbx.width;
|
||||
char.props.set('DWIDTH', char.dwidth);
|
||||
}
|
||||
char.bbx.xoff = 0;
|
||||
char.props.set('BBX', char.bbx);
|
||||
});
|
||||
this.bbx.xoff = 0;
|
||||
this.props.set('FONTBOUNDINGBOX', this.bbx);
|
||||
}
|
||||
|
||||
expandY() {
|
||||
const props = new Map([
|
||||
[ 'FONT_ASCENT', this.pxAscender ],
|
||||
[ 'FONT_DESCENT', -this.pxDescender ],
|
||||
[ 'PIXEL_SIZE', this.bbx.height ]
|
||||
]);
|
||||
|
||||
props.forEach((value, name) => {
|
||||
if (this.props.get(name) != null) {
|
||||
this.props.set(name, value);
|
||||
}
|
||||
});
|
||||
|
||||
this.xlfd[bdf.XLFD.PIXEL_SIZE] = this.bbx.height.toString();
|
||||
this.props.set('FONT', this.xlfd.join('-'));
|
||||
}
|
||||
|
||||
get proportional() {
|
||||
return this.bbx.width > this.minWidth || super.proportional;
|
||||
}
|
||||
|
||||
get pxAscender() {
|
||||
return this.bbx.height + this.bbx.yoff;
|
||||
}
|
||||
|
||||
get pxDescender() {
|
||||
return this.bbx.yoff;
|
||||
}
|
||||
|
||||
_read(input) {
|
||||
super._read(input);
|
||||
this.expand();
|
||||
return this;
|
||||
}
|
||||
|
||||
static read(input) {
|
||||
return (new Font())._read(input);
|
||||
}
|
||||
|
||||
_updateProp(name, value) {
|
||||
if (this.props.get(name) != null) {
|
||||
this.props.set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Export --
|
||||
module.exports = Object.freeze({
|
||||
Font
|
||||
});
|
||||
|
||||
// -- Params --
|
||||
class Params extends fncli.Params {
|
||||
constructor() {
|
||||
super();
|
||||
this.expandX = false;
|
||||
this.expandY = false;
|
||||
this.output = null;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Options --
|
||||
const HELP = ('' +
|
||||
'usage: bdfexp [-X] [-Y] [-o OUTPUT] [INPUT]\n' +
|
||||
'Expand BDF font bitmaps\n' +
|
||||
'\n' +
|
||||
' -X zero xoffs, set character S/DWIDTH.X from the output\n' +
|
||||
' BBX.width if needed\n' +
|
||||
' -Y enlarge FONT_ASCENT, FONT_DESCENT and PIXEL_SIZE to\n' +
|
||||
' cover the font bounding box, if needed\n' +
|
||||
' -o OUTPUT output file (default = stdout)\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'The input must be a BDF 2.1 font with unicode encoding.\n');
|
||||
|
||||
const VERSION = 'bdfexp 1.60, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE;
|
||||
|
||||
class Options extends fncli.Options {
|
||||
constructor() {
|
||||
super(['-o'], HELP, VERSION);
|
||||
}
|
||||
|
||||
parse(name, value, params) {
|
||||
switch (name) {
|
||||
case '-X':
|
||||
params.expandX = true;
|
||||
break;
|
||||
case '-Y':
|
||||
params.expandY = true;
|
||||
break;
|
||||
case '-o':
|
||||
params.output = value;
|
||||
break;
|
||||
default:
|
||||
this.fallback(name, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Main --
|
||||
function mainProgram(nonopt, parsed) {
|
||||
if (nonopt.length > 1) {
|
||||
throw new Error('invalid number of arguments, try --help');
|
||||
}
|
||||
|
||||
// READ INPUT
|
||||
let ifs = new fnio.InputFileStream(nonopt[0]);
|
||||
|
||||
try {
|
||||
var font = Font.read(ifs);
|
||||
ifs.close();
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
|
||||
// EXTRA ACTIONS
|
||||
if (parsed.expandX) {
|
||||
font.expandX();
|
||||
}
|
||||
if (parsed.expandY) {
|
||||
font.expandY();
|
||||
}
|
||||
|
||||
// WRITE OUTPUT
|
||||
let ofs = new fnio.OutputFileStream(parsed.output);
|
||||
|
||||
try {
|
||||
font.write(ofs);
|
||||
ofs.close();
|
||||
} catch (e) {
|
||||
e.message = ofs.location() + e.message() + ofs.destroy();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
fncli.start('bdfexp.js', new Options(), new Params(), mainProgram);
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
import fnutil
|
||||
import fncli
|
||||
import fnio
|
||||
import bdf
|
||||
|
||||
# -- Font --
|
||||
class Font(bdf.Font):
|
||||
def __init__(self):
|
||||
bdf.Font.__init__(self)
|
||||
self.min_width = 0 # used in proportional()
|
||||
self.avg_width = 0
|
||||
|
||||
|
||||
def _expand(self, char):
|
||||
if char.dwidth.x >= 0:
|
||||
if char.bbx.xoff >= 0:
|
||||
width = max(char.bbx.xoff + char.bbx.width, char.dwidth.x)
|
||||
dst_xoff = char.bbx.xoff
|
||||
exp_xoff = 0
|
||||
else:
|
||||
width = max(char.bbx.width, char.dwidth.x - char.bbx.xoff)
|
||||
dst_xoff = 0
|
||||
exp_xoff = char.bbx.xoff
|
||||
else:
|
||||
rev_xoff = char.bbx.xoff + char.bbx.width
|
||||
|
||||
if rev_xoff <= 0:
|
||||
width = -min(char.dwidth.x, char.bbx.xoff)
|
||||
dst_xoff = width + char.bbx.xoff
|
||||
exp_xoff = -width
|
||||
else:
|
||||
width = max(char.bbx.width, rev_xoff - char.dwidth.x)
|
||||
dst_xoff = width - char.bbx.width
|
||||
exp_xoff = rev_xoff - width
|
||||
|
||||
height = self.bbx.height
|
||||
|
||||
if width == char.bbx.width and height == char.bbx.height:
|
||||
return
|
||||
|
||||
src_row_size = char.bbx.row_size()
|
||||
dst_row_size = (width + 7) >> 3
|
||||
dst_ymax = self.px_ascender - char.bbx.yoff
|
||||
dst_ymin = dst_ymax - char.bbx.height
|
||||
copy_row = (dst_xoff & 7) == 0
|
||||
dst_data = bytearray(dst_row_size * height)
|
||||
|
||||
for dst_y in range(dst_ymin, dst_ymax):
|
||||
src_byte_no = (dst_y - dst_ymin) * src_row_size
|
||||
dst_byte_no = dst_y * dst_row_size + (dst_xoff >> 3)
|
||||
|
||||
if copy_row:
|
||||
dst_data[dst_byte_no : dst_byte_no + src_row_size] = \
|
||||
char.data[src_byte_no : src_byte_no + src_row_size]
|
||||
else:
|
||||
src_bit_no = 7
|
||||
dst_bit_no = 7 - (dst_xoff & 7)
|
||||
|
||||
for _ in range(0, char.bbx.width):
|
||||
if char.data[src_byte_no] & (1 << src_bit_no):
|
||||
dst_data[dst_byte_no] |= (1 << dst_bit_no)
|
||||
|
||||
if src_bit_no > 0:
|
||||
src_bit_no -= 1
|
||||
else:
|
||||
src_bit_no = 7
|
||||
src_byte_no += 1
|
||||
|
||||
if dst_bit_no > 0:
|
||||
dst_bit_no -= 1
|
||||
else:
|
||||
dst_bit_no = 7
|
||||
dst_byte_no += 1
|
||||
|
||||
char.bbx = bdf.BBX(width, height, exp_xoff, self.bbx.yoff)
|
||||
char.props.set('BBX', char.bbx)
|
||||
char.data = dst_data
|
||||
|
||||
|
||||
def expand(self):
|
||||
# PREXPAND / VERTICAL
|
||||
ascent = self.props.get('FONT_ASCENT')
|
||||
descent = self.props.get('FONT_DESCENT')
|
||||
px_ascent = 0 if ascent is None else fnutil.parse_dec('FONT_ASCENT', ascent, 0, bdf.DPARSE_LIMIT)
|
||||
px_descent = 0 if descent is None else fnutil.parse_dec('FONT_DESCENT', descent, 0, bdf.DPARSE_LIMIT)
|
||||
|
||||
for char in self.chars:
|
||||
px_ascent = max(px_ascent, char.bbx.height + char.bbx.yoff)
|
||||
px_descent = max(px_descent, -char.bbx.yoff)
|
||||
|
||||
self.bbx.height = px_ascent + px_descent
|
||||
self.bbx.yoff = -px_descent
|
||||
|
||||
# EXPAND / HORIZONTAL
|
||||
total_width = 0
|
||||
self.min_width = self.chars[0].bbx.width
|
||||
|
||||
for char in self.chars:
|
||||
self._expand(char)
|
||||
self.min_width = min(self.min_width, char.bbx.width)
|
||||
self.bbx.width = max(self.bbx.width, char.bbx.width)
|
||||
self.bbx.xoff = min(self.bbx.xoff, char.bbx.xoff)
|
||||
total_width += char.bbx.width
|
||||
|
||||
self.avg_width = round(total_width / len(self.chars))
|
||||
self.props.set('FONTBOUNDINGBOX', self.bbx)
|
||||
|
||||
|
||||
def expand_x(self):
|
||||
for char in self.chars:
|
||||
if char.dwidth.x != char.bbx.width:
|
||||
char.swidth.x = round(char.bbx.width * 1000 / self.bbx.height)
|
||||
char.props.set('SWIDTH', char.swidth)
|
||||
char.dwidth.x = char.bbx.width
|
||||
char.props.set('DWIDTH', char.dwidth)
|
||||
|
||||
char.bbx.xoff = 0
|
||||
char.props.set('BBX', char.bbx)
|
||||
|
||||
self.bbx.xoff = 0
|
||||
self.props.set('FONTBOUNDINGBOX', self.bbx)
|
||||
|
||||
|
||||
def expand_y(self):
|
||||
props = OrderedDict((
|
||||
('FONT_ASCENT', self.px_ascender),
|
||||
('FONT_DESCENT', -self.px_descender),
|
||||
('PIXEL_SIZE', self.bbx.height)
|
||||
))
|
||||
|
||||
for [name, value] in props.items():
|
||||
if self.props.get(name) is not None:
|
||||
self.props.set(name, value)
|
||||
|
||||
self.xlfd[bdf.XLFD.PIXEL_SIZE] = bytes(str(self.bbx.height), 'ascii')
|
||||
self.props.set('FONT', b'-'.join(self.xlfd))
|
||||
|
||||
|
||||
@property
|
||||
def proportional(self):
|
||||
return self.bbx.width > self.min_width or bdf.Font.proportional.fget(self) # pylint: disable=no-member
|
||||
|
||||
@property
|
||||
def px_ascender(self):
|
||||
return self.bbx.height + self.bbx.yoff
|
||||
|
||||
@property
|
||||
def px_descender(self):
|
||||
return self.bbx.yoff
|
||||
|
||||
|
||||
def _read(self, input):
|
||||
bdf.Font._read(self, input)
|
||||
self.expand()
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def read(input):
|
||||
return Font()._read(input) # pylint: disable=protected-access
|
||||
|
||||
|
||||
# -- Params --
|
||||
class Params(fncli.Params):
|
||||
def __init__(self):
|
||||
fncli.Params.__init__(self)
|
||||
self.expand_x = False
|
||||
self.expand_y = False
|
||||
self.output_name = None
|
||||
|
||||
|
||||
# -- Options --
|
||||
HELP = ('' +
|
||||
'usage: bdfexp [-X] [-Y] [-o OUTPUT] [INPUT]\n' +
|
||||
'Expand BDF font bitmaps\n' +
|
||||
'\n' +
|
||||
' -X zero xoffs, set character S/DWIDTH.X from the output\n' +
|
||||
' BBX.width if needed\n' +
|
||||
' -Y enlarge FONT_ASCENT, FONT_DESCENT and PIXEL_SIZE to\n' +
|
||||
' cover the font bounding box, if needed\n' +
|
||||
' -o OUTPUT output file (default = stdout)\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'The input must be a BDF 2.1 font with unicode encoding.\n')
|
||||
|
||||
VERSION = 'bdfexp 1.62, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE
|
||||
|
||||
class Options(fncli.Options):
|
||||
def __init__(self):
|
||||
fncli.Options.__init__(self, ['-o'], HELP, VERSION)
|
||||
|
||||
|
||||
def parse(self, name, value, params):
|
||||
if name == '-X':
|
||||
params.expand_x = True
|
||||
elif name == '-Y':
|
||||
params.expand_y = True
|
||||
elif name == '-o':
|
||||
params.output_name = value
|
||||
else:
|
||||
self.fallback(name, params)
|
||||
|
||||
|
||||
# -- Main --
|
||||
def main_program(nonopt, parsed):
|
||||
if len(nonopt) > 1:
|
||||
raise Exception('invalid number of arguments, try --help')
|
||||
|
||||
# READ INPUT
|
||||
font = fnio.read_file(nonopt[0] if nonopt else None, Font.read)
|
||||
|
||||
# EXTRA ACTIONS
|
||||
if parsed.expand_x:
|
||||
font.expand_x()
|
||||
|
||||
if parsed.expand_y:
|
||||
font.expand_y()
|
||||
|
||||
# WRITE OUTPUT
|
||||
fnio.write_file(parsed.output_name, lambda ofs: font.write(ofs))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fncli.start('bdfexp.py', Options(), Params(), main_program)
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
const fncli = require('./fncli.js');
|
||||
const fnio = require('./fnio.js');
|
||||
const bdf = require('./bdf.js');
|
||||
const bdfexp = require('./bdfexp.js');
|
||||
|
||||
// -- Params --
|
||||
class Params extends fncli.Params {
|
||||
constructor() {
|
||||
super();
|
||||
this.charSet = -1;
|
||||
this.minChar = -1;
|
||||
this.fntFamily = 0;
|
||||
this.output = null;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Options --
|
||||
const HELP = ('' +
|
||||
'usage: bdftofnt [-c CHARSET] [-m MINCHAR] [-f FAMILY] [-o OUTPUT] [INPUT]\n' +
|
||||
'Convert a BDF font to Windows FNT\n' +
|
||||
'\n' +
|
||||
' -c CHARSET fnt character set (default = 0, see wingdi.h ..._CHARSET)\n' +
|
||||
' -m MINCHAR fnt minimum character code (8-bit CP decimal, not unicode)\n' +
|
||||
' -f FAMILY fnt family: DontCare, Roman, Swiss, Modern or Decorative\n' +
|
||||
' -o OUTPUT output file (default = stdout, may not be a terminal)\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'The input must be a BDF 2.1 font with unicode encoding.\n');
|
||||
|
||||
const VERSION = 'bdftofnt 1.60, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE;
|
||||
|
||||
const FNT_FAMILIES = [ 'DontCare', 'Roman', 'Swiss', 'Modern', 'Decorative' ];
|
||||
|
||||
class Options extends fncli.Options {
|
||||
constructor() {
|
||||
super(['-c', '-m', '-f', '-o'], HELP, VERSION);
|
||||
}
|
||||
|
||||
parse(name, value, params) {
|
||||
switch (name) {
|
||||
case '-c':
|
||||
params.charSet = fnutil.parseDec('CHARSET', value, 0, 255);
|
||||
break;
|
||||
case '-m':
|
||||
params.minChar = fnutil.parseDec('MINCHAR', value, 0, 255);
|
||||
break;
|
||||
case '-f':
|
||||
params.fntFamily = FNT_FAMILIES.indexOf(value);
|
||||
|
||||
if (params.fntFamily === -1) {
|
||||
throw new Error('invalid FAMILY');
|
||||
}
|
||||
break;
|
||||
case '-o':
|
||||
params.output = value;
|
||||
break;
|
||||
default:
|
||||
this.fallback(name, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Main --
|
||||
const FNT_HEADER_SIZE = 118;
|
||||
const FNT_CHARSETS = [238, 204, 0, 161, 162, 177, 178, 186, 163];
|
||||
|
||||
function mainProgram(nonopt, parsed) {
|
||||
if (nonopt.length > 1) {
|
||||
throw new Error('invalid number of arguments, try --help');
|
||||
}
|
||||
|
||||
let charSet = parsed.charSet;
|
||||
let minChar = parsed.minChar;
|
||||
|
||||
// READ INPUT
|
||||
let ifs = new fnio.InputFileStream(nonopt[0]);
|
||||
|
||||
try {
|
||||
var font = bdfexp.Font.read(ifs);
|
||||
ifs.close();
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
|
||||
// COMPUTE
|
||||
if (charSet === -1) {
|
||||
const encoding = font.xlfd[bdf.XLFD.CHARSET_ENCODING];
|
||||
|
||||
if (encoding.toLowerCase().match(/^(cp)?125[0-8]$/)) {
|
||||
charSet = FNT_CHARSETS[parseInt(encoding.substring(encoding.length - 1), 10)];
|
||||
} else {
|
||||
charSet = 255;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const numChars = font.chars.length;
|
||||
|
||||
if (numChars > 256) {
|
||||
throw new Error('too many characters, the maximum is 256');
|
||||
}
|
||||
if (minChar === -1) {
|
||||
if (numChars === 192 || numChars === 256) {
|
||||
minChar = 256 - numChars;
|
||||
} else {
|
||||
minChar = font.chars[0].code;
|
||||
}
|
||||
}
|
||||
|
||||
var maxChar = minChar + numChars - 1;
|
||||
|
||||
if (maxChar >= 256) {
|
||||
throw new Error('the maximum character code is too big, (re)specify -m');
|
||||
}
|
||||
|
||||
// HEADER
|
||||
var vtell = FNT_HEADER_SIZE + (numChars + 1) * 4;
|
||||
var bitsOffset = vtell;
|
||||
var ctable = [];
|
||||
var widthBytes = 0;
|
||||
|
||||
// CTABLE/GLYPHS
|
||||
font.chars.forEach(char => {
|
||||
const rowSize = char.bbx.rowSize();
|
||||
|
||||
ctable.push(char.bbx.width);
|
||||
ctable.push(vtell);
|
||||
vtell += rowSize * font.bbx.height;
|
||||
widthBytes += rowSize;
|
||||
});
|
||||
|
||||
if (vtell > 0xFFFF) {
|
||||
throw new Error('too much character data');
|
||||
}
|
||||
|
||||
// SENTINEL
|
||||
var sentinel = 2 - widthBytes % 2;
|
||||
|
||||
ctable.push(sentinel * 8);
|
||||
ctable.push(vtell);
|
||||
vtell += sentinel * font.bbx.height;
|
||||
widthBytes += sentinel;
|
||||
|
||||
if (widthBytes > 0xFFFF) {
|
||||
throw new Error('the total character width is too big');
|
||||
}
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
|
||||
// WRITE
|
||||
let ofs = new fnio.OutputFileStream(parsed.output, null);
|
||||
|
||||
try {
|
||||
// HEADER
|
||||
const family = font.xlfd[bdf.XLFD.FAMILY_NAME];
|
||||
let copyright = font.props.get('COPYRIGHT');
|
||||
|
||||
copyright = (copyright != null) ? fnutil.unquote(copyright).substring(0, 60) : '';
|
||||
ofs.write16(0x0200); // font version
|
||||
ofs.write32(vtell + family.length + 1); // total size
|
||||
ofs.writeZStr(copyright, 60 - copyright.length);
|
||||
ofs.write16(0); // gdi, device type
|
||||
ofs.write16(fnutil.round(font.bbx.height * 72 / 96));
|
||||
ofs.write16(96); // vertical resolution
|
||||
ofs.write16(96); // horizontal resolution
|
||||
ofs.write16(font.pxAscender); // base line
|
||||
ofs.write16(0); // internal leading
|
||||
ofs.write16(0); // external leading
|
||||
ofs.write8(Number(font.italic));
|
||||
ofs.write8(0); // underline
|
||||
ofs.write8(0); // strikeout
|
||||
ofs.write16(font.bold ? 700 : 400);
|
||||
ofs.write8(charSet);
|
||||
ofs.write16(font.proportional ? 0 : font.bbx.width);
|
||||
ofs.write16(font.bbx.height);
|
||||
ofs.write8((parsed.fntFamily << 4) + Number(font.proportional));
|
||||
ofs.write16(font.avgWidth);
|
||||
ofs.write16(font.bbx.width);
|
||||
ofs.write8(minChar);
|
||||
ofs.write8(maxChar);
|
||||
|
||||
let defaultIndex = maxChar - minChar;
|
||||
let breakIndex = 0;
|
||||
|
||||
if (font.defaultCode !== -1) {
|
||||
defaultIndex = font.chars.findIndex(char => char.code === font.defaultCode);
|
||||
}
|
||||
if (minChar <= 0x20 && maxChar >= 0x20) {
|
||||
breakIndex = 0x20 - minChar;
|
||||
}
|
||||
ofs.write8(defaultIndex);
|
||||
ofs.write8(breakIndex);
|
||||
ofs.write16(widthBytes);
|
||||
ofs.write32(0); // device name
|
||||
ofs.write32(vtell);
|
||||
ofs.write32(0); // gdi bits pointer
|
||||
ofs.write32(bitsOffset);
|
||||
ofs.write8(0); // reserved
|
||||
|
||||
// CTABLE
|
||||
ctable.forEach(value => ofs.write16(value));
|
||||
|
||||
// GLYPHS
|
||||
const data = Buffer.alloc(font.bbx.height * font.bbx.rowSize());
|
||||
|
||||
font.chars.forEach(char => {
|
||||
const rowSize = char.bbx.rowSize();
|
||||
let counter = 0;
|
||||
// MS coordinates
|
||||
for (let n = 0; n < rowSize; n++) {
|
||||
for (let y = 0; y < font.bbx.height; y++) {
|
||||
data[counter++] = char.data[rowSize * y + n];
|
||||
}
|
||||
}
|
||||
ofs.write(data.slice(0, counter));
|
||||
});
|
||||
ofs.write(Buffer.alloc(sentinel * font.bbx.height));
|
||||
|
||||
// FAMILY
|
||||
ofs.writeZStr(family, 1);
|
||||
ofs.close();
|
||||
} catch (e) {
|
||||
e.message = ofs.location() + e.message + ofs.destroy();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
fncli.start('bdftofnt.js', new Options(), new Params(), mainProgram);
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import re
|
||||
|
||||
import fnutil
|
||||
import fncli
|
||||
import fnio
|
||||
import bdf
|
||||
import bdfexp
|
||||
|
||||
# -- Params --
|
||||
class Params(fncli.Params):
|
||||
def __init__(self):
|
||||
fncli.Params.__init__(self)
|
||||
self.char_set = -1
|
||||
self.min_char = -1
|
||||
self.fnt_family = 0
|
||||
self.output_name = None
|
||||
|
||||
|
||||
# -- Options --
|
||||
HELP = ('' +
|
||||
'usage: bdftofnt [-c CHARSET] [-m MINCHAR] [-f FAMILY] [-o OUTPUT] [INPUT]\n' +
|
||||
'Convert a BDF font to Windows FNT\n' +
|
||||
'\n' +
|
||||
' -c CHARSET fnt character set (default = 0, see wingdi.h ..._CHARSET)\n' +
|
||||
' -m MINCHAR fnt minimum character code (8-bit CP decimal, not unicode)\n' +
|
||||
' -f FAMILY fnt family: DontCare, Roman, Swiss, Modern or Decorative\n' +
|
||||
' -o OUTPUT output file (default = stdout, may not be a terminal)\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'The input must be a BDF 2.1 font with unicode encoding.\n')
|
||||
|
||||
VERSION = 'bdftofnt 1.62, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE
|
||||
|
||||
FNT_FAMILIES = ['DontCare', 'Roman', 'Swiss', 'Modern', 'Decorative']
|
||||
|
||||
class Options(fncli.Options):
|
||||
def __init__(self):
|
||||
fncli.Options.__init__(self, ['-c', '-m', '-f', '-o'], HELP, VERSION)
|
||||
|
||||
|
||||
def parse(self, name, value, params):
|
||||
if name == '-c':
|
||||
params.char_set = fnutil.parse_dec('CHARSET', value, 0, 255)
|
||||
elif name == '-m':
|
||||
params.min_char = fnutil.parse_dec('MINCHAR', value, 0, 255)
|
||||
elif name == '-f':
|
||||
if value in FNT_FAMILIES:
|
||||
params.fnt_family = FNT_FAMILIES.index(value)
|
||||
else:
|
||||
raise Exception('invalid FAMILY')
|
||||
elif name == '-o':
|
||||
params.output_name = value
|
||||
else:
|
||||
self.fallback(name, params)
|
||||
|
||||
|
||||
# -- Main --
|
||||
FNT_HEADER_SIZE = 118
|
||||
FNT_CHARSETS = [238, 204, 0, 161, 162, 177, 178, 186, 163]
|
||||
|
||||
def main_program(nonopt, parsed):
|
||||
if len(nonopt) > 1:
|
||||
raise Exception('invalid number of arguments, try --help')
|
||||
|
||||
char_set = parsed.char_set
|
||||
min_char = parsed.min_char
|
||||
|
||||
# READ INPUT
|
||||
ifs = fnio.InputFileStream(nonopt[0] if nonopt else None)
|
||||
font = ifs.process(bdfexp.Font.read)
|
||||
|
||||
# COMPUTE
|
||||
if char_set == -1:
|
||||
encoding = font.xlfd[bdf.XLFD.CHARSET_ENCODING]
|
||||
|
||||
if re.fullmatch(b'(cp)?125[0-8]', encoding.lower()):
|
||||
char_set = FNT_CHARSETS[int(encoding[-1:])]
|
||||
else:
|
||||
char_set = 255
|
||||
|
||||
try:
|
||||
num_chars = len(font.chars)
|
||||
|
||||
if num_chars > 256:
|
||||
raise Exception('too many characters, the maximum is 256')
|
||||
|
||||
if min_char == -1:
|
||||
if num_chars in [192, 256]:
|
||||
min_char = 256 - num_chars
|
||||
else:
|
||||
min_char = font.chars[0].code
|
||||
|
||||
max_char = min_char + num_chars - 1
|
||||
|
||||
if max_char >= 256:
|
||||
raise Exception('the maximum character code is too big, (re)specify -m')
|
||||
|
||||
# HEADER
|
||||
vtell = FNT_HEADER_SIZE + (num_chars + 1) * 4
|
||||
bits_offset = vtell
|
||||
ctable = []
|
||||
width_bytes = 0
|
||||
|
||||
# CTABLE/GLYPHS
|
||||
for char in font.chars:
|
||||
row_size = char.bbx.row_size()
|
||||
ctable.append(char.bbx.width)
|
||||
ctable.append(vtell)
|
||||
vtell += row_size * font.bbx.height
|
||||
width_bytes += row_size
|
||||
|
||||
if vtell > 0xFFFF:
|
||||
raise Exception('too much character data')
|
||||
|
||||
# SENTINEL
|
||||
sentinel = 2 - width_bytes % 2
|
||||
ctable.append(sentinel * 8)
|
||||
ctable.append(vtell)
|
||||
vtell += sentinel * font.bbx.height
|
||||
width_bytes += sentinel
|
||||
|
||||
if width_bytes > 0xFFFF:
|
||||
raise Exception('the total character width is too big')
|
||||
|
||||
except Exception as ex:
|
||||
ex.message = ifs.location() + getattr(ex, 'message', str(ex))
|
||||
raise
|
||||
|
||||
# WRITE
|
||||
def write_fnt(output):
|
||||
# HEADER
|
||||
family = font.xlfd[bdf.XLFD.FAMILY_NAME]
|
||||
copyright = font.props.get('COPYRIGHT')
|
||||
copyright = fnutil.unquote(copyright)[:60] if copyright is not None else b''
|
||||
|
||||
output.write16(0x0200) # font version
|
||||
output.write32(vtell + len(family) + 1) # total size
|
||||
output.write_zstr(copyright, 60 - len(copyright))
|
||||
output.write16(0) # gdi, device type
|
||||
output.write16(round(font.bbx.height * 72 / 96))
|
||||
output.write16(96) # vertical resolution
|
||||
output.write16(96) # horizontal resolution
|
||||
output.write16(font.px_ascender) # base line
|
||||
output.write16(0) # internal leading
|
||||
output.write16(0) # external leading
|
||||
output.write8(int(font.italic))
|
||||
output.write8(0) # underline
|
||||
output.write8(0) # strikeout
|
||||
output.write16(700 if font.bold else 400)
|
||||
output.write8(char_set)
|
||||
output.write16(0 if font.proportional else font.bbx.width)
|
||||
output.write16(font.bbx.height)
|
||||
output.write8((parsed.fnt_family << 4) + int(font.proportional))
|
||||
output.write16(font.avg_width)
|
||||
output.write16(font.bbx.width)
|
||||
output.write8(min_char)
|
||||
output.write8(max_char)
|
||||
|
||||
default_index = max_char - min_char
|
||||
break_index = 0
|
||||
|
||||
if font.default_code != -1:
|
||||
default_index = next(index for index, char in enumerate(font.chars) if char.code == font.default_code)
|
||||
|
||||
if min_char <= 0x20 <= max_char:
|
||||
break_index = 0x20 - min_char
|
||||
|
||||
output.write8(default_index)
|
||||
output.write8(break_index)
|
||||
output.write16(width_bytes)
|
||||
output.write32(0) # device name
|
||||
output.write32(vtell)
|
||||
output.write32(0) # gdi bits pointer
|
||||
output.write32(bits_offset)
|
||||
output.write8(0) # reserved
|
||||
|
||||
# CTABLE
|
||||
for value in ctable:
|
||||
output.write16(value)
|
||||
|
||||
# GLYPHS
|
||||
data = bytearray(font.bbx.height * font.bbx.row_size())
|
||||
|
||||
for char in font.chars:
|
||||
row_size = char.bbx.row_size()
|
||||
counter = 0
|
||||
# MS coordinates
|
||||
for n in range(0, row_size):
|
||||
for y in range(0, font.bbx.height):
|
||||
data[counter] = char.data[row_size * y + n]
|
||||
counter += 1
|
||||
output.write(data[:counter])
|
||||
output.write(bytes(sentinel * font.bbx.height))
|
||||
|
||||
# FAMILY
|
||||
output.write_zstr(family, 1)
|
||||
|
||||
fnio.write_file(parsed.output_name, write_fnt, encoding=None)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fncli.start('bdftofnt.py', Options(), Params(), main_program)
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
Copyright (C) 2017-2019 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
const fncli = require('./fncli.js');
|
||||
const fnio = require('./fnio.js');
|
||||
const bdfexp = require('./bdfexp.js');
|
||||
|
||||
// -- Params --
|
||||
class Params extends fncli.Params {
|
||||
constructor() {
|
||||
super();
|
||||
this.version = -1;
|
||||
this.exchange = -1;
|
||||
this.output = null;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Options --
|
||||
const HELP = ('' +
|
||||
'usage: bdftopsf [-1|-2|-r] [-g|-G] [-o OUTPUT] [INPUT.bdf] [TABLE...]\n' +
|
||||
'Convert a BDF font to PC Screen Font or raw font\n' +
|
||||
'\n' +
|
||||
' -1, -2 write a PSF version 1 or 2 font (default = 1 if possible)\n' +
|
||||
' -r, --raw write a RAW font\n' +
|
||||
' -g, --vga exchange the characters at positions 0...31 with these at\n' +
|
||||
' 192...223 (default for VGA text mode compliant PSF fonts\n' +
|
||||
' with 224 to 512 characters starting with unicode 00A3)\n' +
|
||||
' -G do not exchange characters 0...31 and 192...223\n' +
|
||||
' -o OUTPUT output file (default = stdout, may not be a terminal)\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'The input must be a monospaced unicode-encoded BDF 2.1 font.\n' +
|
||||
'\n' +
|
||||
'The tables are text files with two or more hexadecimal unicodes per line:\n' +
|
||||
'a character code from the BDF, and extra code(s) for it. All extra codes\n' +
|
||||
'are stored sequentially in the PSF unicode table for their character.\n' +
|
||||
'<ss> is always specified as FFFE, although it is stored as FE in PSF2.\n');
|
||||
|
||||
const VERSION = 'bdftopsf 1.58, Copyright (C) 2017-2019 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_VERSION;
|
||||
|
||||
class Options extends fncli.Options {
|
||||
constructor() {
|
||||
super(['-o'], HELP, VERSION);
|
||||
}
|
||||
|
||||
parse(name, value, params) {
|
||||
switch (name) {
|
||||
case '-1':
|
||||
case '-2':
|
||||
params.version = parseInt(name[1]);
|
||||
break;
|
||||
case '-r':
|
||||
case '--raw':
|
||||
params.version = 0;
|
||||
break;
|
||||
case '-g':
|
||||
case '--vga':
|
||||
params.exchange = true;
|
||||
break;
|
||||
case '-G':
|
||||
params.exchange = false;
|
||||
break;
|
||||
case '-o':
|
||||
params.output = value;
|
||||
break;
|
||||
default:
|
||||
this.fallback(name, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Main --
|
||||
function mainProgram(nonopt, parsed) {
|
||||
const bdfile = nonopt.length > 0 && nonopt[0].toLowerCase().endsWith('.bdf');
|
||||
let version = parsed.version;
|
||||
let exchange = parsed.exchange;
|
||||
let ver1Unicodes = true;
|
||||
|
||||
// READ INPUT
|
||||
let ifs = new fnio.InputFileStream(bdfile ? nonopt[0] : null);
|
||||
|
||||
try {
|
||||
var font = bdfexp.Font.read(ifs);
|
||||
|
||||
ifs.close();
|
||||
font.chars.forEach(char => {
|
||||
const prefix = `char ${char.code}: `;
|
||||
|
||||
if (char.bbx.width !== font.bbx.width) {
|
||||
throw new Error(prefix + 'output width not equal to maximum output width');
|
||||
}
|
||||
if (char.code === 65534) {
|
||||
throw new Error(prefix + 'not a character, use 65535 for empty position');
|
||||
}
|
||||
if (char.code >= 65536) {
|
||||
if (version === 1) {
|
||||
throw new Error(prefix + '-1 requires unicodes <= 65535');
|
||||
}
|
||||
ver1Unicodes = false;
|
||||
}
|
||||
});
|
||||
|
||||
// VERSION
|
||||
var ver1NumChars = (font.chars.length === 256 || font.chars.length === 512);
|
||||
|
||||
if (version === 1) {
|
||||
if (!ver1NumChars) {
|
||||
throw new Error('-1 requires a font with 256 or 512 characters');
|
||||
}
|
||||
if (font.bbx.width !== 8) {
|
||||
throw new Error('-1 requires a font with width 8');
|
||||
}
|
||||
}
|
||||
|
||||
// EXCHANGE
|
||||
var vgaNumChars = font.chars.length >= 224 && font.chars.length <= 512;
|
||||
var vgaTextSize = font.bbx.width === 8 && [8, 14, 16].indexOf(font.bbx.height) !== -1;
|
||||
|
||||
if (exchange === true) {
|
||||
if (!vgaNumChars) {
|
||||
throw new Error('-g/--vga requires a font with 224...512 characters');
|
||||
}
|
||||
if (!vgaTextSize) {
|
||||
throw new Error('-g/--vga requires an 8x8, 8x14 or 8x16 font');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
|
||||
// READ TABLES
|
||||
let tables = [];
|
||||
|
||||
function loadExtra(line) {
|
||||
const words = line.split(/\s+/);
|
||||
|
||||
if (words.length < 2) {
|
||||
throw new Error('invalid format');
|
||||
}
|
||||
|
||||
const uni = fnutil.parseHex('unicode', words[0]);
|
||||
let table = tables[uni];
|
||||
|
||||
if (uni === 0xFFFE) {
|
||||
throw new Error('FFFE is not a character');
|
||||
}
|
||||
|
||||
if (font.chars.findIndex(char => char.code === uni) !== -1) {
|
||||
if (uni > fnutil.UNICODE_BMP_MAX) {
|
||||
ver1Unicodes = false;
|
||||
}
|
||||
if (table == null) {
|
||||
table = tables[uni] = [];
|
||||
}
|
||||
|
||||
words.slice(1).forEach(word => {
|
||||
const dup = fnutil.parseHex('extra code', word);
|
||||
|
||||
if (dup === 0xFFFF) {
|
||||
throw new Error('FFFF is not a character');
|
||||
}
|
||||
if (dup > fnutil.UNICODE_BMP_MAX) {
|
||||
ver1Unicodes = false;
|
||||
}
|
||||
if (table.indexOf(dup) === -1 || table.indexOf(0xFFFE) !== -1) {
|
||||
table.push(dup);
|
||||
}
|
||||
});
|
||||
if (version === 1 && !ver1Unicodes) {
|
||||
throw new Error('-1 requires unicodes <= ' + fnutil.UNICODE_BMP_MAX.toString(16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonopt.slice(Number(bdfile)).forEach(name => {
|
||||
ifs = new fnio.InputFileStream(name);
|
||||
|
||||
try {
|
||||
ifs.readLines(loadExtra);
|
||||
ifs.close();
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
// VERSION
|
||||
if (version === -1) {
|
||||
version = ver1NumChars && ver1Unicodes && font.bbx.width === 8 ? 1 : 2;
|
||||
}
|
||||
|
||||
// EXCHANGE
|
||||
if (exchange === -1) {
|
||||
exchange = vgaTextSize && version >= 1 && vgaNumChars && font.chars[0].code === 0x00A3;
|
||||
}
|
||||
|
||||
if (exchange) {
|
||||
const control = font.chars.splice(0, 32, ...font.chars.splice(192, 32));
|
||||
font.chars.splice(192, 0, ...control);
|
||||
}
|
||||
|
||||
// WRITE
|
||||
let ofs = new fnio.OutputFileStream(parsed.output, null);
|
||||
|
||||
try {
|
||||
// HEADER
|
||||
if (version === 1) {
|
||||
ofs.write8(0x36);
|
||||
ofs.write8(0x04);
|
||||
ofs.write8((font.chars.length >> 8) + 1);
|
||||
ofs.write8(font.bbx.height);
|
||||
} else if (version === 2) {
|
||||
ofs.write32(0x864AB572);
|
||||
ofs.write32(0x00000000);
|
||||
ofs.write32(0x00000020);
|
||||
ofs.write32(0x00000001);
|
||||
ofs.write32(font.chars.length);
|
||||
ofs.write32(font.chars[0].data.length);
|
||||
ofs.write32(font.bbx.height);
|
||||
ofs.write32(font.bbx.width);
|
||||
}
|
||||
|
||||
// GLYPHS
|
||||
font.chars.forEach(char => ofs.write(char.data));
|
||||
|
||||
// UNICODES
|
||||
if (version > 0) {
|
||||
const writeUnicode = function(code) {
|
||||
if (version === 1) {
|
||||
ofs.write16(code);
|
||||
} else if (code <= 0x7F) {
|
||||
ofs.write8(code);
|
||||
} else if (code === 0xFFFE || code === 0xFFFF) {
|
||||
ofs.write8(code & 0xFF);
|
||||
} else {
|
||||
if (code <= 0x7FF) {
|
||||
ofs.write8(0xC0 + (code >> 6));
|
||||
} else {
|
||||
if (code <= 0xFFFF) {
|
||||
ofs.write8(0xE0 + (code >> 12));
|
||||
} else {
|
||||
ofs.write8(0xF0 + (code >> 18));
|
||||
ofs.write8(0x80 + ((code >> 12) & 0x3F));
|
||||
}
|
||||
ofs.write8(0x80 + ((code >> 6) & 0x3F));
|
||||
}
|
||||
ofs.write8(0x80 + (code & 0x3F));
|
||||
}
|
||||
};
|
||||
|
||||
font.chars.forEach(char => {
|
||||
if (char.code !== 0xFFFF) {
|
||||
writeUnicode(char.code);
|
||||
}
|
||||
if (tables[char.code] != null) {
|
||||
tables[char.code].forEach(extra => writeUnicode(extra));
|
||||
}
|
||||
writeUnicode(0xFFFF);
|
||||
});
|
||||
}
|
||||
|
||||
// FINISH
|
||||
ofs.close();
|
||||
} catch (e) {
|
||||
e.message = ofs.location() + e.message + ofs.destroy();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
fncli.start('bdftopsf.js', new Options(), new Params(), mainProgram);
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import fnutil
|
||||
import fncli
|
||||
import fnio
|
||||
import bdfexp
|
||||
|
||||
# -- Params --
|
||||
class Params(fncli.Params):
|
||||
def __init__(self):
|
||||
fncli.Params.__init__(self)
|
||||
self.version = -1
|
||||
self.exchange = -1
|
||||
self.output_name = None
|
||||
|
||||
|
||||
# -- Options --
|
||||
HELP = ('' +
|
||||
'usage: bdftopsf [-1|-2|-r] [-g|-G] [-o OUTPUT] [INPUT.bdf] [TABLE...]\n' +
|
||||
'Convert a BDF font to PC Screen Font or raw font\n' +
|
||||
'\n' +
|
||||
' -1, -2 write a PSF version 1 or 2 font (default = 1 if possible)\n' +
|
||||
' -r, --raw write a RAW font\n' +
|
||||
' -g, --vga exchange the characters at positions 0...31 with these at\n' +
|
||||
' 192...223 (default for VGA text mode compliant PSF fonts\n' +
|
||||
' with 224 to 512 characters starting with unicode 00A3)\n' +
|
||||
' -G do not exchange characters 0...31 and 192...223\n' +
|
||||
' -o OUTPUT output file (default = stdout, may not be a terminal)\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'The input must be a monospaced unicode-encoded BDF 2.1 font.\n' +
|
||||
'\n' +
|
||||
'The tables are text files with two or more hexadecimal unicodes per line:\n' +
|
||||
'a character code from the BDF, and extra code(s) for it. All extra codes\n' +
|
||||
'are stored sequentially in the PSF unicode table for their character.\n' +
|
||||
'<ss> is always specified as FFFE, although it is stored as FE in PSF2.\n')
|
||||
|
||||
VERSION = 'bdftopsf 1.62, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE
|
||||
|
||||
class Options(fncli.Options):
|
||||
def __init__(self):
|
||||
fncli.Options.__init__(self, ['-o'], HELP, VERSION)
|
||||
|
||||
|
||||
def parse(self, name, value, params):
|
||||
if name in ['-1', '-2']:
|
||||
params.version = int(name[1])
|
||||
elif name in ['-r', '--raw']:
|
||||
params.version = 0
|
||||
elif name in ['-g', '--vga']:
|
||||
params.exchange = True
|
||||
elif name == '-G':
|
||||
params.exchange = False
|
||||
elif name == '-o':
|
||||
params.output_name = value
|
||||
else:
|
||||
self.fallback(name, params)
|
||||
|
||||
|
||||
# -- Main --
|
||||
def main_program(nonopt, parsed):
|
||||
version = parsed.version
|
||||
exchange = parsed.exchange
|
||||
bdfile = len(nonopt) > 0 and nonopt[0].lower().endswith('.bdf')
|
||||
ver1_unicodes = True
|
||||
|
||||
# READ INPUT
|
||||
ifs = fnio.InputFileStream(nonopt[0] if bdfile else None)
|
||||
font = ifs.process(bdfexp.Font.read)
|
||||
|
||||
try:
|
||||
for char in font.chars:
|
||||
prefix = 'char %d: ' % char.code
|
||||
|
||||
if char.bbx.width != font.bbx.width:
|
||||
raise Exception(prefix + 'output width not equal to maximum output width')
|
||||
|
||||
if char.code == 65534:
|
||||
raise Exception(prefix + 'not a character, use 65535 for empty position')
|
||||
|
||||
if char.code >= 65536:
|
||||
if version == 1:
|
||||
raise Exception(prefix + '-1 requires unicodes <= 65535')
|
||||
ver1_unicodes = False
|
||||
|
||||
# VERSION
|
||||
ver1_num_chars = len(font.chars) == 256 or len(font.chars) == 512
|
||||
|
||||
if version == 1:
|
||||
if not ver1_num_chars:
|
||||
raise Exception('-1 requires a font with 256 or 512 characters')
|
||||
|
||||
if font.bbx.width != 8:
|
||||
raise Exception('-1 requires a font with width 8')
|
||||
|
||||
# EXCHANGE
|
||||
vga_num_chars = len(font.chars) >= 224 and len(font.chars) <= 512
|
||||
vga_text_size = font.bbx.width == 8 and font.bbx.height in [8, 14, 16]
|
||||
|
||||
if exchange is True:
|
||||
if not vga_num_chars:
|
||||
raise Exception('-g/--vga requires a font with 224...512 characters')
|
||||
|
||||
if not vga_text_size:
|
||||
raise Exception('-g/--vga requires an 8x8, 8x14 or 8x16 font')
|
||||
|
||||
except Exception as ex:
|
||||
ex.message = ifs.location() + getattr(ex, 'message', str(ex))
|
||||
raise
|
||||
|
||||
# READ TABLES
|
||||
tables = dict()
|
||||
|
||||
def load_extra(line):
|
||||
nonlocal ver1_unicodes
|
||||
words = line.split()
|
||||
|
||||
if len(words) < 2:
|
||||
raise Exception('invalid format')
|
||||
|
||||
uni = fnutil.parse_hex('unicode', words[0])
|
||||
|
||||
if uni == 0xFFFE:
|
||||
raise Exception('FFFE is not a character')
|
||||
|
||||
if next((char for char in font.chars if char.code == uni), None):
|
||||
if uni > fnutil.UNICODE_BMP_MAX:
|
||||
ver1_unicodes = False
|
||||
|
||||
if uni not in tables:
|
||||
tables[uni] = []
|
||||
|
||||
table = tables[uni]
|
||||
|
||||
for word in words[1:]:
|
||||
dup = fnutil.parse_hex('extra code', word)
|
||||
|
||||
if dup == 0xFFFF:
|
||||
raise Exception('FFFF is not a character')
|
||||
|
||||
if dup > fnutil.UNICODE_BMP_MAX:
|
||||
ver1_unicodes = False
|
||||
|
||||
if not dup in table or 0xFFFE in table:
|
||||
tables[uni].append(dup)
|
||||
|
||||
if version == 1 and not ver1_unicodes:
|
||||
raise Exception('-1 requires unicodes <= %X' % fnutil.UNICODE_BMP_MAX)
|
||||
|
||||
for table_name in nonopt[int(bdfile):]:
|
||||
fnio.read_file(table_name, lambda ifs: ifs.read_lines(load_extra))
|
||||
|
||||
# VERSION
|
||||
if version == -1:
|
||||
version = 1 if ver1_num_chars and ver1_unicodes and font.bbx.width == 8 else 2
|
||||
|
||||
# EXCHANGE
|
||||
if exchange == -1:
|
||||
exchange = vga_text_size and version >= 1 and vga_num_chars and font.chars[0].code == 0x00A3
|
||||
|
||||
if exchange:
|
||||
font.chars = font.chars[192:224] + font.chars[32:192] + font.chars[0:32] + font.chars[224:]
|
||||
|
||||
# WRITE
|
||||
def write_psf(output):
|
||||
# HEADER
|
||||
if version == 1:
|
||||
output.write8(0x36)
|
||||
output.write8(0x04)
|
||||
output.write8((len(font.chars) >> 8) + 1)
|
||||
output.write8(font.bbx.height)
|
||||
elif version == 2:
|
||||
output.write32(0x864AB572)
|
||||
output.write32(0x00000000)
|
||||
output.write32(0x00000020)
|
||||
output.write32(0x00000001)
|
||||
output.write32(len(font.chars))
|
||||
output.write32(len(font.chars[0].data))
|
||||
output.write32(font.bbx.height)
|
||||
output.write32(font.bbx.width)
|
||||
|
||||
# GLYPHS
|
||||
for char in font.chars:
|
||||
output.write(char.data)
|
||||
|
||||
# UNICODES
|
||||
if version > 0:
|
||||
def write_unicode(code):
|
||||
if version == 1:
|
||||
output.write16(code)
|
||||
elif code <= 0x7F:
|
||||
output.write8(code)
|
||||
elif code in [0xFFFE, 0xFFFF]:
|
||||
output.write8(code & 0xFF)
|
||||
else:
|
||||
if code <= 0x7FF:
|
||||
output.write8(0xC0 + (code >> 6))
|
||||
else:
|
||||
if code <= 0xFFFF:
|
||||
output.write8(0xE0 + (code >> 12))
|
||||
else:
|
||||
output.write8(0xF0 + (code >> 18))
|
||||
output.write8(0x80 + ((code >> 12) & 0x3F))
|
||||
|
||||
output.write8(0x80 + ((code >> 6) & 0x3F))
|
||||
|
||||
output.write8(0x80 + (code & 0x3F))
|
||||
|
||||
for char in font.chars:
|
||||
if char.code != 0xFFFF:
|
||||
write_unicode(char.code)
|
||||
|
||||
if char.code in tables:
|
||||
for extra in tables[char.code]:
|
||||
write_unicode(extra)
|
||||
|
||||
write_unicode(0xFFFF)
|
||||
|
||||
fnio.write_file(parsed.output_name, write_psf, encoding=None)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fncli.start('bdftopsf.py', Options(), Params(), main_program)
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
Copyright (C) 2018-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// -- Params --
|
||||
class Params {
|
||||
constructor() {
|
||||
this.excstk = false;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Options --
|
||||
class Options {
|
||||
constructor(needArgs, helpText, versionText) {
|
||||
needArgs.forEach(name => {
|
||||
if (!name.match(/^(-[^-]|--[^=]+)$/)) {
|
||||
throw new Error(`invalid option name "${name}"`);
|
||||
}
|
||||
});
|
||||
this.needArgs = needArgs;
|
||||
this.helpText = helpText;
|
||||
this.versionText = versionText;
|
||||
}
|
||||
|
||||
posixlyCorrect() { // eslint-disable-line class-methods-use-this
|
||||
return process.env['POSIXLY_CORRECT'] != null;
|
||||
}
|
||||
|
||||
needsArg(name) {
|
||||
return this.needArgs.includes(name);
|
||||
}
|
||||
|
||||
fallback(name, params) {
|
||||
if (name === '--excstk') {
|
||||
params.excstk = true;
|
||||
} else if (name === '--help' && this.helpText != null) {
|
||||
process.stdout.write(this.helpText);
|
||||
process.exit(0);
|
||||
} else if (name === '--version' && this.versionText != null) {
|
||||
process.stdout.write(this.versionText);
|
||||
process.exit(0);
|
||||
} else {
|
||||
let suffix = this.needsArg(name) ? ' (taking an argument?)' : '';
|
||||
|
||||
suffix += (this.helpText != null) ? ', try --help' : '';
|
||||
throw new Error(`unknown option "${name}"${suffix}`);
|
||||
}
|
||||
}
|
||||
|
||||
reader(args, skip = 2) {
|
||||
return new Options.Reader(this, args, skip);
|
||||
}
|
||||
}
|
||||
|
||||
Options.Reader = class {
|
||||
constructor(options, args, skip) {
|
||||
this.options = options;
|
||||
this.args = args;
|
||||
this.skip = skip;
|
||||
}
|
||||
|
||||
forEach(callback) {
|
||||
let optind;
|
||||
|
||||
for (optind = this.skip; optind < this.args.length; optind++) {
|
||||
let arg = this.args[optind];
|
||||
|
||||
if (arg === '-' || !arg.startsWith('-')) {
|
||||
if (this.options.posixlyCorrect()) {
|
||||
break;
|
||||
}
|
||||
callback(null, arg);
|
||||
} else if (arg === '--') {
|
||||
optind++;
|
||||
break;
|
||||
} else {
|
||||
let name, value;
|
||||
|
||||
if (!arg.startsWith('--')) {
|
||||
for (;;) {
|
||||
name = arg.substring(0, 2);
|
||||
value = (name !== arg) ? arg.substring(2) : null;
|
||||
|
||||
if (this.options.needsArg(name) || value == null) {
|
||||
break;
|
||||
}
|
||||
callback(name, null);
|
||||
arg = '-' + value;
|
||||
}
|
||||
} else if (arg.indexOf('=') >= 3) {
|
||||
name = arg.split('=', 1)[0];
|
||||
if (!this.options.needsArg(name)) {
|
||||
throw new Error(`option "${name}" does not take an argument`);
|
||||
}
|
||||
value = arg.substring(name.length + 1);
|
||||
} else {
|
||||
name = arg;
|
||||
value = null;
|
||||
}
|
||||
|
||||
if (value == null && Number(this.options.needsArg(name)) > 0) {
|
||||
if (++optind === this.args.length) {
|
||||
throw new Error(`option "${name}" requires an argument`);
|
||||
}
|
||||
value = this.args[optind];
|
||||
}
|
||||
callback(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
this.args.slice(optind).forEach(value => callback(null, value));
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(Options, 'Reader', { 'enumerable': false });
|
||||
Object.defineProperty(Options.Reader, 'name', { value: 'Reader' });
|
||||
|
||||
// -- Main --
|
||||
function start(programName, options, params, mainProgram) { // eslint-disable-line consistent-return
|
||||
const parsed = (params != null) ? params : new Params();
|
||||
|
||||
try {
|
||||
const version = process.version.match(/^v?(\d+)\.(\d+)/);
|
||||
|
||||
if (version.length < 3) {
|
||||
throw new Error('unable to obtain node version');
|
||||
} else if ((parseInt(version[1]) * 1000 + parseInt(version[2])) < 6009) {
|
||||
throw new Error('node version 6.9.0 or later required');
|
||||
}
|
||||
|
||||
if (params == null) {
|
||||
return mainProgram(options.reader(process.argv), name => options.fallback(name, parsed));
|
||||
} else {
|
||||
let nonopt = [];
|
||||
|
||||
options.reader(process.argv).forEach((name, value) => {
|
||||
if (name == null) {
|
||||
nonopt.push(value);
|
||||
} else {
|
||||
options.parse(name, value, parsed);
|
||||
}
|
||||
});
|
||||
return mainProgram(nonopt, parsed);
|
||||
}
|
||||
} catch (e) {
|
||||
if (parsed.excstk) {
|
||||
if (e.stack != null) {
|
||||
process.stderr.write(e.stack + '\n');
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
process.stderr.write(`${process.argv.length >= 2 ? process.argv[1] : programName}: ${e.message}\n`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// -- Exports --
|
||||
module.exports = Object.freeze({
|
||||
Params,
|
||||
Options,
|
||||
start
|
||||
});
|
||||
@@ -0,0 +1,162 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
# -- Params --
|
||||
class Params:
|
||||
def __init__(self):
|
||||
self.excstk = False
|
||||
|
||||
|
||||
# -- Options --
|
||||
class Options:
|
||||
def __init__(self, need_args, help_text, version_text):
|
||||
for name in need_args:
|
||||
if not re.fullmatch('(-[^-]|--[^=]+)', name):
|
||||
raise Exception('invalid option name "%s"' % name)
|
||||
|
||||
self.need_args = need_args
|
||||
self.help_text = help_text
|
||||
self.version_text = version_text
|
||||
|
||||
|
||||
def posixly_correct(self): # pylint: disable=no-self-use
|
||||
return 'POSIXLY_CORRECT' in os.environ
|
||||
|
||||
|
||||
def needs_arg(self, name):
|
||||
return name in self.need_args
|
||||
|
||||
|
||||
def fallback(self, name, params):
|
||||
if name == '--excstk':
|
||||
params.excstk = True
|
||||
elif name == '--help' and self.help_text is not None:
|
||||
sys.stdout.write(self.help_text)
|
||||
sys.exit(0)
|
||||
elif name == '--version' and self.version_text is not None:
|
||||
sys.stdout.write(self.version_text)
|
||||
sys.exit(0)
|
||||
else:
|
||||
suffix = ' (taking an argument?)' if self.needs_arg(name) else ''
|
||||
suffix += ', try --help' if self.help_text is not None else ''
|
||||
raise Exception('unknown option "%s"%s' % (name, suffix))
|
||||
|
||||
|
||||
def reader(self, args, skip_zero=True):
|
||||
return Options.Reader(self, args, skip_zero)
|
||||
|
||||
|
||||
class Reader:
|
||||
def __init__(self, options, args, skip_zero):
|
||||
self.options = options
|
||||
self.args = args
|
||||
self.skip_zero = skip_zero
|
||||
|
||||
|
||||
def __iter__(self):
|
||||
return Options.Reader.Iterator(self)
|
||||
|
||||
|
||||
class Iterator:
|
||||
def __init__(self, reader):
|
||||
self.options = reader.options
|
||||
self.args = reader.args
|
||||
self.optind = int(reader.skip_zero)
|
||||
self.chrind = 1
|
||||
self.endopt = False
|
||||
|
||||
|
||||
def __next__(self):
|
||||
if self.chrind == 0:
|
||||
self.optind += 1
|
||||
self.chrind = 1
|
||||
|
||||
if self.optind == len(self.args):
|
||||
raise StopIteration
|
||||
|
||||
arg = self.args[self.optind]
|
||||
|
||||
if self.endopt or arg == '-' or not arg.startswith('-'):
|
||||
self.endopt = self.options.posixly_correct()
|
||||
name = None
|
||||
value = arg
|
||||
elif arg == '--':
|
||||
self.chrind = 0
|
||||
self.endopt = True
|
||||
return next(self)
|
||||
elif not arg.startswith('--'):
|
||||
name = '-' + arg[self.chrind]
|
||||
self.chrind += 1
|
||||
if self.chrind < len(arg):
|
||||
if not self.options.needs_arg(name):
|
||||
return (name, None)
|
||||
value = arg[self.chrind:]
|
||||
else:
|
||||
value = None
|
||||
elif '=' in arg and arg.index('=') >= 3:
|
||||
name = arg.split('=', 1)[0]
|
||||
if not self.options.needs_arg(name):
|
||||
raise Exception('option "%s" does not take an argument' % name)
|
||||
value = arg[len(name) + 1:]
|
||||
else:
|
||||
name = arg
|
||||
value = None
|
||||
|
||||
if value is None and int(self.options.needs_arg(name)) > 0:
|
||||
self.optind += 1
|
||||
if self.optind == len(self.args):
|
||||
raise Exception('option "%s" requires an argument' % name)
|
||||
value = self.args[self.optind]
|
||||
|
||||
self.chrind = 0
|
||||
return (name, value)
|
||||
|
||||
|
||||
# -- Main --
|
||||
def start(program_name, options, params, main_program):
|
||||
parsed = Params() if params is None else params
|
||||
|
||||
try:
|
||||
|
||||
if sys.hexversion < 0x3050000:
|
||||
raise Exception('python 3.5.0 or later required')
|
||||
|
||||
if params is None:
|
||||
return main_program(options.reader(sys.argv), lambda name: options.fallback(name, parsed))
|
||||
|
||||
nonopt = []
|
||||
|
||||
for [name, value] in options.reader(sys.argv):
|
||||
if name is None:
|
||||
nonopt.append(value)
|
||||
else:
|
||||
options.parse(name, value, parsed)
|
||||
|
||||
return main_program(nonopt, parsed)
|
||||
|
||||
except Exception as ex:
|
||||
if parsed.excstk:
|
||||
raise # loses the message information, but preserves the start() caller stack info
|
||||
|
||||
message = getattr(ex, 'message', str(ex))
|
||||
sys.stderr.write('%s: %s\n' % (sys.argv[0] if sys.argv[0] else program_name, message))
|
||||
sys.exit(1)
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const tty = require('tty');
|
||||
const fs = require('fs');
|
||||
|
||||
// -- InputFileStream --
|
||||
const BLOCK_SIZE = 4096;
|
||||
|
||||
class InputFileStream {
|
||||
constructor(fileName, encoding = 'binary') {
|
||||
if (fileName != null) {
|
||||
this.fd = fs.openSync(fileName, 'r');
|
||||
this.stName = fileName;
|
||||
} else {
|
||||
this.fd = process.stdin.fd;
|
||||
this.stName = '<stdin>';
|
||||
}
|
||||
this.encoding = encoding;
|
||||
this.unseek();
|
||||
this.lines = [];
|
||||
this.index = 0;
|
||||
this.buffer = Buffer.alloc(BLOCK_SIZE);
|
||||
this.remainder = '';
|
||||
}
|
||||
|
||||
close() {
|
||||
this.unseek();
|
||||
fs.closeSync(this.fd);
|
||||
}
|
||||
|
||||
fstat() {
|
||||
return (this.fd === process.stdin.fd || tty.isatty(this.fd)) ? null : fs.fstatSync(this.fd);
|
||||
}
|
||||
|
||||
location() {
|
||||
let location = ' ';
|
||||
|
||||
if (this.eof) {
|
||||
location = 'EOF: ';
|
||||
} else if (this.lineNo > 0) {
|
||||
location = `${this.lineNo}: `;
|
||||
|
||||
}
|
||||
return `${this.stName}:${location}`;
|
||||
}
|
||||
|
||||
_readBlock() {
|
||||
for (;;) {
|
||||
try {
|
||||
return fs.readSync(this.fd, this.buffer, 0, BLOCK_SIZE);
|
||||
} catch (e) {
|
||||
if (e.code === 'EOF') {
|
||||
return 0;
|
||||
}
|
||||
if (e.code !== 'EAGAIN') {
|
||||
this.unseek();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readLine() {
|
||||
return this.readLines(line => line);
|
||||
}
|
||||
|
||||
readLines(callback) {
|
||||
let line;
|
||||
|
||||
do {
|
||||
while (this.index < this.lines.length) {
|
||||
this.lineNo++;
|
||||
line = callback(this.lines[this.index++].trimRight());
|
||||
|
||||
if (line != null) {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
|
||||
var count = this._readBlock();
|
||||
|
||||
this.index = 0;
|
||||
this.lines = (this.remainder + this.buffer.toString(this.encoding, 0, count)).split('\n');
|
||||
this.remainder = this.lines.pop();
|
||||
this.eof = false;
|
||||
} while (count > 0);
|
||||
|
||||
if (this.remainder.length > 0) {
|
||||
this.lineNo++;
|
||||
line = callback(this.remainder.trimRight());
|
||||
this.remainder = '';
|
||||
} else {
|
||||
this.eof = true;
|
||||
line = null;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
unseek() {
|
||||
this.lineNo = 0;
|
||||
this.eof = false;
|
||||
}
|
||||
}
|
||||
|
||||
// -- OutputFileStream --
|
||||
class OutputFileStream {
|
||||
constructor(fileName, encoding = 'binary') {
|
||||
if (fileName != null) {
|
||||
this.fd = fs.openSync(fileName, 'w');
|
||||
this.stName = fileName;
|
||||
} else {
|
||||
this.fd = process.stdout.fd;
|
||||
this.stName = '<stdout>';
|
||||
}
|
||||
if (encoding == null && tty.isatty(this.fd)) {
|
||||
throw new Error(this.location() + 'binary output may not be send to a terminal');
|
||||
}
|
||||
this.encoding = (encoding == null ? 'binary' : encoding);
|
||||
this.fbbuf = Buffer.alloc(4);
|
||||
this.closeAttempt = false;
|
||||
}
|
||||
|
||||
close() {
|
||||
this.closeAttempt = true;
|
||||
fs.closeSync(this.fd);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
let errors = '';
|
||||
|
||||
if (this.fd !== process.stdout.fd) {
|
||||
if (!this.closeAttempt) {
|
||||
try {
|
||||
fs.closeSync(this.fd);
|
||||
} catch (e) {
|
||||
errors += `\n${this.stName}: close: ${e.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
fs.unlinkSync(this.stName);
|
||||
} catch (e) {
|
||||
errors += `\n${this.stName}: unlink: ${e.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
location() {
|
||||
return this.stName + ': ';
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
fs.writeSync(this.fd, buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
write8(value) {
|
||||
this.fbbuf.writeUInt8(value, 0);
|
||||
fs.writeSync(this.fd, this.fbbuf, 0, 1);
|
||||
}
|
||||
|
||||
write16(value) {
|
||||
this.fbbuf.writeUInt16LE(value, 0);
|
||||
fs.writeSync(this.fd, this.fbbuf, 0, 2);
|
||||
}
|
||||
|
||||
write32(value) {
|
||||
this.fbbuf.writeUInt32LE(value, 0);
|
||||
fs.writeSync(this.fd, this.fbbuf, 0, 4);
|
||||
}
|
||||
|
||||
writeLine(text) {
|
||||
fs.writeSync(this.fd, text + '\n', null, this.encoding);
|
||||
}
|
||||
|
||||
writeProp(name, value) {
|
||||
this.writeLine((name + ' ' + value).trimRight());
|
||||
}
|
||||
|
||||
writeZStr(bstr, numZeros) {
|
||||
fs.writeSync(this.fd, bstr, null, 'binary');
|
||||
this.write(Buffer.alloc(numZeros));
|
||||
}
|
||||
}
|
||||
|
||||
// -- Export --
|
||||
module.exports = Object.freeze({
|
||||
InputFileStream,
|
||||
OutputFileStream
|
||||
});
|
||||
@@ -0,0 +1,176 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import codecs
|
||||
import struct
|
||||
import sys
|
||||
import os
|
||||
|
||||
# -- InputFileStream --
|
||||
class InputFileStream:
|
||||
def __init__(self, file_name, encoding='binary'):
|
||||
if file_name is not None:
|
||||
self.file = open(file_name, 'r') if encoding is None else open(file_name, 'rb')
|
||||
self.st_name = file_name
|
||||
else:
|
||||
self.file = sys.stdin if encoding is None else sys.stdin.buffer
|
||||
self.st_name = '<stdin>'
|
||||
|
||||
if encoding not in [None, 'binary']:
|
||||
self.file = codecs.getreader(encoding)(self.file)
|
||||
|
||||
self.line_no = 0
|
||||
self.eof = False
|
||||
|
||||
|
||||
def close(self):
|
||||
self.unseek()
|
||||
self.file.close()
|
||||
|
||||
|
||||
def fstat(self):
|
||||
return None if (self.file == sys.stdin.buffer or self.file.isatty()) else os.fstat(self.file.fileno())
|
||||
|
||||
|
||||
def location(self):
|
||||
return '%s:%s' % (self.st_name, 'EOF: ' if self.eof else '%d: ' % self.line_no if self.line_no > 0 else ' ')
|
||||
|
||||
|
||||
def process(self, callback):
|
||||
try:
|
||||
result = callback(self)
|
||||
self.close()
|
||||
return result
|
||||
except Exception as ex:
|
||||
ex.message = self.location() + getattr(ex, 'message', str(ex))
|
||||
raise
|
||||
|
||||
|
||||
def read_line(self):
|
||||
return self.read_lines(lambda line: line)
|
||||
|
||||
|
||||
def read_lines(self, callback):
|
||||
try:
|
||||
for line in self.file:
|
||||
self.line_no += 1
|
||||
self.eof = False
|
||||
line = callback(line.rstrip())
|
||||
if line is not None:
|
||||
return line
|
||||
except OSError:
|
||||
self.unseek()
|
||||
raise
|
||||
|
||||
self.eof = True
|
||||
return None
|
||||
|
||||
|
||||
def unseek(self):
|
||||
self.line_no = 0
|
||||
self.eof = False
|
||||
|
||||
|
||||
# -- OutputFileStream --
|
||||
class OutputFileStream:
|
||||
def __init__(self, file_name, encoding='binary'):
|
||||
if file_name is not None:
|
||||
self.file = open(file_name, 'wb')
|
||||
self.st_name = file_name
|
||||
else:
|
||||
self.file = sys.stdout.buffer
|
||||
self.st_name = '<stdout>'
|
||||
|
||||
if encoding is None and self.file.isatty():
|
||||
raise Exception(self.location() + 'binary output may not be send to a terminal')
|
||||
|
||||
self.encoding = (None if encoding == 'binary' else encoding)
|
||||
self.close_attempt = False
|
||||
|
||||
|
||||
def abort(self):
|
||||
errors = ''
|
||||
|
||||
if self.file != sys.stdout.buffer:
|
||||
if not self.close_attempt:
|
||||
try:
|
||||
self.close()
|
||||
except Exception as ex:
|
||||
errors += '\n%sclose: %s' % (self.location(), str(ex))
|
||||
|
||||
try:
|
||||
os.remove(self.st_name)
|
||||
except Exception as ex:
|
||||
errors += '\n%sunlink: %s' % (self.location(), str(ex))
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def close(self):
|
||||
self.close_attempt = True
|
||||
self.file.close()
|
||||
|
||||
|
||||
def location(self):
|
||||
return self.st_name + ': '
|
||||
|
||||
|
||||
def process(self, callback):
|
||||
try:
|
||||
callback(self)
|
||||
self.close()
|
||||
except Exception as ex:
|
||||
ex.message = self.location() + getattr(ex, 'message', str(ex)) + self.abort()
|
||||
raise
|
||||
|
||||
|
||||
def write(self, data):
|
||||
self.file.write(data)
|
||||
|
||||
|
||||
def write8(self, value):
|
||||
self.write(struct.pack('B', value))
|
||||
|
||||
|
||||
def write16(self, value):
|
||||
self.write(struct.pack('<H', value))
|
||||
|
||||
|
||||
def write32(self, value):
|
||||
self.write(struct.pack('<L', value))
|
||||
|
||||
|
||||
def write_line(self, text):
|
||||
self.write((text if self.encoding is None else bytes(text, self.encoding)) + b'\n')
|
||||
|
||||
|
||||
def write_prop(self, name, value):
|
||||
self.write_line((bytes(name, 'ascii') + b' ' + value).rstrip())
|
||||
|
||||
|
||||
def write_zstr(self, bstr, num_zeros):
|
||||
self.write(bstr + bytes(num_zeros))
|
||||
|
||||
|
||||
# -- read/write file --
|
||||
def read_file(file_name, callback, encoding='binary'):
|
||||
return InputFileStream(file_name, encoding).process(callback)
|
||||
|
||||
|
||||
def write_file(file_name, callback, encoding='binary'):
|
||||
return OutputFileStream(file_name, encoding).process(callback)
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (C) 2017-2019 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// -- Various --
|
||||
const UNICODE_MAX = 1114111; // 0x10FFFF
|
||||
const UNICODE_BMP_MAX = 65535; // 0xFFFF
|
||||
|
||||
function parseDec(name, s, minValue = 0, maxValue = UNICODE_MAX) {
|
||||
if (s.match(/^\s*-?\d+\s*$/) == null) {
|
||||
throw new Error(`invalid ${name} format`);
|
||||
}
|
||||
|
||||
const value = parseInt(s, 10);
|
||||
|
||||
if (minValue != null && value < minValue) {
|
||||
throw new Error(`${name} must be >= ${minValue}`);
|
||||
}
|
||||
if (maxValue != null && value > maxValue) {
|
||||
throw new Error(`${name} must be <= ${maxValue}`);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function parseHex(name, s, minValue = 0, maxValue = UNICODE_MAX) {
|
||||
if (s.match(/^\s*(0[xX])?[\dA-Fa-f]+\s*$/) == null) {
|
||||
throw new Error(`invalid ${name} format`);
|
||||
}
|
||||
|
||||
const value = parseInt(s, 16);
|
||||
|
||||
if (minValue != null && value < minValue) {
|
||||
throw new Error(`${name} must be >= ` + minValue.toString(16).toUpperCase());
|
||||
}
|
||||
if (maxValue != null && value > maxValue) {
|
||||
throw new Error(`${name} must be <= ` + maxValue.toString(16).toUpperCase());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function unihex(code) {
|
||||
return ('000' + code.toString(16).toUpperCase()).replace(/0+(?=[\dA-F]{4})/, '');
|
||||
}
|
||||
|
||||
function round(value) {
|
||||
const esround = Math.round(value);
|
||||
|
||||
return esround - Number(esround % 2 !== 0 && esround - value === 0.5);
|
||||
}
|
||||
|
||||
function quote(s) {
|
||||
return '"' + s.replace(/"/g, '""') + '"';
|
||||
}
|
||||
|
||||
function unquote(s, name) {
|
||||
if (s.length >= 2 && s.startsWith('"') && s.endsWith('"')) {
|
||||
s = s.substring(1, s.length - 1).replace(/""/g, '"');
|
||||
} else if (name != null) {
|
||||
throw new Error(name + ' must be quoted');
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
function message(prefix, severity, text) {
|
||||
process.stderr.write(`${prefix}${severity ? severity + ': ' : ''}${text}\n`);
|
||||
}
|
||||
|
||||
function warning(prefix, text) {
|
||||
message(prefix, 'warning', text);
|
||||
}
|
||||
|
||||
function splitWords(name, value, count) {
|
||||
const words = value.split(/\s+/, count + 1);
|
||||
|
||||
if (words.length !== count) {
|
||||
throw new Error(`${name} must contain ${count} values`);
|
||||
}
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
const GPL2PLUS_LICENSE = ('' +
|
||||
'This program is free software; you can redistribute it and/or modify it\n' +
|
||||
'under the terms of the GNU General Public License as published by the Free\n' +
|
||||
'Software Foundation; either version 2 of the License, or (at your option)\n' +
|
||||
'any later version.\n' +
|
||||
'\n' +
|
||||
'This program is distributed in the hope that it will be useful, but\n' +
|
||||
'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n' +
|
||||
'or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n' +
|
||||
'for more details.\n' +
|
||||
'\n' +
|
||||
'You should have received a copy of the GNU General Public License along\n' +
|
||||
'with this program; if not, write to the Free Software Foundation, Inc.,\n' +
|
||||
'51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n');
|
||||
|
||||
// -- Exports --
|
||||
module.exports = Object.freeze({
|
||||
UNICODE_MAX,
|
||||
UNICODE_BMP_MAX,
|
||||
parseDec,
|
||||
parseHex,
|
||||
unihex,
|
||||
round,
|
||||
quote,
|
||||
unquote,
|
||||
message,
|
||||
warning,
|
||||
splitWords,
|
||||
GPL2PLUS_LICENSE
|
||||
});
|
||||
@@ -0,0 +1,98 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
# -- Various --
|
||||
UNICODE_MAX = 1114111 # 0x10FFFF
|
||||
UNICODE_BMP_MAX = 65535 # 0xFFFF
|
||||
|
||||
def parse_dec(name, s, min_value=0, max_value=UNICODE_MAX):
|
||||
try:
|
||||
value = int(s)
|
||||
except ValueError:
|
||||
raise Exception('invalid %s format' % name)
|
||||
|
||||
if min_value is not None and value < min_value:
|
||||
raise Exception('%s must be >= %d' % (name, min_value))
|
||||
|
||||
if max_value is not None and value > max_value:
|
||||
raise Exception('%s must be <= %d' % (name, max_value))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def parse_hex(name, s, min_value=0, max_value=UNICODE_MAX):
|
||||
try:
|
||||
value = int(s, 16)
|
||||
except ValueError:
|
||||
raise Exception('invalid %s format' % name)
|
||||
|
||||
if min_value is not None and value < min_value:
|
||||
raise Exception('%s must be >= %X' % (name, min_value))
|
||||
|
||||
if max_value is not None and value > max_value:
|
||||
raise Exception('%s must be <= %X' % (name, max_value))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def quote(bstr):
|
||||
return b'"%s"' % bstr.replace(b'"', b'""')
|
||||
|
||||
|
||||
def unquote(bstr, name=None):
|
||||
if len(bstr) >= 2 and bstr.startswith(b'"') and bstr.endswith(b'"'):
|
||||
bstr = bstr[1 : len(bstr) - 1].replace(b'""', b'"')
|
||||
elif name is not None:
|
||||
raise Exception(name + ' must be quoted')
|
||||
|
||||
return bstr
|
||||
|
||||
|
||||
def message(prefix, severity, text):
|
||||
sys.stderr.write('%s%s%s\n' % (prefix, severity + ': ' if severity else '', text))
|
||||
|
||||
|
||||
def warning(prefix, text):
|
||||
message(prefix, 'warning', text)
|
||||
|
||||
|
||||
def split_words(name, value, count):
|
||||
words = value.split(None, count)
|
||||
|
||||
if len(words) != count:
|
||||
raise Exception('%s must contain %d values' % (name, count))
|
||||
|
||||
return words
|
||||
|
||||
|
||||
GPL2PLUS_LICENSE = ('' +
|
||||
'This program is free software; you can redistribute it and/or modify it\n' +
|
||||
'under the terms of the GNU General Public License as published by the Free\n' +
|
||||
'Software Foundation; either version 2 of the License, or (at your option)\n' +
|
||||
'any later version.\n' +
|
||||
'\n' +
|
||||
'This program is distributed in the hope that it will be useful, but\n' +
|
||||
'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n' +
|
||||
'or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n' +
|
||||
'for more details.\n' +
|
||||
'\n' +
|
||||
'You should have received a copy of the GNU General Public License along\n' +
|
||||
'with this program; if not, write to the Free Software Foundation, Inc.,\n' +
|
||||
'51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n')
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (C) 2018-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
const fncli = require('./fncli.js');
|
||||
const fnio = require('./fnio.js');
|
||||
const otb1exp = require('./otb1exp.js');
|
||||
|
||||
// -- Params --
|
||||
class Params extends otb1exp.Params {
|
||||
constructor() {
|
||||
super();
|
||||
this.output = null;
|
||||
this.encoding = 'utf-8';
|
||||
this.realTime = true;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Options --
|
||||
const HELP = ('' +
|
||||
'usage: otb1cli [options] [INPUT]\n' +
|
||||
'Convert a BDF font to OTB\n' +
|
||||
'\n' +
|
||||
' -o OUTPUT output file (default = stdout, may not be a terminal)\n' +
|
||||
' -d DIR-HINT set font direction hint (default = 0)\n' +
|
||||
' -e EM-SIZE set em size (default = 1024)\n' +
|
||||
' -g LINE-GAP set line gap (default = 0)\n' +
|
||||
' -l LOW-PPEM set lowest recorded PPEM (default = font height)\n' +
|
||||
' -E ENCODING BDF string properties encoding (default = utf-8)\n' +
|
||||
' -W WLANG-ID set Windows name-s language ID (default = 0x0409)\n' +
|
||||
' -T use the current date and time for created/modified\n' +
|
||||
' (default = get them from INPUT if not stdin/terminal)\n' +
|
||||
' -X set xMaxExtent = 0 (default = max character width)\n' +
|
||||
' -L write a single loca entry (default = CHARS entries)\n' +
|
||||
' -P write PostScript glyph names (default = no names)\n' +
|
||||
'\n' +
|
||||
'Notes:\n' +
|
||||
' The input must be a BDF 2.1 font with unicode encoding.\n' +
|
||||
' All bitmaps are expanded first. Bitmap widths are used.\n' +
|
||||
' Overlapping characters are not supported.\n');
|
||||
|
||||
const VERSION = 'otb1cli 0.22, Copyright (C) 2018-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE;
|
||||
|
||||
class Options extends otb1exp.Options {
|
||||
constructor() {
|
||||
super(['-o', '-E'], HELP, VERSION);
|
||||
}
|
||||
|
||||
parse(name, value, params) {
|
||||
switch (name) {
|
||||
case '-o':
|
||||
params.output = value;
|
||||
break;
|
||||
case '-E':
|
||||
params.encoding = value;
|
||||
break;
|
||||
case '-T':
|
||||
params.realTime = false;
|
||||
break;
|
||||
default:
|
||||
super.parse(name, value, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Main --
|
||||
function mainProgram(nonopt, parsed) {
|
||||
if (nonopt.length > 1) {
|
||||
throw new Error('invalid number of arguments, try --help');
|
||||
}
|
||||
|
||||
// READ INPUT
|
||||
let ifs = new fnio.InputFileStream(nonopt[0], parsed.encoding);
|
||||
|
||||
try {
|
||||
if (parsed.realTime) {
|
||||
try {
|
||||
const stat = ifs.fstat();
|
||||
|
||||
if (stat != null) {
|
||||
parsed.created = stat.birthtime;
|
||||
parsed.modified = stat.mtime;
|
||||
}
|
||||
} catch (e) {
|
||||
fnutil.warning(ifs.location(), e.message);
|
||||
}
|
||||
}
|
||||
|
||||
var font = otb1exp.Font.read(ifs, parsed);
|
||||
ifs.close();
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
|
||||
// WRITE OUTPUT
|
||||
let ofs = new fnio.OutputFileStream(parsed.output, null);
|
||||
|
||||
try {
|
||||
const table = new otb1exp.SFNT(font);
|
||||
|
||||
ofs.write(table.data.slice(0, table.size));
|
||||
ofs.close();
|
||||
} catch (e) {
|
||||
e.message = ofs.location() + e.message + ofs.destroy();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
fncli.start('otb1cli.js', new Options(), new Params(), mainProgram);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import fnutil
|
||||
import fncli
|
||||
import fnio
|
||||
import otb1exp
|
||||
|
||||
# -- Params --
|
||||
class Params(otb1exp.Params):
|
||||
def __init__(self):
|
||||
otb1exp.Params.__init__(self)
|
||||
self.output_name = None
|
||||
self.real_time = True
|
||||
|
||||
|
||||
# -- Options --
|
||||
HELP = ('' +
|
||||
'usage: otb1cli [options] [INPUT]\n' +
|
||||
'Convert a BDF font to OTB\n' +
|
||||
'\n' +
|
||||
' -o OUTPUT output file (default = stdout, may not be a terminal)\n' +
|
||||
' -d DIR-HINT set font direction hint (default = 0)\n' +
|
||||
' -e EM-SIZE set em size (default = 1024)\n' +
|
||||
' -g LINE-GAP set line gap (default = 0)\n' +
|
||||
' -l LOW-PPEM set lowest recorded PPEM (default = font height)\n' +
|
||||
' -E ENCODING BDF string properties encoding (default = utf-8)\n' +
|
||||
' -W WLANG-ID set Windows name-s language ID (default = 0x0409)\n' +
|
||||
' -T use the current date and time for created/modified\n' +
|
||||
' (default = get them from INPUT if not stdin/terminal)\n' +
|
||||
' -X set xMaxExtent = 0 (default = max character width)\n' +
|
||||
' -L write a single loca entry (default = CHARS entries)\n' +
|
||||
' -P write PostScript glyph names (default = no names)\n' +
|
||||
'\n' +
|
||||
'Notes:\n' +
|
||||
' The input must be a BDF 2.1 font with unicode encoding.\n' +
|
||||
' All bitmaps are expanded first. Bitmap widths are used.\n' +
|
||||
' Overlapping characters are not supported.\n')
|
||||
|
||||
VERSION = 'otb1cli 0.24, Copyright (C) 2018-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE
|
||||
|
||||
class Options(otb1exp.Options):
|
||||
def __init__(self):
|
||||
otb1exp.Options.__init__(self, ['-o'], HELP, VERSION)
|
||||
|
||||
|
||||
def parse(self, name, value, params):
|
||||
if name == '-o':
|
||||
params.output_name = value
|
||||
elif name == '-T':
|
||||
params.real_time = False
|
||||
else:
|
||||
otb1exp.Options.parse(self, name, value, params)
|
||||
|
||||
|
||||
# -- Main --
|
||||
def main_program(nonopt, parsed):
|
||||
if len(nonopt) > 1:
|
||||
raise Exception('invalid number of arguments, try --help')
|
||||
|
||||
# READ INPUT
|
||||
def read_otb(ifs):
|
||||
if parsed.real_time:
|
||||
try:
|
||||
stat = ifs.fstat()
|
||||
if stat:
|
||||
parsed.created = datetime.fromtimestamp(stat.st_ctime, timezone.utc)
|
||||
parsed.modified = datetime.fromtimestamp(stat.st_mtime, timezone.utc)
|
||||
except Exception as ex:
|
||||
fnutil.warning(ifs.location(), str(ex))
|
||||
|
||||
return otb1exp.Font.read(ifs, parsed)
|
||||
|
||||
font = fnio.read_file(nonopt[0] if nonopt else None, read_otb)
|
||||
|
||||
# WRITE OUTPUT
|
||||
sfnt = otb1exp.SFNT(font)
|
||||
fnio.write_file(parsed.output_name, lambda ofs: ofs.write(sfnt.data), encoding=None)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fncli.start('otb1cli.py', Options(), Params(), main_program)
|
||||
@@ -0,0 +1,895 @@
|
||||
/*
|
||||
Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
const fncli = require('./fncli.js');
|
||||
const bdf = require('./bdf.js');
|
||||
const bdfexp = require('./bdfexp.js');
|
||||
const otb1get = require('./otb1get.js');
|
||||
|
||||
// -- Table --
|
||||
const TS_EMPTY = 0;
|
||||
const TS_SMALL = 64;
|
||||
const TS_LARGE = 1024;
|
||||
|
||||
class Table {
|
||||
constructor(size, name) {
|
||||
this.data = Buffer.alloc(size);
|
||||
this.size = 0;
|
||||
this.tableName = name;
|
||||
}
|
||||
|
||||
checkSize(size) {
|
||||
if (size !== this.size) {
|
||||
throw new Error(`internal error: ${this.tableName} size = ${this.size} instead of ${size}`);
|
||||
}
|
||||
}
|
||||
|
||||
checksum() {
|
||||
let cksum = 0;
|
||||
|
||||
for (let offset = 0; offset < this.size; offset += 4) {
|
||||
cksum += this.data.readUInt32BE(offset);
|
||||
}
|
||||
|
||||
return cksum >>> 0;
|
||||
}
|
||||
|
||||
ensure(count) {
|
||||
if (this.size + count > this.data.length) {
|
||||
let newSize = this.data.length << 1;
|
||||
|
||||
while (this.size + count > newSize) {
|
||||
newSize <<= 1;
|
||||
}
|
||||
|
||||
const newData = Buffer.alloc(newSize);
|
||||
|
||||
this.data.copy(newData, 0, 0, this.size);
|
||||
this.data = newData;
|
||||
}
|
||||
}
|
||||
|
||||
get padding() {
|
||||
return ((this.size + 1) & 3) ^ 1;
|
||||
}
|
||||
|
||||
rewriteUInt32(value, offset) {
|
||||
this.data.writeUInt32BE(value, offset);
|
||||
}
|
||||
|
||||
write(buffer) {
|
||||
this.ensure(buffer.length);
|
||||
buffer.copy(this.data, this.size);
|
||||
this.size += buffer.length;
|
||||
}
|
||||
|
||||
writeRC(size, writer, name) {
|
||||
this.ensure(size);
|
||||
try {
|
||||
writer(this.size);
|
||||
} catch (e) {
|
||||
e.message = e.message.replace('"value"', `"${this.tableName}.${name}"`);
|
||||
throw e;
|
||||
}
|
||||
this.size += size;
|
||||
}
|
||||
|
||||
writeInt8(value, name) {
|
||||
this.writeRC(1, (offset) => this.data.writeInt8(value, offset), name);
|
||||
}
|
||||
|
||||
writeInt16(value, name) {
|
||||
this.writeRC(2, (offset) => this.data.writeInt16BE(value, offset), name);
|
||||
}
|
||||
|
||||
writeInt32(value, name) {
|
||||
this.writeRC(4, (offset) => this.data.writeInt32BE(value, offset), name);
|
||||
}
|
||||
|
||||
writeInt64(value, name) {
|
||||
this.writeRC(8, (offset) => this.data.writeInt64BE(value, offset), name);
|
||||
}
|
||||
|
||||
writeUInt8(value, name) {
|
||||
this.writeRC(1, (offset) => this.data.writeUInt8(value, offset), name);
|
||||
}
|
||||
|
||||
writeUInt16(value, name) {
|
||||
this.writeRC(2, (offset) => this.data.writeUInt16BE(value, offset), name);
|
||||
}
|
||||
|
||||
writeUInt32(value, name) {
|
||||
this.writeRC(4, (offset) => this.data.writeUInt32BE(value, offset), name);
|
||||
}
|
||||
|
||||
writeUInt48(value, name) {
|
||||
this.writeUInt16(name, 0);
|
||||
this.writeRC(6, (offset) => this.data.writeUIntBE(value, offset, 6), name);
|
||||
}
|
||||
|
||||
writeFixed(value, name) {
|
||||
this.writeRC(4, (offset) => this.data.writeInt32BE(fnutil.round(value * 65536), offset), name);
|
||||
}
|
||||
|
||||
writeTable(table) {
|
||||
this.write(table.data.slice(0, table.size));
|
||||
}
|
||||
}
|
||||
|
||||
// -- Params --
|
||||
const EM_SIZE_MIN = 64;
|
||||
const EM_SIZE_MAX = 16384;
|
||||
const EM_SIZE_DEFAULT = 1024;
|
||||
|
||||
class Params extends fncli.Params {
|
||||
constructor() {
|
||||
super();
|
||||
this.created = new Date();
|
||||
this.modified = this.created;
|
||||
this.dirHint = 0;
|
||||
this.emSize = EM_SIZE_DEFAULT;
|
||||
this.lineGap = 0;
|
||||
this.lowPPem = 0;
|
||||
this.wLangId = 0x0409;
|
||||
this.xMaxExtent = true;
|
||||
this.singleLoca = false;
|
||||
this.postNames = false;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Options --
|
||||
class Options extends fncli.Options {
|
||||
constructor(needArgs, helpText, versionText) {
|
||||
super(needArgs.concat(['-d', '-e', '-g', '-l', '-W']), helpText, versionText);
|
||||
}
|
||||
|
||||
parse(name, value, params) {
|
||||
switch (name) {
|
||||
case '-d':
|
||||
params.dirHint = fnutil.parseDec('DIR-HINT', value, -2, 2);
|
||||
break;
|
||||
case '-e':
|
||||
params.emSize = fnutil.parseDec('EM-SIZE', value, EM_SIZE_MIN, EM_SIZE_MAX);
|
||||
break;
|
||||
case '-g':
|
||||
params.lineGap = fnutil.parseDec('LINE-GAP', value, 0, EM_SIZE_MAX << 1);
|
||||
break;
|
||||
case '-l':
|
||||
params.lowPPem = fnutil.parseDec('LOW-PPEM', value, 1, bdf.DPARSE_LIMIT);
|
||||
break;
|
||||
case '-W':
|
||||
params.wLangId = fnutil.parseHex('WLANG-ID', value, 0, 0x7FFF);
|
||||
break;
|
||||
case '-X':
|
||||
params.xMaxExtent = false;
|
||||
break;
|
||||
case '-L':
|
||||
params.singleLoca = true;
|
||||
break;
|
||||
case '-P':
|
||||
params.postNames = true;
|
||||
break;
|
||||
default:
|
||||
this.fallback(name, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Font --
|
||||
class Font extends bdfexp.Font {
|
||||
constructor(params) {
|
||||
super();
|
||||
this.params = params;
|
||||
this.emAscender = 0;
|
||||
this.emDescender = 0;
|
||||
this.emMaxWidth = 0;
|
||||
this.macStyle = 0;
|
||||
this.lineSize = 0;
|
||||
}
|
||||
|
||||
get bmpOnly() {
|
||||
return this.maxCode <= fnutil.UNICODE_BMP_MAX;
|
||||
}
|
||||
|
||||
get created() {
|
||||
return Font.sfntime(this.params.created);
|
||||
}
|
||||
|
||||
emScale(value, divisor) {
|
||||
return fnutil.round(value * this.params.emSize / (divisor || this.bbx.height));
|
||||
}
|
||||
|
||||
get italicAngle() {
|
||||
const value = this.props.get('ITALIC_ANGLE'); // must be integer
|
||||
return value != null ? fnutil.parseDec('ITALIC_ANGLE', value, -45, 45) : this.italic ? -11.5 : 0;
|
||||
}
|
||||
|
||||
get maxCode() {
|
||||
return this.chars.slice(-1)[0].code;
|
||||
}
|
||||
|
||||
get minCode() {
|
||||
return this.chars[0].code;
|
||||
}
|
||||
|
||||
get modified() {
|
||||
return Font.sfntime(this.params.modified);
|
||||
}
|
||||
|
||||
prepare() {
|
||||
this.chars.sort((c1, c2) => c1.code - c2.code);
|
||||
this.chars = this.chars.filter((c, index, array) => index === 0 || c.code !== array[index - 1].code);
|
||||
this.props.set('CHARS', this.chars.length);
|
||||
this.emAscender = this.emScale(this.pxAscender);
|
||||
this.emDescender = this.emAscender - this.params.emSize;
|
||||
this.emMaxWidth = this.emScaleWidth(this);
|
||||
this.macStyle = Number(this.bold) + (Number(this.italic) << 1);
|
||||
this.lineSize = this.emScale(fnutil.round(this.bbx.height / 17) || 1);
|
||||
}
|
||||
|
||||
_read(input) {
|
||||
super._read(input);
|
||||
this.prepare();
|
||||
return this;
|
||||
}
|
||||
|
||||
static read(input, params) {
|
||||
return (new Font(params))._read(input);
|
||||
}
|
||||
|
||||
emScaleWidth(base) {
|
||||
return this.emScale(base.bbx.width);
|
||||
}
|
||||
|
||||
static sfntime(stamp) {
|
||||
return Math.floor((stamp - Date.UTC(1904, 0, 1)) / 1000);
|
||||
}
|
||||
|
||||
get underlinePosition() {
|
||||
return fnutil.round((this.emDescender + this.lineSize) / 2);
|
||||
}
|
||||
|
||||
get xMaxExtent() {
|
||||
return this.params.xMaxExtent ? this.emMaxWidth : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// -- BDAT --
|
||||
const BDAT_HEADER_SIZE = 4;
|
||||
const BDAT_METRIC_SIZE = 5;
|
||||
|
||||
class BDAT extends Table {
|
||||
constructor(font) {
|
||||
super(TS_LARGE, 'EBDT');
|
||||
// header
|
||||
this.writeFixed(2, 'version');
|
||||
// format 1 data
|
||||
font.chars.forEach(char => {
|
||||
this.writeUInt8(font.bbx.height, 'height');
|
||||
this.writeUInt8(char.bbx.width, 'width');
|
||||
this.writeInt8(0, 'bearingX');
|
||||
this.writeInt8(font.pxAscender, 'bearingY');
|
||||
this.writeUInt8(char.bbx.width, 'advance');
|
||||
this.write(char.data); // imageData
|
||||
});
|
||||
}
|
||||
|
||||
static getCharSize(char) {
|
||||
return BDAT_METRIC_SIZE + char.data.length;
|
||||
}
|
||||
}
|
||||
|
||||
// -- BLOC --
|
||||
const BLOC_TABLE_SIZE_OFFSET = 12;
|
||||
const BLOC_PREFIX_SIZE = 0x38; // header 0x08 + 1 bitmapSizeTable * 0x30
|
||||
const BLOC_INDEX_ARRAY_SIZE = 8; // 1 index record * 0x08
|
||||
|
||||
class BLOC extends Table {
|
||||
constructor(font) {
|
||||
super(TS_SMALL, 'EBLC');
|
||||
// header
|
||||
this.writeFixed(2, 'version');
|
||||
this.writeUInt32(1, 'numSizes');
|
||||
// bitmapSizeTable
|
||||
this.writeUInt32(BLOC_PREFIX_SIZE, 'indexSubTableArrayOffset');
|
||||
this.writeUInt32(0, 'indexTableSize'); // adjusted later
|
||||
this.writeUInt32(1, 'numberOfIndexSubTables');
|
||||
this.writeUInt32(0, 'colorRef');
|
||||
// hori
|
||||
this.writeInt8(font.pxAscender, 'hori ascender');
|
||||
this.writeInt8(font.pxDescender, 'hori descender');
|
||||
this.writeUInt8(font.bbx.width, 'hori widthMax');
|
||||
this.writeInt8(1, 'hori caretSlopeNumerator');
|
||||
this.writeInt8(0, 'hori caretSlopeDenominator');
|
||||
this.writeInt8(0, 'hori caretOffset');
|
||||
this.writeInt8(0, 'hori minOriginSB');
|
||||
this.writeInt8(0, 'hori minAdvanceSB');
|
||||
this.writeInt8(font.pxAscender, 'hori maxBeforeBL');
|
||||
this.writeInt8(font.pxDescender, 'hori minAfterBL');
|
||||
this.writeInt16(0, 'hori padd');
|
||||
// vert
|
||||
this.writeInt8(0, 'vert ascender');
|
||||
this.writeInt8(0, 'vert descender');
|
||||
this.writeUInt8(0, 'vert widthMax');
|
||||
this.writeInt8(0, 'vert caretSlopeNumerator');
|
||||
this.writeInt8(0, 'vert caretSlopeDenominator');
|
||||
this.writeInt8(0, 'vert caretOffset');
|
||||
this.writeInt8(0, 'vert minOriginSB');
|
||||
this.writeInt8(0, 'vert minAdvanceSB');
|
||||
this.writeInt8(0, 'vert maxBeforeBL');
|
||||
this.writeInt8(0, 'vert minAfterBL');
|
||||
this.writeInt16(0, 'vert padd');
|
||||
// (bitmapSizeTable)
|
||||
this.writeUInt16(0, 'startGlyphIndex');
|
||||
this.writeUInt16(font.chars.length - 1, 'endGlyphIndex');
|
||||
this.writeUInt8(font.bbx.height, 'ppemX');
|
||||
this.writeUInt8(font.bbx.height, 'ppemY');
|
||||
this.writeUInt8(1, 'bitDepth');
|
||||
this.writeUInt8(1, 'flags'); // small metrics are horizontal
|
||||
// indexSubTableArray
|
||||
this.writeUInt16(0, 'firstGlyphIndex');
|
||||
this.writeUInt16(font.chars.length - 1, 'lastGlyphIndex');
|
||||
this.writeUInt32(BLOC_INDEX_ARRAY_SIZE, 'additionalOffsetToIndexSubtable');
|
||||
// indexSubtableHeader
|
||||
this.writeUInt16(font.proportional ? 1 : 2, 'indexFormat');
|
||||
this.writeUInt16(1, 'imageFormat'); // BDAT -> small metrics, byte-aligned
|
||||
this.writeUInt32(BDAT_HEADER_SIZE, 'imageDataOffset');
|
||||
// indexSubtable data
|
||||
if (font.proportional) {
|
||||
let offset = 0;
|
||||
|
||||
font.chars.forEach(char => {
|
||||
this.writeUInt32(offset, 'offsetArray[]');
|
||||
offset += BDAT.getCharSize(char);
|
||||
});
|
||||
this.writeUInt32(offset, 'offsetArray[]');
|
||||
} else {
|
||||
this.writeUInt32(BDAT.getCharSize(font.chars[0]), 'imageSize');
|
||||
this.writeUInt8(font.bbx.height, 'height');
|
||||
this.writeUInt8(font.bbx.width, 'width');
|
||||
this.writeInt8(0, 'horiBearingX');
|
||||
this.writeInt8(font.pxAscender, 'horiBearingY');
|
||||
this.writeUInt8(font.bbx.width, 'horiAdvance');
|
||||
this.writeInt8(-(font.bbx.width >> 1), 'vertBearingX');
|
||||
this.writeInt8(0, 'vertBearingY');
|
||||
this.writeUInt8(font.bbx.height, 'vertAdvance');
|
||||
}
|
||||
// adjust
|
||||
this.rewriteUInt32(this.size - BLOC_PREFIX_SIZE, BLOC_TABLE_SIZE_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
// -- OS/2 --
|
||||
const OS_2_TABLE_SIZE = 96;
|
||||
|
||||
class OS_2 extends Table {
|
||||
constructor(font) {
|
||||
super(TS_SMALL, 'OS/2');
|
||||
// Version 4
|
||||
const xAvgCharWidth = font.emScale(font.avgWidth); // otb1get.xAvgCharWidth(font);
|
||||
const ulCharRanges = otb1get.ulCharRanges(font);
|
||||
const ulCodePages = font.bmpOnly ? otb1get.ulCodePages(font) : [0, 0];
|
||||
// mostly from FontForge
|
||||
const scriptXSize = font.emScale(30, 100);
|
||||
const scriptYSize = font.emScale(40, 100);
|
||||
const subscriptYOff = scriptYSize >> 1;
|
||||
const xfactor = Math.tan(font.italicAngle * Math.PI / 180);
|
||||
const subscriptXOff = 0; // stub, no overlapping characters yet
|
||||
const superscriptYOff = font.emAscender - scriptYSize;
|
||||
const superscriptXOff = -fnutil.round(xfactor * superscriptYOff);
|
||||
// write
|
||||
this.writeUInt16(4, 'version');
|
||||
this.writeInt16(xAvgCharWidth, 'xAvgCharWidth');
|
||||
this.writeUInt16(font.bold ? 700 : 400, 'usWeightClass');
|
||||
this.writeUInt16(5, 'usWidthClass'); // medium
|
||||
this.writeInt16(0, 'fsType');
|
||||
this.writeInt16(scriptXSize, 'ySubscriptXSize');
|
||||
this.writeInt16(scriptYSize, 'ySubscriptYSize');
|
||||
this.writeInt16(subscriptXOff, 'ySubscriptXOffset');
|
||||
this.writeInt16(subscriptYOff, 'ySubscriptYOffset');
|
||||
this.writeInt16(scriptXSize, 'ySuperscriptXSize');
|
||||
this.writeInt16(scriptYSize, 'ySuperscriptYSize');
|
||||
this.writeInt16(superscriptXOff, 'ySuperscriptXOffset');
|
||||
this.writeInt16(superscriptYOff, 'ySuperscriptYOffset');
|
||||
this.writeInt16(font.lineSize, 'yStrikeoutSize');
|
||||
this.writeInt16(font.emScale(25, 100), 'yStrikeoutPosition');
|
||||
this.writeInt16(0, 'sFamilyClass'); // no classification
|
||||
this.writeUInt8(2, 'bFamilyType'); // text and display
|
||||
this.writeUInt8(0, 'bSerifStyle'); // any
|
||||
this.writeUInt8(font.bold ? 8 : 6, 'bWeight');
|
||||
this.writeUInt8(font.proportional ? 3 : 9, 'bProportion');
|
||||
this.writeUInt8(0, 'bContrast');
|
||||
this.writeUInt8(0, 'bStrokeVariation');
|
||||
this.writeUInt8(0, 'bArmStyle');
|
||||
this.writeUInt8(0, 'bLetterform');
|
||||
this.writeUInt8(0, 'bMidline');
|
||||
this.writeUInt8(0, 'bXHeight');
|
||||
this.writeUInt32(ulCharRanges[0], 'ulCharRange1');
|
||||
this.writeUInt32(ulCharRanges[1], 'ulCharRange2');
|
||||
this.writeUInt32(ulCharRanges[2], 'ulCharRange3');
|
||||
this.writeUInt32(ulCharRanges[3], 'ulCharRange4');
|
||||
this.writeUInt32(0x586F7334, 'achVendID'); // 'Xos4'
|
||||
this.writeUInt16(OS_2.fsSelection(font), 'fsSelection');
|
||||
this.writeUInt16(Math.min(font.minCode, fnutil.UNICODE_BMP_MAX), 'firstChar');
|
||||
this.writeUInt16(Math.min(font.maxCode, fnutil.UNICODE_BMP_MAX), 'lastChar');
|
||||
this.writeInt16(font.emAscender, 'sTypoAscender');
|
||||
this.writeInt16(font.emDescender, 'sTypoDescender');
|
||||
this.writeInt16(font.params.lineGap, 'sTypoLineGap');
|
||||
this.writeUInt16(font.emAscender, 'usWinAscent');
|
||||
this.writeUInt16(-font.emDescender, 'usWinDescent');
|
||||
this.writeUInt32(ulCodePages[0], 'ulCodePageRange1');
|
||||
this.writeUInt32(ulCodePages[1], 'ulCodePageRange2');
|
||||
this.writeInt16(font.emScale(font.pxAscender * 0.6), 'sxHeight'); // stub
|
||||
this.writeInt16(font.emScale(font.pxAscender * 0.8), 'sCapHeight'); // stub
|
||||
this.writeUInt16(OS_2.defaultChar(font), 'usDefaultChar');
|
||||
this.writeUInt16(OS_2.breakChar(font), 'usBreakChar');
|
||||
this.writeUInt16(1, 'usMaxContext');
|
||||
// check
|
||||
this.checkSize(OS_2_TABLE_SIZE);
|
||||
}
|
||||
|
||||
static breakChar(font) {
|
||||
return font.chars.findIndex(char => char.code === 0x20) !== -1 ? 0x20 : font.minCode;
|
||||
}
|
||||
|
||||
static defaultChar(font) {
|
||||
if (font.defaultCode !== -1 && font.defaultCode <= fnutil.UNICODE_BMP_MAX) {
|
||||
return font.defaultCode;
|
||||
}
|
||||
return font.minCode && font.maxCode;
|
||||
}
|
||||
|
||||
static fsSelection(font) {
|
||||
const fsSelection = Number(font.bold) * 5 + Number(font.italic);
|
||||
return fsSelection || (font.xlfd[bdf.XLFD.SLANT] === 'R' ? 0x40 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
// -- cmap --
|
||||
const CMAP_4_PREFIX_SIZE = 12;
|
||||
const CMAP_4_FORMAT_SIZE = 16;
|
||||
const CMAP_4_SEGMENT_SIZE = 8;
|
||||
|
||||
const CMAP_12_PREFIX_SIZE = 20;
|
||||
const CMAP_12_FORMAT_SIZE = 16;
|
||||
const CMAP_12_GROUP_SIZE = 12;
|
||||
|
||||
class CMapRange {
|
||||
constructor(glyphIndex = 0, startCode = 0, finalCode = -2) {
|
||||
this.glyphIndex = glyphIndex;
|
||||
this.startCode = startCode;
|
||||
this.finalCode = finalCode;
|
||||
}
|
||||
|
||||
get idDelta() {
|
||||
return (this.glyphIndex - this.startCode) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
class CMAP extends Table {
|
||||
constructor(font) {
|
||||
super(TS_LARGE, 'cmap');
|
||||
// make ranges
|
||||
let ranges = [];
|
||||
let range = new CMapRange();
|
||||
|
||||
for (let index = 0; index < font.chars.length; index++) {
|
||||
let code = font.chars[index].code;
|
||||
|
||||
if (code === range.finalCode + 1) {
|
||||
range.finalCode++;
|
||||
} else {
|
||||
range = new CMapRange(index, code, code);
|
||||
ranges.push(range);
|
||||
}
|
||||
}
|
||||
// write
|
||||
if (font.bmpOnly) {
|
||||
if (font.maxCode < 0xFFFF) {
|
||||
ranges.push(new CMapRange(0, 0xFFFF, 0xFFFF));
|
||||
}
|
||||
this.writeFormat4(ranges);
|
||||
} else {
|
||||
this.writeFormat12(ranges);
|
||||
}
|
||||
}
|
||||
|
||||
writeFormat4(ranges) {
|
||||
// index
|
||||
this.writeUInt16(0, 'version');
|
||||
this.writeUInt16(1, 'numberSubtables');
|
||||
// encoding subtables index
|
||||
this.writeUInt16(3, 'platformID'); // Microsoft
|
||||
this.writeUInt16(1, 'platformSpecificID'); // Unicode BMP (UCS-2)
|
||||
this.writeUInt32(CMAP_4_PREFIX_SIZE, 'offset'); // for Unicode BMP (UCS-2)
|
||||
// cmap format 4
|
||||
const segCount = ranges.length;
|
||||
const subtableSize = CMAP_4_FORMAT_SIZE + segCount * CMAP_4_SEGMENT_SIZE;
|
||||
const searchRange = 2 << Math.floor(Math.log2(segCount));
|
||||
|
||||
this.writeUInt16(4, 'format');
|
||||
this.writeUInt16(subtableSize, 'length');
|
||||
this.writeUInt16(0, 'language'); // none/independent
|
||||
this.writeUInt16(segCount * 2, 'segCountX2');
|
||||
this.writeUInt16(searchRange, 'searchRange');
|
||||
this.writeUInt16(Math.log2(searchRange / 2), 'entrySelector');
|
||||
this.writeUInt16((segCount * 2) - searchRange, 'rangeShift');
|
||||
ranges.forEach(range => {
|
||||
this.writeUInt16(range.finalCode, 'endCode');
|
||||
});
|
||||
this.writeUInt16(0, 'reservedPad');
|
||||
ranges.forEach(range => {
|
||||
this.writeUInt16(range.startCode, 'startCode');
|
||||
});
|
||||
ranges.forEach(range => {
|
||||
this.writeUInt16(range.idDelta, 'idDelta');
|
||||
});
|
||||
ranges.forEach(() => this.writeUInt16(0), 'idRangeOffset');
|
||||
// check
|
||||
this.checkSize(CMAP_4_PREFIX_SIZE + subtableSize);
|
||||
}
|
||||
|
||||
writeFormat12(ranges) {
|
||||
// index
|
||||
this.writeUInt16(0, 'version');
|
||||
this.writeUInt16(2, 'numberSubtables');
|
||||
// encoding subtables
|
||||
this.writeUInt16(0, 'platformID'); // Unicode
|
||||
this.writeUInt16(4, 'platformSpecificID'); // Unicode 2.0+ full range
|
||||
this.writeUInt32(CMAP_12_PREFIX_SIZE, 'offset'); // for Unicode 2.0+ full range
|
||||
this.writeUInt16(3, 'platformID'); // Microsoft
|
||||
this.writeUInt16(10, 'platformSpecificID'); // Unicode UCS-4
|
||||
this.writeUInt32(CMAP_12_PREFIX_SIZE, 'offset'); // for Unicode UCS-4
|
||||
// cmap format 12
|
||||
const subtableSize = CMAP_12_FORMAT_SIZE + ranges.length * CMAP_12_GROUP_SIZE;
|
||||
|
||||
this.writeFixed(12, 'format');
|
||||
this.writeUInt32(subtableSize, 'length');
|
||||
this.writeUInt32(0, 'language'); // none/independent
|
||||
this.writeUInt32(ranges.length, 'nGroups');
|
||||
this.ranges.forEach(range => {
|
||||
this.writeUInt32(range.startCode, 'startCharCode');
|
||||
this.writeUInt32(range.finalCode, 'endCharCode');
|
||||
this.writeUInt32(range.glyphIndex, 'startGlyphID');
|
||||
});
|
||||
// check
|
||||
this.checkSize(CMAP_12_PREFIX_SIZE + subtableSize);
|
||||
}
|
||||
}
|
||||
|
||||
// -- glyf --
|
||||
class GLYF extends Table {
|
||||
constructor() {
|
||||
super(TS_EMPTY, 'glyf');
|
||||
}
|
||||
}
|
||||
|
||||
// -- head --
|
||||
const HEAD_TABLE_SIZE = 54;
|
||||
const HEAD_CHECKSUM_OFFSET = 8;
|
||||
|
||||
class HEAD extends Table {
|
||||
constructor(font) {
|
||||
super(TS_SMALL, 'head');
|
||||
this.writeFixed(1, 'version');
|
||||
this.writeFixed(1, 'fontRevision');
|
||||
this.writeUInt32(0, 'checksumAdjustment'); // adjusted later
|
||||
this.writeUInt32(0x5F0F3CF5, 'magicNumber');
|
||||
this.writeUInt16(HEAD.flags(font), 'flags');
|
||||
this.writeUInt16(font.params.emSize, 'unitsPerEm');
|
||||
this.writeUInt48(font.created, 'created');
|
||||
this.writeUInt48(font.modified, 'modified');
|
||||
this.writeInt16(0, 'xMin');
|
||||
this.writeInt16(font.emDescender, 'yMin');
|
||||
this.writeInt16(font.emMaxWidth, 'xMax');
|
||||
this.writeInt16(font.emAscender, 'yMax');
|
||||
this.writeUInt16(font.macStyle, 'macStyle');
|
||||
this.writeUInt16(font.params.lowPPem || font.bbx.height, 'lowestRecPPEM');
|
||||
this.writeInt16(font.params.dirHint, 'fontDirectionHint');
|
||||
this.writeInt16(0, 'indexToLocFormat'); // short
|
||||
this.writeInt16(0, 'glyphDataFormat'); // current
|
||||
// check
|
||||
this.checkSize(HEAD_TABLE_SIZE);
|
||||
}
|
||||
|
||||
static flags(font) {
|
||||
return otb1get.containsRTL(font) ? 0x020B : 0x0B; // y0 base, x0 lsb, scale int
|
||||
}
|
||||
}
|
||||
|
||||
// -- hhea --
|
||||
const HHEA_TABLE_SIZE = 36;
|
||||
|
||||
class HHEA extends Table {
|
||||
constructor(font) {
|
||||
super(TS_SMALL, 'hhea');
|
||||
this.writeFixed(1, 'version');
|
||||
this.writeInt16(font.emAscender, 'ascender');
|
||||
this.writeInt16(font.emDescender, 'descender');
|
||||
this.writeInt16(font.params.lineGap, 'lineGap');
|
||||
this.writeUInt16(font.emMaxWidth, 'advanceWidthMax');
|
||||
this.writeInt16(0, 'minLeftSideBearing');
|
||||
this.writeInt16(0, 'minRightSideBearing');
|
||||
this.writeInt16(font.xMaxExtent, 'xMaxExtent');
|
||||
this.writeInt16(font.italic ? 100 : 1, 'caretSlopeRise');
|
||||
this.writeInt16(font.italic ? 20 : 0, 'caretSlopeRun');
|
||||
this.writeInt16(0, 'caretOffset');
|
||||
this.writeInt16(0, 'reserved');
|
||||
this.writeInt16(0, 'reserved');
|
||||
this.writeInt16(0, 'reserved');
|
||||
this.writeInt16(0, 'reserved');
|
||||
this.writeInt16(0, 'metricDataFormat'); // current
|
||||
this.writeUInt16(font.chars.length, 'numOfLongHorMetrics');
|
||||
// check
|
||||
this.checkSize(HHEA_TABLE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// -- hmtx --
|
||||
class HMTX extends Table {
|
||||
constructor(font) {
|
||||
super(TS_LARGE, 'hmtx');
|
||||
font.chars.forEach(char => {
|
||||
this.writeUInt16(font.emScaleWidth(char), 'advanceWidth');
|
||||
this.writeInt16(0, 'leftSideBearing');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// -- loca --
|
||||
class LOCA extends Table {
|
||||
constructor(font) {
|
||||
super(TS_SMALL, 'loca');
|
||||
if (!font.params.singleLoca) {
|
||||
font.chars.forEach(() => this.writeUInt16(0, 'offset'));
|
||||
}
|
||||
this.writeUInt16(0, 'offset');
|
||||
}
|
||||
}
|
||||
|
||||
// -- maxp --
|
||||
const MAXP_TABLE_SIZE = 32;
|
||||
|
||||
class MAXP extends Table {
|
||||
constructor(font) {
|
||||
super(TS_SMALL, 'maxp');
|
||||
this.writeFixed(1, 'version');
|
||||
this.writeUInt16(font.chars.length, 'numGlyphs');
|
||||
this.writeUInt16(0, 'maxPoints');
|
||||
this.writeUInt16(0, 'maxContours');
|
||||
this.writeUInt16(0, 'maxComponentPoints');
|
||||
this.writeUInt16(0, 'maxComponentContours');
|
||||
this.writeUInt16(2, 'maxZones');
|
||||
this.writeUInt16(0, 'maxTwilightPoints');
|
||||
this.writeUInt16(1, 'maxStorage');
|
||||
this.writeUInt16(1, 'maxFunctionDefs');
|
||||
this.writeUInt16(0, 'maxInstructionDefs');
|
||||
this.writeUInt16(64, 'maxStackElements');
|
||||
this.writeUInt16(0, 'maxSizeOfInstructions');
|
||||
this.writeUInt16(0, 'maxComponentElements');
|
||||
this.writeUInt16(0, 'maxComponentDepth');
|
||||
// check
|
||||
this.checkSize(MAXP_TABLE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// -- name --
|
||||
const NAME_ID = {
|
||||
COPYRIGHT: 0,
|
||||
FONT_FAMILY: 1,
|
||||
FONT_SUBFAMILY: 2,
|
||||
UNIQUE_SUBFAMILY: 3,
|
||||
FULL_FONT_NAME: 4,
|
||||
LICENSE: 14
|
||||
};
|
||||
|
||||
const NAME_HEADER_SIZE = 6;
|
||||
const NAME_RECORD_SIZE = 12;
|
||||
|
||||
class NAME extends Table {
|
||||
constructor(font) {
|
||||
super(TS_LARGE, 'name');
|
||||
// compute names
|
||||
let names = new Map();
|
||||
const copyright = font.props.get('COPYRIGHT');
|
||||
|
||||
if (copyright != null) {
|
||||
names.set(NAME_ID.COPYRIGHT, fnutil.unquote(copyright));
|
||||
}
|
||||
|
||||
const family = font.xlfd[bdf.XLFD.FAMILY_NAME];
|
||||
const style = ['Regular', 'Bold', 'Italic', 'Bold Italic'][font.macStyle];
|
||||
|
||||
names.set(NAME_ID.FONT_FAMILY, family);
|
||||
names.set(NAME_ID.FONT_SUBFAMILY, style);
|
||||
names.set(NAME_ID.UNIQUE_SUBFAMILY, `${family} ${style} bitmap height ${font.bbx.height}`);
|
||||
names.set(NAME_ID.FULL_FONT_NAME, `${family} ${style}`);
|
||||
|
||||
let license = font.props.get('LICENSE');
|
||||
const notice = font.props.get('NOTICE');
|
||||
|
||||
if (license == null && notice != null && notice.toLowerCase().includes('license')) {
|
||||
license = notice;
|
||||
}
|
||||
if (license != null) {
|
||||
names.set(NAME_ID.LICENSE, fnutil.unquote(license));
|
||||
}
|
||||
// header
|
||||
const count = names.size * (1 + 1); // Unicode + Microsoft
|
||||
const stringOffset = NAME_HEADER_SIZE + NAME_RECORD_SIZE * count;
|
||||
|
||||
this.writeUInt16(0, 'format');
|
||||
this.writeUInt16(count, 'count');
|
||||
this.writeUInt16(stringOffset, 'stringOffset');
|
||||
// name records / create values
|
||||
let values = new Table(TS_LARGE, 'name');
|
||||
|
||||
names.forEach((str, nameID) => {
|
||||
const value = Buffer.from(str, 'utf16le').swap16();
|
||||
const bmp = font.bmpOnly && value.length === str.length * 2;
|
||||
// Unicode
|
||||
this.writeUInt16(0, 'platformID'); // Unicode
|
||||
this.writeUInt16(bmp ? 3 : 4, 'platformSpecificID');
|
||||
this.writeUInt16(0, 'languageID');
|
||||
this.writeUInt16(nameID, 'nameID');
|
||||
this.writeUInt16(value.length, 'length'); // in bytes
|
||||
this.writeUInt16(values.size, 'offset');
|
||||
// Windows
|
||||
this.writeUInt16(3, 'platformID'); // Microsoft
|
||||
this.writeUInt16(bmp ? 1 : 10, 'platformSpecificID');
|
||||
this.writeUInt16(font.params.wLangId, 'languageID');
|
||||
this.writeUInt16(nameID, 'nameID');
|
||||
this.writeUInt16(value.length, 'length'); // in bytes
|
||||
this.writeUInt16(values.size, 'offset');
|
||||
// value
|
||||
values.write(value);
|
||||
});
|
||||
// write values
|
||||
this.writeTable(values);
|
||||
// check
|
||||
this.checkSize(stringOffset + values.size);
|
||||
}
|
||||
}
|
||||
|
||||
// -- post --
|
||||
const POST_TABLE_SIZE = 32;
|
||||
|
||||
class POST extends Table {
|
||||
constructor(font) {
|
||||
super(TS_SMALL, 'post');
|
||||
this.writeFixed(font.params.postNames ? 2 : 3, 'format');
|
||||
this.writeFixed(font.italicAngle, 'italicAngle');
|
||||
this.writeInt16(font.underlinePosition, 'underlinePosition');
|
||||
this.writeInt16(font.lineSize, 'underlineThickness');
|
||||
this.writeUInt32(font.proportional ? 0 : 1, 'isFixedPitch');
|
||||
this.writeUInt32(0, 'minMemType42');
|
||||
this.writeUInt32(0, 'maxMemType42');
|
||||
this.writeUInt32(0, 'minMemType1');
|
||||
this.writeUInt32(0, 'maxMemType1');
|
||||
// names
|
||||
if (font.params.postNames) {
|
||||
let postNames = otb1get.postMacNames();
|
||||
const postMacCount = postNames.length;
|
||||
|
||||
this.writeUInt16(font.chars.length, 'numberOfGlyphs');
|
||||
font.chars.forEach(char => {
|
||||
const name = char.props.get('STARTCHAR');
|
||||
const index = postNames.indexOf(name);
|
||||
|
||||
if (index !== -1) {
|
||||
this.writeUInt16(index, 'glyphNameIndex');
|
||||
} else {
|
||||
this.writeUInt16(postNames.length, 'glyphNameIndex');
|
||||
postNames.push(name);
|
||||
}
|
||||
});
|
||||
|
||||
postNames.slice(postMacCount).forEach(name => {
|
||||
this.writeUInt8(name.length, 'glyphNameLength');
|
||||
this.write(Buffer.from(name, 'binary'));
|
||||
});
|
||||
// check
|
||||
} else {
|
||||
this.checkSize(POST_TABLE_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- SFNT --
|
||||
const SFNT_HEADER_SIZE = 12;
|
||||
const SFNT_RECORD_SIZE = 16;
|
||||
const SFNT_SUBTABLES = [ BDAT, BLOC, OS_2, CMAP, GLYF, HEAD, HHEA, HMTX, LOCA, MAXP, NAME, POST ];
|
||||
|
||||
class SFNT extends Table {
|
||||
constructor(font) {
|
||||
super(TS_LARGE, 'SFNT');
|
||||
// create tables
|
||||
let tables = [];
|
||||
|
||||
SFNT_SUBTABLES.forEach(Ctor => {
|
||||
tables.push(new Ctor(font));
|
||||
});
|
||||
// header
|
||||
const numTables = tables.length;
|
||||
const entrySelector = Math.floor(Math.log2(numTables));
|
||||
const searchRange = 16 << entrySelector;
|
||||
const contentOffset = SFNT_HEADER_SIZE + numTables * SFNT_RECORD_SIZE;
|
||||
let offset = contentOffset;
|
||||
let content = new Table(TS_LARGE, 'SFNT');
|
||||
let headChecksumOffset = -1;
|
||||
|
||||
this.writeFixed(1, 'sfntVersion');
|
||||
this.writeUInt16(numTables, 'numTables');
|
||||
this.writeUInt16(searchRange, 'searchRange');
|
||||
this.writeUInt16(entrySelector, 'entrySelector');
|
||||
this.writeUInt16(numTables * 16 - searchRange, 'rangeShift');
|
||||
// table records / create content
|
||||
tables.forEach(table => {
|
||||
this.write(Buffer.from(table.tableName, 'binary'));
|
||||
this.writeUInt32(table.checksum(), 'checkSum');
|
||||
this.writeUInt32(offset, 'offset');
|
||||
this.writeUInt32(table.size, 'length');
|
||||
// create content
|
||||
if (table.tableName === 'head') {
|
||||
headChecksumOffset = offset + HEAD_CHECKSUM_OFFSET;
|
||||
}
|
||||
const paddedSize = table.size + table.padding;
|
||||
|
||||
content.write(table.data.slice(0, paddedSize));
|
||||
offset += paddedSize;
|
||||
});
|
||||
// write content
|
||||
this.writeTable(content);
|
||||
// check
|
||||
this.checkSize(contentOffset + content.size);
|
||||
// adjust
|
||||
if (headChecksumOffset !== -1) {
|
||||
this.rewriteUInt32((0xB1B0AFBA - this.checksum()) >>> 0, headChecksumOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Export --
|
||||
module.exports = Object.freeze({
|
||||
TS_EMPTY,
|
||||
TS_SMALL,
|
||||
TS_LARGE,
|
||||
Table,
|
||||
EM_SIZE_MIN,
|
||||
EM_SIZE_MAX,
|
||||
EM_SIZE_DEFAULT,
|
||||
Params,
|
||||
Options,
|
||||
Font,
|
||||
BDAT,
|
||||
BLOC,
|
||||
OS_2,
|
||||
CMAP,
|
||||
GLYF,
|
||||
HEAD,
|
||||
HHEA,
|
||||
HMTX,
|
||||
LOCA,
|
||||
MAXP,
|
||||
NAME,
|
||||
POST,
|
||||
SFNT
|
||||
});
|
||||
@@ -0,0 +1,808 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import struct
|
||||
import codecs
|
||||
import math
|
||||
from datetime import datetime, timezone
|
||||
from itertools import groupby
|
||||
from enum import IntEnum, unique
|
||||
from collections import OrderedDict
|
||||
|
||||
import fnutil
|
||||
import fncli
|
||||
import bdf
|
||||
import bdfexp
|
||||
import otb1get
|
||||
|
||||
# -- Table --
|
||||
class Table:
|
||||
def __init__(self, name):
|
||||
self.data = bytearray(0)
|
||||
self.table_name = name
|
||||
|
||||
|
||||
def check_size(self, size):
|
||||
if size != self.size:
|
||||
raise Exception('internal error: %s size = %d instead of %d' % (self.table_name, self.size, size))
|
||||
|
||||
|
||||
def checksum(self):
|
||||
cksum = 0
|
||||
data = self.data + self.padding
|
||||
|
||||
for offset in range(0, self.size, 4):
|
||||
cksum += struct.unpack('>L', data[offset : offset + 4])[0]
|
||||
|
||||
return cksum & 0xFFFFFFFF
|
||||
|
||||
|
||||
def pack(self, format, value, name):
|
||||
try:
|
||||
return struct.pack(format, value)
|
||||
except struct.error as ex:
|
||||
raise Exception('%s.%s: %s' % (self.table_name, name, str(ex)))
|
||||
|
||||
|
||||
@property
|
||||
def size(self):
|
||||
return len(self.data)
|
||||
|
||||
|
||||
@property
|
||||
def padding(self):
|
||||
return bytes(((self.size + 1) & 3) ^ 1)
|
||||
|
||||
|
||||
def rewrite_uint32(self, value, offset):
|
||||
self.data[offset : offset + 4] = struct.pack('>L', value)
|
||||
|
||||
|
||||
def write(self, data):
|
||||
self.data += data
|
||||
|
||||
|
||||
def write_int8(self, value, name):
|
||||
self.data += self.pack('b', value, name)
|
||||
|
||||
|
||||
def write_uint8(self, value, name):
|
||||
self.data += self.pack('B', value, name)
|
||||
|
||||
|
||||
def write_int16(self, value, name):
|
||||
self.data += self.pack('>h', value, name)
|
||||
|
||||
|
||||
def write_uint16(self, value, name):
|
||||
self.data += self.pack('>H', value, name)
|
||||
|
||||
|
||||
def write_uint32(self, value, name):
|
||||
self.data += self.pack('>L', value, name)
|
||||
|
||||
|
||||
def write_uint64(self, value, name):
|
||||
self.data += self.pack('>Q', value, name)
|
||||
|
||||
|
||||
def write_fixed(self, value, name):
|
||||
self.data += self.pack('>l', round(value * 65536), name)
|
||||
|
||||
|
||||
def write_table(self, table):
|
||||
self.data += table.data
|
||||
|
||||
|
||||
# -- Params --
|
||||
EM_SIZE_MIN = 64
|
||||
EM_SIZE_MAX = 16384
|
||||
EM_SIZE_DEFAULT = 1024
|
||||
|
||||
class Params(fncli.Params): # pylint: disable=too-many-instance-attributes
|
||||
def __init__(self):
|
||||
fncli.Params.__init__(self)
|
||||
self.created = datetime.now(timezone.utc)
|
||||
self.modified = self.created
|
||||
self.dir_hint = 0
|
||||
self.em_size = EM_SIZE_DEFAULT
|
||||
self.line_gap = 0
|
||||
self.low_ppem = 0
|
||||
self.encoding = 'utf_8'
|
||||
self.w_lang_id = 0x0409
|
||||
self.x_max_extent = True
|
||||
self.single_loca = False
|
||||
self.post_names = False
|
||||
|
||||
|
||||
# -- Options --
|
||||
class Options(fncli.Options):
|
||||
def __init__(self, need_args, help_text, version_text):
|
||||
fncli.Options.__init__(self, need_args + ['-d', '-e', '-g', '-l', '-E', '-W'], help_text, version_text)
|
||||
|
||||
|
||||
def parse(self, name, value, params):
|
||||
if name == '-d':
|
||||
params.dir_hint = fnutil.parse_dec('DIR-HINT', value, -2, 2)
|
||||
elif name == '-e':
|
||||
params.em_size = fnutil.parse_dec('EM-SIZE', value, EM_SIZE_MIN, EM_SIZE_MAX)
|
||||
elif name == '-g':
|
||||
params.line_gap = fnutil.parse_dec('LINE-GAP', value, 0, EM_SIZE_MAX << 1)
|
||||
elif name == '-l':
|
||||
params.low_ppem = fnutil.parse_dec('LOW-PPEM', value, 1, bdf.DPARSE_LIMIT)
|
||||
elif name == '-E':
|
||||
params.encoding = value
|
||||
elif name == '-W':
|
||||
params.w_lang_id = fnutil.parse_hex('WLANG-ID', value, 0, 0x7FFF)
|
||||
elif name == '-X':
|
||||
params.x_max_extent = False
|
||||
elif name == '-L':
|
||||
params.single_loca = True
|
||||
elif name == '-P':
|
||||
params.post_names = True
|
||||
else:
|
||||
self.fallback(name, params)
|
||||
|
||||
|
||||
# -- Font --
|
||||
class Font(bdfexp.Font):
|
||||
def __init__(self, params):
|
||||
bdfexp.Font.__init__(self)
|
||||
self.params = params
|
||||
self.em_ascender = 0
|
||||
self.em_descender = 0
|
||||
self.em_max_width = 0
|
||||
self.mac_style = 0
|
||||
self.line_size = 0
|
||||
|
||||
|
||||
@property
|
||||
def bmp_only(self):
|
||||
return self.max_code <= fnutil.UNICODE_BMP_MAX
|
||||
|
||||
@property
|
||||
def created(self):
|
||||
return Font.sfntime(self.params.created)
|
||||
|
||||
def decode(self, data):
|
||||
return codecs.decode(data, self.params.encoding)
|
||||
|
||||
def em_scale(self, value, divisor=0):
|
||||
return round(value * self.params.em_size / (divisor or self.bbx.height))
|
||||
|
||||
def em_scale_width(self, base):
|
||||
return self.em_scale(base.bbx.width)
|
||||
|
||||
@property
|
||||
def italic_angle(self):
|
||||
value = self.props.get('ITALIC_ANGLE') # must be integer
|
||||
return fnutil.parse_dec('ITALIC_ANGLE', value, -45, 45) if value else -11.5 if self.italic else 0
|
||||
|
||||
@property
|
||||
def max_code(self):
|
||||
return self.chars[-1].code
|
||||
|
||||
@property
|
||||
def min_code(self):
|
||||
return self.chars[0].code
|
||||
|
||||
@property
|
||||
def modified(self):
|
||||
return Font.sfntime(self.params.modified)
|
||||
|
||||
|
||||
def prepare(self):
|
||||
self.chars.sort(key=lambda c: c.code)
|
||||
self.chars = [next(elem[1]) for elem in groupby(self.chars, key=lambda c: c.code)]
|
||||
self.props.set('CHARS', len(self.chars))
|
||||
self.em_ascender = self.em_scale(self.px_ascender)
|
||||
self.em_descender = self.em_ascender - self.params.em_size
|
||||
self.em_max_width = self.em_scale_width(self)
|
||||
self.mac_style = int(self.bold) + (int(self.italic) << 1)
|
||||
self.line_size = self.em_scale(round(self.bbx.height / 17) or 1)
|
||||
|
||||
|
||||
def _read(self, input):
|
||||
bdfexp.Font._read(self, input)
|
||||
self.prepare()
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
def read(input, params): # pylint: disable=arguments-differ
|
||||
return Font(params)._read(input) # pylint: disable=protected-access
|
||||
|
||||
|
||||
@staticmethod
|
||||
def sfntime(stamp):
|
||||
return math.floor((stamp - datetime(1904, 1, 1, tzinfo=timezone.utc)).total_seconds())
|
||||
|
||||
@property
|
||||
def underline_position(self):
|
||||
return round((self.em_descender + self.line_size) / 2)
|
||||
|
||||
@property
|
||||
def x_max_extent(self):
|
||||
return self.em_max_width if self.params.x_max_extent else 0
|
||||
|
||||
|
||||
# -- BDAT --
|
||||
BDAT_HEADER_SIZE = 4
|
||||
BDAT_METRIC_SIZE = 5
|
||||
|
||||
class BDAT(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'EBDT')
|
||||
# header
|
||||
self.write_fixed(2, 'version')
|
||||
# format 1 data
|
||||
for char in font.chars:
|
||||
self.write_uint8(font.bbx.height, 'height')
|
||||
self.write_uint8(char.bbx.width, 'width')
|
||||
self.write_int8(0, 'bearingX')
|
||||
self.write_int8(font.px_ascender, 'bearingY')
|
||||
self.write_uint8(char.bbx.width, 'advance')
|
||||
self.write(char.data) # imageData
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_char_size(char):
|
||||
return BDAT_METRIC_SIZE + len(char.data)
|
||||
|
||||
|
||||
# -- BLOC --
|
||||
BLOC_TABLE_SIZE_OFFSET = 12
|
||||
BLOC_PREFIX_SIZE = 0x38 # header 0x08 + 1 bitmapSizeTable * 0x30
|
||||
BLOC_INDEX_ARRAY_SIZE = 8 # 1 index record * 0x08
|
||||
|
||||
class BLOC(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'EBLC')
|
||||
# header
|
||||
self.write_fixed(2, 'version')
|
||||
self.write_uint32(1, 'numSizes')
|
||||
# bitmapSizeTable
|
||||
self.write_uint32(BLOC_PREFIX_SIZE, 'indexSubTableArrayOffset')
|
||||
self.write_uint32(0, 'indexTableSize') # adjusted later
|
||||
self.write_uint32(1, 'numberOfIndexSubTables')
|
||||
self.write_uint32(0, 'colorRef')
|
||||
# hori
|
||||
self.write_int8(font.px_ascender, 'hori ascender')
|
||||
self.write_int8(font.px_descender, 'hori descender')
|
||||
self.write_uint8(font.bbx.width, 'hori widthMax')
|
||||
self.write_int8(1, 'hori caretSlopeNumerator')
|
||||
self.write_int8(0, 'hori caretSlopeDenominator')
|
||||
self.write_int8(0, 'hori caretOffset')
|
||||
self.write_int8(0, 'hori minOriginSB')
|
||||
self.write_int8(0, 'hori minAdvanceSB')
|
||||
self.write_int8(font.px_ascender, 'hori maxBeforeBL')
|
||||
self.write_int8(font.px_descender, 'hori minAfterBL')
|
||||
self.write_int16(0, 'hori padd')
|
||||
# vert
|
||||
self.write_int8(0, 'vert ascender')
|
||||
self.write_int8(0, 'vert descender')
|
||||
self.write_uint8(0, 'vert widthMax')
|
||||
self.write_int8(0, 'vert caretSlopeNumerator')
|
||||
self.write_int8(0, 'vert caretSlopeDenominator')
|
||||
self.write_int8(0, 'vert caretOffset')
|
||||
self.write_int8(0, 'vert minOriginSB')
|
||||
self.write_int8(0, 'vert minAdvanceSB')
|
||||
self.write_int8(0, 'vert maxBeforeBL')
|
||||
self.write_int8(0, 'vert minAfterBL')
|
||||
self.write_int16(0, 'vert padd')
|
||||
# (bitmapSizeTable)
|
||||
self.write_uint16(0, 'startGlyphIndex')
|
||||
self.write_uint16(len(font.chars) - 1, 'endGlyphIndex')
|
||||
self.write_uint8(font.bbx.height, 'ppemX')
|
||||
self.write_uint8(font.bbx.height, 'ppemY')
|
||||
self.write_uint8(1, 'bitDepth')
|
||||
self.write_uint8(1, 'flags') # small metrics are horizontal
|
||||
# indexSubTableArray
|
||||
self.write_uint16(0, 'firstGlyphIndex')
|
||||
self.write_uint16(len(font.chars) - 1, 'lastGlyphIndex')
|
||||
self.write_uint32(BLOC_INDEX_ARRAY_SIZE, 'additionalOffsetToIndexSubtable')
|
||||
# indexSubtableHeader
|
||||
self.write_uint16(1 if font.proportional else 2, 'indexFormat')
|
||||
self.write_uint16(1, 'imageFormat') # BDAT -> small metrics, byte-aligned
|
||||
self.write_uint32(BDAT_HEADER_SIZE, 'imageDataOffset')
|
||||
# indexSubtable data
|
||||
if font.proportional:
|
||||
offset = 0
|
||||
|
||||
for char in font.chars:
|
||||
self.write_uint32(offset, 'offsetArray[]')
|
||||
offset += BDAT.get_char_size(char)
|
||||
|
||||
self.write_uint32(offset, 'offsetArray[]')
|
||||
else:
|
||||
self.write_uint32(BDAT.get_char_size(font.chars[0]), 'imageSize')
|
||||
self.write_uint8(font.bbx.height, 'height')
|
||||
self.write_uint8(font.bbx.width, 'width')
|
||||
self.write_int8(0, 'horiBearingX')
|
||||
self.write_int8(font.px_ascender, 'horiBearingY')
|
||||
self.write_uint8(font.bbx.width, 'horiAdvance')
|
||||
self.write_int8(-(font.bbx.width >> 1), 'vertBearingX')
|
||||
self.write_int8(0, 'vertBearingY')
|
||||
self.write_uint8(font.bbx.height, 'vertAdvance')
|
||||
# adjust
|
||||
self.rewrite_uint32(self.size - BLOC_PREFIX_SIZE, BLOC_TABLE_SIZE_OFFSET)
|
||||
|
||||
|
||||
# -- OS/2 --
|
||||
OS_2_TABLE_SIZE = 96
|
||||
|
||||
class OS_2(Table): # pylint: disable=invalid-name
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'OS/2')
|
||||
# Version 4
|
||||
x_avg_char_width = font.em_scale(font.avg_width) # otb1get.x_avg_char_width(font)
|
||||
ul_char_ranges = otb1get.ul_char_ranges(font)
|
||||
ul_code_pages = otb1get.ul_code_pages(font) if font.bmp_only else [0, 0]
|
||||
# mostly from FontForge
|
||||
script_xsize = font.em_scale(30, 100)
|
||||
script_ysize = font.em_scale(40, 100)
|
||||
subscript_yoff = script_ysize >> 1
|
||||
xfactor = math.tan(font.italic_angle * math.pi / 180)
|
||||
subscript_xoff = 0 # stub, no overlapping characters yet
|
||||
superscript_yoff = font.em_ascender - script_ysize
|
||||
superscript_xoff = -round(xfactor * superscript_yoff)
|
||||
# write
|
||||
self.write_uint16(4, 'version')
|
||||
self.write_int16(x_avg_char_width, 'xAvgCharWidth')
|
||||
self.write_uint16(700 if font.bold else 400, 'usWeightClass')
|
||||
self.write_uint16(5, 'usWidthClass') # medium
|
||||
self.write_int16(0, 'fsType')
|
||||
self.write_int16(script_xsize, 'ySubscriptXSize')
|
||||
self.write_int16(script_ysize, 'ySubscriptYSize')
|
||||
self.write_int16(subscript_xoff, 'ySubscriptXOffset')
|
||||
self.write_int16(subscript_yoff, 'ySubscriptYOffset')
|
||||
self.write_int16(script_xsize, 'ySuperscriptXSize')
|
||||
self.write_int16(script_ysize, 'ySuperscriptYSize')
|
||||
self.write_int16(superscript_xoff, 'ySuperscriptXOffset')
|
||||
self.write_int16(superscript_yoff, 'ySuperscriptYOffset')
|
||||
self.write_int16(font.line_size, 'yStrikeoutSize')
|
||||
self.write_int16(font.em_scale(25, 100), 'yStrikeoutPosition')
|
||||
self.write_int16(0, 'sFamilyClass') # no classification
|
||||
self.write_uint8(2, 'bFamilyType') # text and display
|
||||
self.write_uint8(0, 'bSerifStyle') # any
|
||||
self.write_uint8(8 if font.bold else 6, 'bWeight')
|
||||
self.write_uint8(3 if font.proportional else 9, 'bProportion')
|
||||
self.write_uint8(0, 'bContrast')
|
||||
self.write_uint8(0, 'bStrokeVariation')
|
||||
self.write_uint8(0, 'bArmStyle')
|
||||
self.write_uint8(0, 'bLetterform')
|
||||
self.write_uint8(0, 'bMidline')
|
||||
self.write_uint8(0, 'bXHeight')
|
||||
self.write_uint32(ul_char_ranges[0], 'ulCharRange1')
|
||||
self.write_uint32(ul_char_ranges[1], 'ulCharRange2')
|
||||
self.write_uint32(ul_char_ranges[2], 'ulCharRange3')
|
||||
self.write_uint32(ul_char_ranges[3], 'ulCharRange4')
|
||||
self.write_uint32(0x586F7334, 'achVendID') # 'Xos4'
|
||||
self.write_uint16(OS_2.fs_selection(font), 'fsSelection')
|
||||
self.write_uint16(min(font.min_code, fnutil.UNICODE_BMP_MAX), 'firstChar')
|
||||
self.write_uint16(min(font.max_code, fnutil.UNICODE_BMP_MAX), 'lastChar')
|
||||
self.write_int16(font.em_ascender, 'sTypoAscender')
|
||||
self.write_int16(font.em_descender, 'sTypoDescender')
|
||||
self.write_int16(font.params.line_gap, 'sTypoLineGap')
|
||||
self.write_uint16(font.em_ascender, 'usWinAscent')
|
||||
self.write_uint16(-font.em_descender, 'usWinDescent')
|
||||
self.write_uint32(ul_code_pages[0], 'ulCodePageRange1')
|
||||
self.write_uint32(ul_code_pages[1], 'ulCodePageRange2')
|
||||
self.write_int16(font.em_scale(font.px_ascender * 0.6), 'sxHeight') # stub
|
||||
self.write_int16(font.em_scale(font.px_ascender * 0.8), 'sCapHeight') # stub
|
||||
self.write_uint16(OS_2.default_char(font), 'usDefaultChar')
|
||||
self.write_uint16(OS_2.break_char(font), 'usBreakChar')
|
||||
self.write_uint16(1, 'usMaxContext')
|
||||
# check
|
||||
self.check_size(OS_2_TABLE_SIZE)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def break_char(font):
|
||||
return 0x20 if next((char for char in font.chars if char.code == 0x20), None) else font.min_code
|
||||
|
||||
|
||||
@staticmethod
|
||||
def default_char(font):
|
||||
if font.default_code != -1 and font.default_code <= fnutil.UNICODE_BMP_MAX:
|
||||
return font.default_code
|
||||
|
||||
return 0 if font.min_code == 0 else font.max_code
|
||||
|
||||
|
||||
@staticmethod
|
||||
def fs_selection(font):
|
||||
fs_selection = int(font.bold) * 5 + int(font.italic)
|
||||
return fs_selection if fs_selection != 0 else 0x40 if font.xlfd[bdf.XLFD.SLANT] == 'R' else 0
|
||||
|
||||
|
||||
# -- cmap --
|
||||
CMAP_4_PREFIX_SIZE = 12
|
||||
CMAP_4_FORMAT_SIZE = 16
|
||||
CMAP_4_SEGMENT_SIZE = 8
|
||||
|
||||
CMAP_12_PREFIX_SIZE = 20
|
||||
CMAP_12_FORMAT_SIZE = 16
|
||||
CMAP_12_GROUP_SIZE = 12
|
||||
|
||||
class CMapRange:
|
||||
def __init__(self, glyph_index=0, start_code=0, final_code=-2):
|
||||
self.glyph_index = glyph_index
|
||||
self.start_code = start_code
|
||||
self.final_code = final_code
|
||||
|
||||
|
||||
@property
|
||||
def id_delta(self):
|
||||
return (self.glyph_index - self.start_code) & 0xFFFF
|
||||
|
||||
|
||||
class CMAP(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'cmap')
|
||||
# make ranges
|
||||
ranges = []
|
||||
range = CMapRange()
|
||||
index = -1
|
||||
|
||||
for char in font.chars:
|
||||
index += 1
|
||||
code = char.code
|
||||
|
||||
if code == range.final_code + 1:
|
||||
range.final_code += 1
|
||||
else:
|
||||
range = CMapRange(index, code, code)
|
||||
ranges.append(range)
|
||||
# write
|
||||
if font.bmp_only:
|
||||
if font.max_code < 0xFFFF:
|
||||
ranges.append(CMapRange(0, 0xFFFF, 0xFFFF))
|
||||
|
||||
self.write_format_4(ranges)
|
||||
else:
|
||||
self.write_format_12(ranges)
|
||||
|
||||
|
||||
def write_format_4(self, ranges):
|
||||
# index
|
||||
self.write_uint16(0, 'version')
|
||||
self.write_uint16(1, 'numberSubtables')
|
||||
# encoding subtables index
|
||||
self.write_uint16(3, 'platformID') # Microsoft
|
||||
self.write_uint16(1, 'platformSpecificID') # Unicode BMP (UCS-2)
|
||||
self.write_uint32(CMAP_4_PREFIX_SIZE, 'offset') # for Unicode BMP (UCS-2)
|
||||
# cmap format 4
|
||||
seg_count = len(ranges)
|
||||
subtable_size = CMAP_4_FORMAT_SIZE + seg_count * CMAP_4_SEGMENT_SIZE
|
||||
search_range = 2 << math.floor(math.log2(seg_count))
|
||||
|
||||
self.write_uint16(4, 'format')
|
||||
self.write_uint16(subtable_size, 'length')
|
||||
self.write_uint16(0, 'language') # none/independent
|
||||
self.write_uint16(seg_count * 2, 'segCountX2')
|
||||
self.write_uint16(search_range, 'searchRange')
|
||||
self.write_uint16(int(math.log2(search_range / 2)), 'entrySelector')
|
||||
self.write_uint16((seg_count * 2) - search_range, 'rangeShift')
|
||||
for range in ranges:
|
||||
self.write_uint16(range.final_code, 'endCode')
|
||||
self.write_uint16(0, 'reservedPad')
|
||||
for range in ranges:
|
||||
self.write_uint16(range.start_code, 'startCode')
|
||||
for range in ranges:
|
||||
self.write_uint16(range.id_delta, 'idDelta')
|
||||
for _ in ranges:
|
||||
self.write_uint16(0, 'idRangeOffset')
|
||||
# check
|
||||
self.check_size(CMAP_4_PREFIX_SIZE + subtable_size)
|
||||
|
||||
|
||||
def write_format_12(self, ranges):
|
||||
# index
|
||||
self.write_uint16(0, 'version')
|
||||
self.write_uint16(2, 'numberSubtables')
|
||||
# encoding subtables
|
||||
self.write_uint16(0, 'platformID') # Unicode
|
||||
self.write_uint16(4, 'platformSpecificID') # Unicode 2.0+ full range
|
||||
self.write_uint32(CMAP_12_PREFIX_SIZE, 'offset') # for Unicode 2.0+ full range
|
||||
self.write_uint16(3, 'platformID') # Microsoft
|
||||
self.write_uint16(10, 'platformSpecificID') # Unicode UCS-4
|
||||
self.write_uint32(CMAP_12_PREFIX_SIZE, 'offset') # for Unicode UCS-4
|
||||
# cmap format 12
|
||||
subtable_size = CMAP_12_FORMAT_SIZE + len(ranges) * CMAP_12_GROUP_SIZE
|
||||
|
||||
self.write_fixed(12, 'format')
|
||||
self.write_uint32(subtable_size, 'length')
|
||||
self.write_uint32(0, 'language') # none/independent
|
||||
self.write_uint32(len(ranges), 'nGroups')
|
||||
for range in ranges:
|
||||
self.write_uint32(range.start_code, 'startCharCode')
|
||||
self.write_uint32(range.final_code, 'endCharCode')
|
||||
self.write_uint32(range.glyph_index, 'startGlyphID')
|
||||
# check
|
||||
self.check_size(CMAP_12_PREFIX_SIZE + subtable_size)
|
||||
|
||||
|
||||
# -- glyf --
|
||||
class GLYF(Table):
|
||||
def __init__(self, _font):
|
||||
Table.__init__(self, 'glyf')
|
||||
|
||||
|
||||
# -- head --
|
||||
HEAD_TABLE_SIZE = 54
|
||||
HEAD_CHECKSUM_OFFSET = 8
|
||||
|
||||
class HEAD(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'head')
|
||||
self.write_fixed(1, 'version')
|
||||
self.write_fixed(1, 'fontRevision')
|
||||
self.write_uint32(0, 'checksumAdjustment') # adjusted later
|
||||
self.write_uint32(0x5F0F3CF5, 'magicNumber')
|
||||
self.write_uint16(HEAD.flags(font), 'flags')
|
||||
self.write_uint16(font.params.em_size, 'unitsPerEm')
|
||||
self.write_uint64(font.created, 'created')
|
||||
self.write_uint64(font.modified, 'modified')
|
||||
self.write_int16(0, 'xMin')
|
||||
self.write_int16(font.em_descender, 'yMin')
|
||||
self.write_int16(font.em_max_width, 'xMax')
|
||||
self.write_int16(font.em_ascender, 'yMax')
|
||||
self.write_uint16(font.mac_style, 'macStyle')
|
||||
self.write_uint16(font.params.low_ppem or font.bbx.height, 'lowestRecPPEM')
|
||||
self.write_int16(font.params.dir_hint, 'fontDirectionHint')
|
||||
self.write_int16(0, 'indexToLocFormat') # short
|
||||
self.write_int16(0, 'glyphDataFormat') # current
|
||||
# check
|
||||
self.check_size(HEAD_TABLE_SIZE)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def flags(font):
|
||||
return 0x20B if otb1get.contains_rtl(font) else 0x0B # y0 base, x0 lsb, scale int
|
||||
|
||||
|
||||
# -- hhea --
|
||||
HHEA_TABLE_SIZE = 36
|
||||
|
||||
class HHEA(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'hhea')
|
||||
self.write_fixed(1, 'version')
|
||||
self.write_int16(font.em_ascender, 'ascender')
|
||||
self.write_int16(font.em_descender, 'descender')
|
||||
self.write_int16(font.params.line_gap, 'lineGap')
|
||||
self.write_uint16(font.em_max_width, 'advanceWidthMax')
|
||||
self.write_int16(0, 'minLeftSideBearing')
|
||||
self.write_int16(0, 'minRightSideBearing')
|
||||
self.write_int16(font.x_max_extent, 'xMaxExtent')
|
||||
self.write_int16(100 if font.italic else 1, 'caretSlopeRise')
|
||||
self.write_int16(20 if font.italic else 0, 'caretSlopeRun')
|
||||
self.write_int16(0, 'caretOffset')
|
||||
self.write_int16(0, 'reserved')
|
||||
self.write_int16(0, 'reserved')
|
||||
self.write_int16(0, 'reserved')
|
||||
self.write_int16(0, 'reserved')
|
||||
self.write_int16(0, 'metricDataFormat') # current
|
||||
self.write_uint16(len(font.chars), 'numOfLongHorMetrics')
|
||||
# check
|
||||
self.check_size(HHEA_TABLE_SIZE)
|
||||
|
||||
|
||||
# -- hmtx --
|
||||
class HMTX(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'hmtx')
|
||||
for char in font.chars:
|
||||
self.write_uint16(font.em_scale_width(char), 'advanceWidth')
|
||||
self.write_int16(0, 'leftSideBearing')
|
||||
|
||||
|
||||
# -- loca --
|
||||
class LOCA(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'loca')
|
||||
if not font.params.single_loca:
|
||||
for _ in font.chars:
|
||||
self.write_uint16(0, 'offset')
|
||||
self.write_uint16(0, 'offset')
|
||||
|
||||
|
||||
# -- maxp --
|
||||
MAXP_TABLE_SIZE = 32
|
||||
|
||||
class MAXP(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'maxp')
|
||||
self.write_fixed(1, 'version')
|
||||
self.write_uint16(len(font.chars), 'numGlyphs')
|
||||
self.write_uint16(0, 'maxPoints')
|
||||
self.write_uint16(0, 'maxContours')
|
||||
self.write_uint16(0, 'maxComponentPoints')
|
||||
self.write_uint16(0, 'maxComponentContours')
|
||||
self.write_uint16(2, 'maxZones')
|
||||
self.write_uint16(0, 'maxTwilightPoints')
|
||||
self.write_uint16(1, 'maxStorage')
|
||||
self.write_uint16(1, 'maxFunctionDefs')
|
||||
self.write_uint16(0, 'maxInstructionDefs')
|
||||
self.write_uint16(64, 'maxStackElements')
|
||||
self.write_uint16(0, 'maxSizeOfInstructions')
|
||||
self.write_uint16(0, 'maxComponentElements')
|
||||
self.write_uint16(0, 'maxComponentDepth')
|
||||
# check
|
||||
self.check_size(MAXP_TABLE_SIZE)
|
||||
|
||||
|
||||
# -- name --
|
||||
@unique # pylint: disable=invalid-name
|
||||
class NAME_ID(IntEnum): # pylint: disable=invalid-name
|
||||
COPYRIGHT = 0
|
||||
FONT_FAMILY = 1
|
||||
FONT_SUBFAMILY = 2
|
||||
UNIQUE_SUBFAMILY = 3
|
||||
FULL_FONT_NAME = 4
|
||||
LICENSE = 14
|
||||
|
||||
NAME_HEADER_SIZE = 6
|
||||
NAME_RECORD_SIZE = 12
|
||||
|
||||
class NAME(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'name')
|
||||
# compute names
|
||||
names = OrderedDict()
|
||||
copyright = font.props.get('COPYRIGHT')
|
||||
|
||||
if copyright is not None:
|
||||
names[NAME_ID.COPYRIGHT] = fnutil.unquote(copyright)
|
||||
|
||||
family = font.xlfd[bdf.XLFD.FAMILY_NAME]
|
||||
style = [b'Regular', b'Bold', b'Italic', b'Bold Italic'][font.mac_style]
|
||||
|
||||
names[NAME_ID.FONT_FAMILY] = family
|
||||
names[NAME_ID.FONT_SUBFAMILY] = style
|
||||
names[NAME_ID.UNIQUE_SUBFAMILY] = b'%s %s bitmap height %d' % (family, style, font.bbx.height)
|
||||
names[NAME_ID.FULL_FONT_NAME] = b'%s %s' % (family, style)
|
||||
|
||||
license = font.props.get('LICENSE')
|
||||
notice = font.props.get('NOTICE')
|
||||
|
||||
if license is None and notice is not None and b'license' in notice.lower():
|
||||
license = notice
|
||||
|
||||
if license is not None:
|
||||
names[NAME_ID.LICENSE] = fnutil.unquote(license)
|
||||
|
||||
# header
|
||||
count = len(names) * (1 + 1) # Unicode + Microsoft
|
||||
string_offset = NAME_HEADER_SIZE + NAME_RECORD_SIZE * count
|
||||
|
||||
self.write_uint16(0, 'format')
|
||||
self.write_uint16(count, 'count')
|
||||
self.write_uint16(string_offset, 'stringOffset')
|
||||
# name records / create values
|
||||
values = Table('name')
|
||||
|
||||
for [name_id, bstr] in names.items():
|
||||
s = font.decode(bstr)
|
||||
value = codecs.encode(s, 'utf_16_be')
|
||||
bmp = font.bmp_only and len(value) == len(s) * 2
|
||||
# Unicode
|
||||
self.write_uint16(0, 'platformID') # Unicode
|
||||
self.write_uint16(3 if bmp else 4, 'platformSpecificID')
|
||||
self.write_uint16(0, 'languageID') # none
|
||||
self.write_uint16(name_id, 'nameID')
|
||||
self.write_uint16(len(value), 'length') # in bytes
|
||||
self.write_uint16(values.size, 'offset')
|
||||
# Microsoft
|
||||
self.write_uint16(3, 'platformID') # Microsoft
|
||||
self.write_uint16(1 if bmp else 10, 'platformSpecificID')
|
||||
self.write_uint16(font.params.w_lang_id, 'languageID')
|
||||
self.write_uint16(name_id, 'nameID')
|
||||
self.write_uint16(len(value), 'length') # in bytes
|
||||
self.write_uint16(values.size, 'offset')
|
||||
# value
|
||||
values.write(value)
|
||||
|
||||
# write values
|
||||
self.write_table(values)
|
||||
# check
|
||||
self.check_size(string_offset + values.size)
|
||||
|
||||
|
||||
# -- post --
|
||||
POST_TABLE_SIZE = 32
|
||||
|
||||
class POST(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'post')
|
||||
self.write_fixed(2 if font.params.post_names else 3, 'format')
|
||||
self.write_fixed(font.italic_angle, 'italicAngle')
|
||||
self.write_int16(font.underline_position, 'underlinePosition')
|
||||
self.write_int16(font.line_size, 'underlineThickness')
|
||||
self.write_uint32(0 if font.proportional else 1, 'isFixedPitch')
|
||||
self.write_uint32(0, 'minMemType42')
|
||||
self.write_uint32(0, 'maxMemType42')
|
||||
self.write_uint32(0, 'minMemType1')
|
||||
self.write_uint32(0, 'maxMemType1')
|
||||
# names
|
||||
if font.params.post_names:
|
||||
self.write_uint16(len(font.chars), 'numberOfGlyphs')
|
||||
post_names = otb1get.post_mac_names()
|
||||
post_mac_count = len(post_names)
|
||||
|
||||
for name in [char.props['STARTCHAR'] for char in font.chars]:
|
||||
if name in post_names:
|
||||
self.write_uint16(post_names.index(name), 'glyphNameIndex')
|
||||
else:
|
||||
self.write_uint16(len(post_names), 'glyphNameIndex')
|
||||
post_names.append(name)
|
||||
|
||||
for name in post_names[post_mac_count:]:
|
||||
self.write_uint8(len(name), 'glyphNameLength')
|
||||
self.write(name)
|
||||
# check
|
||||
else:
|
||||
self.check_size(POST_TABLE_SIZE)
|
||||
|
||||
|
||||
# -- SFNT --
|
||||
SFNT_HEADER_SIZE = 12
|
||||
SFNT_RECORD_SIZE = 16
|
||||
SFNT_SUBTABLES = (BDAT, BLOC, OS_2, CMAP, GLYF, HEAD, HHEA, HMTX, LOCA, MAXP, NAME, POST)
|
||||
|
||||
class SFNT(Table):
|
||||
def __init__(self, font):
|
||||
Table.__init__(self, 'SFNT')
|
||||
# create tables
|
||||
tables = []
|
||||
for ctor in SFNT_SUBTABLES:
|
||||
tables.append(ctor(font))
|
||||
# header
|
||||
num_tables = len(tables)
|
||||
entry_selector = math.floor(math.log2(num_tables))
|
||||
search_range = 16 << entry_selector
|
||||
content_offset = SFNT_HEADER_SIZE + num_tables * SFNT_RECORD_SIZE
|
||||
offset = content_offset
|
||||
content = Table('SFNT')
|
||||
head_checksum_offset = -1
|
||||
|
||||
self.write_fixed(1, 'sfntVersion')
|
||||
self.write_uint16(num_tables, 'numTables')
|
||||
self.write_uint16(search_range, 'searchRange')
|
||||
self.write_uint16(entry_selector, 'entrySelector')
|
||||
self.write_uint16(num_tables * 16 - search_range, 'rangeShift')
|
||||
# table records / create content
|
||||
for table in tables:
|
||||
self.write(bytes(table.table_name, 'ascii'))
|
||||
self.write_uint32(table.checksum(), 'checkSum')
|
||||
self.write_uint32(offset, 'offset')
|
||||
self.write_uint32(len(table.data), 'length')
|
||||
# create content
|
||||
if table.table_name == 'head':
|
||||
head_checksum_offset = offset + HEAD_CHECKSUM_OFFSET
|
||||
|
||||
padded_data = table.data + table.padding
|
||||
content.write(padded_data)
|
||||
offset += len(padded_data)
|
||||
# write content
|
||||
self.write_table(content)
|
||||
# check
|
||||
self.check_size(content_offset + len(content.data))
|
||||
# adjust
|
||||
if head_checksum_offset != -1:
|
||||
self.rewrite_uint32((0xB1B0AFBA - self.checksum()) & 0xFFFFFFFF, head_checksum_offset)
|
||||
@@ -0,0 +1,706 @@
|
||||
/*
|
||||
Copyright (C) 2018-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
|
||||
// -- xAvgCharWidth --
|
||||
const WEIGHT_FACTORS = [
|
||||
[ 'a', 64 ],
|
||||
[ 'b', 14 ],
|
||||
[ 'c', 27 ],
|
||||
[ 'd', 35 ],
|
||||
[ 'e', 100 ],
|
||||
[ 'f', 20 ],
|
||||
[ 'g', 14 ],
|
||||
[ 'h', 42 ],
|
||||
[ 'i', 63 ],
|
||||
[ 'j', 3 ],
|
||||
[ 'k', 6 ],
|
||||
[ 'l', 35 ],
|
||||
[ 'm', 20 ],
|
||||
[ 'n', 56 ],
|
||||
[ 'o', 56 ],
|
||||
[ 'p', 17 ],
|
||||
[ 'q', 4 ],
|
||||
[ 'r', 49 ],
|
||||
[ 's', 56 ],
|
||||
[ 't', 71 ],
|
||||
[ 'u', 31 ],
|
||||
[ 'v', 10 ],
|
||||
[ 'w', 18 ],
|
||||
[ 'x', 3 ],
|
||||
[ 'y', 18 ],
|
||||
[ 'z', 2 ],
|
||||
[ ' ', 166 ]
|
||||
];
|
||||
|
||||
function xAvgCharWidth(font) {
|
||||
let xAvgTotalWidth = 0;
|
||||
|
||||
for (let factor of WEIGHT_FACTORS) {
|
||||
const char = font.chars.find(_char => _char.code === factor[0].charCodeAt(0));
|
||||
|
||||
if (char == null) {
|
||||
return 0;
|
||||
}
|
||||
xAvgTotalWidth += font.scaleWidth(char) * factor[1];
|
||||
}
|
||||
|
||||
return fnutil.round(xAvgTotalWidth / 1000);
|
||||
}
|
||||
|
||||
// -- ulCharRanges --
|
||||
const CHAR_RANGES = [
|
||||
[ 0, 0x0000, 0x007F ],
|
||||
[ 1, 0x0080, 0x00FF ],
|
||||
[ 2, 0x0100, 0x017F ],
|
||||
[ 3, 0x0180, 0x024F ],
|
||||
[ 4, 0x0250, 0x02AF ],
|
||||
[ 4, 0x1D00, 0x1D7F ],
|
||||
[ 4, 0x1D80, 0x1DBF ],
|
||||
[ 5, 0x02B0, 0x02FF ],
|
||||
[ 5, 0xA700, 0xA71F ],
|
||||
[ 6, 0x0300, 0x036F ],
|
||||
[ 6, 0x1DC0, 0x1DFF ],
|
||||
[ 7, 0x0370, 0x03FF ],
|
||||
[ 8, 0x2C80, 0x2CFF ],
|
||||
[ 9, 0x0400, 0x04FF ],
|
||||
[ 9, 0x0500, 0x052F ],
|
||||
[ 9, 0x2DE0, 0x2DFF ],
|
||||
[ 9, 0xA640, 0xA69F ],
|
||||
[ 10, 0x0530, 0x058F ],
|
||||
[ 11, 0x0590, 0x05FF ],
|
||||
[ 12, 0xA500, 0xA63F ],
|
||||
[ 13, 0x0600, 0x06FF ],
|
||||
[ 13, 0x0750, 0x077F ],
|
||||
[ 14, 0x07C0, 0x07FF ],
|
||||
[ 15, 0x0900, 0x097F ],
|
||||
[ 16, 0x0980, 0x09FF ],
|
||||
[ 17, 0x0A00, 0x0A7F ],
|
||||
[ 18, 0x0A80, 0x0AFF ],
|
||||
[ 19, 0x0B00, 0x0B7F ],
|
||||
[ 20, 0x0B80, 0x0BFF ],
|
||||
[ 21, 0x0C00, 0x0C7F ],
|
||||
[ 22, 0x0C80, 0x0CFF ],
|
||||
[ 23, 0x0D00, 0x0D7F ],
|
||||
[ 24, 0x0E00, 0x0E7F ],
|
||||
[ 25, 0x0E80, 0x0EFF ],
|
||||
[ 26, 0x10A0, 0x10FF ],
|
||||
[ 26, 0x2D00, 0x2D2F ],
|
||||
[ 27, 0x1B00, 0x1B7F ],
|
||||
[ 28, 0x1100, 0x11FF ],
|
||||
[ 29, 0x1E00, 0x1EFF ],
|
||||
[ 29, 0x2C60, 0x2C7F ],
|
||||
[ 29, 0xA720, 0xA7FF ],
|
||||
[ 30, 0x1F00, 0x1FFF ],
|
||||
[ 31, 0x2000, 0x206F ],
|
||||
[ 31, 0x2E00, 0x2E7F ],
|
||||
[ 32, 0x2070, 0x209F ],
|
||||
[ 33, 0x20A0, 0x20CF ],
|
||||
[ 34, 0x20D0, 0x20FF ],
|
||||
[ 35, 0x2100, 0x214F ],
|
||||
[ 36, 0x2150, 0x218F ],
|
||||
[ 37, 0x2190, 0x21FF ],
|
||||
[ 37, 0x27F0, 0x27FF ],
|
||||
[ 37, 0x2900, 0x297F ],
|
||||
[ 37, 0x2B00, 0x2BFF ],
|
||||
[ 38, 0x2200, 0x22FF ],
|
||||
[ 38, 0x2A00, 0x2AFF ],
|
||||
[ 38, 0x27C0, 0x27EF ],
|
||||
[ 38, 0x2980, 0x29FF ],
|
||||
[ 39, 0x2300, 0x23FF ],
|
||||
[ 40, 0x2400, 0x243F ],
|
||||
[ 41, 0x2440, 0x245F ],
|
||||
[ 42, 0x2460, 0x24FF ],
|
||||
[ 43, 0x2500, 0x257F ],
|
||||
[ 44, 0x2580, 0x259F ],
|
||||
[ 45, 0x25A0, 0x25FF ],
|
||||
[ 46, 0x2600, 0x26FF ],
|
||||
[ 47, 0x2700, 0x27BF ],
|
||||
[ 48, 0x3000, 0x303F ],
|
||||
[ 49, 0x3040, 0x309F ],
|
||||
[ 50, 0x30A0, 0x30FF ],
|
||||
[ 50, 0x31F0, 0x31FF ],
|
||||
[ 51, 0x3100, 0x312F ],
|
||||
[ 51, 0x31A0, 0x31BF ],
|
||||
[ 52, 0x3130, 0x318F ],
|
||||
[ 53, 0xA840, 0xA87F ],
|
||||
[ 54, 0x3200, 0x32FF ],
|
||||
[ 55, 0x3300, 0x33FF ],
|
||||
[ 56, 0xAC00, 0xD7AF ],
|
||||
[ 57, 0xD800, 0xDFFF ],
|
||||
[ 58, 0x10900, 0x1091F ],
|
||||
[ 59, 0x4E00, 0x9FFF ],
|
||||
[ 59, 0x2E80, 0x2EFF ],
|
||||
[ 59, 0x2F00, 0x2FDF ],
|
||||
[ 59, 0x2FF0, 0x2FFF ],
|
||||
[ 59, 0x3400, 0x4DBF ],
|
||||
[ 59, 0x20000, 0x2A6DF ],
|
||||
[ 59, 0x3190, 0x319F ],
|
||||
[ 60, 0xE000, 0xF8FF ],
|
||||
[ 61, 0x31C0, 0x31EF ],
|
||||
[ 61, 0xF900, 0xFAFF ],
|
||||
[ 61, 0x2F800, 0x2FA1F ],
|
||||
[ 62, 0xFB00, 0xFB4F ],
|
||||
[ 63, 0xFB50, 0xFDFF ],
|
||||
[ 64, 0xFE20, 0xFE2F ],
|
||||
[ 65, 0xFE10, 0xFE1F ],
|
||||
[ 65, 0xFE30, 0xFE4F ],
|
||||
[ 66, 0xFE50, 0xFE6F ],
|
||||
[ 67, 0xFE70, 0xFEFF ],
|
||||
[ 68, 0xFF00, 0xFFEF ],
|
||||
[ 69, 0xFFF0, 0xFFFF ],
|
||||
[ 70, 0x0F00, 0x0FFF ],
|
||||
[ 71, 0x0700, 0x074F ],
|
||||
[ 72, 0x0780, 0x07BF ],
|
||||
[ 73, 0x0D80, 0x0DFF ],
|
||||
[ 74, 0x1000, 0x109F ],
|
||||
[ 75, 0x1200, 0x137F ],
|
||||
[ 75, 0x1380, 0x139F ],
|
||||
[ 75, 0x2D80, 0x2DDF ],
|
||||
[ 76, 0x13A0, 0x13FF ],
|
||||
[ 77, 0x1400, 0x167F ],
|
||||
[ 78, 0x1680, 0x169F ],
|
||||
[ 79, 0x16A0, 0x16FF ],
|
||||
[ 80, 0x1780, 0x17FF ],
|
||||
[ 80, 0x19E0, 0x19FF ],
|
||||
[ 81, 0x1800, 0x18AF ],
|
||||
[ 82, 0x2800, 0x28FF ],
|
||||
[ 83, 0xA000, 0xA48F ],
|
||||
[ 83, 0xA490, 0xA4CF ],
|
||||
[ 84, 0x1700, 0x171F ],
|
||||
[ 84, 0x1720, 0x173F ],
|
||||
[ 84, 0x1740, 0x175F ],
|
||||
[ 84, 0x1760, 0x177F ],
|
||||
[ 85, 0x10300, 0x1032F ],
|
||||
[ 86, 0x10330, 0x1034F ],
|
||||
[ 87, 0x10400, 0x1044F ],
|
||||
[ 88, 0x1D000, 0x1D0FF ],
|
||||
[ 88, 0x1D100, 0x1D1FF ],
|
||||
[ 88, 0x1D200, 0x1D24F ],
|
||||
[ 89, 0x1D400, 0x1D7FF ],
|
||||
[ 90, 0xF0000, 0xFFFFD ],
|
||||
[ 90, 0x100000, 0x10FFFD ],
|
||||
[ 91, 0xFE00, 0xFE0F ],
|
||||
[ 91, 0xE0100, 0xE01EF ],
|
||||
[ 92, 0xE0000, 0xE007F ],
|
||||
[ 93, 0x1900, 0x194F ],
|
||||
[ 94, 0x1950, 0x197F ],
|
||||
[ 95, 0x1980, 0x19DF ],
|
||||
[ 96, 0x1A00, 0x1A1F ],
|
||||
[ 97, 0x2C00, 0x2C5F ],
|
||||
[ 98, 0x2D30, 0x2D7F ],
|
||||
[ 99, 0x4DC0, 0x4DFF ],
|
||||
[ 100, 0xA800, 0xA82F ],
|
||||
[ 101, 0x10000, 0x1007F ],
|
||||
[ 101, 0x10080, 0x100FF ],
|
||||
[ 101, 0x10100, 0x1013F ],
|
||||
[ 102, 0x10140, 0x1018F ],
|
||||
[ 103, 0x10380, 0x1039F ],
|
||||
[ 104, 0x103A0, 0x103DF ],
|
||||
[ 105, 0x10450, 0x1047F ],
|
||||
[ 106, 0x10480, 0x104AF ],
|
||||
[ 107, 0x10800, 0x1083F ],
|
||||
[ 108, 0x10A00, 0x10A5F ],
|
||||
[ 109, 0x1D300, 0x1D35F ],
|
||||
[ 110, 0x12000, 0x123FF ],
|
||||
[ 110, 0x12400, 0x1247F ],
|
||||
[ 111, 0x1D360, 0x1D37F ],
|
||||
[ 112, 0x1B80, 0x1BBF ],
|
||||
[ 113, 0x1C00, 0x1C4F ],
|
||||
[ 114, 0x1C50, 0x1C7F ],
|
||||
[ 115, 0xA880, 0xA8DF ],
|
||||
[ 116, 0xA900, 0xA92F ],
|
||||
[ 117, 0xA930, 0xA95F ],
|
||||
[ 118, 0xAA00, 0xAA5F ],
|
||||
[ 119, 0x10190, 0x101CF ],
|
||||
[ 120, 0x101D0, 0x101FF ],
|
||||
[ 121, 0x102A0, 0x102DF ],
|
||||
[ 121, 0x10280, 0x1029F ],
|
||||
[ 121, 0x10920, 0x1093F ],
|
||||
[ 122, 0x1F030, 0x1F09F ],
|
||||
[ 122, 0x1F000, 0x1F02F ]
|
||||
];
|
||||
|
||||
function ulCharRanges(font) {
|
||||
let charRanges = [0, 0, 0, 0];
|
||||
|
||||
font.chars.forEach(char => {
|
||||
const unicode = char.code;
|
||||
const range = CHAR_RANGES.find(_range => unicode >= _range[1] && unicode <= _range[2]);
|
||||
|
||||
if (range != null) {
|
||||
charRanges[range[0] >> 5] |= 1 << (range[0] & 0x1F);
|
||||
}
|
||||
});
|
||||
|
||||
if (font.maxCode >= 0x10000) {
|
||||
charRanges[57 >> 5] |= 1 << (57 & 0x1F);
|
||||
}
|
||||
return [ charRanges[0] >>> 0, charRanges[1] >>> 0, charRanges[2] >>> 0, charRanges[3] >>> 0 ];
|
||||
}
|
||||
|
||||
// -- ulCodePages --
|
||||
function ulCodePages(font) {
|
||||
const spaceIndex = font.chars.findIndex(char => char.code === 0x20);
|
||||
const ascii = Number(spaceIndex !== -1 && font.chars[spaceIndex + 0x5E].code === 0x7E);
|
||||
const findf = (unicode) => Number(font.chars.findIndex(char => char.code === unicode) !== -1);
|
||||
const graph = findf(0x2524);
|
||||
const radic = findf(0x221A);
|
||||
let codePages = [0, 0];
|
||||
|
||||
// conditions from FontForge
|
||||
font.chars.forEach(char => {
|
||||
switch (char.code) {
|
||||
case 0x00DE:
|
||||
codePages[0] |= (ascii) << 0; // 1252 Latin1
|
||||
break;
|
||||
case 0x255A:
|
||||
codePages[1] |= (ascii) << 30; // 850 WE/Latin1
|
||||
codePages[1] |= (ascii) << 31; // 437 US
|
||||
break;
|
||||
case 0x013D:
|
||||
codePages[0] |= (ascii) << 1; // 1250 Latin 2: Eastern Europe
|
||||
codePages[1] |= (ascii & graph) << 26; // 852 Latin 2
|
||||
break;
|
||||
case 0x0411:
|
||||
codePages[0] |= 1 << 2; // 1251 Cyrillic
|
||||
codePages[1] |= (findf(0x255C) & graph) << 17; // 866 MS-DOS Russian
|
||||
codePages[1] |= (findf(0x0405) & graph) << 25; // 855 IBM Cyrillic
|
||||
break;
|
||||
case 0x0386:
|
||||
codePages[0] |= 1 << 3; // 1253 Greek
|
||||
codePages[1] |= (findf(0x00BD) & graph) << 16; // 869 IBM Greek
|
||||
codePages[1] |= (graph & radic) << 28; // 737 Greek; former 437 G
|
||||
break;
|
||||
case 0x0130:
|
||||
codePages[0] |= (ascii) << 4; // 1254 Turkish
|
||||
codePages[1] |= (ascii & graph) << 24; // 857 IBM Turkish
|
||||
break;
|
||||
case 0x05D0:
|
||||
codePages[0] |= 1 << 5; // 1255 Hebrew
|
||||
codePages[1] |= (graph & radic) << 21; // 862 Hebrew
|
||||
break;
|
||||
case 0x0631:
|
||||
codePages[0] |= 1 << 6; // 1256 Arabic
|
||||
codePages[1] |= (radic) << 19; // 864 Arabic
|
||||
codePages[1] |= (graph) << 29; // 708 Arabic; ASMO 708
|
||||
break;
|
||||
case 0x0157:
|
||||
codePages[0] |= (ascii) << 7; // 1257 Windows Baltic
|
||||
codePages[1] |= (ascii & graph) << 27; // 775 MS-DOS Baltic
|
||||
break;
|
||||
case 0x20AB:
|
||||
codePages[0] |= 1 << 8; // 1258 Vietnamese
|
||||
break;
|
||||
case 0x0E45:
|
||||
codePages[0] |= 1 << 16; // 874 Thai
|
||||
break;
|
||||
case 0x30A8:
|
||||
codePages[0] |= 1 << 17; // 932 JIS/Japan
|
||||
break;
|
||||
case 0x3105:
|
||||
codePages[0] |= 1 << 18; // 936 Chinese: Simplified chars
|
||||
break;
|
||||
case 0x3131:
|
||||
codePages[0] |= 1 << 19; // 949 Korean Wansung
|
||||
break;
|
||||
case 0x592E:
|
||||
codePages[0] |= 1 << 20; // 950 Chinese: Traditional chars
|
||||
break;
|
||||
case 0xACF4:
|
||||
codePages[0] |= 1 << 21; // 1361 Korean Johab
|
||||
break;
|
||||
case 0x2030:
|
||||
codePages[0] |= (findf(0x2211) & ascii) << 29; // Macintosh Character Set (Roman)
|
||||
break;
|
||||
case 0x2665:
|
||||
codePages[0] |= (ascii) << 30; // OEM Character Set
|
||||
break;
|
||||
case 0x00C5:
|
||||
codePages[1] |= (ascii & graph & radic) << 18; // 865 MS-DOS Nordic
|
||||
break;
|
||||
case 0x00E9:
|
||||
codePages[1] |= (ascii & graph & radic) << 20; // 863 MS-DOS Canadian French
|
||||
break;
|
||||
case 0x00F5:
|
||||
codePages[1] |= (ascii & graph & radic) << 23; // 860 MS-DOS Portuguese
|
||||
break;
|
||||
case 0x00FE:
|
||||
codePages[1] |= (ascii & graph) << 22; // 861 MS-DOS Icelandic
|
||||
break;
|
||||
default :
|
||||
if (char.code >= 0xF000 && char.code <= 0xF0FF) {
|
||||
codePages[0] |= 1 << 31; // Symbol Character Set
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
return [ codePages[0] >>> 0, codePages[1] >>> 0 ];
|
||||
}
|
||||
|
||||
// -- containsRTL --
|
||||
const RTL_RANGES = [
|
||||
[ 0x05BE, 0x05BE ],
|
||||
[ 0x05C0, 0x05C0 ],
|
||||
[ 0x05C3, 0x05C3 ],
|
||||
[ 0x05C6, 0x05C6 ],
|
||||
[ 0x05D0, 0x05EA ],
|
||||
[ 0x05EF, 0x05F4 ],
|
||||
[ 0x0608, 0x0608 ],
|
||||
[ 0x060B, 0x060B ],
|
||||
[ 0x060D, 0x060D ],
|
||||
[ 0x061B, 0x061C ],
|
||||
[ 0x061E, 0x064A ],
|
||||
[ 0x066D, 0x066F ],
|
||||
[ 0x0671, 0x06D5 ],
|
||||
[ 0x06E5, 0x06E6 ],
|
||||
[ 0x06EE, 0x06EF ],
|
||||
[ 0x06FA, 0x070D ],
|
||||
[ 0x070F, 0x0710 ],
|
||||
[ 0x0712, 0x072F ],
|
||||
[ 0x074D, 0x07A5 ],
|
||||
[ 0x07B1, 0x07B1 ],
|
||||
[ 0x07C0, 0x07EA ],
|
||||
[ 0x07F4, 0x07F5 ],
|
||||
[ 0x07FA, 0x07FA ],
|
||||
[ 0x07FE, 0x0815 ],
|
||||
[ 0x081A, 0x081A ],
|
||||
[ 0x0824, 0x0824 ],
|
||||
[ 0x0828, 0x0828 ],
|
||||
[ 0x0830, 0x083E ],
|
||||
[ 0x0840, 0x0858 ],
|
||||
[ 0x085E, 0x085E ],
|
||||
[ 0x0860, 0x086A ],
|
||||
[ 0x08A0, 0x08B4 ],
|
||||
[ 0x08B6, 0x08BD ],
|
||||
[ 0x200F, 0x200F ],
|
||||
[ 0x202B, 0x202B ],
|
||||
[ 0x202E, 0x202E ],
|
||||
[ 0xFB1D, 0xFB1D ],
|
||||
[ 0xFB1F, 0xFB28 ],
|
||||
[ 0xFB2A, 0xFB36 ],
|
||||
[ 0xFB38, 0xFB3C ],
|
||||
[ 0xFB3E, 0xFB3E ],
|
||||
[ 0xFB40, 0xFB41 ],
|
||||
[ 0xFB43, 0xFB44 ],
|
||||
[ 0xFB46, 0xFBC1 ],
|
||||
[ 0xFBD3, 0xFD3D ],
|
||||
[ 0xFD50, 0xFD8F ],
|
||||
[ 0xFD92, 0xFDC7 ],
|
||||
[ 0xFDF0, 0xFDFC ],
|
||||
[ 0xFE70, 0xFE74 ],
|
||||
[ 0xFE76, 0xFEFC ],
|
||||
[ 0x10800, 0x10FFF ],
|
||||
[ 0x1E800, 0x1EFFF ],
|
||||
[ -1, 0 ]
|
||||
];
|
||||
|
||||
function containsRTL(font) {
|
||||
let index = 0;
|
||||
|
||||
for (let char of font.chars) {
|
||||
while (char.code > RTL_RANGES[index][1]) {
|
||||
if (RTL_RANGES[++index][0] === -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (char.code >= RTL_RANGES[index][0]) {
|
||||
return 0x200;
|
||||
}
|
||||
}
|
||||
return 0x000;
|
||||
}
|
||||
|
||||
// -- postMacIndex --
|
||||
const POST_MAC_NAMES = [
|
||||
'.notdef',
|
||||
'.null',
|
||||
'nonmarkingreturn',
|
||||
'space',
|
||||
'exclam',
|
||||
'quotedbl',
|
||||
'numbersign',
|
||||
'dollar',
|
||||
'percent',
|
||||
'ampersand',
|
||||
'quotesingle',
|
||||
'parenleft',
|
||||
'parenright',
|
||||
'asterisk',
|
||||
'plus',
|
||||
'comma',
|
||||
'hyphen',
|
||||
'period',
|
||||
'slash',
|
||||
'zero',
|
||||
'one',
|
||||
'two',
|
||||
'three',
|
||||
'four',
|
||||
'five',
|
||||
'six',
|
||||
'seven',
|
||||
'eight',
|
||||
'nine',
|
||||
'colon',
|
||||
'semicolon',
|
||||
'less',
|
||||
'equal',
|
||||
'greater',
|
||||
'question',
|
||||
'at',
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z',
|
||||
'bracketleft',
|
||||
'backslash',
|
||||
'bracketright',
|
||||
'asciicircum',
|
||||
'underscore',
|
||||
'grave',
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
'd',
|
||||
'e',
|
||||
'f',
|
||||
'g',
|
||||
'h',
|
||||
'i',
|
||||
'j',
|
||||
'k',
|
||||
'l',
|
||||
'm',
|
||||
'n',
|
||||
'o',
|
||||
'p',
|
||||
'q',
|
||||
'r',
|
||||
's',
|
||||
't',
|
||||
'u',
|
||||
'v',
|
||||
'w',
|
||||
'x',
|
||||
'y',
|
||||
'z',
|
||||
'braceleft',
|
||||
'bar',
|
||||
'braceright',
|
||||
'asciitilde',
|
||||
'Adieresis',
|
||||
'Aring',
|
||||
'Ccedilla',
|
||||
'Eacute',
|
||||
'Ntilde',
|
||||
'Odieresis',
|
||||
'Udieresis',
|
||||
'aacute',
|
||||
'agrave',
|
||||
'acircumflex',
|
||||
'adieresis',
|
||||
'atilde',
|
||||
'aring',
|
||||
'ccedilla',
|
||||
'eacute',
|
||||
'egrave',
|
||||
'ecircumflex',
|
||||
'edieresis',
|
||||
'iacute',
|
||||
'igrave',
|
||||
'icircumflex',
|
||||
'idieresis',
|
||||
'ntilde',
|
||||
'oacute',
|
||||
'ograve',
|
||||
'ocircumflex',
|
||||
'odieresis',
|
||||
'otilde',
|
||||
'uacute',
|
||||
'ugrave',
|
||||
'ucircumflex',
|
||||
'udieresis',
|
||||
'dagger',
|
||||
'degree',
|
||||
'cent',
|
||||
'sterling',
|
||||
'section',
|
||||
'bullet',
|
||||
'paragraph',
|
||||
'germandbls',
|
||||
'registered',
|
||||
'copyright',
|
||||
'trademark',
|
||||
'acute',
|
||||
'dieresis',
|
||||
'notequal',
|
||||
'AE',
|
||||
'Oslash',
|
||||
'infinity',
|
||||
'plusminus',
|
||||
'lessequal',
|
||||
'greaterequal',
|
||||
'yen',
|
||||
'mu',
|
||||
'partialdiff',
|
||||
'summation',
|
||||
'product',
|
||||
'pi',
|
||||
'integral',
|
||||
'ordfeminine',
|
||||
'ordmasculine',
|
||||
'Omega',
|
||||
'ae',
|
||||
'oslash',
|
||||
'questiondown',
|
||||
'exclamdown',
|
||||
'logicalnot',
|
||||
'radical',
|
||||
'florin',
|
||||
'approxequal',
|
||||
'Delta',
|
||||
'guillemotleft',
|
||||
'guillemotright',
|
||||
'ellipsis',
|
||||
'nonbreakingspace',
|
||||
'Agrave',
|
||||
'Atilde',
|
||||
'Otilde',
|
||||
'OE',
|
||||
'oe',
|
||||
'endash',
|
||||
'emdash',
|
||||
'quotedblleft',
|
||||
'quotedblright',
|
||||
'quoteleft',
|
||||
'quoteright',
|
||||
'divide',
|
||||
'lozenge',
|
||||
'ydieresis',
|
||||
'Ydieresis',
|
||||
'fraction',
|
||||
'currency',
|
||||
'guilsinglleft',
|
||||
'guilsinglright',
|
||||
'fi',
|
||||
'fl',
|
||||
'daggerdbl',
|
||||
'periodcentered',
|
||||
'quotesinglbase',
|
||||
'quotedblbase',
|
||||
'perthousand',
|
||||
'Acircumflex',
|
||||
'Ecircumflex',
|
||||
'Aacute',
|
||||
'Edieresis',
|
||||
'Egrave',
|
||||
'Iacute',
|
||||
'Icircumflex',
|
||||
'Idieresis',
|
||||
'Igrave',
|
||||
'Oacute',
|
||||
'Ocircumflex',
|
||||
'apple',
|
||||
'Ograve',
|
||||
'Uacute',
|
||||
'Ucircumflex',
|
||||
'Ugrave',
|
||||
'dotlessi',
|
||||
'circumflex',
|
||||
'tilde',
|
||||
'macron',
|
||||
'breve',
|
||||
'dotaccent',
|
||||
'ring',
|
||||
'cedilla',
|
||||
'hungarumlaut',
|
||||
'ogonek',
|
||||
'caron',
|
||||
'Lslash',
|
||||
'lslash',
|
||||
'Scaron',
|
||||
'scaron',
|
||||
'Zcaron',
|
||||
'zcaron',
|
||||
'brokenbar',
|
||||
'Eth',
|
||||
'eth',
|
||||
'Yacute',
|
||||
'yacute',
|
||||
'Thorn',
|
||||
'thorn',
|
||||
'minus',
|
||||
'multiply',
|
||||
'onesuperior',
|
||||
'twosuperior',
|
||||
'threesuperior',
|
||||
'onehalf',
|
||||
'onequarter',
|
||||
'threequarters',
|
||||
'franc',
|
||||
'Gbreve',
|
||||
'gbreve',
|
||||
'Idotaccent',
|
||||
'Scedilla',
|
||||
'scedilla',
|
||||
'Cacute',
|
||||
'cacute',
|
||||
'Ccaron',
|
||||
'ccaron',
|
||||
'dcroat'
|
||||
];
|
||||
|
||||
function postMacNames() {
|
||||
return POST_MAC_NAMES.slice();
|
||||
}
|
||||
|
||||
// -- Export --
|
||||
module.exports = Object.freeze({
|
||||
xAvgCharWidth,
|
||||
ulCharRanges,
|
||||
ulCodePages,
|
||||
containsRTL,
|
||||
postMacNames
|
||||
});
|
||||
@@ -0,0 +1,663 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
# pylint: disable=bad-whitespace
|
||||
|
||||
# -- x_avg_char_width --
|
||||
WEIGHT_FACTORS = (
|
||||
( 'a', 64 ),
|
||||
( 'b', 14 ),
|
||||
( 'c', 27 ),
|
||||
( 'd', 35 ),
|
||||
( 'e', 100 ),
|
||||
( 'f', 20 ),
|
||||
( 'g', 14 ),
|
||||
( 'h', 42 ),
|
||||
( 'i', 63 ),
|
||||
( 'j', 3 ),
|
||||
( 'k', 6 ),
|
||||
( 'l', 35 ),
|
||||
( 'm', 20 ),
|
||||
( 'n', 56 ),
|
||||
( 'o', 56 ),
|
||||
( 'p', 17 ),
|
||||
( 'q', 4 ),
|
||||
( 'r', 49 ),
|
||||
( 's', 56 ),
|
||||
( 't', 71 ),
|
||||
( 'u', 31 ),
|
||||
( 'v', 10 ),
|
||||
( 'w', 18 ),
|
||||
( 'x', 3 ),
|
||||
( 'y', 18 ),
|
||||
( 'z', 2 ),
|
||||
( ' ', 166 )
|
||||
)
|
||||
|
||||
def x_avg_char_width(font):
|
||||
x_avg_total_width = 0
|
||||
|
||||
for factor in WEIGHT_FACTORS:
|
||||
char = next((char for char in font.chars if char.code == ord(factor[0])), None)
|
||||
|
||||
if char is None:
|
||||
return 0
|
||||
|
||||
x_avg_total_width += font.scaleWidth(char) * factor[1]
|
||||
|
||||
return round(x_avg_total_width / 1000)
|
||||
|
||||
|
||||
# -- ul_char_ranges --
|
||||
CHAR_RANGES = (
|
||||
( 0, 0x0000, 0x007F ),
|
||||
( 1, 0x0080, 0x00FF ),
|
||||
( 2, 0x0100, 0x017F ),
|
||||
( 3, 0x0180, 0x024F ),
|
||||
( 4, 0x0250, 0x02AF ),
|
||||
( 4, 0x1D00, 0x1D7F ),
|
||||
( 4, 0x1D80, 0x1DBF ),
|
||||
( 5, 0x02B0, 0x02FF ),
|
||||
( 5, 0xA700, 0xA71F ),
|
||||
( 6, 0x0300, 0x036F ),
|
||||
( 6, 0x1DC0, 0x1DFF ),
|
||||
( 7, 0x0370, 0x03FF ),
|
||||
( 8, 0x2C80, 0x2CFF ),
|
||||
( 9, 0x0400, 0x04FF ),
|
||||
( 9, 0x0500, 0x052F ),
|
||||
( 9, 0x2DE0, 0x2DFF ),
|
||||
( 9, 0xA640, 0xA69F ),
|
||||
( 10, 0x0530, 0x058F ),
|
||||
( 11, 0x0590, 0x05FF ),
|
||||
( 12, 0xA500, 0xA63F ),
|
||||
( 13, 0x0600, 0x06FF ),
|
||||
( 13, 0x0750, 0x077F ),
|
||||
( 14, 0x07C0, 0x07FF ),
|
||||
( 15, 0x0900, 0x097F ),
|
||||
( 16, 0x0980, 0x09FF ),
|
||||
( 17, 0x0A00, 0x0A7F ),
|
||||
( 18, 0x0A80, 0x0AFF ),
|
||||
( 19, 0x0B00, 0x0B7F ),
|
||||
( 20, 0x0B80, 0x0BFF ),
|
||||
( 21, 0x0C00, 0x0C7F ),
|
||||
( 22, 0x0C80, 0x0CFF ),
|
||||
( 23, 0x0D00, 0x0D7F ),
|
||||
( 24, 0x0E00, 0x0E7F ),
|
||||
( 25, 0x0E80, 0x0EFF ),
|
||||
( 26, 0x10A0, 0x10FF ),
|
||||
( 26, 0x2D00, 0x2D2F ),
|
||||
( 27, 0x1B00, 0x1B7F ),
|
||||
( 28, 0x1100, 0x11FF ),
|
||||
( 29, 0x1E00, 0x1EFF ),
|
||||
( 29, 0x2C60, 0x2C7F ),
|
||||
( 29, 0xA720, 0xA7FF ),
|
||||
( 30, 0x1F00, 0x1FFF ),
|
||||
( 31, 0x2000, 0x206F ),
|
||||
( 31, 0x2E00, 0x2E7F ),
|
||||
( 32, 0x2070, 0x209F ),
|
||||
( 33, 0x20A0, 0x20CF ),
|
||||
( 34, 0x20D0, 0x20FF ),
|
||||
( 35, 0x2100, 0x214F ),
|
||||
( 36, 0x2150, 0x218F ),
|
||||
( 37, 0x2190, 0x21FF ),
|
||||
( 37, 0x27F0, 0x27FF ),
|
||||
( 37, 0x2900, 0x297F ),
|
||||
( 37, 0x2B00, 0x2BFF ),
|
||||
( 38, 0x2200, 0x22FF ),
|
||||
( 38, 0x2A00, 0x2AFF ),
|
||||
( 38, 0x27C0, 0x27EF ),
|
||||
( 38, 0x2980, 0x29FF ),
|
||||
( 39, 0x2300, 0x23FF ),
|
||||
( 40, 0x2400, 0x243F ),
|
||||
( 41, 0x2440, 0x245F ),
|
||||
( 42, 0x2460, 0x24FF ),
|
||||
( 43, 0x2500, 0x257F ),
|
||||
( 44, 0x2580, 0x259F ),
|
||||
( 45, 0x25A0, 0x25FF ),
|
||||
( 46, 0x2600, 0x26FF ),
|
||||
( 47, 0x2700, 0x27BF ),
|
||||
( 48, 0x3000, 0x303F ),
|
||||
( 49, 0x3040, 0x309F ),
|
||||
( 50, 0x30A0, 0x30FF ),
|
||||
( 50, 0x31F0, 0x31FF ),
|
||||
( 51, 0x3100, 0x312F ),
|
||||
( 51, 0x31A0, 0x31BF ),
|
||||
( 52, 0x3130, 0x318F ),
|
||||
( 53, 0xA840, 0xA87F ),
|
||||
( 54, 0x3200, 0x32FF ),
|
||||
( 55, 0x3300, 0x33FF ),
|
||||
( 56, 0xAC00, 0xD7AF ),
|
||||
( 57, 0xD800, 0xDFFF ),
|
||||
( 58, 0x10900, 0x1091F ),
|
||||
( 59, 0x4E00, 0x9FFF ),
|
||||
( 59, 0x2E80, 0x2EFF ),
|
||||
( 59, 0x2F00, 0x2FDF ),
|
||||
( 59, 0x2FF0, 0x2FFF ),
|
||||
( 59, 0x3400, 0x4DBF ),
|
||||
( 59, 0x20000, 0x2A6DF ),
|
||||
( 59, 0x3190, 0x319F ),
|
||||
( 60, 0xE000, 0xF8FF ),
|
||||
( 61, 0x31C0, 0x31EF ),
|
||||
( 61, 0xF900, 0xFAFF ),
|
||||
( 61, 0x2F800, 0x2FA1F ),
|
||||
( 62, 0xFB00, 0xFB4F ),
|
||||
( 63, 0xFB50, 0xFDFF ),
|
||||
( 64, 0xFE20, 0xFE2F ),
|
||||
( 65, 0xFE10, 0xFE1F ),
|
||||
( 65, 0xFE30, 0xFE4F ),
|
||||
( 66, 0xFE50, 0xFE6F ),
|
||||
( 67, 0xFE70, 0xFEFF ),
|
||||
( 68, 0xFF00, 0xFFEF ),
|
||||
( 69, 0xFFF0, 0xFFFF ),
|
||||
( 70, 0x0F00, 0x0FFF ),
|
||||
( 71, 0x0700, 0x074F ),
|
||||
( 72, 0x0780, 0x07BF ),
|
||||
( 73, 0x0D80, 0x0DFF ),
|
||||
( 74, 0x1000, 0x109F ),
|
||||
( 75, 0x1200, 0x137F ),
|
||||
( 75, 0x1380, 0x139F ),
|
||||
( 75, 0x2D80, 0x2DDF ),
|
||||
( 76, 0x13A0, 0x13FF ),
|
||||
( 77, 0x1400, 0x167F ),
|
||||
( 78, 0x1680, 0x169F ),
|
||||
( 79, 0x16A0, 0x16FF ),
|
||||
( 80, 0x1780, 0x17FF ),
|
||||
( 80, 0x19E0, 0x19FF ),
|
||||
( 81, 0x1800, 0x18AF ),
|
||||
( 82, 0x2800, 0x28FF ),
|
||||
( 83, 0xA000, 0xA48F ),
|
||||
( 83, 0xA490, 0xA4CF ),
|
||||
( 84, 0x1700, 0x171F ),
|
||||
( 84, 0x1720, 0x173F ),
|
||||
( 84, 0x1740, 0x175F ),
|
||||
( 84, 0x1760, 0x177F ),
|
||||
( 85, 0x10300, 0x1032F ),
|
||||
( 86, 0x10330, 0x1034F ),
|
||||
( 87, 0x10400, 0x1044F ),
|
||||
( 88, 0x1D000, 0x1D0FF ),
|
||||
( 88, 0x1D100, 0x1D1FF ),
|
||||
( 88, 0x1D200, 0x1D24F ),
|
||||
( 89, 0x1D400, 0x1D7FF ),
|
||||
( 90, 0xF0000, 0xFFFFD ),
|
||||
( 90, 0x100000, 0x10FFFD ),
|
||||
( 91, 0xFE00, 0xFE0F ),
|
||||
( 91, 0xE0100, 0xE01EF ),
|
||||
( 92, 0xE0000, 0xE007F ),
|
||||
( 93, 0x1900, 0x194F ),
|
||||
( 94, 0x1950, 0x197F ),
|
||||
( 95, 0x1980, 0x19DF ),
|
||||
( 96, 0x1A00, 0x1A1F ),
|
||||
( 97, 0x2C00, 0x2C5F ),
|
||||
( 98, 0x2D30, 0x2D7F ),
|
||||
( 99, 0x4DC0, 0x4DFF ),
|
||||
( 100, 0xA800, 0xA82F ),
|
||||
( 101, 0x10000, 0x1007F ),
|
||||
( 101, 0x10080, 0x100FF ),
|
||||
( 101, 0x10100, 0x1013F ),
|
||||
( 102, 0x10140, 0x1018F ),
|
||||
( 103, 0x10380, 0x1039F ),
|
||||
( 104, 0x103A0, 0x103DF ),
|
||||
( 105, 0x10450, 0x1047F ),
|
||||
( 106, 0x10480, 0x104AF ),
|
||||
( 107, 0x10800, 0x1083F ),
|
||||
( 108, 0x10A00, 0x10A5F ),
|
||||
( 109, 0x1D300, 0x1D35F ),
|
||||
( 110, 0x12000, 0x123FF ),
|
||||
( 110, 0x12400, 0x1247F ),
|
||||
( 111, 0x1D360, 0x1D37F ),
|
||||
( 112, 0x1B80, 0x1BBF ),
|
||||
( 113, 0x1C00, 0x1C4F ),
|
||||
( 114, 0x1C50, 0x1C7F ),
|
||||
( 115, 0xA880, 0xA8DF ),
|
||||
( 116, 0xA900, 0xA92F ),
|
||||
( 117, 0xA930, 0xA95F ),
|
||||
( 118, 0xAA00, 0xAA5F ),
|
||||
( 119, 0x10190, 0x101CF ),
|
||||
( 120, 0x101D0, 0x101FF ),
|
||||
( 121, 0x102A0, 0x102DF ),
|
||||
( 121, 0x10280, 0x1029F ),
|
||||
( 121, 0x10920, 0x1093F ),
|
||||
( 122, 0x1F030, 0x1F09F ),
|
||||
( 122, 0x1F000, 0x1F02F )
|
||||
)
|
||||
|
||||
def ul_char_ranges(font):
|
||||
char_ranges = [0, 0, 0, 0]
|
||||
|
||||
for char in font.chars:
|
||||
range = next((range for range in CHAR_RANGES if range[1] <= char.code <= range[2]), None)
|
||||
|
||||
if range is not None:
|
||||
char_ranges[range[0] >> 5] |= 1 << (range[0] & 0x1F)
|
||||
|
||||
if font.max_code >= 0x10000:
|
||||
char_ranges[57 >> 5] |= 1 << (57 & 0x1F)
|
||||
|
||||
return char_ranges
|
||||
|
||||
|
||||
# -- ul_code_pages --
|
||||
def ul_code_pages(font):
|
||||
space_index = next((index for index, char in enumerate(font.chars) if char.code == 0x20), len(font.chars))
|
||||
ascii = int(len(font.chars) >= space_index + 0x5F and font.chars[space_index + 0x5E].code == 0x7E)
|
||||
findf = lambda unicode: int(next((char for char in font.chars if char.code == unicode), None) is not None)
|
||||
graph = findf(0x2524)
|
||||
radic = findf(0x221A)
|
||||
code_pages = [0, 0]
|
||||
|
||||
# conditions from FontForge
|
||||
for char in font.chars:
|
||||
unicode = char.code
|
||||
|
||||
if unicode == 0x00DE:
|
||||
code_pages[0] |= (ascii) << 0 # 1252 Latin1
|
||||
elif unicode == 0x255A:
|
||||
code_pages[1] |= (ascii) << 30 # 850 WE/Latin1
|
||||
code_pages[1] |= (ascii) << 31 # 437 US
|
||||
elif unicode == 0x013D:
|
||||
code_pages[0] |= (ascii) << 1 # 1250 Latin 2: Eastern Europe
|
||||
code_pages[1] |= (ascii & graph) << 26 # 852 Latin 2
|
||||
elif unicode == 0x0411:
|
||||
code_pages[0] |= 1 << 2 # 1251 Cyrillic
|
||||
code_pages[1] |= (findf(0x255C) & graph) << 17 # 866 MS-DOS Russian
|
||||
code_pages[1] |= (findf(0x0405) & graph) << 25 # 855 IBM Cyrillic
|
||||
elif unicode == 0x0386:
|
||||
code_pages[0] |= 1 << 3 # 1253 Greek
|
||||
code_pages[1] |= (findf(0x00BD) & graph) << 16 # 869 IBM Greek
|
||||
code_pages[1] |= (graph & radic) << 28 # 737 Greek; former 437 G
|
||||
elif unicode == 0x0130:
|
||||
code_pages[0] |= (ascii) << 4 # 1254 Turkish
|
||||
code_pages[1] |= (ascii & graph) << 24 # 857 IBM Turkish
|
||||
elif unicode == 0x05D0:
|
||||
code_pages[0] |= 1 << 5 # 1255 Hebrew
|
||||
code_pages[1] |= (graph & radic) << 21 # 862 Hebrew
|
||||
elif unicode == 0x0631:
|
||||
code_pages[0] |= 1 << 6 # 1256 Arabic
|
||||
code_pages[1] |= (radic) << 19 # 864 Arabic
|
||||
code_pages[1] |= (graph) << 29 # 708 Arabic; ASMO 708
|
||||
elif unicode == 0x0157:
|
||||
code_pages[0] |= (ascii) << 7 # 1257 Windows Baltic
|
||||
code_pages[1] |= (ascii & graph) << 27 # 775 MS-DOS Baltic
|
||||
elif unicode == 0x20AB:
|
||||
code_pages[0] |= 1 << 8 # 1258 Vietnamese
|
||||
elif unicode == 0x0E45:
|
||||
code_pages[0] |= 1 << 16 # 874 Thai
|
||||
elif unicode == 0x30A8:
|
||||
code_pages[0] |= 1 << 17 # 932 JIS/Japan
|
||||
elif unicode == 0x3105:
|
||||
code_pages[0] |= 1 << 18 # 936 Chinese: Simplified chars
|
||||
elif unicode == 0x3131:
|
||||
code_pages[0] |= 1 << 19 # 949 Korean Wansung
|
||||
elif unicode == 0x592E:
|
||||
code_pages[0] |= 1 << 20 # 950 Chinese: Traditional chars
|
||||
elif unicode == 0xACF4:
|
||||
code_pages[0] |= 1 << 21 # 1361 Korean Johab
|
||||
elif unicode == 0x2030:
|
||||
code_pages[0] |= (findf(0x2211) & ascii) << 29 # Macintosh Character Set (Roman)
|
||||
elif unicode == 0x2665:
|
||||
code_pages[0] |= (ascii) << 30 # OEM Character Set
|
||||
elif unicode == 0x00C5:
|
||||
code_pages[1] |= (ascii & graph & radic) << 18 # 865 MS-DOS Nordic
|
||||
elif unicode == 0x00E9:
|
||||
code_pages[1] |= (ascii & graph & radic) << 20 # 863 MS-DOS Canadian French
|
||||
elif unicode == 0x00F5:
|
||||
code_pages[1] |= (ascii & graph & radic) << 23 # 860 MS-DOS Portuguese
|
||||
elif unicode == 0x00FE:
|
||||
code_pages[1] |= (ascii & graph) << 22 # 861 MS-DOS Icelandic
|
||||
elif 0xF000 <= unicode <= 0xF0FF:
|
||||
code_pages[0] |= 1 << 31 # Symbol Character Set
|
||||
|
||||
return code_pages
|
||||
|
||||
|
||||
# -- strong_rtl_flag --
|
||||
RTL_RANGES = (
|
||||
( 0x05BE, 0x05BE ),
|
||||
( 0x05C0, 0x05C0 ),
|
||||
( 0x05C3, 0x05C3 ),
|
||||
( 0x05C6, 0x05C6 ),
|
||||
( 0x05D0, 0x05EA ),
|
||||
( 0x05EF, 0x05F4 ),
|
||||
( 0x0608, 0x0608 ),
|
||||
( 0x060B, 0x060B ),
|
||||
( 0x060D, 0x060D ),
|
||||
( 0x061B, 0x061C ),
|
||||
( 0x061E, 0x064A ),
|
||||
( 0x066D, 0x066F ),
|
||||
( 0x0671, 0x06D5 ),
|
||||
( 0x06E5, 0x06E6 ),
|
||||
( 0x06EE, 0x06EF ),
|
||||
( 0x06FA, 0x070D ),
|
||||
( 0x070F, 0x0710 ),
|
||||
( 0x0712, 0x072F ),
|
||||
( 0x074D, 0x07A5 ),
|
||||
( 0x07B1, 0x07B1 ),
|
||||
( 0x07C0, 0x07EA ),
|
||||
( 0x07F4, 0x07F5 ),
|
||||
( 0x07FA, 0x07FA ),
|
||||
( 0x07FE, 0x0815 ),
|
||||
( 0x081A, 0x081A ),
|
||||
( 0x0824, 0x0824 ),
|
||||
( 0x0828, 0x0828 ),
|
||||
( 0x0830, 0x083E ),
|
||||
( 0x0840, 0x0858 ),
|
||||
( 0x085E, 0x085E ),
|
||||
( 0x0860, 0x086A ),
|
||||
( 0x08A0, 0x08B4 ),
|
||||
( 0x08B6, 0x08BD ),
|
||||
( 0x200F, 0x200F ),
|
||||
( 0x202B, 0x202B ),
|
||||
( 0x202E, 0x202E ),
|
||||
( 0xFB1D, 0xFB1D ),
|
||||
( 0xFB1F, 0xFB28 ),
|
||||
( 0xFB2A, 0xFB36 ),
|
||||
( 0xFB38, 0xFB3C ),
|
||||
( 0xFB3E, 0xFB3E ),
|
||||
( 0xFB40, 0xFB41 ),
|
||||
( 0xFB43, 0xFB44 ),
|
||||
( 0xFB46, 0xFBC1 ),
|
||||
( 0xFBD3, 0xFD3D ),
|
||||
( 0xFD50, 0xFD8F ),
|
||||
( 0xFD92, 0xFDC7 ),
|
||||
( 0xFDF0, 0xFDFC ),
|
||||
( 0xFE70, 0xFE74 ),
|
||||
( 0xFE76, 0xFEFC ),
|
||||
( 0x10800, 0x10FFF ),
|
||||
( 0x1E800, 0x1EFFF ),
|
||||
(-1, 0)
|
||||
)
|
||||
|
||||
def contains_rtl(font):
|
||||
index = 0
|
||||
|
||||
for char in font.chars:
|
||||
while char.code > RTL_RANGES[index][1]:
|
||||
index += 1
|
||||
if RTL_RANGES[index][0] == -1:
|
||||
break
|
||||
|
||||
if char.code >= RTL_RANGES[index][0]:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
# -- post_mac_names --
|
||||
POST_MAC_NAMES = (
|
||||
b'.notdef',
|
||||
b'.null',
|
||||
b'nonmarkingreturn',
|
||||
b'space',
|
||||
b'exclam',
|
||||
b'quotedbl',
|
||||
b'numbersign',
|
||||
b'dollar',
|
||||
b'percent',
|
||||
b'ampersand',
|
||||
b'quotesingle',
|
||||
b'parenleft',
|
||||
b'parenright',
|
||||
b'asterisk',
|
||||
b'plus',
|
||||
b'comma',
|
||||
b'hyphen',
|
||||
b'period',
|
||||
b'slash',
|
||||
b'zero',
|
||||
b'one',
|
||||
b'two',
|
||||
b'three',
|
||||
b'four',
|
||||
b'five',
|
||||
b'six',
|
||||
b'seven',
|
||||
b'eight',
|
||||
b'nine',
|
||||
b'colon',
|
||||
b'semicolon',
|
||||
b'less',
|
||||
b'equal',
|
||||
b'greater',
|
||||
b'question',
|
||||
b'at',
|
||||
b'A',
|
||||
b'B',
|
||||
b'C',
|
||||
b'D',
|
||||
b'E',
|
||||
b'F',
|
||||
b'G',
|
||||
b'H',
|
||||
b'I',
|
||||
b'J',
|
||||
b'K',
|
||||
b'L',
|
||||
b'M',
|
||||
b'N',
|
||||
b'O',
|
||||
b'P',
|
||||
b'Q',
|
||||
b'R',
|
||||
b'S',
|
||||
b'T',
|
||||
b'U',
|
||||
b'V',
|
||||
b'W',
|
||||
b'X',
|
||||
b'Y',
|
||||
b'Z',
|
||||
b'bracketleft',
|
||||
b'backslash',
|
||||
b'bracketright',
|
||||
b'asciicircum',
|
||||
b'underscore',
|
||||
b'grave',
|
||||
b'a',
|
||||
b'b',
|
||||
b'c',
|
||||
b'd',
|
||||
b'e',
|
||||
b'f',
|
||||
b'g',
|
||||
b'h',
|
||||
b'i',
|
||||
b'j',
|
||||
b'k',
|
||||
b'l',
|
||||
b'm',
|
||||
b'n',
|
||||
b'o',
|
||||
b'p',
|
||||
b'q',
|
||||
b'r',
|
||||
b's',
|
||||
b't',
|
||||
b'u',
|
||||
b'v',
|
||||
b'w',
|
||||
b'x',
|
||||
b'y',
|
||||
b'z',
|
||||
b'braceleft',
|
||||
b'bar',
|
||||
b'braceright',
|
||||
b'asciitilde',
|
||||
b'Adieresis',
|
||||
b'Aring',
|
||||
b'Ccedilla',
|
||||
b'Eacute',
|
||||
b'Ntilde',
|
||||
b'Odieresis',
|
||||
b'Udieresis',
|
||||
b'aacute',
|
||||
b'agrave',
|
||||
b'acircumflex',
|
||||
b'adieresis',
|
||||
b'atilde',
|
||||
b'aring',
|
||||
b'ccedilla',
|
||||
b'eacute',
|
||||
b'egrave',
|
||||
b'ecircumflex',
|
||||
b'edieresis',
|
||||
b'iacute',
|
||||
b'igrave',
|
||||
b'icircumflex',
|
||||
b'idieresis',
|
||||
b'ntilde',
|
||||
b'oacute',
|
||||
b'ograve',
|
||||
b'ocircumflex',
|
||||
b'odieresis',
|
||||
b'otilde',
|
||||
b'uacute',
|
||||
b'ugrave',
|
||||
b'ucircumflex',
|
||||
b'udieresis',
|
||||
b'dagger',
|
||||
b'degree',
|
||||
b'cent',
|
||||
b'sterling',
|
||||
b'section',
|
||||
b'bullet',
|
||||
b'paragraph',
|
||||
b'germandbls',
|
||||
b'registered',
|
||||
b'copyright',
|
||||
b'trademark',
|
||||
b'acute',
|
||||
b'dieresis',
|
||||
b'notequal',
|
||||
b'AE',
|
||||
b'Oslash',
|
||||
b'infinity',
|
||||
b'plusminus',
|
||||
b'lessequal',
|
||||
b'greaterequal',
|
||||
b'yen',
|
||||
b'mu',
|
||||
b'partialdiff',
|
||||
b'summation',
|
||||
b'product',
|
||||
b'pi',
|
||||
b'integral',
|
||||
b'ordfeminine',
|
||||
b'ordmasculine',
|
||||
b'Omega',
|
||||
b'ae',
|
||||
b'oslash',
|
||||
b'questiondown',
|
||||
b'exclamdown',
|
||||
b'logicalnot',
|
||||
b'radical',
|
||||
b'florin',
|
||||
b'approxequal',
|
||||
b'Delta',
|
||||
b'guillemotleft',
|
||||
b'guillemotright',
|
||||
b'ellipsis',
|
||||
b'nonbreakingspace',
|
||||
b'Agrave',
|
||||
b'Atilde',
|
||||
b'Otilde',
|
||||
b'OE',
|
||||
b'oe',
|
||||
b'endash',
|
||||
b'emdash',
|
||||
b'quotedblleft',
|
||||
b'quotedblright',
|
||||
b'quoteleft',
|
||||
b'quoteright',
|
||||
b'divide',
|
||||
b'lozenge',
|
||||
b'ydieresis',
|
||||
b'Ydieresis',
|
||||
b'fraction',
|
||||
b'currency',
|
||||
b'guilsinglleft',
|
||||
b'guilsinglright',
|
||||
b'fi',
|
||||
b'fl',
|
||||
b'daggerdbl',
|
||||
b'periodcentered',
|
||||
b'quotesinglbase',
|
||||
b'quotedblbase',
|
||||
b'perthousand',
|
||||
b'Acircumflex',
|
||||
b'Ecircumflex',
|
||||
b'Aacute',
|
||||
b'Edieresis',
|
||||
b'Egrave',
|
||||
b'Iacute',
|
||||
b'Icircumflex',
|
||||
b'Idieresis',
|
||||
b'Igrave',
|
||||
b'Oacute',
|
||||
b'Ocircumflex',
|
||||
b'apple',
|
||||
b'Ograve',
|
||||
b'Uacute',
|
||||
b'Ucircumflex',
|
||||
b'Ugrave',
|
||||
b'dotlessi',
|
||||
b'circumflex',
|
||||
b'tilde',
|
||||
b'macron',
|
||||
b'breve',
|
||||
b'dotaccent',
|
||||
b'ring',
|
||||
b'cedilla',
|
||||
b'hungarumlaut',
|
||||
b'ogonek',
|
||||
b'caron',
|
||||
b'Lslash',
|
||||
b'lslash',
|
||||
b'Scaron',
|
||||
b'scaron',
|
||||
b'Zcaron',
|
||||
b'zcaron',
|
||||
b'brokenbar',
|
||||
b'Eth',
|
||||
b'eth',
|
||||
b'Yacute',
|
||||
b'yacute',
|
||||
b'Thorn',
|
||||
b'thorn',
|
||||
b'minus',
|
||||
b'multiply',
|
||||
b'onesuperior',
|
||||
b'twosuperior',
|
||||
b'threesuperior',
|
||||
b'onehalf',
|
||||
b'onequarter',
|
||||
b'threequarters',
|
||||
b'franc',
|
||||
b'Gbreve',
|
||||
b'gbreve',
|
||||
b'Idotaccent',
|
||||
b'Scedilla',
|
||||
b'scedilla',
|
||||
b'Cacute',
|
||||
b'cacute',
|
||||
b'Ccaron',
|
||||
b'ccaron',
|
||||
b'dcroat'
|
||||
)
|
||||
|
||||
def post_mac_names():
|
||||
return list(POST_MAC_NAMES)
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
Copyright (C) 2017-2019 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fnutil = require('./fnutil.js');
|
||||
const fncli = require('./fncli.js');
|
||||
const fnio = require('./fnio.js');
|
||||
const bdf = require('./bdf.js');
|
||||
|
||||
// -- Params --
|
||||
class Params extends fncli.Params {
|
||||
constructor() {
|
||||
super();
|
||||
this.filter = false;
|
||||
this.family = null;
|
||||
this.output = null;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Options --
|
||||
const HELP = ('' +
|
||||
'usage: ucstoany [-f] [-F FAMILY] [-o OUTPUT] INPUT REGISTRY ENCODING TABLE...\n' +
|
||||
'Generate a BDF font subset.\n' +
|
||||
'\n' +
|
||||
' -f, --filter Discard characters with unicode FFFF; with registry ISO10646,\n' +
|
||||
' encode the first 32 characters with their indexes; with other\n' +
|
||||
' registries, encode all characters with indexes\n' +
|
||||
' -F FAMILY output font family name (default = input)\n' +
|
||||
' -o OUTPUT output file (default = stdout)\n' +
|
||||
' TABLE text file, one hexadecimal unicode per line\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'The input must be a BDF 2.1 font with unicode encoding.\n' +
|
||||
'Unlike ucs2any, all TABLE-s form a single subset of the input font.\n');
|
||||
|
||||
const VERSION = 'ucstoany 1.55, Copyright (C) 2019 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE;
|
||||
|
||||
class Options extends fncli.Options {
|
||||
constructor() {
|
||||
super(['-F', '-o'], HELP, VERSION);
|
||||
}
|
||||
|
||||
parse(name, value, params) {
|
||||
switch (name) {
|
||||
case '-f':
|
||||
case '--filter':
|
||||
params.filter = true;
|
||||
break;
|
||||
case '-F':
|
||||
if (value.includes('-')) {
|
||||
throw new Error('FAMILY may not contain "-"');
|
||||
}
|
||||
params.family = value;
|
||||
break;
|
||||
case '-o':
|
||||
params.output = value;
|
||||
break;
|
||||
default:
|
||||
this.fallback(name, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Main --
|
||||
function mainProgram(nonopt, parsed) {
|
||||
if (nonopt.length < 4) {
|
||||
throw new Error('invalid number of arguments, try --help');
|
||||
}
|
||||
|
||||
const input = nonopt[0];
|
||||
const registry = nonopt[1];
|
||||
const encoding = nonopt[2];
|
||||
let newCodes = [];
|
||||
|
||||
if (!registry.match(/^[A-Za-z][\w.:()]*$/) || !encoding.match(/^[\w.:()]+$/)) {
|
||||
throw new Error('invalid registry or encoding');
|
||||
}
|
||||
|
||||
// READ INPUT
|
||||
let ifs = new fnio.InputFileStream(input);
|
||||
|
||||
try {
|
||||
var oldFont = bdf.Font.read(ifs);
|
||||
ifs.close();
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
|
||||
// READ TABLES
|
||||
nonopt.slice(3).forEach(name => {
|
||||
ifs = new fnio.InputFileStream(name);
|
||||
|
||||
try {
|
||||
ifs.readLines(line => {
|
||||
newCodes.push(fnutil.parseHex('unicode', line));
|
||||
});
|
||||
ifs.close();
|
||||
} catch (e) {
|
||||
e.message = ifs.location() + e.message;
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
if (newCodes.length === 0) {
|
||||
throw new Error('no characters in the output font');
|
||||
}
|
||||
|
||||
// CREATE GLYPHS
|
||||
const newFont = new bdf.Font();
|
||||
const charMap = [];
|
||||
let index = 0;
|
||||
let unstart = 0;
|
||||
|
||||
if (parsed.filter) {
|
||||
unstart = (registry === 'ISO10646') ? 32 : bdf.CHARS_MAX;
|
||||
}
|
||||
|
||||
// faster than Map() for <= 4K chars
|
||||
oldFont.chars.forEach(char => (charMap[char.code] = char));
|
||||
|
||||
newCodes.forEach(code => {
|
||||
let oldChar = charMap[code];
|
||||
const uniFFFF = (oldChar == null);
|
||||
|
||||
if (code === 0xFFFF && parsed.filter) {
|
||||
index++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (uniFFFF) {
|
||||
if (code !== 0xFFFF) {
|
||||
throw new Error(`${input} does not contain U+${fnutil.unihex(code)}`);
|
||||
}
|
||||
|
||||
if (oldFont.defaultCode !== -1) {
|
||||
oldChar = charMap[oldFont.defaultCode];
|
||||
} else {
|
||||
oldChar = charMap[0xFFFD];
|
||||
|
||||
if (oldChar == null) {
|
||||
throw new Error(`${input} does not contain U+FFFF, and no replacement found`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const newChar = Object.assign(new bdf.Char(), oldChar);
|
||||
|
||||
newChar.code = index >= unstart ? code : index;
|
||||
index++;
|
||||
newChar.props = new bdf.Props();
|
||||
oldChar.props.forEach((name, value) => newChar.props.set(name, value));
|
||||
newChar.props.set('ENCODING', newChar.code);
|
||||
newFont.chars.push(newChar);
|
||||
|
||||
if (uniFFFF) {
|
||||
newChar.props.set('STARTCHAR', 'uniFFFF');
|
||||
} else if (oldChar.code === oldFont.defaultCode || (oldChar.code === 0xFFFD && newFont.defaultCode === -1)) {
|
||||
newFont.defaultCode = newChar.code;
|
||||
}
|
||||
});
|
||||
|
||||
// CREATE HEADER
|
||||
let numProps;
|
||||
const family = (parsed.family != null) ? parsed.family : oldFont.xlfd[bdf.XLFD.FAMILY_NAME];
|
||||
|
||||
oldFont.props.forEach((name, value) => {
|
||||
switch (name) {
|
||||
case 'FONT':
|
||||
newFont.xlfd = oldFont.xlfd.slice();
|
||||
newFont.xlfd[bdf.XLFD.FAMILY_NAME] = family;
|
||||
newFont.xlfd[bdf.XLFD.CHARSET_REGISTRY] = registry;
|
||||
newFont.xlfd[bdf.XLFD.CHARSET_ENCODING] = encoding;
|
||||
value = newFont.xlfd.join('-');
|
||||
break;
|
||||
case 'STARTPROPERTIES':
|
||||
numProps = fnutil.parseDec(name, value, 1);
|
||||
break;
|
||||
case 'FAMILY_NAME':
|
||||
value = fnutil.quote(family);
|
||||
break;
|
||||
case 'CHARSET_REGISTRY':
|
||||
value = fnutil.quote(registry);
|
||||
break;
|
||||
case 'CHARSET_ENCODING':
|
||||
value = fnutil.quote(encoding);
|
||||
break;
|
||||
case 'DEFAULT_CHAR':
|
||||
if (newFont.defaultCode !== -1) {
|
||||
value = newFont.defaultCode;
|
||||
} else {
|
||||
numProps -= 1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'ENDPROPERTIES':
|
||||
if (newFont.defaultCode !== -1 && newFont.props.get('DEFAULT_CHAR') == null) {
|
||||
newFont.props.set('DEFAULT_CHAR', newFont.defaultCode);
|
||||
numProps += 1;
|
||||
}
|
||||
newFont.props.set('STARTPROPERTIES', numProps);
|
||||
break;
|
||||
case 'CHARS':
|
||||
value = newFont.chars.length;
|
||||
break;
|
||||
}
|
||||
newFont.props.set(name, value);
|
||||
});
|
||||
|
||||
// COPY FIELDS
|
||||
newFont.bbx = oldFont.bbx;
|
||||
|
||||
// WRITE OUTPUT
|
||||
let ofs = new fnio.OutputFileStream(parsed.output);
|
||||
|
||||
try {
|
||||
newFont.write(ofs);
|
||||
ofs.close();
|
||||
} catch (e) {
|
||||
e.message = ofs.location() + e.message + ofs.destroy();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
fncli.start('ucstoany.js', new Options(), new Params(), mainProgram);
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
#
|
||||
# Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import re
|
||||
import copy
|
||||
|
||||
import fnutil
|
||||
import fncli
|
||||
import fnio
|
||||
import bdf
|
||||
|
||||
# -- Params --
|
||||
class Params(fncli.Params):
|
||||
def __init__(self):
|
||||
fncli.Params.__init__(self)
|
||||
self.filter_ffff = False
|
||||
self.family_name = None
|
||||
self.output_name = None
|
||||
|
||||
|
||||
# -- Options --
|
||||
HELP = ('' +
|
||||
'usage: ucstoany [-f] [-F FAMILY] [-o OUTPUT] INPUT REGISTRY ENCODING TABLE...\n' +
|
||||
'Generate a BDF font subset.\n' +
|
||||
'\n' +
|
||||
' -f, --filter Discard characters with unicode FFFF; with registry ISO10646,\n' +
|
||||
' encode the first 32 characters with their indexes; with other\n' +
|
||||
' registries, encode all characters with indexes\n' +
|
||||
' -F FAMILY output font family name (default = input)\n' +
|
||||
' -o OUTPUT output file (default = stdout)\n' +
|
||||
' TABLE text file, one hexadecimal unicode per line\n' +
|
||||
' --help display this help and exit\n' +
|
||||
' --version display the program version and license, and exit\n' +
|
||||
' --excstk display the exception stack on error\n' +
|
||||
'\n' +
|
||||
'The input must be a BDF 2.1 font with unicode encoding.\n' +
|
||||
'Unlike ucs2any, all TABLE-s form a single subset of the input font.\n')
|
||||
|
||||
VERSION = 'ucstoany 1.62, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE
|
||||
|
||||
class Options(fncli.Options):
|
||||
def __init__(self):
|
||||
fncli.Options.__init__(self, ['-F', '-o'], HELP, VERSION)
|
||||
|
||||
|
||||
def parse(self, name, value, params):
|
||||
if name in ['-f', '--filter']:
|
||||
params.filter_ffff = True
|
||||
elif name == '-F':
|
||||
params.family_name = bytes(value, 'ascii')
|
||||
if '-' in value:
|
||||
raise Exception('FAMILY may not contain "-"')
|
||||
elif name == '-o':
|
||||
params.output_name = value
|
||||
else:
|
||||
self.fallback(name, params)
|
||||
|
||||
|
||||
# -- Main --
|
||||
def main_program(nonopt, parsed):
|
||||
# NON-OPTIONS
|
||||
if len(nonopt) < 4:
|
||||
raise Exception('invalid number of arguments, try --help')
|
||||
|
||||
input_name = nonopt[0]
|
||||
registry = nonopt[1]
|
||||
encoding = nonopt[2]
|
||||
new_codes = []
|
||||
|
||||
if not re.fullmatch(r'[A-Za-z][\w.:()]*', registry) or not re.fullmatch(r'[\w.:()]+', encoding):
|
||||
raise Exception('invalid registry or encoding')
|
||||
|
||||
# READ INPUT
|
||||
old_font = fnio.read_file(input_name, bdf.Font.read)
|
||||
|
||||
# READ TABLES
|
||||
def load_code(line):
|
||||
new_codes.append(fnutil.parse_hex('unicode', line))
|
||||
|
||||
for table_name in nonopt[3:]:
|
||||
fnio.read_file(table_name, lambda ifs: ifs.read_lines(load_code))
|
||||
|
||||
if not new_codes:
|
||||
raise Exception('no characters in the output font')
|
||||
|
||||
# CREATE GLYPHS
|
||||
new_font = bdf.Font()
|
||||
charmap = {char.code:char for char in old_font.chars}
|
||||
index = 0
|
||||
unstart = 0
|
||||
family = parsed.family_name if parsed.family_name is not None else old_font.xlfd[bdf.XLFD.FAMILY_NAME]
|
||||
|
||||
if parsed.filter_ffff:
|
||||
unstart = 32 if registry == 'ISO10646' else bdf.CHARS_MAX
|
||||
|
||||
for code in new_codes:
|
||||
if code == 0xFFFF and parsed.filter_ffff:
|
||||
index += 1
|
||||
continue
|
||||
|
||||
if code in charmap:
|
||||
old_char = charmap[code]
|
||||
uni_ffff = False
|
||||
else:
|
||||
uni_ffff = True
|
||||
|
||||
if code != 0xFFFF:
|
||||
raise Exception('%s does not contain U+%04X' % (input, code))
|
||||
|
||||
if old_font.default_code != -1:
|
||||
old_char = charmap[old_font.default_code]
|
||||
elif 0xFFFD in charmap:
|
||||
old_char = charmap[0xFFFD]
|
||||
else:
|
||||
raise Exception('%s does not contain U+FFFF, and no replacement found' % input)
|
||||
|
||||
new_char = copy.copy(old_char)
|
||||
new_char.code = code if index >= unstart else index
|
||||
index += 1
|
||||
new_char.props = copy.copy(old_char.props)
|
||||
new_char.props.set('ENCODING', new_char.code)
|
||||
new_font.chars.append(new_char)
|
||||
|
||||
if uni_ffff:
|
||||
new_char.props.set('STARTCHAR', b'uniFFFF')
|
||||
elif old_char.code == old_font.default_code or (old_char.code == 0xFFFD and new_font.default_code == -1):
|
||||
new_font.default_code = new_char.code
|
||||
|
||||
# CREATE HEADER
|
||||
registry = bytes(registry, 'ascii')
|
||||
encoding = bytes(encoding, 'ascii')
|
||||
|
||||
for [name, value] in old_font.props:
|
||||
if name == 'FONT':
|
||||
new_font.xlfd = old_font.xlfd[:]
|
||||
new_font.xlfd[bdf.XLFD.FAMILY_NAME] = family
|
||||
new_font.xlfd[bdf.XLFD.CHARSET_REGISTRY] = registry
|
||||
new_font.xlfd[bdf.XLFD.CHARSET_ENCODING] = encoding
|
||||
value = b'-'.join(new_font.xlfd)
|
||||
elif name == 'STARTPROPERTIES':
|
||||
num_props = fnutil.parse_dec(name, value, 1)
|
||||
elif name == 'FAMILY_NAME':
|
||||
value = fnutil.quote(family)
|
||||
elif name == 'CHARSET_REGISTRY':
|
||||
value = fnutil.quote(registry)
|
||||
elif name == 'CHARSET_ENCODING':
|
||||
value = fnutil.quote(encoding)
|
||||
elif name == 'DEFAULT_CHAR':
|
||||
if new_font.default_code != -1:
|
||||
value = new_font.default_code
|
||||
else:
|
||||
num_props -= 1
|
||||
continue
|
||||
elif name == 'ENDPROPERTIES':
|
||||
if new_font.default_code != -1 and new_font.props.get('DEFAULT_CHAR') is None:
|
||||
new_font.props.set('DEFAULT_CHAR', new_font.default_code)
|
||||
num_props += 1
|
||||
|
||||
new_font.props.set('STARTPROPERTIES', num_props)
|
||||
elif name == 'CHARS':
|
||||
value = len(new_font.chars)
|
||||
|
||||
new_font.props.set(name, value)
|
||||
|
||||
# COPY FIELDS
|
||||
new_font.bbx = old_font.bbx
|
||||
|
||||
# WRITE OUTPUT
|
||||
fnio.write_file(parsed.output_name, lambda ofs: new_font.write(ofs))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fncli.start('ucstoany.py', Options(), Params(), main_program)
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "$1" = "--help" ; then
|
||||
echo usage: $0 [--var=VALUE] [VAR=VALUE] ...
|
||||
echo
|
||||
cat configure.help 2> /dev/null && echo
|
||||
echo "Any variables not explicitly set are reset to their defaults"
|
||||
elif test "$1" = "--version" ; then
|
||||
cat << EOT
|
||||
micro configure 0.21, Copyright (C) 2015 Dimitar Toshkov Zhekov
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
EOT
|
||||
elif test -z `printf "\r"` ; then
|
||||
echo "$0: printf failure"
|
||||
false
|
||||
elif test -f Makefile ; then
|
||||
if test -f Makefile.in ; then
|
||||
cp -fp Makefile.in Makefile
|
||||
else
|
||||
cp -p Makefile Makefile.in
|
||||
fi
|
||||
w=`printf "[\t ]*"`
|
||||
r=`printf "\r"`
|
||||
l="[a-z][a-z0-9-]*[^-]"
|
||||
for i do
|
||||
if test "$i" != "`echo "$i" | sed -e 1q`" ; then
|
||||
echo "$0: `echo "$i" | sed -e "s/$r/^M/" -e 1q`^J...: contains line feed" 1>&2
|
||||
elif echo "$i" | grep "$r" > /dev/null ; then
|
||||
echo "$0: `echo "$i" | sed -e "s/$r.*//"`^M...: contains carriage return" 1>&2
|
||||
elif test -n "$i" ; then
|
||||
if echo "$i" | grep -E "^--$l=|^[A-Z][A-Z0-9_]*[^_]=" > /dev/null ; then
|
||||
n=`echo "$i" | sed -e "s$r^-*$r$r" -e "s$r=.*$r$r" | sed -e "s/-/_/g"`
|
||||
if grep -E "^$n$w:?=" Makefile > /dev/null ; then
|
||||
cp -f Makefile Makefile.$$
|
||||
sed -e "s$r^\($n$w:*=$w\).*$r\1`echo "$i" | sed -e "s$r^[^=]*=$r$r"`$r" Makefile.$$ > Makefile
|
||||
grep -E "^$n$w:?=" Makefile /dev/null
|
||||
else
|
||||
echo "$0: $n: not found in Makefile" 1>&2
|
||||
fi
|
||||
unset n
|
||||
else
|
||||
echo "$0: $i: not recognized" 1>&2
|
||||
fi
|
||||
fi
|
||||
done
|
||||
unset i l r w
|
||||
if test -f Makefile.$$ ; then
|
||||
rm -f Makefile.$$
|
||||
else
|
||||
rm -f Makefile.in
|
||||
fi
|
||||
else
|
||||
echo "$0: Makefile: not found" 1>&2
|
||||
false
|
||||
fi
|
||||
@@ -0,0 +1,14 @@
|
||||
To assign environment variables (e.g., CC, CFLAGS...), specify them as
|
||||
NAME=VALUE. See README for a description of all options and targets.
|
||||
|
||||
The default values are specified in brackets.
|
||||
|
||||
Configuration:
|
||||
--help display this help and exit
|
||||
--version display version information and exit
|
||||
|
||||
Installation directories:
|
||||
--prefix=PREFIX prefix for all directories [/usr/local]
|
||||
--psfdir=DIR PC screen fonts directory [PREFIX/share/consolefonts]
|
||||
--x11dir=DIR X11 fonts directory [PREFIX/share/fonts/terminus]
|
||||
--otbdir=DIR TrueType/OTB fonts directory [PREFIX/share/fonts/terminus]
|
||||
@@ -0,0 +1,2 @@
|
||||
0020 0000
|
||||
2302 007F
|
||||
@@ -0,0 +1,5 @@
|
||||
25B6 25BA
|
||||
25C0 25C4
|
||||
2666 25C6
|
||||
266B 266C
|
||||
FFFD 0000
|
||||
@@ -0,0 +1,7 @@
|
||||
00B5 03BC
|
||||
03A3 2211
|
||||
03A9 2126
|
||||
03B2 00DF
|
||||
220A 03B5
|
||||
220A 2208
|
||||
2205 03C6
|
||||
@@ -0,0 +1 @@
|
||||
0138 043A
|
||||
@@ -0,0 +1 @@
|
||||
006B 043A
|
||||
@@ -0,0 +1 @@
|
||||
043F 03C0
|
||||
@@ -0,0 +1,8 @@
|
||||
2191 25B2
|
||||
2193 25BC
|
||||
25B6 2192
|
||||
25B6 25BA
|
||||
25A0 FFFD
|
||||
25C0 2190
|
||||
25C0 25C4
|
||||
2666 25C6
|
||||
@@ -0,0 +1,107 @@
|
||||
0020 0000
|
||||
0020 00A0
|
||||
0020 2000
|
||||
0020 2001
|
||||
0020 2002
|
||||
0020 2003
|
||||
0020 2004
|
||||
0020 2005
|
||||
0020 2006
|
||||
0020 2007
|
||||
0020 2008
|
||||
0020 2009
|
||||
0020 200A
|
||||
0020 202F
|
||||
002D 2012
|
||||
002D 2013
|
||||
002D 2212
|
||||
0033 0417
|
||||
0041 0391
|
||||
0041 0410
|
||||
0042 0392
|
||||
0042 0412
|
||||
0043 0421
|
||||
0045 0395
|
||||
0045 0415
|
||||
0048 0397
|
||||
0048 041D
|
||||
0049 0399
|
||||
0049 0406
|
||||
0049 04C0
|
||||
004A 0408
|
||||
004B 039A
|
||||
004B 041A
|
||||
004D 039C
|
||||
004D 041C
|
||||
004E 039D
|
||||
004F 039F
|
||||
004F 041E
|
||||
0050 03A1
|
||||
0050 0420
|
||||
0053 0405
|
||||
0054 03A4
|
||||
0054 0422
|
||||
0058 03A7
|
||||
0058 0425
|
||||
0059 03A5
|
||||
0059 04AE
|
||||
005A 0396
|
||||
0061 0430
|
||||
0063 03F2
|
||||
0063 0441
|
||||
0065 0435
|
||||
0068 210E
|
||||
0069 0456
|
||||
006A 03F3
|
||||
006A 0458
|
||||
006C 04CF
|
||||
006F 03BF
|
||||
006F 043E
|
||||
0070 0440
|
||||
0073 0455
|
||||
0076 03BD
|
||||
0078 0445
|
||||
0079 0443
|
||||
00AD 2010
|
||||
00AD 2011
|
||||
00B4 0301
|
||||
00B5 03BC
|
||||
00C4 04D2
|
||||
00C6 04D4
|
||||
00C8 0400
|
||||
00CB 0401
|
||||
00CF 03AA
|
||||
00CF 0407
|
||||
00D0 0110
|
||||
00D6 04E6
|
||||
00E4 04D3
|
||||
00E6 04D5
|
||||
00E8 0450
|
||||
00EB 0451
|
||||
00EF 0457
|
||||
00F3 03CC
|
||||
00F6 04E7
|
||||
0102 04D0
|
||||
0103 04D1
|
||||
0138 03BA
|
||||
0178 03AB
|
||||
02C6 0302
|
||||
02C7 030C
|
||||
02D8 0306
|
||||
02DC 0303
|
||||
0393 0413
|
||||
03A9 2126
|
||||
03B5 2208
|
||||
03B5 220A
|
||||
03C0 043F
|
||||
03C6 2205
|
||||
041F 03A0
|
||||
045B 0127
|
||||
045B 210F
|
||||
04AF 03B3
|
||||
04D8 018F
|
||||
04D9 0259
|
||||
04E8 03F4
|
||||
2014 2015
|
||||
2206 0394
|
||||
0138 043A
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,96 @@
|
||||
00A0
|
||||
201D
|
||||
00A2
|
||||
00A3
|
||||
00A4
|
||||
201E
|
||||
00A6
|
||||
00A7
|
||||
00D8
|
||||
00A9
|
||||
0156
|
||||
00AB
|
||||
00AC
|
||||
00AD
|
||||
00AE
|
||||
00C6
|
||||
00B0
|
||||
00B1
|
||||
00B2
|
||||
00B3
|
||||
201C
|
||||
00B5
|
||||
00B6
|
||||
00B7
|
||||
00F8
|
||||
00B9
|
||||
0157
|
||||
00BB
|
||||
00BC
|
||||
00BD
|
||||
00BE
|
||||
00E6
|
||||
0104
|
||||
012E
|
||||
0100
|
||||
0106
|
||||
00C4
|
||||
00C5
|
||||
0118
|
||||
0112
|
||||
010C
|
||||
00C9
|
||||
0179
|
||||
0116
|
||||
0122
|
||||
0136
|
||||
012A
|
||||
013B
|
||||
0160
|
||||
0143
|
||||
0145
|
||||
00D3
|
||||
014C
|
||||
00D5
|
||||
00D6
|
||||
00D7
|
||||
0172
|
||||
0141
|
||||
015A
|
||||
016A
|
||||
00DC
|
||||
017B
|
||||
017D
|
||||
00DF
|
||||
0105
|
||||
012F
|
||||
0101
|
||||
0107
|
||||
00E4
|
||||
00E5
|
||||
0119
|
||||
0113
|
||||
010D
|
||||
00E9
|
||||
017A
|
||||
0117
|
||||
0123
|
||||
0137
|
||||
012B
|
||||
013C
|
||||
0161
|
||||
0144
|
||||
0146
|
||||
00F3
|
||||
014D
|
||||
00F5
|
||||
00F6
|
||||
00F7
|
||||
0173
|
||||
0142
|
||||
015B
|
||||
016B
|
||||
00FC
|
||||
017C
|
||||
017E
|
||||
2019
|
||||
@@ -0,0 +1,96 @@
|
||||
00A0
|
||||
00A1
|
||||
00A2
|
||||
00A3
|
||||
20AC
|
||||
00A5
|
||||
0160
|
||||
00A7
|
||||
0161
|
||||
00A9
|
||||
00AA
|
||||
00AB
|
||||
00AC
|
||||
00AD
|
||||
00AE
|
||||
00AF
|
||||
00B0
|
||||
00B1
|
||||
00B2
|
||||
00B3
|
||||
017D
|
||||
00B5
|
||||
00B6
|
||||
00B7
|
||||
017E
|
||||
00B9
|
||||
00BA
|
||||
00BB
|
||||
0152
|
||||
0153
|
||||
0178
|
||||
00BF
|
||||
00C0
|
||||
00C1
|
||||
00C2
|
||||
00C3
|
||||
00C4
|
||||
00C5
|
||||
00C6
|
||||
00C7
|
||||
00C8
|
||||
00C9
|
||||
00CA
|
||||
00CB
|
||||
00CC
|
||||
00CD
|
||||
00CE
|
||||
00CF
|
||||
00D0
|
||||
00D1
|
||||
00D2
|
||||
00D3
|
||||
00D4
|
||||
00D5
|
||||
00D6
|
||||
00D7
|
||||
00D8
|
||||
00D9
|
||||
00DA
|
||||
00DB
|
||||
00DC
|
||||
00DD
|
||||
00DE
|
||||
00DF
|
||||
00E0
|
||||
00E1
|
||||
00E2
|
||||
00E3
|
||||
00E4
|
||||
00E5
|
||||
00E6
|
||||
00E7
|
||||
00E8
|
||||
00E9
|
||||
00EA
|
||||
00EB
|
||||
00EC
|
||||
00ED
|
||||
00EE
|
||||
00EF
|
||||
00F0
|
||||
00F1
|
||||
00F2
|
||||
00F3
|
||||
00F4
|
||||
00F5
|
||||
00F6
|
||||
00F7
|
||||
00F8
|
||||
00F9
|
||||
00FA
|
||||
00FB
|
||||
00FC
|
||||
00FD
|
||||
00FE
|
||||
00FF
|
||||
@@ -0,0 +1,96 @@
|
||||
00A0
|
||||
0104
|
||||
0105
|
||||
0141
|
||||
20AC
|
||||
201E
|
||||
0160
|
||||
00A7
|
||||
0161
|
||||
00A9
|
||||
0218
|
||||
00AB
|
||||
0179
|
||||
00AD
|
||||
017A
|
||||
017B
|
||||
00B0
|
||||
00B1
|
||||
010C
|
||||
0142
|
||||
017D
|
||||
201D
|
||||
00B6
|
||||
00B7
|
||||
017E
|
||||
010D
|
||||
0219
|
||||
00BB
|
||||
0152
|
||||
0153
|
||||
0178
|
||||
017C
|
||||
00C0
|
||||
00C1
|
||||
00C2
|
||||
0102
|
||||
00C4
|
||||
0106
|
||||
00C6
|
||||
00C7
|
||||
00C8
|
||||
00C9
|
||||
00CA
|
||||
00CB
|
||||
00CC
|
||||
00CD
|
||||
00CE
|
||||
00CF
|
||||
0110
|
||||
0143
|
||||
00D2
|
||||
00D3
|
||||
00D4
|
||||
0150
|
||||
00D6
|
||||
015A
|
||||
0170
|
||||
00D9
|
||||
00DA
|
||||
00DB
|
||||
00DC
|
||||
0118
|
||||
021A
|
||||
00DF
|
||||
00E0
|
||||
00E1
|
||||
00E2
|
||||
0103
|
||||
00E4
|
||||
0107
|
||||
00E6
|
||||
00E7
|
||||
00E8
|
||||
00E9
|
||||
00EA
|
||||
00EB
|
||||
00EC
|
||||
00ED
|
||||
00EE
|
||||
00EF
|
||||
0111
|
||||
0144
|
||||
00F2
|
||||
00F3
|
||||
00F4
|
||||
0151
|
||||
00F6
|
||||
015B
|
||||
0171
|
||||
00F9
|
||||
00FA
|
||||
00FB
|
||||
00FC
|
||||
0119
|
||||
021B
|
||||
00FF
|
||||
@@ -0,0 +1,96 @@
|
||||
00A0
|
||||
0104
|
||||
02D8
|
||||
0141
|
||||
00A4
|
||||
013D
|
||||
015A
|
||||
00A7
|
||||
00A8
|
||||
0160
|
||||
015E
|
||||
0164
|
||||
0179
|
||||
00AD
|
||||
017D
|
||||
017B
|
||||
00B0
|
||||
0105
|
||||
02DB
|
||||
0142
|
||||
00B4
|
||||
013E
|
||||
015B
|
||||
02C7
|
||||
00B8
|
||||
0161
|
||||
015F
|
||||
0165
|
||||
017A
|
||||
02DD
|
||||
017E
|
||||
017C
|
||||
0154
|
||||
00C1
|
||||
00C2
|
||||
0102
|
||||
00C4
|
||||
0139
|
||||
0106
|
||||
00C7
|
||||
010C
|
||||
00C9
|
||||
0118
|
||||
00CB
|
||||
011A
|
||||
00CD
|
||||
00CE
|
||||
010E
|
||||
0110
|
||||
0143
|
||||
0147
|
||||
00D3
|
||||
00D4
|
||||
0150
|
||||
00D6
|
||||
00D7
|
||||
0158
|
||||
016E
|
||||
00DA
|
||||
0170
|
||||
00DC
|
||||
00DD
|
||||
0162
|
||||
00DF
|
||||
0155
|
||||
00E1
|
||||
00E2
|
||||
0103
|
||||
00E4
|
||||
013A
|
||||
0107
|
||||
00E7
|
||||
010D
|
||||
00E9
|
||||
0119
|
||||
00EB
|
||||
011B
|
||||
00ED
|
||||
00EE
|
||||
010F
|
||||
0111
|
||||
0144
|
||||
0148
|
||||
00F3
|
||||
00F4
|
||||
0151
|
||||
00F6
|
||||
00F7
|
||||
0159
|
||||
016F
|
||||
00FA
|
||||
0171
|
||||
00FC
|
||||
00FD
|
||||
0163
|
||||
02D9
|
||||
@@ -0,0 +1,96 @@
|
||||
00A0
|
||||
0401
|
||||
0402
|
||||
0403
|
||||
0404
|
||||
0405
|
||||
0406
|
||||
0407
|
||||
0408
|
||||
0409
|
||||
040A
|
||||
040B
|
||||
040C
|
||||
00AD
|
||||
040E
|
||||
040F
|
||||
0410
|
||||
0411
|
||||
0412
|
||||
0413
|
||||
0414
|
||||
0415
|
||||
0416
|
||||
0417
|
||||
0418
|
||||
0419
|
||||
041A
|
||||
041B
|
||||
041C
|
||||
041D
|
||||
041E
|
||||
041F
|
||||
0420
|
||||
0421
|
||||
0422
|
||||
0423
|
||||
0424
|
||||
0425
|
||||
0426
|
||||
0427
|
||||
0428
|
||||
0429
|
||||
042A
|
||||
042B
|
||||
042C
|
||||
042D
|
||||
042E
|
||||
042F
|
||||
0430
|
||||
0431
|
||||
0432
|
||||
0433
|
||||
0434
|
||||
0435
|
||||
0436
|
||||
0437
|
||||
0438
|
||||
0439
|
||||
043A
|
||||
043B
|
||||
043C
|
||||
043D
|
||||
043E
|
||||
043F
|
||||
0440
|
||||
0441
|
||||
0442
|
||||
0443
|
||||
0444
|
||||
0445
|
||||
0446
|
||||
0447
|
||||
0448
|
||||
0449
|
||||
044A
|
||||
044B
|
||||
044C
|
||||
044D
|
||||
044E
|
||||
044F
|
||||
2116
|
||||
0451
|
||||
0452
|
||||
0453
|
||||
0454
|
||||
0455
|
||||
0456
|
||||
0457
|
||||
0458
|
||||
0459
|
||||
045A
|
||||
045B
|
||||
045C
|
||||
00A7
|
||||
045E
|
||||
045F
|
||||
@@ -0,0 +1,96 @@
|
||||
00A0
|
||||
02BD
|
||||
02BC
|
||||
00A3
|
||||
20AC
|
||||
FFFF
|
||||
00A6
|
||||
00A7
|
||||
00A8
|
||||
00A9
|
||||
FFFF
|
||||
00AB
|
||||
00AC
|
||||
00AD
|
||||
FFFF
|
||||
2015
|
||||
00B0
|
||||
00B1
|
||||
00B2
|
||||
00B3
|
||||
0384
|
||||
0385
|
||||
0386
|
||||
00B7
|
||||
0388
|
||||
0389
|
||||
038A
|
||||
00BB
|
||||
038C
|
||||
00BD
|
||||
038E
|
||||
038F
|
||||
0390
|
||||
0391
|
||||
0392
|
||||
0393
|
||||
0394
|
||||
0395
|
||||
0396
|
||||
0397
|
||||
0398
|
||||
0399
|
||||
039A
|
||||
039B
|
||||
039C
|
||||
039D
|
||||
039E
|
||||
039F
|
||||
03A0
|
||||
03A1
|
||||
FFFF
|
||||
03A3
|
||||
03A4
|
||||
03A5
|
||||
03A6
|
||||
03A7
|
||||
03A8
|
||||
03A9
|
||||
03AA
|
||||
03AB
|
||||
03AC
|
||||
03AD
|
||||
03AE
|
||||
03AF
|
||||
03B0
|
||||
03B1
|
||||
03B2
|
||||
03B3
|
||||
03B4
|
||||
03B5
|
||||
03B6
|
||||
03B7
|
||||
03B8
|
||||
03B9
|
||||
03BA
|
||||
03BB
|
||||
03BC
|
||||
03BD
|
||||
03BE
|
||||
03BF
|
||||
03C0
|
||||
03C1
|
||||
03C2
|
||||
03C3
|
||||
03C4
|
||||
03C5
|
||||
03C6
|
||||
03C7
|
||||
03C8
|
||||
03C9
|
||||
03CA
|
||||
03CB
|
||||
03CC
|
||||
03CD
|
||||
03CE
|
||||
FFFF
|
||||
@@ -0,0 +1,96 @@
|
||||
0020
|
||||
0021
|
||||
0022
|
||||
0023
|
||||
0024
|
||||
0025
|
||||
0026
|
||||
0027
|
||||
0028
|
||||
0029
|
||||
002A
|
||||
002B
|
||||
002C
|
||||
002D
|
||||
002E
|
||||
002F
|
||||
0030
|
||||
0031
|
||||
0032
|
||||
0033
|
||||
0034
|
||||
0035
|
||||
0036
|
||||
0037
|
||||
0038
|
||||
0039
|
||||
003A
|
||||
003B
|
||||
003C
|
||||
003D
|
||||
003E
|
||||
003F
|
||||
0040
|
||||
0041
|
||||
0042
|
||||
0043
|
||||
0044
|
||||
0045
|
||||
0046
|
||||
0047
|
||||
0048
|
||||
0049
|
||||
004A
|
||||
004B
|
||||
004C
|
||||
004D
|
||||
004E
|
||||
004F
|
||||
0050
|
||||
0051
|
||||
0052
|
||||
0053
|
||||
0054
|
||||
0055
|
||||
0056
|
||||
0057
|
||||
0058
|
||||
0059
|
||||
005A
|
||||
005B
|
||||
005C
|
||||
005D
|
||||
005E
|
||||
005F
|
||||
0060
|
||||
0061
|
||||
0062
|
||||
0063
|
||||
0064
|
||||
0065
|
||||
0066
|
||||
0067
|
||||
0068
|
||||
0069
|
||||
006A
|
||||
006B
|
||||
006C
|
||||
006D
|
||||
006E
|
||||
006F
|
||||
0070
|
||||
0071
|
||||
0072
|
||||
0073
|
||||
0074
|
||||
0075
|
||||
0076
|
||||
0077
|
||||
0078
|
||||
0079
|
||||
007A
|
||||
007B
|
||||
007C
|
||||
007D
|
||||
007E
|
||||
2302
|
||||
@@ -0,0 +1,128 @@
|
||||
0410
|
||||
0411
|
||||
0412
|
||||
0413
|
||||
0414
|
||||
0415
|
||||
0416
|
||||
0417
|
||||
0418
|
||||
0419
|
||||
041A
|
||||
041B
|
||||
041C
|
||||
041D
|
||||
041E
|
||||
041F
|
||||
0420
|
||||
0421
|
||||
0422
|
||||
0423
|
||||
0424
|
||||
0425
|
||||
0426
|
||||
0427
|
||||
0428
|
||||
0429
|
||||
042A
|
||||
042B
|
||||
042C
|
||||
042D
|
||||
042E
|
||||
042F
|
||||
0430
|
||||
0431
|
||||
0432
|
||||
0433
|
||||
0434
|
||||
0435
|
||||
0436
|
||||
0437
|
||||
0438
|
||||
0439
|
||||
043A
|
||||
043B
|
||||
043C
|
||||
043D
|
||||
043E
|
||||
043F
|
||||
0440
|
||||
0441
|
||||
0442
|
||||
0443
|
||||
0444
|
||||
0445
|
||||
0446
|
||||
0447
|
||||
0448
|
||||
0449
|
||||
044A
|
||||
044B
|
||||
044C
|
||||
044D
|
||||
044E
|
||||
044F
|
||||
2514
|
||||
2534
|
||||
252C
|
||||
251C
|
||||
2500
|
||||
253C
|
||||
2563
|
||||
2551
|
||||
255A
|
||||
2554
|
||||
2569
|
||||
2566
|
||||
2560
|
||||
2550
|
||||
256C
|
||||
2510
|
||||
2591
|
||||
2592
|
||||
2593
|
||||
2502
|
||||
2524
|
||||
2116
|
||||
00A7
|
||||
2557
|
||||
255D
|
||||
2518
|
||||
250C
|
||||
2588
|
||||
2584
|
||||
258C
|
||||
2590
|
||||
2580
|
||||
03B1
|
||||
03B2
|
||||
0393
|
||||
03C0
|
||||
03A3
|
||||
03C3
|
||||
00B5
|
||||
03C4
|
||||
03A6
|
||||
0398
|
||||
03A9
|
||||
03B4
|
||||
221E
|
||||
2205
|
||||
220A
|
||||
2229
|
||||
2261
|
||||
00B1
|
||||
2265
|
||||
2264
|
||||
2320
|
||||
2321
|
||||
00F7
|
||||
2248
|
||||
00B0
|
||||
2219
|
||||
00B7
|
||||
221A
|
||||
207F
|
||||
00B2
|
||||
25A0
|
||||
00A0
|
||||
@@ -0,0 +1,32 @@
|
||||
0000
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
@@ -0,0 +1,32 @@
|
||||
FFFD
|
||||
263A
|
||||
263B
|
||||
2665
|
||||
2666
|
||||
2663
|
||||
2660
|
||||
2022
|
||||
25D8
|
||||
25CB
|
||||
25D9
|
||||
2642
|
||||
2640
|
||||
266A
|
||||
266B
|
||||
263C
|
||||
25B6
|
||||
25C0
|
||||
2195
|
||||
203C
|
||||
00B6
|
||||
00A7
|
||||
25AC
|
||||
21A8
|
||||
2191
|
||||
2193
|
||||
2192
|
||||
2190
|
||||
221F
|
||||
2194
|
||||
25B2
|
||||
25BC
|
||||
@@ -0,0 +1,32 @@
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
FFFF
|
||||
@@ -0,0 +1,128 @@
|
||||
00C7
|
||||
00FC
|
||||
00E9
|
||||
00E2
|
||||
00E4
|
||||
00E0
|
||||
00E5
|
||||
00E7
|
||||
00EA
|
||||
00EB
|
||||
00E8
|
||||
00EF
|
||||
00EE
|
||||
00EC
|
||||
00C4
|
||||
00C5
|
||||
00C9
|
||||
00E6
|
||||
00C6
|
||||
00F4
|
||||
00F6
|
||||
00F2
|
||||
00FB
|
||||
00F9
|
||||
00FF
|
||||
00D6
|
||||
00DC
|
||||
00A2
|
||||
00A3
|
||||
00A5
|
||||
20A7
|
||||
0192
|
||||
00E1
|
||||
00ED
|
||||
00F3
|
||||
00FA
|
||||
00F1
|
||||
00D1
|
||||
00AA
|
||||
00BA
|
||||
00BF
|
||||
2310
|
||||
00AC
|
||||
00BD
|
||||
00BC
|
||||
00A1
|
||||
00AB
|
||||
00BB
|
||||
2591
|
||||
2592
|
||||
2593
|
||||
2502
|
||||
2524
|
||||
2561
|
||||
2562
|
||||
2556
|
||||
2555
|
||||
2563
|
||||
2551
|
||||
2557
|
||||
255D
|
||||
255C
|
||||
255B
|
||||
2510
|
||||
2514
|
||||
2534
|
||||
252C
|
||||
251C
|
||||
2500
|
||||
253C
|
||||
255E
|
||||
255F
|
||||
255A
|
||||
2554
|
||||
2569
|
||||
2566
|
||||
2560
|
||||
2550
|
||||
256C
|
||||
2567
|
||||
2568
|
||||
2564
|
||||
2565
|
||||
2559
|
||||
2558
|
||||
2552
|
||||
2553
|
||||
256B
|
||||
256A
|
||||
2518
|
||||
250C
|
||||
2588
|
||||
2584
|
||||
258C
|
||||
2590
|
||||
2580
|
||||
03B1
|
||||
03B2
|
||||
0393
|
||||
03C0
|
||||
03A3
|
||||
03C3
|
||||
00B5
|
||||
03C4
|
||||
03A6
|
||||
0398
|
||||
03A9
|
||||
03B4
|
||||
221E
|
||||
2205
|
||||
220A
|
||||
2229
|
||||
2261
|
||||
00B1
|
||||
2265
|
||||
2264
|
||||
2320
|
||||
2321
|
||||
00F7
|
||||
2248
|
||||
00B0
|
||||
2219
|
||||
00B7
|
||||
221A
|
||||
207F
|
||||
00B2
|
||||
25A0
|
||||
00A0
|
||||
@@ -0,0 +1,128 @@
|
||||
2500
|
||||
2502
|
||||
250C
|
||||
2510
|
||||
2514
|
||||
2518
|
||||
251C
|
||||
2524
|
||||
252C
|
||||
2534
|
||||
253C
|
||||
2580
|
||||
2584
|
||||
2588
|
||||
258C
|
||||
2590
|
||||
2591
|
||||
2592
|
||||
2593
|
||||
2320
|
||||
25A0
|
||||
2022
|
||||
221A
|
||||
2248
|
||||
2264
|
||||
2265
|
||||
00A0
|
||||
2321
|
||||
00B0
|
||||
00B2
|
||||
00B7
|
||||
00F7
|
||||
2550
|
||||
2551
|
||||
2552
|
||||
0451
|
||||
2553
|
||||
2554
|
||||
2555
|
||||
2556
|
||||
2557
|
||||
2558
|
||||
2559
|
||||
255A
|
||||
255B
|
||||
255C
|
||||
255D
|
||||
255E
|
||||
255F
|
||||
2560
|
||||
2561
|
||||
0401
|
||||
2562
|
||||
2563
|
||||
2564
|
||||
2565
|
||||
2566
|
||||
2567
|
||||
2568
|
||||
2569
|
||||
256A
|
||||
256B
|
||||
256C
|
||||
00A9
|
||||
044E
|
||||
0430
|
||||
0431
|
||||
0446
|
||||
0434
|
||||
0435
|
||||
0444
|
||||
0433
|
||||
0445
|
||||
0438
|
||||
0439
|
||||
043A
|
||||
043B
|
||||
043C
|
||||
043D
|
||||
043E
|
||||
043F
|
||||
044F
|
||||
0440
|
||||
0441
|
||||
0442
|
||||
0443
|
||||
0436
|
||||
0432
|
||||
044C
|
||||
044B
|
||||
0437
|
||||
0448
|
||||
044D
|
||||
0449
|
||||
0447
|
||||
044A
|
||||
042E
|
||||
0410
|
||||
0411
|
||||
0426
|
||||
0414
|
||||
0415
|
||||
0424
|
||||
0413
|
||||
0425
|
||||
0418
|
||||
0419
|
||||
041A
|
||||
041B
|
||||
041C
|
||||
041D
|
||||
041E
|
||||
041F
|
||||
042F
|
||||
0420
|
||||
0421
|
||||
0422
|
||||
0423
|
||||
0416
|
||||
0412
|
||||
042C
|
||||
042B
|
||||
0417
|
||||
0428
|
||||
042D
|
||||
0429
|
||||
0427
|
||||
042A
|
||||
@@ -0,0 +1,128 @@
|
||||
2500
|
||||
2502
|
||||
250C
|
||||
2510
|
||||
2514
|
||||
2518
|
||||
251C
|
||||
2524
|
||||
252C
|
||||
2534
|
||||
253C
|
||||
2580
|
||||
2584
|
||||
2588
|
||||
258C
|
||||
2590
|
||||
2591
|
||||
2592
|
||||
2593
|
||||
2320
|
||||
25A0
|
||||
2022
|
||||
221A
|
||||
2248
|
||||
2264
|
||||
2265
|
||||
00A0
|
||||
2321
|
||||
00B0
|
||||
00B2
|
||||
00B7
|
||||
00F7
|
||||
2550
|
||||
2551
|
||||
2552
|
||||
0451
|
||||
0454
|
||||
2554
|
||||
0456
|
||||
0457
|
||||
2557
|
||||
2558
|
||||
2559
|
||||
255A
|
||||
255B
|
||||
0491
|
||||
255D
|
||||
255E
|
||||
255F
|
||||
2560
|
||||
2561
|
||||
0401
|
||||
0404
|
||||
2563
|
||||
0406
|
||||
0407
|
||||
2566
|
||||
2567
|
||||
2568
|
||||
2569
|
||||
256A
|
||||
0490
|
||||
256C
|
||||
00A9
|
||||
044E
|
||||
0430
|
||||
0431
|
||||
0446
|
||||
0434
|
||||
0435
|
||||
0444
|
||||
0433
|
||||
0445
|
||||
0438
|
||||
0439
|
||||
043A
|
||||
043B
|
||||
043C
|
||||
043D
|
||||
043E
|
||||
043F
|
||||
044F
|
||||
0440
|
||||
0441
|
||||
0442
|
||||
0443
|
||||
0436
|
||||
0432
|
||||
044C
|
||||
044B
|
||||
0437
|
||||
0448
|
||||
044D
|
||||
0449
|
||||
0447
|
||||
044A
|
||||
042E
|
||||
0410
|
||||
0411
|
||||
0426
|
||||
0414
|
||||
0415
|
||||
0424
|
||||
0413
|
||||
0425
|
||||
0418
|
||||
0419
|
||||
041A
|
||||
041B
|
||||
041C
|
||||
041D
|
||||
041E
|
||||
041F
|
||||
042F
|
||||
0420
|
||||
0421
|
||||
0422
|
||||
0423
|
||||
0416
|
||||
0412
|
||||
042C
|
||||
042B
|
||||
0417
|
||||
0428
|
||||
042D
|
||||
0429
|
||||
0427
|
||||
042A
|
||||
@@ -0,0 +1,128 @@
|
||||
2502
|
||||
2510
|
||||
2524
|
||||
2591
|
||||
2592
|
||||
2593
|
||||
2320
|
||||
25A0
|
||||
2022
|
||||
221A
|
||||
2248
|
||||
2264
|
||||
2265
|
||||
00A0
|
||||
2321
|
||||
00B0
|
||||
00B2
|
||||
00B7
|
||||
00F7
|
||||
2551
|
||||
0451
|
||||
2555
|
||||
2556
|
||||
2557
|
||||
255B
|
||||
255C
|
||||
255D
|
||||
2561
|
||||
0401
|
||||
2562
|
||||
2563
|
||||
00A9
|
||||
044E
|
||||
0430
|
||||
0431
|
||||
0446
|
||||
0434
|
||||
0435
|
||||
0444
|
||||
0433
|
||||
0445
|
||||
0438
|
||||
0439
|
||||
043A
|
||||
043B
|
||||
043C
|
||||
043D
|
||||
043E
|
||||
043F
|
||||
044F
|
||||
0440
|
||||
0441
|
||||
0442
|
||||
0443
|
||||
0436
|
||||
0432
|
||||
044C
|
||||
044B
|
||||
0437
|
||||
0448
|
||||
044D
|
||||
0449
|
||||
0447
|
||||
044A
|
||||
2514
|
||||
2534
|
||||
252C
|
||||
251C
|
||||
2500
|
||||
253C
|
||||
255E
|
||||
255F
|
||||
255A
|
||||
2554
|
||||
2569
|
||||
2566
|
||||
2560
|
||||
2550
|
||||
256C
|
||||
2567
|
||||
2568
|
||||
2564
|
||||
2565
|
||||
2559
|
||||
2558
|
||||
2552
|
||||
2553
|
||||
256B
|
||||
256A
|
||||
2518
|
||||
250C
|
||||
2588
|
||||
2584
|
||||
258C
|
||||
2590
|
||||
2580
|
||||
042E
|
||||
0410
|
||||
0411
|
||||
0426
|
||||
0414
|
||||
0415
|
||||
0424
|
||||
0413
|
||||
0425
|
||||
0418
|
||||
0419
|
||||
041A
|
||||
041B
|
||||
041C
|
||||
041D
|
||||
041E
|
||||
041F
|
||||
042F
|
||||
0420
|
||||
0421
|
||||
0422
|
||||
0423
|
||||
0416
|
||||
0412
|
||||
042C
|
||||
042B
|
||||
0417
|
||||
0428
|
||||
042D
|
||||
0429
|
||||
0427
|
||||
042A
|
||||
@@ -0,0 +1,128 @@
|
||||
2502
|
||||
2510
|
||||
2524
|
||||
2591
|
||||
2592
|
||||
2593
|
||||
2320
|
||||
25A0
|
||||
2022
|
||||
221A
|
||||
2248
|
||||
2264
|
||||
2265
|
||||
00A0
|
||||
2321
|
||||
00B0
|
||||
00B2
|
||||
00B7
|
||||
00F7
|
||||
2551
|
||||
0451
|
||||
0456
|
||||
0457
|
||||
2557
|
||||
255B
|
||||
0491
|
||||
255D
|
||||
2561
|
||||
0401
|
||||
0404
|
||||
2563
|
||||
00A9
|
||||
044E
|
||||
0430
|
||||
0431
|
||||
0446
|
||||
0434
|
||||
0435
|
||||
0444
|
||||
0433
|
||||
0445
|
||||
0438
|
||||
0439
|
||||
043A
|
||||
043B
|
||||
043C
|
||||
043D
|
||||
043E
|
||||
043F
|
||||
044F
|
||||
0440
|
||||
0441
|
||||
0442
|
||||
0443
|
||||
0436
|
||||
0432
|
||||
044C
|
||||
044B
|
||||
0437
|
||||
0448
|
||||
044D
|
||||
0449
|
||||
0447
|
||||
044A
|
||||
2514
|
||||
2534
|
||||
252C
|
||||
251C
|
||||
2500
|
||||
253C
|
||||
255E
|
||||
255F
|
||||
255A
|
||||
2554
|
||||
2569
|
||||
2566
|
||||
2560
|
||||
2550
|
||||
256C
|
||||
2567
|
||||
2568
|
||||
0406
|
||||
0407
|
||||
2559
|
||||
2558
|
||||
2552
|
||||
0454
|
||||
0490
|
||||
256A
|
||||
2518
|
||||
250C
|
||||
2588
|
||||
2584
|
||||
258C
|
||||
2590
|
||||
2580
|
||||
042E
|
||||
0410
|
||||
0411
|
||||
0426
|
||||
0414
|
||||
0415
|
||||
0424
|
||||
0413
|
||||
0425
|
||||
0418
|
||||
0419
|
||||
041A
|
||||
041B
|
||||
041C
|
||||
041D
|
||||
041E
|
||||
041F
|
||||
042F
|
||||
0420
|
||||
0421
|
||||
0422
|
||||
0423
|
||||
0416
|
||||
0412
|
||||
042C
|
||||
042B
|
||||
0417
|
||||
0428
|
||||
042D
|
||||
0429
|
||||
0427
|
||||
042A
|
||||
@@ -0,0 +1,32 @@
|
||||
0164
|
||||
0165
|
||||
02C7
|
||||
02D8
|
||||
00A8
|
||||
015E
|
||||
02DB
|
||||
00B4
|
||||
00B8
|
||||
015F
|
||||
013D
|
||||
02DD
|
||||
013E
|
||||
0154
|
||||
0139
|
||||
011A
|
||||
010E
|
||||
0147
|
||||
0158
|
||||
016E
|
||||
00DD
|
||||
0162
|
||||
0155
|
||||
013A
|
||||
011B
|
||||
010F
|
||||
0148
|
||||
0159
|
||||
016F
|
||||
00FD
|
||||
0163
|
||||
02D9
|
||||
@@ -0,0 +1,128 @@
|
||||
0496
|
||||
0492
|
||||
04EE
|
||||
0493
|
||||
201E
|
||||
2026
|
||||
04B6
|
||||
04AE
|
||||
04B2
|
||||
04AF
|
||||
04A0
|
||||
04E2
|
||||
04A2
|
||||
049A
|
||||
04BA
|
||||
04B8
|
||||
0497
|
||||
2018
|
||||
2019
|
||||
201C
|
||||
201D
|
||||
2022
|
||||
2013
|
||||
2014
|
||||
04B3
|
||||
04B7
|
||||
04A1
|
||||
04E3
|
||||
04A3
|
||||
049B
|
||||
04BB
|
||||
04B9
|
||||
00A0
|
||||
040E
|
||||
045E
|
||||
0408
|
||||
04E8
|
||||
0498
|
||||
04B0
|
||||
00A7
|
||||
0401
|
||||
00A9
|
||||
04D8
|
||||
00AB
|
||||
00AC
|
||||
04EF
|
||||
00AE
|
||||
049C
|
||||
00B0
|
||||
04B1
|
||||
0406
|
||||
0456
|
||||
0499
|
||||
04E9
|
||||
00B6
|
||||
00B7
|
||||
0451
|
||||
2116
|
||||
04D9
|
||||
00BB
|
||||
0458
|
||||
04AA
|
||||
04AB
|
||||
049D
|
||||
0410
|
||||
0411
|
||||
0412
|
||||
0413
|
||||
0414
|
||||
0415
|
||||
0416
|
||||
0417
|
||||
0418
|
||||
0419
|
||||
041A
|
||||
041B
|
||||
041C
|
||||
041D
|
||||
041E
|
||||
041F
|
||||
0420
|
||||
0421
|
||||
0422
|
||||
0423
|
||||
0424
|
||||
0425
|
||||
0426
|
||||
0427
|
||||
0428
|
||||
0429
|
||||
042A
|
||||
042B
|
||||
042C
|
||||
042D
|
||||
042E
|
||||
042F
|
||||
0430
|
||||
0431
|
||||
0432
|
||||
0433
|
||||
0434
|
||||
0435
|
||||
0436
|
||||
0437
|
||||
0438
|
||||
0439
|
||||
043A
|
||||
043B
|
||||
043C
|
||||
043D
|
||||
043E
|
||||
043F
|
||||
0440
|
||||
0441
|
||||
0442
|
||||
0443
|
||||
0444
|
||||
0445
|
||||
0446
|
||||
0447
|
||||
0448
|
||||
0449
|
||||
044A
|
||||
044B
|
||||
044C
|
||||
044D
|
||||
044E
|
||||
044F
|
||||
@@ -0,0 +1,128 @@
|
||||
0410
|
||||
0411
|
||||
0412
|
||||
0413
|
||||
0414
|
||||
0415
|
||||
0416
|
||||
0417
|
||||
0418
|
||||
0419
|
||||
041A
|
||||
041B
|
||||
041C
|
||||
041D
|
||||
041E
|
||||
041F
|
||||
0420
|
||||
0421
|
||||
0422
|
||||
0423
|
||||
0424
|
||||
0425
|
||||
0426
|
||||
0427
|
||||
0428
|
||||
0429
|
||||
042A
|
||||
042B
|
||||
042C
|
||||
042D
|
||||
042E
|
||||
042F
|
||||
04B6
|
||||
00B0
|
||||
0498
|
||||
00A3
|
||||
00A7
|
||||
2022
|
||||
00B6
|
||||
0406
|
||||
00AE
|
||||
00A9
|
||||
04B7
|
||||
0496
|
||||
0497
|
||||
04AE
|
||||
0492
|
||||
0493
|
||||
04B0
|
||||
04B1
|
||||
04E2
|
||||
04E3
|
||||
0456
|
||||
04E9
|
||||
0499
|
||||
0408
|
||||
04D8
|
||||
04D9
|
||||
049C
|
||||
049D
|
||||
04A0
|
||||
04A1
|
||||
04A2
|
||||
04A3
|
||||
0458
|
||||
04AA
|
||||
00AC
|
||||
04B2
|
||||
04EE
|
||||
04B3
|
||||
04AF
|
||||
00AB
|
||||
00BB
|
||||
2026
|
||||
00A0
|
||||
04BA
|
||||
04BB
|
||||
049A
|
||||
049B
|
||||
04AB
|
||||
2013
|
||||
2014
|
||||
201C
|
||||
201D
|
||||
2018
|
||||
2019
|
||||
04EF
|
||||
201E
|
||||
040E
|
||||
045E
|
||||
04B8
|
||||
04B9
|
||||
2116
|
||||
0401
|
||||
0451
|
||||
044F
|
||||
0430
|
||||
0431
|
||||
0432
|
||||
0433
|
||||
0434
|
||||
0435
|
||||
0436
|
||||
0437
|
||||
0438
|
||||
0439
|
||||
043A
|
||||
043B
|
||||
043C
|
||||
043D
|
||||
043E
|
||||
043F
|
||||
0440
|
||||
0441
|
||||
0442
|
||||
0443
|
||||
0444
|
||||
0445
|
||||
0446
|
||||
0447
|
||||
0448
|
||||
0449
|
||||
044A
|
||||
044B
|
||||
044C
|
||||
044D
|
||||
044E
|
||||
04E8
|
||||
@@ -0,0 +1,32 @@
|
||||
20AC
|
||||
FFFF
|
||||
201A
|
||||
FFFF
|
||||
201E
|
||||
2026
|
||||
2020
|
||||
2021
|
||||
FFFF
|
||||
2030
|
||||
2039
|
||||
FFFF
|
||||
2018
|
||||
2019
|
||||
201C
|
||||
201D
|
||||
2022
|
||||
2013
|
||||
2014
|
||||
FFFF
|
||||
2122
|
||||
203A
|
||||
00A6
|
||||
00A9
|
||||
00AB
|
||||
00AC
|
||||
00AE
|
||||
00B1
|
||||
00B5
|
||||
00B6
|
||||
00B7
|
||||
00BB
|
||||
@@ -0,0 +1,32 @@
|
||||
0402
|
||||
0403
|
||||
201A
|
||||
0453
|
||||
201E
|
||||
2026
|
||||
2020
|
||||
2021
|
||||
20AC
|
||||
2030
|
||||
0409
|
||||
2039
|
||||
040A
|
||||
040C
|
||||
040B
|
||||
040F
|
||||
0452
|
||||
2018
|
||||
2019
|
||||
201C
|
||||
201D
|
||||
2022
|
||||
2013
|
||||
2014
|
||||
045D
|
||||
2122
|
||||
0459
|
||||
203A
|
||||
045A
|
||||
045C
|
||||
045B
|
||||
045F
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user