From 5edbb7a80a158583a81de286b7fcc5392916ba38 Mon Sep 17 00:00:00 2001 From: mnerv Date: Sun, 27 Aug 2023 18:03:45 +0200 Subject: [PATCH] FreeType 1.31.1 --- .cvsignore | 7 + CMakeLists.txt | 6 + FILES | 76 + INSTALL | 879 +++ MakeSub.in | 7 + Makefile.in | 60 + PATENTS | 27 + README | 695 ++ aclocal.m4 | 427 ++ announce | 60 + config.guess | 1087 +++ config.sub | 1215 +++ configure | 4515 +++++++++++ configure.in | 201 + contrib/ftos2/DEVELFAQ | 38 + contrib/ftos2/FAQ | 260 + contrib/ftos2/ft2.gif | Bin 0 -> 3817 bytes contrib/ftos2/ifi/32fddef.h | 53 + contrib/ftos2/ifi/32fdstrc.h | 161 + contrib/ftos2/ifi/32ifimet.h | 118 + contrib/ftos2/ifi/32pmifi.h | 79 + contrib/ftos2/ifi/FreeType.def | 10 + contrib/ftos2/ifi/FreeType.icc | 35 + contrib/ftos2/ifi/FreeType.wat | 29 + contrib/ftos2/ifi/ftifi.c | 3209 ++++++++ contrib/ftos2/ifi/ftifi.h | 305 + contrib/ftos2/ifi/ftmem.c | 184 + contrib/ftos2/ifi/ftmem.icc | 4 + contrib/ftos2/ifi/ftmem.ico | Bin 0 -> 2692 bytes contrib/ftos2/ifi/test.c | 238 + contrib/ftos2/ifi/test.icc | 6 + contrib/ftos2/ifi/test.wat | 4 + contrib/ftos2/install.cmd | 30 + contrib/ftos2/lib/arch/os2/Makefile.icc | 72 + contrib/ftos2/lib/arch/os2/Makefile.wat | 41 + contrib/ftos2/lib/ttmemory.c | 385 + contrib/ftos2/limit.cmd | 63 + contrib/ftos2/query.cmd | 15 + contrib/ftos2/readme.1st | 87 + contrib/ftos2/readme.txt | 113 + contrib/ftos2/uninst.c | 60 + contrib/ftos2/uninstall.cmd | 34 + contrib/mac/mac.hqx | Bin 0 -> 45034 bytes contrib/ttf2bdf/.cvsignore | 5 + contrib/ttf2bdf/Makefile.in | 74 + contrib/ttf2bdf/README | 315 + contrib/ttf2bdf/configure | 1357 ++++ contrib/ttf2bdf/configure.in | 40 + contrib/ttf2bdf/contrib/KOI2iso_pcf | 28 + contrib/ttf2bdf/contrib/creatett | 60 + contrib/ttf2bdf/contrib/creatett.m | 59 + contrib/ttf2bdf/maps/iso8859.1 | 278 + contrib/ttf2bdf/maps/iso8859.2 | 276 + contrib/ttf2bdf/maps/iso8859.3 | 271 + contrib/ttf2bdf/maps/iso8859.5 | 265 + contrib/ttf2bdf/maps/koi8.r | 232 + contrib/ttf2bdf/maps/windows.1251 | 233 + contrib/ttf2bdf/remap.c | 690 ++ contrib/ttf2bdf/remap.h | 64 + contrib/ttf2bdf/ttf2bdf.c | 1581 ++++ contrib/ttf2bdf/ttf2bdf.man | 196 + contrib/ttf2pfb/.cvsignore | 3 + contrib/ttf2pfb/Makefile.emx | 16 + contrib/ttf2pfb/Makefile.in | 74 + contrib/ttf2pfb/TODO | 40 + contrib/ttf2pfb/Uni-T1.enc | 397 + contrib/ttf2pfb/configure | 1553 ++++ contrib/ttf2pfb/configure.in | 45 + contrib/ttf2pfb/getafm | 364 + contrib/ttf2pfb/t1asm.c | 529 ++ contrib/ttf2pfb/ttf2pfb.c | 1725 +++++ contrib/ttf2pk/.cvsignore | 8 + contrib/ttf2pk/BUGS | 3 + contrib/ttf2pk/MakeSub.in | 6 + contrib/ttf2pk/Makefile.dm | 71 + contrib/ttf2pk/Makefile.in | 116 + contrib/ttf2pk/README | 104 + contrib/ttf2pk/TODO | 22 + contrib/ttf2pk/c-auto.h | 23 + contrib/ttf2pk/case.c | 179 + contrib/ttf2pk/case.h | 27 + contrib/ttf2pk/configure | 1700 +++++ contrib/ttf2pk/configure.in | 87 + contrib/ttf2pk/data/Big5.sfd | 65 + contrib/ttf2pk/data/ET5.enc | 119 + contrib/ttf2pk/data/EUC.sfd | 49 + contrib/ttf2pk/data/SJIS.sfd | 52 + contrib/ttf2pk/data/T1-WGL4.enc | 128 + contrib/ttf2pk/data/UBg5plus.sfd | 3002 ++++++++ contrib/ttf2pk/data/UBig5.sfd | 1854 +++++ contrib/ttf2pk/data/UGB.sfd | 1114 +++ contrib/ttf2pk/data/UGBK.sfd | 3002 ++++++++ contrib/ttf2pk/data/UJIS.sfd | 1114 +++ contrib/ttf2pk/data/UKS.sfd | 1114 +++ contrib/ttf2pk/data/Unicode.sfd | 265 + contrib/ttf2pk/data/VPS.rpl | 244 + contrib/ttf2pk/data/ttfonts.map | 18 + contrib/ttf2pk/dvidrv.btm | 334 + contrib/ttf2pk/dvidrv.doc | 56 + contrib/ttf2pk/emdir.c | 109 + contrib/ttf2pk/emdir.h | 25 + contrib/ttf2pk/emtexdir.c | 405 + contrib/ttf2pk/emtexdir.h | 57 + contrib/ttf2pk/errormsg.c | 96 + contrib/ttf2pk/errormsg.h | 43 + contrib/ttf2pk/filesrch.c | 602 ++ contrib/ttf2pk/filesrch.h | 51 + contrib/ttf2pk/ligkern.c | 275 + contrib/ttf2pk/ligkern.h | 23 + contrib/ttf2pk/newobj.c | 352 + contrib/ttf2pk/newobj.h | 43 + contrib/ttf2pk/parse.c | 304 + contrib/ttf2pk/parse.h | 22 + contrib/ttf2pk/pklib.c | 872 +++ contrib/ttf2pk/pklib.h | 29 + contrib/ttf2pk/scripts/README | 8 + .../ttf2pk/scripts/teTeX-0.4/MakeTeXPK.diff | 63 + .../ttf2pk/scripts/web2c-6.1/MakeTeXPK.diff | 75 + contrib/ttf2pk/scripts/web2c-6.1/README | 1 + .../ttf2pk/scripts/web2c-7.0/MakeTeXPK.diff | 67 + .../ttf2pk/scripts/web2c-7.1/MakeTeXPK.diff | 72 + contrib/ttf2pk/scripts/web2c-7.1/README | 1 + contrib/ttf2pk/scripts/web2c-7.2/mktexpk.diff | 72 + contrib/ttf2pk/subfont.c | 264 + contrib/ttf2pk/subfont.h | 26 + contrib/ttf2pk/texenc.c | 203 + contrib/ttf2pk/texenc.h | 28 + contrib/ttf2pk/tfmaux.c | 579 ++ contrib/ttf2pk/tfmaux.h | 28 + contrib/ttf2pk/ttf2pk.1 | 289 + contrib/ttf2pk/ttf2pk.c | 592 ++ contrib/ttf2pk/ttf2pk.doc | 733 ++ contrib/ttf2pk/ttf2tfm.1 | 1095 +++ contrib/ttf2pk/ttf2tfm.c | 885 +++ contrib/ttf2pk/ttf2tfm.h | 234 + contrib/ttf2pk/ttfaux.c | 714 ++ contrib/ttf2pk/ttfaux.h | 21 + contrib/ttf2pk/ttfenc.c | 1281 ++++ contrib/ttf2pk/ttfenc.h | 41 + contrib/ttf2pk/ttflib.c | 703 ++ contrib/ttf2pk/ttflib.h | 31 + contrib/ttf2pk/vplaux.c | 588 ++ contrib/ttf2pk/vplaux.h | 23 + contrib/ttfbanner/.cvsignore | 2 + contrib/ttfbanner/Makefile.emx | 9 + contrib/ttfbanner/Makefile.in | 64 + contrib/ttfbanner/README | 38 + contrib/ttfbanner/configure | 1372 ++++ contrib/ttfbanner/configure.in | 38 + contrib/ttfbanner/ttfbanner.c | 320 + contrib/ttfbanner/ttfbanner.h | 9 + contrib/win32/driver32.c | 106 + contrib/win32/hack_common.c | 8 + contrib/win32/hack_ftdump.c | 9 + contrib/win32/hack_ftlint.c | 9 + contrib/win32/hack_ftstring.c | 9 + contrib/win32/hack_fttimer.c | 9 + contrib/win32/hack_ftview.c | 9 + contrib/win32/readme.txt | 19 + contrib/win32/res/testw32.ico | Bin 0 -> 1078 bytes contrib/win32/res/testw32.rc2 | 13 + contrib/win32/resource.h | 24 + contrib/win32/stdafx.cpp | 6 + contrib/win32/stdafx.h | 25 + contrib/win32/testw32.cpp | 79 + contrib/win32/testw32.dsp | 190 + contrib/win32/testw32.dsw | 29 + contrib/win32/testw32.h | 50 + contrib/win32/testw32.mak | 533 ++ contrib/win32/testw32.mdp | Bin 0 -> 43008 bytes contrib/win32/testw32.rc | 202 + contrib/win32/testw32dlg.cpp | 358 + contrib/win32/testw32dlg.h | 51 + docs/FAQ | 799 ++ docs/TODO | 23 + docs/apiref.txt | 1867 +++++ docs/apirefx.txt | 864 +++ docs/bitmaps.txt | 771 ++ docs/changes.txt | 851 +++ docs/convntns.txt | 970 +++ docs/credits | 94 + docs/freetype.lsm | 16 + docs/glyphs.htm | 1257 ++++ docs/glyphs.txt | 999 +++ docs/i18n.txt | 161 + docs/image/baselin2.gif | Bin 0 -> 1282 bytes docs/image/baseline.gif | Bin 0 -> 2976 bytes docs/image/emsquare.gif | Bin 0 -> 2917 bytes docs/image/freetype.gif | Bin 0 -> 10545 bytes docs/image/freetype.png | Bin 0 -> 10756 bytes docs/image/grid1.gif | Bin 0 -> 1399 bytes docs/image/grid2.gif | Bin 0 -> 3390 bytes docs/image/grid3.gif | Bin 0 -> 3313 bytes docs/image/metrics.gif | Bin 0 -> 3296 bytes docs/image/metrics2.gif | Bin 0 -> 2934 bytes docs/image/small2.gif | Bin 0 -> 8814 bytes docs/image/tfp-back.png | Bin 0 -> 53962 bytes docs/optimize.txt | 158 + docs/porting.txt | 1078 +++ docs/raster.txt | 577 ++ docs/readme.txt | 106 + docs/threads.txt | 117 + docs/user.txt | 916 +++ freetype.spec | 162 + ft_conf.h.in | 211 + howto/mac.txt | 19 + howto/msdos.txt | 250 + howto/os2.txt | 200 + howto/unix.txt | 255 + howto/windows.txt | 344 + install-sh | 250 + lib/.cvsignore | 3 + lib/arch/amigaos/Makefile.gcc | 69 + lib/arch/amigaos/freetype.c | 25 + lib/arch/amigaos/ft_conf.h | 220 + lib/arch/ansi/freetype.c | 32 + lib/arch/ansi/ft_conf.h | 227 + lib/arch/debugger/Makefile | 96 + lib/arch/debugger/freetype.c | 32 + lib/arch/debugger/ft_conf.h | 236 + lib/arch/mac/README | 47 + lib/arch/mac/freetype.c | 48 + lib/arch/mac/ft_conf.h | 211 + lib/arch/mac/ttmmap.c | 1069 +++ lib/arch/msdos/Makefile.BC | 132 + lib/arch/msdos/Makefile.MS | 117 + lib/arch/msdos/Makefile.TC | 86 + lib/arch/msdos/Makefile.VC | 117 + lib/arch/msdos/Makefile.dm | 84 + lib/arch/msdos/Makefile.gcc | 92 + lib/arch/msdos/Makefile.wat | 88 + lib/arch/msdos/depend.dos | 107 + lib/arch/msdos/freetype.c | 39 + lib/arch/msdos/ft_conf.h | 253 + lib/arch/msdos/hugefile.c | 84 + lib/arch/msdos/hugemem.c | 496 ++ lib/arch/msdos/makedep | 26 + lib/arch/os2/Makefile.dm | 84 + lib/arch/os2/Makefile.emx | 91 + lib/arch/os2/Makefile.icc | 73 + lib/arch/os2/Makefile.wat | 88 + lib/arch/os2/freetype.c | 32 + lib/arch/os2/ft_conf.h | 239 + lib/arch/os2/os2file.c | 1237 +++ lib/arch/unix/.cvsignore | 1 + lib/arch/unix/Makefile.in | 244 + lib/arch/unix/freetype.c | 27 + lib/arch/unix/ttmmap.c | 1027 +++ lib/arch/vms/README | 20 + lib/arch/vms/descrip.mms | 155 + lib/arch/vms/ft_conf.h | 215 + lib/arch/win16/Makefile.BC | 180 + lib/arch/win16/Makefile.MS | 106 + lib/arch/win16/Makefile.VC | 175 + lib/arch/win16/depend.win | 109 + lib/arch/win16/freetype.c | 39 + lib/arch/win16/ft_conf.h | 209 + lib/arch/win16/hugefile.c | 51 + lib/arch/win16/hugemem.c | 539 ++ lib/arch/win16/makedef | 24 + lib/arch/win16/makedep | 32 + lib/arch/win16/ttf.def | 127 + lib/arch/win32/Makefile.BC | 161 + lib/arch/win32/Makefile.CL | 165 + lib/arch/win32/Makefile.Min | 98 + lib/arch/win32/Makefile.VC | 195 + lib/arch/win32/Makefile.gcc | 96 + lib/arch/win32/depend.win | 103 + lib/arch/win32/freetype.c | 42 + lib/arch/win32/freetype.dsp | 104 + lib/arch/win32/freetype.dsw | 29 + lib/arch/win32/freetype.ide | Bin 0 -> 35542 bytes lib/arch/win32/freetype.mak | 353 + lib/arch/win32/freetype.mdp | Bin 0 -> 37376 bytes lib/arch/win32/ft_conf.h | 210 + lib/arch/win32/makedef | 24 + lib/arch/win32/makedep | 29 + lib/arch/win32/ttf.def | 127 + lib/extend/ftxcmap.c | 347 + lib/extend/ftxcmap.h | 60 + lib/extend/ftxerr18.c | 241 + lib/extend/ftxerr18.h | 38 + lib/extend/ftxgasp.c | 69 + lib/extend/ftxgasp.h | 53 + lib/extend/ftxgdef.c | 1099 +++ lib/extend/ftxgdef.h | 216 + lib/extend/ftxgpos.c | 4045 ++++++++++ lib/extend/ftxgpos.h | 767 ++ lib/extend/ftxgsub.c | 4307 +++++++++++ lib/extend/ftxgsub.h | 581 ++ lib/extend/ftxkern.c | 564 ++ lib/extend/ftxkern.h | 181 + lib/extend/ftxopen.c | 1439 ++++ lib/extend/ftxopen.h | 304 + lib/extend/ftxopenf.h | 135 + lib/extend/ftxpost.c | 522 ++ lib/extend/ftxpost.h | 107 + lib/extend/ftxsbit.c | 1391 ++++ lib/extend/ftxsbit.h | 490 ++ lib/extend/ftxwidth.c | 185 + lib/extend/ftxwidth.h | 80 + lib/extend/readme.1st | 61 + lib/freetype.h | 1147 +++ lib/fterrid.h | 161 + lib/ftnameid.h | 628 ++ lib/header.h | 49 + lib/ttapi.c | 2219 ++++++ lib/ttcache.c | 463 ++ lib/ttcache.h | 216 + lib/ttcalc.c | 403 + lib/ttcalc.h | 97 + lib/ttcmap.c | 503 ++ lib/ttcmap.h | 169 + lib/ttconfig.h | 279 + lib/ttdebug.c | 404 + lib/ttdebug.h | 170 + lib/ttengine.h | 115 + lib/ttextend.c | 212 + lib/ttextend.h | 168 + lib/ttfile.c | 1175 +++ lib/ttfile.h | 271 + lib/ttgload.c | 1351 ++++ lib/ttgload.h | 51 + lib/ttinterp.c | 6654 +++++++++++++++++ lib/ttinterp.h | 54 + lib/ttload.c | 1574 ++++ lib/ttload.h | 217 + lib/ttmemory.c | 397 + lib/ttmemory.h | 125 + lib/ttmutex.c | 85 + lib/ttmutex.h | 59 + lib/ttobjs.c | 1495 ++++ lib/ttobjs.h | 873 +++ lib/ttraster.c | 2727 +++++++ lib/ttraster.h | 127 + lib/tttables.h | 215 + lib/tttags.h | 61 + lib/tttypes.h | 150 + license.txt | 158 + ltconfig | 3017 ++++++++ ltmain.sh | 3975 ++++++++++ mkinstalldirs | 40 + net.m4 | 55 + pascal/lib/freetype.pas | 1931 +++++ pascal/lib/ttcache.pas | 433 ++ pascal/lib/ttcalc.pas | 289 + pascal/lib/ttcalc1.inc | 124 + pascal/lib/ttcalc2.inc | 107 + pascal/lib/ttcalc3.inc | 99 + pascal/lib/ttcalc4.inc | 134 + pascal/lib/ttcmap.pas | 431 ++ pascal/lib/ttconfig.inc | 75 + pascal/lib/ttdebug.pas | 851 +++ pascal/lib/tterror.pas | 69 + pascal/lib/ttfile.pas | 979 +++ pascal/lib/ttgload.pas | 1391 ++++ pascal/lib/ttinterp.pas | 4797 ++++++++++++ pascal/lib/ttload.pas | 1496 ++++ pascal/lib/ttmemory.pas | 282 + pascal/lib/ttobjs.pas | 1945 +++++ pascal/lib/ttraster.pas | 3445 +++++++++ pascal/lib/tttables.pas | 247 + pascal/lib/tttypes.pas | 102 + pascal/test/codetv.pas | 248 + pascal/test/common.pas | 84 + pascal/test/debugger.inc | 42 + pascal/test/debugger.pas | 924 +++ pascal/test/dump.pas | 551 ++ pascal/test/gdriver.pas | 123 + pascal/test/gdrv_dos.inc | 96 + pascal/test/gdrv_os2.inc | 148 + pascal/test/gevents.pas | 42 + pascal/test/gmain.pas | 474 ++ pascal/test/lint.pas | 277 + pascal/test/stacktv.pas | 148 + pascal/test/statetv.pas | 196 + pascal/test/timer.pas | 377 + pascal/test/view.pas | 523 ++ pascal/test/zonetv.pas | 222 + po/.cvsignore | 8 + po/Makefile.in.in | 216 + po/POTFILES.in | 10 + po/cs.po | 756 ++ po/de.po | 760 ++ po/es.po | 762 ++ po/fr.po | 752 ++ po/freetype.pot | 727 ++ po/nl.po | 758 ++ readme.1st | 10 + test/.cvsignore | 12 + test/README | 6 + test/arabic.c | 386 + test/arabic.h | 66 + test/arch/amigaos/Makefile.gcc | 106 + test/arch/amigaos/TODO | 16 + test/arch/amigaos/gfsamiga.c | 428 ++ test/arch/amigaos/gw_amiga.c | 522 ++ test/arch/amigaos/smakefile | 180 + test/arch/debugger/Makefile | 99 + test/arch/msdos/Makefile.BC | 181 + test/arch/msdos/Makefile.MS | 142 + test/arch/msdos/Makefile.TC | 196 + test/arch/msdos/Makefile.VC | 143 + test/arch/msdos/Makefile.dm | 145 + test/arch/msdos/Makefile.gcc | 130 + test/arch/msdos/depend.dos | 50 + test/arch/msdos/gfs_dos.c | 357 + test/arch/msdos/makedep | 22 + test/arch/msdos/time_tc.h | 124 + test/arch/os2/Makefile.dm | 143 + test/arch/os2/Makefile.emx | 108 + test/arch/os2/Makefile.icc | 145 + test/arch/os2/Makefile.wat | 155 + test/arch/os2/gfs_os2.c | 219 + test/arch/os2/gpm_os2.c | 654 ++ test/arch/os2/gpm_os2.def | 5 + test/arch/unix/.cvsignore | 1 + test/arch/unix/Makefile.in | 170 + test/arch/unix/gwin_x11.c | 451 ++ test/arch/win16/Makefile.BC | 212 + test/arch/win16/Makefile.MS | 145 + test/arch/win16/Makefile.VC | 187 + test/arch/win16/depend.win | 52 + test/arch/win16/gw_win16.c | 430 ++ test/arch/win16/makedep | 30 + test/arch/win32/Makefile.BC | 197 + test/arch/win32/Makefile.CL | 175 + test/arch/win32/Makefile.Min | 122 + test/arch/win32/Makefile.gcc | 131 + test/arch/win32/depend.win | 52 + test/arch/win32/gw_win32.c | 378 + test/arch/win32/makedep | 29 + test/blitter.c | 492 ++ test/blitter.h | 52 + test/common.c | 310 + test/common.h | 82 + test/display.c | 299 + test/display.h | 73 + test/fdebug.c | 285 + test/ftdump.c | 928 +++ test/fterror.c | 76 + test/ftlint.c | 296 + test/ftmetric.c | 396 + test/ftsbit.c | 293 + test/ftstring.c | 486 ++ test/ftstrpnm.c | 510 ++ test/ftstrtto.c | 1158 +++ test/fttimer.c | 455 ++ test/ftview.c | 540 ++ test/ftzoom.c | 681 ++ test/gdriver.h | 55 + test/gevents.h | 43 + test/gmain.c | 475 ++ test/gmain.h | 71 + 454 files changed, 173977 insertions(+) create mode 100644 .cvsignore create mode 100644 CMakeLists.txt create mode 100644 FILES create mode 100644 INSTALL create mode 100644 MakeSub.in create mode 100644 Makefile.in create mode 100644 PATENTS create mode 100644 README create mode 100644 aclocal.m4 create mode 100644 announce create mode 100644 config.guess create mode 100644 config.sub create mode 100644 configure create mode 100644 configure.in create mode 100644 contrib/ftos2/DEVELFAQ create mode 100644 contrib/ftos2/FAQ create mode 100644 contrib/ftos2/ft2.gif create mode 100644 contrib/ftos2/ifi/32fddef.h create mode 100644 contrib/ftos2/ifi/32fdstrc.h create mode 100644 contrib/ftos2/ifi/32ifimet.h create mode 100644 contrib/ftos2/ifi/32pmifi.h create mode 100644 contrib/ftos2/ifi/FreeType.def create mode 100644 contrib/ftos2/ifi/FreeType.icc create mode 100644 contrib/ftos2/ifi/FreeType.wat create mode 100644 contrib/ftos2/ifi/ftifi.c create mode 100644 contrib/ftos2/ifi/ftifi.h create mode 100644 contrib/ftos2/ifi/ftmem.c create mode 100644 contrib/ftos2/ifi/ftmem.icc create mode 100644 contrib/ftos2/ifi/ftmem.ico create mode 100644 contrib/ftos2/ifi/test.c create mode 100644 contrib/ftos2/ifi/test.icc create mode 100644 contrib/ftos2/ifi/test.wat create mode 100644 contrib/ftos2/install.cmd create mode 100644 contrib/ftos2/lib/arch/os2/Makefile.icc create mode 100644 contrib/ftos2/lib/arch/os2/Makefile.wat create mode 100644 contrib/ftos2/lib/ttmemory.c create mode 100644 contrib/ftos2/limit.cmd create mode 100644 contrib/ftos2/query.cmd create mode 100644 contrib/ftos2/readme.1st create mode 100644 contrib/ftos2/readme.txt create mode 100644 contrib/ftos2/uninst.c create mode 100644 contrib/ftos2/uninstall.cmd create mode 100644 contrib/mac/mac.hqx create mode 100644 contrib/ttf2bdf/.cvsignore create mode 100644 contrib/ttf2bdf/Makefile.in create mode 100644 contrib/ttf2bdf/README create mode 100644 contrib/ttf2bdf/configure create mode 100644 contrib/ttf2bdf/configure.in create mode 100644 contrib/ttf2bdf/contrib/KOI2iso_pcf create mode 100644 contrib/ttf2bdf/contrib/creatett create mode 100644 contrib/ttf2bdf/contrib/creatett.m create mode 100644 contrib/ttf2bdf/maps/iso8859.1 create mode 100644 contrib/ttf2bdf/maps/iso8859.2 create mode 100644 contrib/ttf2bdf/maps/iso8859.3 create mode 100644 contrib/ttf2bdf/maps/iso8859.5 create mode 100644 contrib/ttf2bdf/maps/koi8.r create mode 100644 contrib/ttf2bdf/maps/windows.1251 create mode 100644 contrib/ttf2bdf/remap.c create mode 100644 contrib/ttf2bdf/remap.h create mode 100644 contrib/ttf2bdf/ttf2bdf.c create mode 100644 contrib/ttf2bdf/ttf2bdf.man create mode 100644 contrib/ttf2pfb/.cvsignore create mode 100644 contrib/ttf2pfb/Makefile.emx create mode 100644 contrib/ttf2pfb/Makefile.in create mode 100644 contrib/ttf2pfb/TODO create mode 100644 contrib/ttf2pfb/Uni-T1.enc create mode 100644 contrib/ttf2pfb/configure create mode 100644 contrib/ttf2pfb/configure.in create mode 100644 contrib/ttf2pfb/getafm create mode 100644 contrib/ttf2pfb/t1asm.c create mode 100644 contrib/ttf2pfb/ttf2pfb.c create mode 100644 contrib/ttf2pk/.cvsignore create mode 100644 contrib/ttf2pk/BUGS create mode 100644 contrib/ttf2pk/MakeSub.in create mode 100644 contrib/ttf2pk/Makefile.dm create mode 100644 contrib/ttf2pk/Makefile.in create mode 100644 contrib/ttf2pk/README create mode 100644 contrib/ttf2pk/TODO create mode 100644 contrib/ttf2pk/c-auto.h create mode 100644 contrib/ttf2pk/case.c create mode 100644 contrib/ttf2pk/case.h create mode 100644 contrib/ttf2pk/configure create mode 100644 contrib/ttf2pk/configure.in create mode 100644 contrib/ttf2pk/data/Big5.sfd create mode 100644 contrib/ttf2pk/data/ET5.enc create mode 100644 contrib/ttf2pk/data/EUC.sfd create mode 100644 contrib/ttf2pk/data/SJIS.sfd create mode 100644 contrib/ttf2pk/data/T1-WGL4.enc create mode 100644 contrib/ttf2pk/data/UBg5plus.sfd create mode 100644 contrib/ttf2pk/data/UBig5.sfd create mode 100644 contrib/ttf2pk/data/UGB.sfd create mode 100644 contrib/ttf2pk/data/UGBK.sfd create mode 100644 contrib/ttf2pk/data/UJIS.sfd create mode 100644 contrib/ttf2pk/data/UKS.sfd create mode 100644 contrib/ttf2pk/data/Unicode.sfd create mode 100644 contrib/ttf2pk/data/VPS.rpl create mode 100644 contrib/ttf2pk/data/ttfonts.map create mode 100644 contrib/ttf2pk/dvidrv.btm create mode 100644 contrib/ttf2pk/dvidrv.doc create mode 100644 contrib/ttf2pk/emdir.c create mode 100644 contrib/ttf2pk/emdir.h create mode 100644 contrib/ttf2pk/emtexdir.c create mode 100644 contrib/ttf2pk/emtexdir.h create mode 100644 contrib/ttf2pk/errormsg.c create mode 100644 contrib/ttf2pk/errormsg.h create mode 100644 contrib/ttf2pk/filesrch.c create mode 100644 contrib/ttf2pk/filesrch.h create mode 100644 contrib/ttf2pk/ligkern.c create mode 100644 contrib/ttf2pk/ligkern.h create mode 100644 contrib/ttf2pk/newobj.c create mode 100644 contrib/ttf2pk/newobj.h create mode 100644 contrib/ttf2pk/parse.c create mode 100644 contrib/ttf2pk/parse.h create mode 100644 contrib/ttf2pk/pklib.c create mode 100644 contrib/ttf2pk/pklib.h create mode 100644 contrib/ttf2pk/scripts/README create mode 100644 contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK.diff create mode 100644 contrib/ttf2pk/scripts/web2c-6.1/MakeTeXPK.diff create mode 100644 contrib/ttf2pk/scripts/web2c-6.1/README create mode 100644 contrib/ttf2pk/scripts/web2c-7.0/MakeTeXPK.diff create mode 100644 contrib/ttf2pk/scripts/web2c-7.1/MakeTeXPK.diff create mode 100644 contrib/ttf2pk/scripts/web2c-7.1/README create mode 100644 contrib/ttf2pk/scripts/web2c-7.2/mktexpk.diff create mode 100644 contrib/ttf2pk/subfont.c create mode 100644 contrib/ttf2pk/subfont.h create mode 100644 contrib/ttf2pk/texenc.c create mode 100644 contrib/ttf2pk/texenc.h create mode 100644 contrib/ttf2pk/tfmaux.c create mode 100644 contrib/ttf2pk/tfmaux.h create mode 100644 contrib/ttf2pk/ttf2pk.1 create mode 100644 contrib/ttf2pk/ttf2pk.c create mode 100644 contrib/ttf2pk/ttf2pk.doc create mode 100644 contrib/ttf2pk/ttf2tfm.1 create mode 100644 contrib/ttf2pk/ttf2tfm.c create mode 100644 contrib/ttf2pk/ttf2tfm.h create mode 100644 contrib/ttf2pk/ttfaux.c create mode 100644 contrib/ttf2pk/ttfaux.h create mode 100644 contrib/ttf2pk/ttfenc.c create mode 100644 contrib/ttf2pk/ttfenc.h create mode 100644 contrib/ttf2pk/ttflib.c create mode 100644 contrib/ttf2pk/ttflib.h create mode 100644 contrib/ttf2pk/vplaux.c create mode 100644 contrib/ttf2pk/vplaux.h create mode 100644 contrib/ttfbanner/.cvsignore create mode 100644 contrib/ttfbanner/Makefile.emx create mode 100644 contrib/ttfbanner/Makefile.in create mode 100644 contrib/ttfbanner/README create mode 100644 contrib/ttfbanner/configure create mode 100644 contrib/ttfbanner/configure.in create mode 100644 contrib/ttfbanner/ttfbanner.c create mode 100644 contrib/ttfbanner/ttfbanner.h create mode 100644 contrib/win32/driver32.c create mode 100644 contrib/win32/hack_common.c create mode 100644 contrib/win32/hack_ftdump.c create mode 100644 contrib/win32/hack_ftlint.c create mode 100644 contrib/win32/hack_ftstring.c create mode 100644 contrib/win32/hack_fttimer.c create mode 100644 contrib/win32/hack_ftview.c create mode 100644 contrib/win32/readme.txt create mode 100644 contrib/win32/res/testw32.ico create mode 100644 contrib/win32/res/testw32.rc2 create mode 100644 contrib/win32/resource.h create mode 100644 contrib/win32/stdafx.cpp create mode 100644 contrib/win32/stdafx.h create mode 100644 contrib/win32/testw32.cpp create mode 100644 contrib/win32/testw32.dsp create mode 100644 contrib/win32/testw32.dsw create mode 100644 contrib/win32/testw32.h create mode 100644 contrib/win32/testw32.mak create mode 100644 contrib/win32/testw32.mdp create mode 100644 contrib/win32/testw32.rc create mode 100644 contrib/win32/testw32dlg.cpp create mode 100644 contrib/win32/testw32dlg.h create mode 100644 docs/FAQ create mode 100644 docs/TODO create mode 100644 docs/apiref.txt create mode 100644 docs/apirefx.txt create mode 100644 docs/bitmaps.txt create mode 100644 docs/changes.txt create mode 100644 docs/convntns.txt create mode 100644 docs/credits create mode 100644 docs/freetype.lsm create mode 100644 docs/glyphs.htm create mode 100644 docs/glyphs.txt create mode 100644 docs/i18n.txt create mode 100644 docs/image/baselin2.gif create mode 100644 docs/image/baseline.gif create mode 100644 docs/image/emsquare.gif create mode 100644 docs/image/freetype.gif create mode 100644 docs/image/freetype.png create mode 100644 docs/image/grid1.gif create mode 100644 docs/image/grid2.gif create mode 100644 docs/image/grid3.gif create mode 100644 docs/image/metrics.gif create mode 100644 docs/image/metrics2.gif create mode 100644 docs/image/small2.gif create mode 100644 docs/image/tfp-back.png create mode 100644 docs/optimize.txt create mode 100644 docs/porting.txt create mode 100644 docs/raster.txt create mode 100644 docs/readme.txt create mode 100644 docs/threads.txt create mode 100644 docs/user.txt create mode 100644 freetype.spec create mode 100644 ft_conf.h.in create mode 100644 howto/mac.txt create mode 100644 howto/msdos.txt create mode 100644 howto/os2.txt create mode 100644 howto/unix.txt create mode 100644 howto/windows.txt create mode 100644 install-sh create mode 100644 lib/.cvsignore create mode 100644 lib/arch/amigaos/Makefile.gcc create mode 100644 lib/arch/amigaos/freetype.c create mode 100644 lib/arch/amigaos/ft_conf.h create mode 100644 lib/arch/ansi/freetype.c create mode 100644 lib/arch/ansi/ft_conf.h create mode 100644 lib/arch/debugger/Makefile create mode 100644 lib/arch/debugger/freetype.c create mode 100644 lib/arch/debugger/ft_conf.h create mode 100644 lib/arch/mac/README create mode 100644 lib/arch/mac/freetype.c create mode 100644 lib/arch/mac/ft_conf.h create mode 100644 lib/arch/mac/ttmmap.c create mode 100644 lib/arch/msdos/Makefile.BC create mode 100644 lib/arch/msdos/Makefile.MS create mode 100644 lib/arch/msdos/Makefile.TC create mode 100644 lib/arch/msdos/Makefile.VC create mode 100644 lib/arch/msdos/Makefile.dm create mode 100644 lib/arch/msdos/Makefile.gcc create mode 100644 lib/arch/msdos/Makefile.wat create mode 100644 lib/arch/msdos/depend.dos create mode 100644 lib/arch/msdos/freetype.c create mode 100644 lib/arch/msdos/ft_conf.h create mode 100644 lib/arch/msdos/hugefile.c create mode 100644 lib/arch/msdos/hugemem.c create mode 100644 lib/arch/msdos/makedep create mode 100644 lib/arch/os2/Makefile.dm create mode 100644 lib/arch/os2/Makefile.emx create mode 100644 lib/arch/os2/Makefile.icc create mode 100644 lib/arch/os2/Makefile.wat create mode 100644 lib/arch/os2/freetype.c create mode 100644 lib/arch/os2/ft_conf.h create mode 100644 lib/arch/os2/os2file.c create mode 100644 lib/arch/unix/.cvsignore create mode 100644 lib/arch/unix/Makefile.in create mode 100644 lib/arch/unix/freetype.c create mode 100644 lib/arch/unix/ttmmap.c create mode 100644 lib/arch/vms/README create mode 100644 lib/arch/vms/descrip.mms create mode 100644 lib/arch/vms/ft_conf.h create mode 100644 lib/arch/win16/Makefile.BC create mode 100644 lib/arch/win16/Makefile.MS create mode 100644 lib/arch/win16/Makefile.VC create mode 100644 lib/arch/win16/depend.win create mode 100644 lib/arch/win16/freetype.c create mode 100644 lib/arch/win16/ft_conf.h create mode 100644 lib/arch/win16/hugefile.c create mode 100644 lib/arch/win16/hugemem.c create mode 100644 lib/arch/win16/makedef create mode 100644 lib/arch/win16/makedep create mode 100644 lib/arch/win16/ttf.def create mode 100644 lib/arch/win32/Makefile.BC create mode 100644 lib/arch/win32/Makefile.CL create mode 100644 lib/arch/win32/Makefile.Min create mode 100644 lib/arch/win32/Makefile.VC create mode 100644 lib/arch/win32/Makefile.gcc create mode 100644 lib/arch/win32/depend.win create mode 100644 lib/arch/win32/freetype.c create mode 100644 lib/arch/win32/freetype.dsp create mode 100644 lib/arch/win32/freetype.dsw create mode 100644 lib/arch/win32/freetype.ide create mode 100644 lib/arch/win32/freetype.mak create mode 100644 lib/arch/win32/freetype.mdp create mode 100644 lib/arch/win32/ft_conf.h create mode 100644 lib/arch/win32/makedef create mode 100644 lib/arch/win32/makedep create mode 100644 lib/arch/win32/ttf.def create mode 100644 lib/extend/ftxcmap.c create mode 100644 lib/extend/ftxcmap.h create mode 100644 lib/extend/ftxerr18.c create mode 100644 lib/extend/ftxerr18.h create mode 100644 lib/extend/ftxgasp.c create mode 100644 lib/extend/ftxgasp.h create mode 100644 lib/extend/ftxgdef.c create mode 100644 lib/extend/ftxgdef.h create mode 100644 lib/extend/ftxgpos.c create mode 100644 lib/extend/ftxgpos.h create mode 100644 lib/extend/ftxgsub.c create mode 100644 lib/extend/ftxgsub.h create mode 100644 lib/extend/ftxkern.c create mode 100644 lib/extend/ftxkern.h create mode 100644 lib/extend/ftxopen.c create mode 100644 lib/extend/ftxopen.h create mode 100644 lib/extend/ftxopenf.h create mode 100644 lib/extend/ftxpost.c create mode 100644 lib/extend/ftxpost.h create mode 100644 lib/extend/ftxsbit.c create mode 100644 lib/extend/ftxsbit.h create mode 100644 lib/extend/ftxwidth.c create mode 100644 lib/extend/ftxwidth.h create mode 100644 lib/extend/readme.1st create mode 100644 lib/freetype.h create mode 100644 lib/fterrid.h create mode 100644 lib/ftnameid.h create mode 100644 lib/header.h create mode 100644 lib/ttapi.c create mode 100644 lib/ttcache.c create mode 100644 lib/ttcache.h create mode 100644 lib/ttcalc.c create mode 100644 lib/ttcalc.h create mode 100644 lib/ttcmap.c create mode 100644 lib/ttcmap.h create mode 100644 lib/ttconfig.h create mode 100644 lib/ttdebug.c create mode 100644 lib/ttdebug.h create mode 100644 lib/ttengine.h create mode 100644 lib/ttextend.c create mode 100644 lib/ttextend.h create mode 100644 lib/ttfile.c create mode 100644 lib/ttfile.h create mode 100644 lib/ttgload.c create mode 100644 lib/ttgload.h create mode 100644 lib/ttinterp.c create mode 100644 lib/ttinterp.h create mode 100644 lib/ttload.c create mode 100644 lib/ttload.h create mode 100644 lib/ttmemory.c create mode 100644 lib/ttmemory.h create mode 100644 lib/ttmutex.c create mode 100644 lib/ttmutex.h create mode 100644 lib/ttobjs.c create mode 100644 lib/ttobjs.h create mode 100644 lib/ttraster.c create mode 100644 lib/ttraster.h create mode 100644 lib/tttables.h create mode 100644 lib/tttags.h create mode 100644 lib/tttypes.h create mode 100644 license.txt create mode 100644 ltconfig create mode 100644 ltmain.sh create mode 100644 mkinstalldirs create mode 100644 net.m4 create mode 100644 pascal/lib/freetype.pas create mode 100644 pascal/lib/ttcache.pas create mode 100644 pascal/lib/ttcalc.pas create mode 100644 pascal/lib/ttcalc1.inc create mode 100644 pascal/lib/ttcalc2.inc create mode 100644 pascal/lib/ttcalc3.inc create mode 100644 pascal/lib/ttcalc4.inc create mode 100644 pascal/lib/ttcmap.pas create mode 100644 pascal/lib/ttconfig.inc create mode 100644 pascal/lib/ttdebug.pas create mode 100644 pascal/lib/tterror.pas create mode 100644 pascal/lib/ttfile.pas create mode 100644 pascal/lib/ttgload.pas create mode 100644 pascal/lib/ttinterp.pas create mode 100644 pascal/lib/ttload.pas create mode 100644 pascal/lib/ttmemory.pas create mode 100644 pascal/lib/ttobjs.pas create mode 100644 pascal/lib/ttraster.pas create mode 100644 pascal/lib/tttables.pas create mode 100644 pascal/lib/tttypes.pas create mode 100644 pascal/test/codetv.pas create mode 100644 pascal/test/common.pas create mode 100644 pascal/test/debugger.inc create mode 100644 pascal/test/debugger.pas create mode 100644 pascal/test/dump.pas create mode 100644 pascal/test/gdriver.pas create mode 100644 pascal/test/gdrv_dos.inc create mode 100644 pascal/test/gdrv_os2.inc create mode 100644 pascal/test/gevents.pas create mode 100644 pascal/test/gmain.pas create mode 100644 pascal/test/lint.pas create mode 100644 pascal/test/stacktv.pas create mode 100644 pascal/test/statetv.pas create mode 100644 pascal/test/timer.pas create mode 100644 pascal/test/view.pas create mode 100644 pascal/test/zonetv.pas create mode 100644 po/.cvsignore create mode 100644 po/Makefile.in.in create mode 100644 po/POTFILES.in create mode 100644 po/cs.po create mode 100644 po/de.po create mode 100644 po/es.po create mode 100644 po/fr.po create mode 100644 po/freetype.pot create mode 100644 po/nl.po create mode 100644 readme.1st create mode 100644 test/.cvsignore create mode 100644 test/README create mode 100644 test/arabic.c create mode 100644 test/arabic.h create mode 100644 test/arch/amigaos/Makefile.gcc create mode 100644 test/arch/amigaos/TODO create mode 100644 test/arch/amigaos/gfsamiga.c create mode 100644 test/arch/amigaos/gw_amiga.c create mode 100644 test/arch/amigaos/smakefile create mode 100644 test/arch/debugger/Makefile create mode 100644 test/arch/msdos/Makefile.BC create mode 100644 test/arch/msdos/Makefile.MS create mode 100644 test/arch/msdos/Makefile.TC create mode 100644 test/arch/msdos/Makefile.VC create mode 100644 test/arch/msdos/Makefile.dm create mode 100644 test/arch/msdos/Makefile.gcc create mode 100644 test/arch/msdos/depend.dos create mode 100644 test/arch/msdos/gfs_dos.c create mode 100644 test/arch/msdos/makedep create mode 100644 test/arch/msdos/time_tc.h create mode 100644 test/arch/os2/Makefile.dm create mode 100644 test/arch/os2/Makefile.emx create mode 100644 test/arch/os2/Makefile.icc create mode 100644 test/arch/os2/Makefile.wat create mode 100644 test/arch/os2/gfs_os2.c create mode 100644 test/arch/os2/gpm_os2.c create mode 100644 test/arch/os2/gpm_os2.def create mode 100644 test/arch/unix/.cvsignore create mode 100644 test/arch/unix/Makefile.in create mode 100644 test/arch/unix/gwin_x11.c create mode 100644 test/arch/win16/Makefile.BC create mode 100644 test/arch/win16/Makefile.MS create mode 100644 test/arch/win16/Makefile.VC create mode 100644 test/arch/win16/depend.win create mode 100644 test/arch/win16/gw_win16.c create mode 100644 test/arch/win16/makedep create mode 100644 test/arch/win32/Makefile.BC create mode 100644 test/arch/win32/Makefile.CL create mode 100644 test/arch/win32/Makefile.Min create mode 100644 test/arch/win32/Makefile.gcc create mode 100644 test/arch/win32/depend.win create mode 100644 test/arch/win32/gw_win32.c create mode 100644 test/arch/win32/makedep create mode 100644 test/blitter.c create mode 100644 test/blitter.h create mode 100644 test/common.c create mode 100644 test/common.h create mode 100644 test/display.c create mode 100644 test/display.h create mode 100644 test/fdebug.c create mode 100644 test/ftdump.c create mode 100644 test/fterror.c create mode 100644 test/ftlint.c create mode 100644 test/ftmetric.c create mode 100644 test/ftsbit.c create mode 100644 test/ftstring.c create mode 100644 test/ftstrpnm.c create mode 100644 test/ftstrtto.c create mode 100644 test/fttimer.c create mode 100644 test/ftview.c create mode 100644 test/ftzoom.c create mode 100644 test/gdriver.h create mode 100644 test/gevents.h create mode 100644 test/gmain.c create mode 100644 test/gmain.h diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..acd3f61 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,7 @@ +config.cache +MakeSub +Makefile +config.status +libtool +ft_conf.h +config.log diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d461635 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) +project(freetype VERSION 1.3.1) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Generate compile_commands.json for ccls +set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Group CMake targets inside a folder + + diff --git a/FILES b/FILES new file mode 100644 index 0000000..b02bce9 --- /dev/null +++ b/FILES @@ -0,0 +1,76 @@ +This text file contains an overview of this package's directory and +file hierarchy. + + + docs/ Documentation. + docs/image GIF images for documentation. + + lib/ The C engine source directory. + lib/extend Some standard engine extensions. + lib/arch/ System-specific configuration header files. + + howto/ Various system-specific HOWTOs, explaining how + to compile the library on different platforms. + + test/ The C test programs. + test/arch/ System-specific graphics drivers for test + programs. + + contrib/ Contributions directory. + contrib/mac An HQX archive containing a port to the Mac. + contrib/ttf2pk The ttf2pk TrueType to PK converter source + code. + contrib/ttf2pfb The ttf2pfb TrueType to PS font converter + source code. + contrib/ttf2bdf The ttf2bdf TrueType to BDF converter source + code. + contrib/ftos2 The FreeType/2 font server source code for + OS/2. + contrib/ttfbanner An ASCII poster program source code. + + po/ Contributions to the internationalized error + message strings extension. + + pascal/lib Pascal engine source directory. + pascal/test Pascal test programs. + + +The following files might be helpful: + +FILES This file. + +README A short and general introduction to FreeType. + +INSTALL The FreeType installation How-To. Everything you need + to know to build the library and the test programs. + This file contains only generic explanations. See the + `freetype/howto' directory for system-specific hints. + +license.txt The FreeType license. + +announce The FreeType UseNet announce post. This file is sent + to some newsgroups when a new release is made. + + +The following files are Unix-specific and can be ignored on other +platforms: + +ft_conf.h.in Generic library configuration header file for + autoconf. +configure.in Generic configure script for autoconf. +configure Configure script generated from `configure.in' by + autoconf. +config.sub Script needed by configure. +config.guess Script needed by configure. +Makefile.in Generic makefile for configure. +MakeSub.in Generic makefile for libtool. +ltconfig Libtool configuration script. +ltmain.sh Libtool script. +mkinstalldirs Tool for generating subdirectories. +a4local.m4, +net.m4 Auxiliary data files for autoconf. +install-sh Script used to install the library in a portable way +freetype.spec This file can be used as a specification to build RPMs + from the FreeType package. + +--- end of FILES --- diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..09fff40 --- /dev/null +++ b/INSTALL @@ -0,0 +1,879 @@ + + The FreeType compilation guide + + +Table of contents +----------------- + + I. Introduction + + II. Compiling and installing the C library + + 1. Choosing a configuration file + 2. Compiling the library + 3. System-specific builds + 4. Compiling the extensions + 5. Using a Makefile + 6. Building a dynamic library (`DLL' or `so') + 7. Internationalization and the `ftxerr18' extension + 8. TrueType patents + + +III. Compiling the test programs + + 1. Compiling the graphics sub-system + 2. Internationalization on Unix + 3. Compiling the test programs + 4. The `fdebug' program + + + IV. Compiling the Pascal source + + 1. Compiling the library + 2. Compiling the test programs + 3. Porting the library to a different Pascal compiler + +-------------------------------------------------------------------- + + + +I. Introduction +=============== + + This file gives detailed information on how to compile and install + this release of FreeType on your system. + + +******************************************************************** +* * +* FOR A QUICK INSTALLATION GUIDE, WE STRONGLY RECOMMEND TO READ * +* THE SYSTEM-SPECIFIC DOCUMENTS LOCATED IN THE `howto' DIRECTORY * +* INSTEAD OF THIS GENERIC DOCUMENTATION. * +* * +******************************************************************** + + + This package, known as the FreeType 1.3.1 Public Release, contains + several things which are best described by the directories + containing them: + + - `lib' + + Contains the 1.3.1 release of the FreeType library. It is written + in portable ANSI C and should compile fine with any type of + ANSI C compiler. + + Note however that some system-specific files are provided in the + `lib/arch' directory, in order to provide enhanced performance. + + If you need to include FreeType in a graphics library or an + embedded system, you will most probably only need to use its + contents and discard the rest. + + - `test' + + Contains test and demo programs used during development. Note + that some of these programs might not compile on all platforms, + as they need to display graphics. + + - `pascal' + + Contains the Pascal version of FreeType's source code. Note + that the library has been successfully compiled with Turbo + Pascal 6, Borland Pascal 7, Virtual Pascal, Free Pascal, + Delphi 1, 2 and 3. + + The pascal source tree contains its own test programs which + should *only* run with either Borland or Virtual Pascal + compilers. + + - `po' + + On Unix, all of FreeType test programs support + internationalization through the use of the `gettext' library. + This directory contains `po' files, which are used to translate + the original english text into language-specific one. + + Note also that this release contains an extension, called + `ftxerr18' used to return internationalized strings from the + usual FreeType error codes. The `po' files also contain + translations for this extension. + + If you don't plan to use `ftxerr18' or internationalization, + simply ignore it. Note also that even if `gettext' isn't + available on your system, the test programs will be compiled + correctly (using the `--disable-nls' configure switch). + + - `contrib' + + Contains a set of contributed tools and utilities related to + TrueType or FreeType. Here you can find real situations how to + use the library. + + + This file explains how to compile the library, and the test + programs on various platforms. + + + +II. Compiling the C library +=========================== + + +******************************************************************** +* * +* NOTE THAT WE STRONGLY RECOMMEND TO READ THE SYSTEM-SPECIFIC * +* DOCUMENTS LOCATED IN THE `howto' DIRECTORY FOR A * +* `QUICK'N'EASY' COMPILATION & INSTALLATION GUIDE ON YOUR * +* PLATFORM. THE FOLLOWING IS A VERY DETAILED EXPLANATION ON HOW * +* TO COMPILE THE LIBRARY. * +* * +******************************************************************** + + + The following concepts are important to build the library. + + + 1. Choosing a configuration file + -------------------------------- + + The source code for the C library is located in the `lib' + directory. + + It uses a file named `ft_conf.h', which contains the definitions + of many configuration macros to toggle various engine features, + as well as tell system-specific information (e.g., the size of + the `int' type in bytes, etc). + + There are several configuration files provided with this + release. They are located in the `lib/arch/' directory, + where stands for a given architecture or environment. + + For example, the file `lib/arch/ansi/ft_conf.h' can be used to + build the library with any ANSI-compliant compiler and runtime + library. + + This release also provides configuration files for the following + systems: MS-DOS, OS/2, Unix, VMS, Win 16, Amiga OS, and Win 32. + + Make sure, when compiling each source file of the FreeType + library, to include the path to your configuration file in your + include directories. + + + 2. Compiling the library + ------------------------ + + The library can be quickly compiled by invoking a Makefile, as + described in the system-specific documents in the `howto' + directory. + + We will now describe how to compile the library by hand. + + Traditionally, building a library like FreeType needs the + following steps: + + - Compile each individual `.c' file into the corresponding + object file, whose extension might be `.o' or `.obj', + depending on the platform. + + - Group all object files into a library (e.g. `libfreetype.a' or + `freetype.lib'), which is later used at link time to build the + executables using it. + + For example, to build a static FreeType library on an ANSI + system, with gcc, one should type + + cd lib # go to `lib' directory + gcc -c -Iarch/ansi tt*.c # compile base engine sources + ar -r libfreetype.a tt*.o # create library from objects + + Note that we included the path to the configuration file in the + include list during compilation, by using the `-I' switch on the + `arch/ansi' directory. This is required to use the + configuration file named `lib/arch/ansi/ft_conf.h'. + + However, we recommend you to build the base FreeType engine as a + SINGLE OBJECT FILE, i.e., a single `freetype.o' or + `freetype.obj' file containing all the code for the base engine. + It works by including all the `.c' files in a single one, and + has a few advantages over a `traditional build': + + - Because all the code is `part' of a single source file, many + internal functions need not be declared as `extern' anymore. + + This means that when compiling the engine as a dynamic + library, only FreeType external functions will (correctly) be + exported as entry points. + + This also typically allows the compiler to perform more + aggressive optimizations on the source code, and results in + somewhat faster and/or smaller overall code size depending on + your compiler and environment. + + - Compilation speed is greatly improved, as the pre-processor + and compiler need to be called only once, instead of a dozen + times. + + - During development, this allows to detect very easily + unresolved dependencies regarding the base engine's internal + symbols. + + To compile the engine as a single object file, simply go to the + `lib' directory and compile the file + `lib/arch//freetype.c'. + + For example, to compile the ANSI build with gcc in SINGLE OBJECT + MODE, use + + cd lib + gcc -c -Iarch/ansi -I. arch/ansi/freetype.c + + This will create a single file called `freetype.o' containing + the object code for the base TrueType engine. + + Note that we did include the paths to the configuration file + (i.e. `arch/ansi') AND to the current directory (i.e. `.', + where the included source files are located). + + `freetype.o' only contains the base engine. Extensions to the + engine are located in the `lib/extend' directory and must be + compiled separately as described later. + + + 3. System-specific builds + ------------------------- + + The files `ttfile.c', `ttmemory.c', and `ttmutex.c' are used to + provide an implementation of i/o access, memory management, and + thread synchronization for the rest of the library. + + These source files, located in the `lib' directory, use the ANSI + C library for i/o and memory, and simply ignore threads (as the + standard doesn't know threads at all). + + However, this release provides, for each supported platform, + system-specific versions of these files, located in the + `lib/arch/' hierarchy. Here are a few examples: + + lib/arch/os2/os2file.c: + + A replacement for `ttfile' which directly uses OS/2 system + calls for i/o access. This results in slightly better + performance, but much reduced resource requirements. + + lib/arch/unix/ttmmap.c: + + A replacement for `ttfile' which uses memory-mapped files + instead of buffered-based reads on Unix. This increases + *dramatically* the engine's performance when reading font + files and loading glyphs. + + These files are directly included by the platform specific + versions of `freetype.c' which are located in + `lib/arch/'. This means that, by default, the + single-object build of FreeType always chooses the best + implementation available for a supported system. + + Note that it is also possible to redefine `ttmemory' or + `ttmutex' with a similar scheme. This is used, for example, by + the OS/2 font driver based on FreeType (called FreeType/2), + which uses some special system calls to allocate memory + shareable among distinct processes. + + By providing your own version of `ttfile', `ttmemory', and + `ttmutex', you are able to tailor the FreeType engine for + optimal performance and resource usage on your system. + + + 4. Compiling the extensions + --------------------------- + + The base TrueType engine is located in the `lib' directory. + This release also provides many specific extensions in + `lib/extend'. + + An extension is a simple way to extend FreeType's capabilities. + It is used to perform any of the following: + + - Access some TrueType tables that are not loaded and returned + by the base engine, like + + * the kerning table(s) + * the `gasp' table + * the glyph Postscript names + * some OpenType layout tables (GDEF, GSUB; GPOS is not + finished yet) + + - Perform some advanced operations on the TrueType data for very + specific uses, like + + * enumerate the contents of a given charmap + * access a font file's embedded bitmaps (called sbits) + * return an array containing the dimensions of each glyph in + the font + + The idea is to keep the base engine small (under 50kByte), while + providing optional enhancements for specific uses. + + Writing an extension is rather easy. And adding a new extension + to the engine doesn't need any modifications to the base + engine's source code. + + To compile the extensions, simply go to the `lib' directory, + then compile each file in `lib/extend'. Here is an example with + gcc: + + cd lib ; go to `lib' + gcc -c -Iarch/ansi -I. extend/ftx*.c ; compile all extensions + + + You can later add each extension object file to the FreeType + library file. For example, here is how to create the static + library on Unix: + + cd lib + -- compile the engine, then the extensions + ar libfreetype.a *.o ; create static library + + + 5. Using a Makefile + ------------------- + + This release also provides Makefiles for many systems and + compilers in the `lib/arch/' hierarchy. For more + information, please read the documentation in the `howto' + directory, which contains system-specific instructions on how to + use them. + + Generally, you should go the `lib' directory, then invoke your + system-specific Makefile from there. Here is an example: + + cd lib + make -farch\msdos\Makefile.TC + + to compile the library under DOS with the Turbo C compiler and + make tool. Or: + + cd lib + wmake -f arch\msdos\Makefile.wat + + to compile it under DOS with the Watcom compiler and wmake tool. + + The ANSI target does not come with a Makefile, as there is no + standard make tool available on all platforms. You will have to + compile the library by hand as described in section I.3. + + We welcome new Makefile submissions for platforms not currently + listed in the `lib/arch' hierarchy. + + Finally, note that most of the makefiles will build the library + in single object mode; for a `traditional compile', try the + `debug' target (i.e., say `make debug'). + + + 6. Building a dynamic library (`DLL' or `so') + --------------------------------------------- + + It is possible to build the engine as a dynamic library. The + method to do so can vary greatly depending on the platform. + + a. Building a shared object on Unix + + NOTE THAT THIS RELEASE USES `libtool' TO AUTOMATICALLY CREATE + A SHARED OBJECT FOR FREETYPE ON UNIX SYSTEMS THAT SUPPORT + DYNAMIC LIBRARIES. WE STRONGLY RECOMMEND YOU TO READ THE + `howto/unix.txt' FILE TO KNOW HOW TO USE THE `configure' + SCRIPT. THIS SUB-SECTION DESCRIBES HOW TO COMPILE THE SHARED + OBJECT BY HAND. + + In order to build a shared object like `libfreetype.so' on + Unix, one has to compile each object file as + position-independent code (a.k.a. PIC). + + We also strongly recommend to build the base engine as a + single object, as this prevents internal `extern' functions to + be exported as entry points (and creating a smaller overall + .so file). + + For example, this with gcc, one can use the `-fPIC' flag when + compiling the object files. Here is an example: + + cd lib ; go to `lib' + gcc -c -fPIC -Iarch/ansi -I. \ + arch/ansi/freetype.c ; compile engine + gcc -c -fPIC -Iarch/ansi -I. extend/ftx*.c ; & extensions + + You can now invoke your linker to create the shared object + from the various object files. See your system's + documentation for details, or read the Unix-specific howto to + know how to do it `easily' through the use of `libtool'. + + b. Building a DLL on Windows or OS/2 + + The dynamic linkers of Windows and OS/2 differ greatly from + Unix ones. + + - The first difference is that the object files that make up + the DLL do not need to be compiled as position-independent + code. + + - The second difference is that the DLL's entry points must + generally be declared as so in the source file, and/or maybe + listed in a `definition' file used at link time when + creating the DLL. + + Each FreeType API function is declared with the help of a + special macro named EXPORT_DEF. For example, here is the + declaration of the function `FT_Init_FreeType', as written in + `freetype.h': + + EXPORT_DEF + TT_Error TT_Init_FreeType( TT_Engine* engine ); + + If the configuration file `ft_conf.h' doesn't define + EXPORT_DEF, it is automatically set to `extern' by default. + + In order to build FreeType as a DLL, one might need to define + EXPORT_DEF in its `ft_conf.h' to a keyword tagging the + function as a DLL entry point. This keyword varies with + compilers and platforms; examples are `__system', + `__dllentry', etc. + + Please refer to your compiler's user guide for instructions. + + You can also `grep' for EXPORT_DEF in the `freetype.h' source + file to obtain the list of exported functions of the FreeType + API, which could then be used to write a `def' file for the + DLL. We provide a sample .def file (built with an Unix script) + for Windows. + + Note also that the definition (i.e. its implementation) of + each exported function is preceded with the EXPORT_FUNC macro, + as in + + EXPORT_FUNC + TT_Error TT_Init_FreeType( TT_Engine* engine ) + { + TT_Error error; + ... + } + + (to be found in `ttapi.c'). + + By default, EXPORT_FUNC converts to an empty string, but it + can also be redefined if you need to. + + Note that the EXPORT_DEF/EXPORT_FUNC mechanism does not work + for 16-bit Windows (in this environment, the special keyword + for declaring entry points, (the `__export' keyword), must be + after the type name). We suggest you to use the makefiles we + provide for both Microsoft and Borland compilers. + + + 7. Internationalization and the `ftxerr18' extension + ---------------------------------------------------- + + The engine extension named `ftxerr18' is used to convert a + FreeType error code into a human-readable string of text. + + However, it is able to support internationalization on Unix + systems through the use of the `gettext' library. This means + that the error messages will be localized to your system's + language, provided it is available in this release. The + currently available languages are + + - English (by default) + - Czech + - German + - Spanish + - French + - Dutch + + One can add a new language by adding a `.po' file in the `po' + directory. Please read the file `docs/i18n.txt' for more + details on how to use `gettext'. + + In order to enable localization of the `ftxerr18' extension, one + has to set the macro HAVE_LIBINTL_H at compile time. By + default, the extension will build with support for the English + language. + + Unix-specific: ------------------------------------------------- + + Note that the Unix `configure' script that comes with this + release is able to automatically detect whether your system + has `gettext' installed and set HAVE_LIBINTL_H in the + `ft_conf_h' file accordingly. + + To disable internationalization, run `configure' with the + option `--disable-nls' (NLS stands for `National Language + Support'). Then rebuild the library. + + ---------------------------------------------------------------- + + Note that we do not support internationalization on non-Unix + platforms, as the `gettext' library isn't available everywhere, + or does not work in a consistent way in different environments. + + + 8. TrueType patents + ------------------- + + We have recently discovered that Apple owns several patents that + relate to the rendering of TrueType fonts. This could mean that + the free use and distribution of the FreeType library could be + illegal in the US, Japan, and possibly other countries. + + For more information, please see the FreeType Patents page at: + + http://www.freetype.org/patents.htm + + This section will now explain how to build a `patent-free' + engine, at the cost of rendering quality. This is done simply + by de-activating the compilation of the TrueType bytecode + interpreter (which is the only part of FreeType that might + violate an Apple patent). This has two effects: + + - saving about 18kByte of code in the engine + - ignoring completely the grid-fitting of vector outlines, which + results in extremely low quality at small pixel sizes. + + Such an engine can be used by font converters and/or graphics + libraries to display glyphs at high pixel sizes. + + In order to do so, simply look for the following line in your + configuration file `ft_conf.h': + + #undef FT_CONFIG_OPTION_NO_INTERPRETER + + Then change the `#undef' into a `#define': + + #define FT_CONFIG_OPTION_NO_INTERPRETER + + Now rebuild the engine with this new configuration file. + + + +III. Compiling the test programs +================================ + + This section explains how to compile the FreeType test programs + located in the `test' directory. Note that you should have + successfully compiled the library, as described in section I + before proceeding. + + WE STRONGLY RECOMMEND TO READ THE SYSTEM-SPECIFIC DOCUMENTS IN THE + `howto' DIRECTORY FOR A `QUICK'N'EASY' GUIDE ON HOW TO COMPILE AND + RUN THE TEST PROGRAMS. + + + 1. Compile the graphics sub-system and utility sources + ------------------------------------------------------ + + Some of the test programs need to display a graphics window to + show their results. In order to do so, they use a tiny graphics + system which was specifically written for FreeType (Note: The + code isn't really clean there -- you have been warned). + + Also, some simple C sources in the `test' directory are utility + functions used by nearly all test programs, and they should also + be compiled before them. These are the following files: + + gmain.h: the sub-system interface + gmain.c: the sub-system device-independent implementation + gevents.h: the definition of the events used by the test + program + gdriver.h: the system-specific device interface + blitter.c: a set of simple bitmap blitting functions + common.c: common routines used by all test programs + display.c: some routines dealing with text display + + as well as a system-specific `graphics driver' located in the + `test/arch/' hierarchy. For example: + + test/arch/msdos/gfs_dos.c: used to display graphics in a + full-screen Dos session + test/arch/os2/gpm_os2.c: used to display graphics in an OS/2 + Presentation Manager window + test/arch/unix/gwin_x11.c: used to display graphics in an X11 + window. + + You must compile the graphics sub-system and utilities before + compiling the test programs. This can be done simply with gcc + as: + + cd test + gcc -c -I../lib gmain.c blitter.c common.c display.c + gcc -c -I../lib -I. arch//yourdriver.c -o ./gdriver.o + + Note that a given test program may require some specific include + paths (like `/usr/X11/include' with X11 for example). + + The resulting object files can be grouped in a library if you + want to. + + + 2. Internationalization on Unix + ------------------------------- + + On Unix and Unix-like systems, the test programs are able to + support internationalization through the use of the `gettext' + library and the `ftxerr18' engine extension (see section I.7). + + To enable it, one has to compile each test program with the + macro HAVE_LIBINTL_H set. This is the same macro used to enable + it in `ftxerr18'. + + Note that the Unix `configure' script that comes with this + release is able to automatically detect whether `gettext' is + available on your system and set the macro accordingly when + compiling the test programs. + + You can disable internationalisation with the `--disable-nls' + option when invoking the `configure' script. + + + 3. Compile the test programs + ---------------------------- + + All test programs begin with the `ft' prefix in the `test' + directory, as in `ftzoom', `ftdump', `ftmetric'", etc. are test + programs. + + The easiest way to compile the test programs is compiling each + source file to an object file, including the path to the + FreeType engine source and its extensions. You need to use the + following include paths: + + - the path to the engine's public header file, i.e. `freetype.h' + which normally is `lib' + + - the path to the engine's extensions header files, located + normally in `lib/extend' + + - the path to the configuration file `ft_conf.h'. This is only + required to support internationalisation, as the test programs + read `ft_conf.h' only to see whether HAVE_LIBINTL_H is + defined. + + When compiling your own programs to FreeType, you shouldn't + normally need this file and path. + + Here is an example, compiling a test program with the ANSI + build: + + cd test + gcc -c -I../lib -I../lib/extend -I../lib/arch/ansi \ + .c + + Then, link this object file to the FreeType library, utilities + and graphics sub-system to build an executable. + + You can then invoke each program directly. + + + 4. The `fdebug' test program + ---------------------------- + + All test programs begin with the `ft' prefix (in the `test' + directory) as in `ftzoom', `ftdump', `ftmetric', etc. + + However, one test program named `fdebug' is used exclusively by + FreeType developers. It is a very simple TrueType bytecode + debugger, and was written to inspect the execution of the + TrueType interpreter. + + Note that we rather use the Pascal debugger for real work on the + interpreter, as it provides a much easier windowed interface + through the use of the Turbo Vision library. The C debugger is + mainly used to check that both Pascal and C sources produce the + same output. + + You will need gcc to compile the debugger. It uses a special + build of the FreeType engine to work. Follow these steps to + compile it: + + 1. Compile the library for the `debugger' system, i.e. + + cd freetype/lib + make -f arch/debugger/Makefile + + this will create a file named `libttf.a' in the directory + `freetype/lib/arch/debugger' which will NOT interfere with + your normal build (which is located in `freetype/lib'). + + 2. Compile the debugger: + + cd freetype/test + make -f arch/debugger/Makefile + + This will create an executable called `fdebug.exe' or + `fdebug', which is linked with the version of the library + found in `freetype/lib/arch/debugger' as described above. + + [For old Unix variants like 4.2BSD please uncomment the flag + HAVE_POSIX_TERMIOS in the makefile.] + + You can invoke the debugger in two ways: + + a. To debug a given glyph program in a given font, type + + fdebug glyph_number pointsize fontfile[.ttf] + + b. To debug a given font's CVT program, type + + fdebug --cvt pointsize fontfile[.ttf] + + Type `?' while running fdebug for a list of key bindings. + + +IV. Compiling the Pascal source +=============================== + + This section deals with the compilation of the Pascal version of + the FreeType engine, whose source code is located in the `pascal' + directory. + + Note that the Pascal version is more limited than the C one, as it + lacks the following `features': + + - Extensions are neither supported nor provided in Pascal. + + - The interpreter is more pedantic than the C one and will + probably not work with many broken glyphs. + + - It doesn't compile on old Turbo Pascal (TP 6.0 is a minimum), as + it uses inline assembly code. + + Other than that, the Pascal version supports charmaps and the name + table correctly since the 1.3 release. + +******************************************************************** +* * +* AN IMPORTANT NOTE REGARDING TURBO AND BORLAND PASCAL USERS * +* ========================================================== * +* * +* Programs compiled with TP6 and BP7 might not be able to run on * +* fast machines! * +* * +* Usually, the program aborts immediately with a message like * +* * +* Runtime error 200: Divide by zero at xxxx:xxxx * +* * +* The bug is located in the runtime's initialization routine * +* used to compute the machine's speed. It does so by dividing a * +* value taken through the BIOS timer by a small constant. * +* * +* On fast machines, the result exceeds 16 bits, which causes a * +* CPU exception/interrupt. The latter is caught by the * +* runtime's exception handlers which aborts the execution and * +* prints the above message. * +* * +* We don't know anything that can be done to fix this bug, as it * +* would need a recompilation of a version of the Borland runtime * +* initialization code. * +* * +******************************************************************** + + Due to lack of time, the library could not be fully tested under + TP6 or BP7. + + + 1. Compiling the library + ------------------------ + + The library itself is located in `pascal/lib'. You can compile + it very simply by invoking your Pascal compiler on the file + `freetype.pas'. + + As always with Pascal, dependencies are resolved automatically. + + + 2. Compiling the test programs + ------------------------------ + + The test programs are located in `pascal/test'. You will mainly + find there the following: + + lint - A TrueType glyph loading checker. This test program + will simply load each glyph in a font file and check + for errors in its hinting programs. It is useful to + find broken glyphs in fonts. + + view - A simple TrueType glyph viewer. Shows all the glyphs + within a given font file on a graphics screen. Only + works under DOS (with Borland Pascal) and OS/2 (with + Virtual Pascal). + + timer - A simple benchmark program for the scan-line + converter. Similar to the C `fttimer' test program. + + debugger - A TrueType bytecode debugger. This one must be + compiled with the Turbo Vision library. It uses a + rather advanced windowed interface to display the + glyph program and their execution. It can also + display the current glyph in a graphics window. A + bit rough but extremely useful to the development + of FreeType. + + dump - A TrueType metrics checker. This test program simply + checks that the hinted width of each glyph corresponds + to the one found in the TrueType `hdmx' table when + present. This program is now obsolete and should be + ignored. + + As always, simply invoke the root source file to make an + executable automatically -- don't forget to include the path to + the FreeType unit as described in section III.1. + + + 3. Porting the library to a different Pascal compiler + ----------------------------------------------------- + + The Pascal sources use inline assembly to implement the 64-bit + computation routines needed by the TrueType engine. This + release comes with various versions of the `ttcalc' inline + assembly. + + These files are (within `pascal/lib'): + + ttcalc1.inc: for Turbo and Borland Pascal & Delphi 1 (16-bit) + ttcalc2.inc: for Virtual Pascal (32-bit) + ttcalc3.inc: for Delphi 2 & 3 (untested on Delphi 4 & 5) + ttcalc4.inc: for Free Pascal on a i386 (32-bit) + + Note that in order to port the Pascal source to a new compiler, + one has to: + + a. Write a specific version of `ttcalc?.inc' for the compiler's + inline assembly. + + Be sure to respect the compiler's assembler syntax, as well + as its parameter-passing function interface, i.e., which + registers and/or stack slots are used to pass arguments at + function call. + + b. Add some lines to detect your compiler in `ttconfig.inc'. + + This file contains some tests to define macros used to + determine which compiler is used. These macros are used + later in `ttcalc.pas' in order to select the correct inline + assembly file to use. + + See the source files for more details. + + c. Add an include to the new `ttcalc?.inc' in `ttcalc.pas'. + + Make this according to the compiler detected in + `ttconfig.inc'. + + See the source files for more details. + + d. Submit your changes to the FreeType Developers list. + + In order to see them added to the next release of the Pascal + engine. + + +--- end of INSTALL --- diff --git a/MakeSub.in b/MakeSub.in new file mode 100644 index 0000000..90d10b9 --- /dev/null +++ b/MakeSub.in @@ -0,0 +1,7 @@ +# this file is part of the FreeType project + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +bindir = @bindir@ +includedir = @includedir@ diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..f4e1c94 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,60 @@ +# This file is part of the FreeType project. + +RMF = @RM@ -f + +MAKEFILE = arch/unix/Makefile + +FTLIBDIR = lib +FTTESTDIR = test +FTPODIR = po + +all: ttlib tttest ttpo + +debug: ttlibdebug tttest ttpo + +# we can't use the target names 'lib', 'test', etc. +# because make will believe that the directories are +# the targets and are up-to-date! Grrr... >:-( + +ttlib: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) all + +ttlibdebug: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) debug + +tttest: + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) all + +ttpo: + cd $(FTPODIR); $(MAKE) all + +install: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) install + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) install + cd $(FTPODIR); $(MAKE) install + +uninstall: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) uninstall + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) uninstall + cd $(FTPODIR); $(MAKE) uninstall + +clean: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) clean + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) clean + cd $(FTPODIR); $(MAKE) clean + +distclean: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) distclean + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) distclean + cd $(FTPODIR); $(MAKE) distclean + $(RMF) config.cache config.log config.status Makefile \ + MakeSub ft_conf.h libtool + +check: + @echo This package does not yet have a validation suite + +depend: + cd $(FTLIBDIR); $(MAKE) -f $(MAKEFILE) depend + cd $(FTTESTDIR); $(MAKE) -f $(MAKEFILE) depend + +# end of Makefile.in diff --git a/PATENTS b/PATENTS new file mode 100644 index 0000000..8c02625 --- /dev/null +++ b/PATENTS @@ -0,0 +1,27 @@ + + FreeType Patents Disclaimer + August 1999 + + + +WE HAVE DISCOVERED THAT APPLE OWNS SEVERAL PATENTS RELATED TO THE +RENDERING OF TRUETYPE FONTS. THIS COULD MEAN THAT THE FREE USE OF +FREETYPE MIGHT BE ILLEGAL IN THE USA, JAPAN, AND POSSIBLY OTHER +COUNTRIES, BE IT IN COMMERCIAL OR OPEN SOURCE PRODUCTS. + +FOR MORE DETAILS, WE STRONGLY ADVISE YOU TO GO TO THE FREETYPE +PATENTS PAGE AT THE FOLLOWING WEB ADDRESS: + + http://www.freetype.org/patents.htm + +WE WILL NOT PLACE INFORMATION IN THIS FILE AS THE SITUATION IS STILL +UNDETERMINED FOR NOW. AT THE TIME THESE LINES ARE WRITTEN, WE HAVE +CONTACTED APPLE'S LEGAL DEPARTMENT AND ARE STILL WAITING FOR THEIR +ANSWER ON THE SUBJECT. + +PLEASE READ THE `INSTALL' FILE TO SEE HOW TO DISABLE THE ENGINE'S +BYTECODE INTERPRETER IN ORDER TO BUILD A PATENT-FREE ENGINE, AT THE +COST OF RENDERING QUALITY. + + +--- end of PATENTS --- diff --git a/README b/README new file mode 100644 index 0000000..28950be --- /dev/null +++ b/README @@ -0,0 +1,695 @@ + + + Welcome to the + + F R E E T Y P E P R O J E C T + + http://www.freetype.org + + Release 1.3.1 + + The FREE TrueType Font Engine + + Copyright 1996 David Turner + - 1999 Robert Wilhelm + Werner Lemberg + + + Table of Contents + ----------------- + + I. Introduction + + II. The FreeType mini-FAQ + + III. How to use the test programs + + 1. ftzoom + 2. ftlint + 3. ftview + 4. fttimer + 5. ftdump + 6. ftstring + 7. ftstrpnm + 8. fterror + 9. ftsbit + 10. ftmetric + 11. ftstrtto + + IV. How to use the programs in the `contrib' directory + + V. Final remarks + + +I. Introduction +=============== + + Please read the file `INSTALL' for installation instructions! + + The FreeType engine is a free and portable TrueType font rendering + engine. It has been developed to provide TrueType support to a + great variety of platforms and environments. + + Notice that FreeType is a *library*. It is *not* a font server + for your preferred environment, even though it has been written to + allow the design of many font servers. + + To our knowledge, this is the only royalty-free complete TrueType + engine available. Moreover, its quality fully matches these of + Windows or the Macintosh, a thing that cannot be said for most + other commercial engines available. + + FreeType is a clean-room implementation that is not derived from + the original TrueType engine developed by Apple and Microsoft. It + has been created with the sole help of the published TrueType + specifications, which, to our great surprise and pain, turned out + to be extremely poor or misleading in critical areas. Much hard + work has been undertaken to solve numerous ambiguities; + nevertheless, its end result is a portable, fast quality renderer! + + The library itself takes about 55kByte of Intel code, complete + with a TrueType byte-code interpreter and a high-performance + scan-line converter. + + You will find in this release: + + - A TrueType engine, with source code in ANSI C and Pascal. + + The C source code has been successfully compiled and run on + various platforms, including MS-DOS, OS/2, Amiga, Linux, and + several other variants of Unix. It should be portable to many + other platforms too. + + The Pascal code has been successfully compiled and run on DOS + (Borland's BP7) and OS/2 (fPrint's Virtual Pascal). A Delphi + port is in beta (the code in freetype/pascal compiles). + Unfortunately, it is not up to date compared to the C version. + + - An API to be used by client applications and font servers, + providing several low level abstractions that can be used to + open font files and collections, create point sizes and load, + process and render glyph outlines and bitmaps. + + - Support for the following features: + + o Font smoothing, a.k.a. gray-level rendering. + + Just like Windows 95, the renderer uses a `fine' algorithm + that only smoothes diagonals and curves, while keeping the + horizontal and vertical stems intact. + + This results in glyphs that are much more legible than the + `fuzzy' ones generated by programs like Acrobat. + + o Support for all character mapping formats. + + o A full-featured TrueType byte-code interpreter. + + The engine is able to hint the glyphs to produce excellent + output at small sizes. It was extremely difficult to get this + component right, due to the ambiguous and misleading TrueType + specifications. However, we now *match* Windows and Macintosh + qualities. + + o TrueType collection support, when several fonts are embedded + in the same file. + + o Support for extensions. + + It is now possible to extend the library in parts to support + additional features, like optional tables that are not + considered by the current core engine. + + o Kerning support. + + Provided as a sample extension with this release, kerning + tables can be accessed from a TrueType font for applications + that need it. + + o Support for vertical metrics. + + It is possible to load vertical metrics when they are present + in a font file. Metrics can be retrieved glyph by glyph, + using the loader, or in arrays with a new API. + + o Support for thread-safety and re-entrancy. + + You will only need to specialize the file `ttmutex.c' for your + platform to include system-specific synchronization calls. + + o New in 1.3: Support for embedded bitmaps. + + This feature is already used in xtt, a TrueType font server + for X Window System. + + Note also that: + + - Though development of the library is mainly performed on OS/2 + and Linux, the library does not contain system-specific code. + + - The package contains some graphics drivers used by the test + programs for display purposes on MS-DOS, OS/2, Amiga, and X11. + These drivers are absolutely not mandatory for running the + FreeType engine. Some console-mode test programs like `ftlint' + or `ftdump' don't use graphics at all. + + - FreeType 1.3 is binary compatible with 1.2, which means that you + won't need to recompile your programs if they used the engine as + a shared library (libttf.so on Linux, or FreeType.dll on + Windows). See the file `freetype/docs/changes.txt' for more + information about (minimal) API changes. + + +II. The FreeType mini-FAQ +========================= + + Summary + + 0. Where to find the latest FreeType release? + + 1. Did the API change? + + 2. What does the `Free' in FreeType means? Can you use it in a + commercial product? (YES!) + + 3. I have made a small program based on the test programs but I + would like to know how to do xxx? + + 4. When will I be able to use FreeType to display TrueType fonts + under X11, OS/2 or Wine? (NOW!) + + 5. Trying to compile the FreeType sources gives me lots of + warnings with my ANSI C compliant compiler! + + ------------------------------------------------------------------ + + 0. Where to find the latest FreeType release? + + The latest package is usually uploaded to various source + repositories, like SunSite, SimTel, or Hobbes. There are two + archive formats (zip and tar.gz), which also differ by their + CR/LF conventions. + + * for DOS and OS/2: `ft-13.zip' + + which should be available at: + + Hobbes: ftp://ftp.cdrom.com/pub/os2/fonts + SimTel: ftp://oak.oakland.edu/pub/simtel.net/msdos/graphics + + * for UNIX and Amiga: `freetype-1.3.tar.gz' + + look at: + + SunSite: ftp://sunsite.unc.edu/pub/Linux/X11/fonts + + * As uploading can take several days before the package becomes + available to the public, we advise you to download it from + our own ftp site if you read this message few days after the + announcement at: + + ftp://ftp.freetype.org/pub/freetype + + Our home page is at: + + http://www.freetype.org + + Screen shots are available! + + There are also three mailing lists: + + o freetype-announce@freetype.org + + Announcements only about new versions of FreeType and + related packages. This list is moderated and expected to + have very low traffic. + + o freetype@freetype.org + + Discusses general use of FreeType, future, and needed + additions, as well as many other font-related discussions + which do not always relate directly to the FreeType code + itself... + + o devel@freetype.org + + Discusses development, design choices, portability issues, + internals, specific licenses, etc. + + To subscribe, send the usual subscription commands to: + + majordomo@freetype.org + + To report bugs please use send an email to the address + bugs@freetype.org -- if you want help fixing bugs, contact + robert.wilhelm@freetype.org to be manually subscribed to this + closed list. + + ------------------------------------------------------------------ + + 1. Did the API change since the version 1.2? + + Only very marginally. Please refer to `changes.txt'. + + ------------------------------------------------------------------ + + 2. What does the `Free' in FreeType means? Can you use it in a + commercial product? (YES!) + + We have placed this release under our special FreeType license. + + It was inspired by the BSD, Artistic, and IJG (Independent JPEG + group) licences, which specifically encourage the use of this + software in commercial products! + + The reason we did this is that we believe that TrueType is a + very useful technology, and want to make it available on all + machines and platforms. The license is there to ensure that + the engine can be spread as widely as possible. + + However, free does not mean public domain. This engine is + copyrighted by its authors, and they will fiercely defend their + rights. + + ------------------------------------------------------------------ + + 3. I have made a small program based on the test programs but I + would like to know how to do xxx? + + (Where xxx is a feature lacking from the current + implementation). + + First of all, read the documentation. The user guide gives + some basic hints and concepts. You can also read the source + code of the test programs that you didn't consider yet. If + you're really stuck, mail your question to: + + freetype@freetype.org + + We'll try to help you. + + ------------------------------------------------------------------ + + 4. When will I be able to use FreeType to display TrueType fonts + under X11, OS/2, or Wine? + + You can already do that under X11 and OS/2 :-) Go to the + FreeType web page (http://www.freetype.org) for up-to-date + information. + + And yes, it looks terrific! + + For X11, you could also take a look at `xfstt', an independent + TrueType font server for Unix which doesn't rely on the + FreeType code. + + You're welcome to volunteer for other platforms, like: + + Amiga, RISC OS, BeOS, and others + + Please contact devel@freetype.org for more information. + + ------------------------------------------------------------------ + + 5. Trying to compile the FreeType sources gives me lots of + warnings with my ANSI C compliant compiler! + + We use gcc as our reference compiler for warnings. This means + that we use the `-ansi -pedantic -Wall' flags and try to get + rid of warnings in this situation. + + If you're compiling with another compiler, you may encounter + warnings, not errors. + + We have spent much efforts to reduce seriously the number of + warnings produced by major compilers, including Visual Age, + Visual C++ and Borland C++. + + Note that the Borland compilers seem to produce lots of + irrelevant warnings (like `potential loss of precision'). + + +III. How to use the test programs +================================= + + All test programs having a graphic interface use the same key + convention: + + x : fine counter_clockwise rotation + c : fine clockwise rotation + + v : fast counter_clockwise rotation + b : fast clockwise rotation + + h : toggle hinting on/off + K : toggle kerning on/off + B : toggle display of embedded bitmaps on/off + G : toggle GSUB on/off + + + : fast scale up + - : fast scale down + u : fine scale up + j : fine scale down + + l : go to next glyph + k : go to previous glyph + + o : go to tenth next glyph + i : go to tenth previous glyph + + 0 : go to hundredth next glyph (useful for CJK fonts) + 9 : go to hundredth previous glyph + + ) : go to thousandth next glyph + ( : go to thousandth previous glyph + + } : go to tenthousandth next glyph + { : go to tenthousandth previous glyph + + q : + ESC : exit + + These keys were chosen because they are available on all + platforms. Note also that each program uses only a subset of this + key map. + + 1. FTZOOM + --------- + + `ftzoom' is a very simple glyph viewer that supports font + smoothing. Its usage is: + + ftzoom [-g] [-p platformID -e encodingID] + [-r resolution] [-z magnification] [-n] fontfilename + + With -g you can select gray-scaling; with -n you can suppress + usage of the `post' table in the TrueType font. + + For example: + + ftzoom arial.ttf to show the glyphs found + in the Arial font + ftzoom -g times.ttf to show smoothed version of + Times's glyphs. + ftzoom -p 3 -e 1 uwjmg3.ttf use cmap for platform ID 3, + encoding ID 1 for this Japanese + font. + + 2. FTLINT + --------- + + `ftlint' is used to execute all glyphs instructions found in a + font file at a given char size size. Its usage is: + + ftlint pointsize fontfilename [fontfilename] ... + + For example: + + ftlint 12 arial.ttf + ftlint 15 times.ttf + + It reports error codes and faulty glyph numbers. This is a + console tool that doesn't need the graphics subsystem. + + NOTE: Trying to hint at sizes smaller than 7 is irrelevant. + + 3. FTVIEW + --------- + + A font viewer that supports hinting and font smoothing. Its + usage: + + ftview [-g] -[r resolution] [-B] pointsize fontfilename + + like in: + + ftview 12 arial.ttf show the hinted Arial at size 12pt. + + ftview -g 15 timesi.ttf show the hinted and font-smoothed + Times at size 15pt. + + `-r' selects the resolution; `-B' forces the use of embedded + bitmaps. + + Note that it is possible to change the point size during display + with the keys `u', `j', `+', and `-'. It is also possible to + browse the whole glyph set with the `k', `l', `i', `o', `0', + `9', `(', `)', `{', and `}' keys (see key map above). + + The OS/2 PM driver comes with an additional magnifying window. + The magnified zone is set with the mouse, while the scale is + changed with the help of `PageUp' and `PageDown'. + + Note 1: The engine uses the font's CVT program to determine at + which size to enable or disable glyph hinting. Don't be + surprised to see unhinted glyphs at sizes < 7pt. + + Note 2: Vertical drop-out control has been added to the gray + scaling renderer. As a consequence, the library doesn't + produce unpleasant results at small ppems with badly + hinted glyphs. + + 4. FTTIMER + ---------- + + This program is used to benchmark FreeType's scan-converter (the + component in charge of translating a vectorial shape description + into a bitmap). It does so in preloading all glyphs from a font + file, then rendering them as fast as possible in a 640x450 + buffer. The glyphs are rendered at size 400pt / 96dpi, which is + _quite_ big. + + Its usage is: + + fttimer [-g] [-v] fontfilename + + where + + -g : Asks for gray-level rendering at size 200pt instead + (a.k.a. font-smoothing). + + -v : Asks for the display of the produced bitmap. Beware + that display slows things down (display on X11 is + _terrible_, especially with gray-levels, but this is + not a problem for us :-). + + Note that the returned numbers are not a benchmark of FreeType's + overall performance! Only of the scan-line renderer (which + seems quite fast, apparently :-). + + When comparing measured performances across machines, please + only consider the undisplayed ones. We're interested in all + kinds of results (please provide the following information: + + font file + number of rendered glyphs + render time + total time + glyphs / s + processor type + CPU clock + + and which compiler used (with optimization involved)! This + can make a great difference! + + etc.) + + 5. FTDUMP + --------- + + This program is a very simple font dumper. In its current + incarnation, it will only output a font's name table, character + encoding maps IDs and total memory consumption. For TrueType + Open files, the available GSUB tables are also shown. + + The `total memory used' reported is the amount that is used by + the engine to load one face, with one instance (a point size). + + Each additional instance takes only a fraction of that amount, + and is labeled by `instance object'. As you can see, FreeType + isn't really greedy. + + Usage: ftdump fontpathname[.ttf|.ttc] + + 6. FTSTRING + ----------- + + This program demonstrates string text generation. It only + displays a given message on the screen, and lets you resize it + with the classic key bindings `u', `j', `+', and `-'. + + Usage: + + ftstring ptsize fontname[.ttf|.ttc] [message_string] + + If the message is omitted, it will revert to the classic + typographic test sentence: + + The quick brown fox jumps over the lazy dog + + which is made of all letters of the English alphabet. + + `ftstring' only works with font files that contain a Unicode + character mapping table (either Windows Unicode or Apple + Unicode). For the moment, the message can however only be + written in ASCII, as accents aren't supported yet. + + 7. FTSTRPNM + ----------- + + Usage: + + ftstrpnm [options] filename [string] + + Options: + + -g gray-level rendering (default: off) + -h hinting off (default: on) + -r X resolution X dpi (default: 96) + -p X pointsize X pt (default: 12) + -b X border X pixels wide (default: 0) + + This program is quite similar to ftstring but converts the + rendered image of the specified string into a bitmap in PBM or + PGM format written to stdout; PBM (Portable BitMap) and PGM + (Portable GrayMap) formats can be further converted to popular + graphics formats like GIF or PNG with the netpbm tool suite + available via Internet. + + 8. FTERROR + ---------- + + This program tests the gettext() functionality on UNIX platforms + (usually provided in the GNU gettext package). It will return + language specific error and warning messages depending on your + locale. Currently French, Dutch, Spanish, German, and Czech + translations of the FreeType messages are included -- we invite + you to contribute more translations. + + Typically, you have to set the LANG environment variable to your + locale to get localized messages. Example: + + LANG=de fterror + + Note that providing message strings for FreeType's error and + warning messages is an extension and not part of the FreeType + library itself. Please refer to `docs/i18n.txt' for further + details. + + 9. FTSBIT + --------- + + Usage: + + ftsbit ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..] + + This tool dumps the information in the tables for embedded + bitmaps. Additionally, it prints (to the console) a selected + glyph bitmap. + + 10. FTMETRIC + ------------ + + Usage: + + ftmetric [options below] point fontname[.ttf|.ttc] ... + + -B show sbit's metrics (default: none) + -c C use C'th font index of TrueType collection + (default: 0) + -i index glyph index (default: 0) + -r R use resolution R dpi (default: 72dpi) + + With this small program you can inspect the metric data of a + given glyph; additionally, it dumps the particular glyph to the + console. + + 11. FTSTRTTO + ------------ + + Usage: + + ftstrtto [options below] ppem fontname[.ttf|.ttc] [string|-] + + -c C use font with index C in TrueType collection + (default: 0) + -f F use feature F (can be specified more than once) + -g gray-level rendering + -l L use language L + -r R use resolution R dpi (default: 96dpi) + -s S use script S + -u interpret input data as UTF8-encoded + -v display string vertically + -x display string from right to left + + F, L, and S must be specified as 4-character tags. + Specifying only F and S selects default language system of S. + Specifying only L and S selects the req. feature of L only + (if any). + + If `-' is specified as input string, stdin is read instead. + + This program uses almost all features of FreeType to display a + string on screen. Its usage is similar to `ftstring', but you + can additionally select GSUB features, the collection in a font, + toggle kerning and embedded bitmaps interactively, and input the + optional string in UTF8 encoding. + + For a list of available script, language, and feature tags + please refer to the TrueType Open (resp. OpenType) + specification. + + Example: + + ftstrtto -s "latn" -l "DEU " -f "liga" -f "frac" \ + 40 pala.ttf "fi ff ffi ffl 1/2" + + Note that you can inspect the available tags in a font with + `ftdump'. + + The features `init', `medi', and `fina', and `isol' are treated + specially. Internally, ftstrtto assigns initial, medial, + isolated, and final properties to Arabic characters in the input + string. If one of the features is switched on, all glyphs with + the corresponding property are modified (if covered). + + Example: + + ftstrtto -s arab -f init -f medi -f fina -f isol \ + -f liga -f mset -x -u 20 trado.ttf - < arab.utf8 + + `mset' is another, Arabic specific feature to position combining + marks. + + If you select the swash feature `swsh', the displayed + alternative in the string is always the first available one. + + + +IV. HOW TO USE THE PROGRAMS IN THE `CONTRIB' DIRECTORY +====================================================== + + These programs are contributions to FreeType and not really part + of it. Please read the documentation files in the respective + subdirectories how to compile and install them. + + +V. FINAL REMARKS +================ + +Of course, all source code is provided `as is'. Please read the +file `license.txt' for more information. + +We hope you will find this engine useful, and look forward to file. +your feed-back. We're of course very interested in bug reports, as +well as FreeType success stories :-) + + +Thanks for your time and consideration, + + + David Turner, Robert Wilhelm, Werner Lemberg, + and all the FreeType enthusiasts... + + +--- end of README --- diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..2ad3206 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,427 @@ +## libtool.m4 - Configure libtool for the target system. -*-Shell-script-*- +## Copyright (C) 1996-1999 Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +# serial 40 AC_PROG_LIBTOOL +AC_DEFUN(AC_PROG_LIBTOOL, +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ +DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN(AC_LIBTOOL_SETUP, +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_RANLIB])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +dnl + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], +[libtool_flags="$libtool_flags --enable-dlopen"]) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[libtool_flags="$libtool_flags --enable-win32-dll"]) +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +]) +esac +]) + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_SHARED, [dnl +define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_STATIC, [dnl +define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl +define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN(AC_PROG_LD, +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. +changequote(,)dnl + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' +changequote([,])dnl + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(ac_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$ac_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_SUBST(LD) +AC_PROG_LD_GNU +]) + +AC_DEFUN(AC_PROG_LD_GNU, +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi]) +]) + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN(AC_PROG_NM, +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(ac_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi]) +NM="$ac_cv_path_NM" +AC_MSG_RESULT([$NM]) +AC_SUBST(NM) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN(AC_CHECK_LIBM, +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case "$host" in +*-*-beos* | *-*-cygwin*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library, adds --enable-ltdl-convenience to +# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor +# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed +# to be `${top_builddir}/libltdl'. Make sure you start DIR with +# '${top_builddir}/' (note the single quotes!) if your package is not +# flat, and, if you're not using automake, define top_builddir as +# appropriate in the Makefiles. +AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case "$enable_ltdl_convenience" in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la + INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library, and adds --enable-ltdl-install to +# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor +# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed +# to be `${top_builddir}/libltdl'. Make sure you start DIR with +# '${top_builddir}/' (note the single quotes!) if your package is not +# flat, and, if you're not using automake, define top_builddir as +# appropriate in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la + INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +dnl old names +AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl +AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl +AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl +AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl +AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl +AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl +AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl + +dnl This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL])dnl diff --git a/announce b/announce new file mode 100644 index 0000000..1412202 --- /dev/null +++ b/announce @@ -0,0 +1,60 @@ + + + Announcing + + + F R E E T Y P E 1 . 3 . 1 + + + The FREE TrueType Font Engine + + + Copyright (C) 1996-1999 The FreeType Development Team + + + + The FreeType engine is a free and portable TrueType font rendering + engine, available in ANSI C and Pascal source code. It has been + developed to provide TrueType support to a great variety of + platforms and environments. + + Notice that FreeType is a *library*. It is *not* a font server + for your preferred environment, even though it has been designed + to be the basis of many high-level libraries, tools and font + servers. + + + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + + WE HAVE RECENTLY DISCOVERED THAT APPLE OWNS SEVERAL PATENTS + RELATED TO THE RENDERING OF TRUETYPE FONTS. THIS COULD MEAN THAT + THE FREE USE OF THE FREETYPE LIBRARY MIGHT BE ILLEGAL IN THE USA, + JAPAN, AND POSSIBLY OTHER COUNTRIES. FOR MORE INFORMATION, WE + STRONGLY ADVISE YOU TO GO TO THE FREETYPE WEB SITE AT: + + http://www.freetype.org/patents.htm + + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER DISCLAIMER + + + It's a clean-room implementation that is not derived from the + original TrueType engine developed by Apple and Microsoft, though + it matches it regarding rendering quality. To our knowledge, it's + the only royalty-free complete TrueType engine available. + + Version 1.3.1 fixes several bugs found in 1.3. + + Version 1.3 fixes several bugs found in 1.2, as well as provide + the engine with enhanced capabilities, like support for embedded + bitmaps and rudimentary TrueType Open support. + + For more information, please visit the freetype web site at: + + http://www.freetype.org + diff --git a/config.guess b/config.guess new file mode 100644 index 0000000..6cb567b --- /dev/null +++ b/config.guess @@ -0,0 +1,1087 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 +# Free Software Foundation, Inc. +# +# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to the Autoconf mailing list . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .globl main + .ent main +main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + arm32:NetBSD:*:*) + echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + macppc:NetBSD:*:*) + echo powerpc-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + ($CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*T3E:*:*:*) + echo t3e-cray-unicosmk${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + if test -x /usr/bin/objformat; then + if test "elf" = "`/usr/bin/objformat`"; then + echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'` + exit 0 + fi + fi + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # uname on the ARM produces all sorts of strangeness, and we need to + # filter it out. + case "$UNAME_MACHINE" in + armv*) UNAME_MACHINE=$UNAME_MACHINE ;; + arm* | sa110*) UNAME_MACHINE="arm" ;; + esac + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; + i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; + sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + elf32ppc) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + sed 's/^ //' <$dummy.s + .globl main + .ent main + main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c </dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:5:7*) + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent.*II' >/dev/null) && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) && UNAME_MACHINE=i585 + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}${UNAME_VERSION}-sysv${UNAME_RELEASE} + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/config.sub b/config.sub new file mode 100644 index 0000000..2436b45 --- /dev/null +++ b/config.sub @@ -0,0 +1,1215 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v) + basic_machine=$basic_machine-unknown + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \ + | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* \ + | f301-* | armv*-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* ) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | *MiNT) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-corel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + np1) + basic_machine=np1-gould + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -openstep* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -*MiNT) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-corel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/configure b/configure new file mode 100644 index 0000000..3907281 --- /dev/null +++ b/configure @@ -0,0 +1,4515 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=no]" +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock avoid locking (might break parallel builds)" +ac_help="$ac_help + --disable-nls don't use NLS" +ac_help="$ac_help + --with-locale-dir=DIR Location of the locale file(s) + [PREFIX/share/locale]" +ac_help="$ac_help + --with-x use the X Window System" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +srcdir=`cd $srcdir; pwd` + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=no +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:640: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:661: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:681: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:711: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:741: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:792: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:824: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 835 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:840: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:866: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:871: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:899: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:942: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:966: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:969: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$ac_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } + +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1005: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 + + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1021: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi +fi + +NM="$ac_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1058: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + : +fi + +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$host" in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 1102 "configure"' > conftest.$ac_ext + if { (eval echo configure:1103: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:1124: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + + +esac + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ +DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + +freetype_version='1.2.0' + +version_info='4:0:2' + +# Check whether --enable-nls or --disable-nls was given. +if test "${enable_nls+set}" = set; then + enableval="$enable_nls" + USE_NLS=no +else + USE_NLS=yes +fi + + + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:1280: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:1301: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:1319: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1345: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1375: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1426: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1458: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1469 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1474: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1500: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1505: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1533: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1565: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1586: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1603: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1620: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic -ansi" +else + case "$host" in + *-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + + +case "$host" in + *-dec-osf*) + ln -s ../../MakeSub lib/arch + ln -s ../../MakeSub test/arch + ;; +esac + + + + +if test "$USE_NLS" = "yes"; then + + echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:1674: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +for ac_hdr in locale.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1704: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1714: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + for ac_func in setlocale +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1743: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + + + ALL_LINGUAS="de fr cs nl es" + for ac_hdr in libintl.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1802: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1812: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 +echo "configure:1839: checking for gettext in -lintl" >&5 +ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo intl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + + + + LOCALEDIR='${prefix}/share/locale' + # Check whether --with-locale-dir or --without-locale-dir was given. +if test "${with_locale_dir+set}" = set; then + withval="$with_locale_dir" + + if test x$withval = xyes; then + echo "configure: warning: Usage is: --with-locale-dir=basedir" 1>&2 + else + if test x$withval = xno; then + echo "configure: warning: Usage is: --with-locale-dir=basedir" 1>&2 + else + LOCALEDIR=$withval + fi + fi + +fi + + + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1910: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="$MSGFMT" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -n "$MSGFMT"; then + for ac_func in dcgettext +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1947: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2002: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GMSGFMT" in + /*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT="$ac_cv_path_GMSGFMT" +if test -n "$GMSGFMT"; then + echo "$ac_t""$GMSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2038: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT="$XGETTEXT" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # Extract the first word of "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2074: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_MSGMERGE'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$MSGMERGE" in + /*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_MSGMERGE="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE="$MSGMERGE" + ;; +esac +fi +MSGMERGE="$ac_cv_path_MSGMERGE" +if test -n "$MSGMERGE"; then + echo "$ac_t""$MSGMERGE" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + if test -n "$XGETTEXT"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6 + XGETTEXT="" + fi + fi + + if test -n "$XGETTEXT"; then + if $XGETTEXT --help > /dev/null 2> /dev/null; then + : ; + else + echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6 + XGETTEXT="" + fi + fi + + if test -n "$MSGFMT"; then + if $MSGFMT < /dev/null 2> /dev/null; then + echo "$ac_t""found msgfmt program is not GNU msgfmt; NLS won't be installed" 1>&6 + MSGFMT="" + fi + fi + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + CATOBJEXT=.gmo + DATADIRNAME=share +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CATOBJEXT=.mo + DATADIRNAME=lib +fi +rm -f conftest* + INSTOBJEXT=.mo + fi + + if test -n "$ALL_LINGUAS"; then + for lang in $ALL_LINGUAS; do + CATALOGS="$CATALOGS $lang$CATOBJEXT" + done + fi + + + + +fi + +if test x"$MSGFMT" = x; then + USE_NLS=no +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2176: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "rmdir", so it can be a program name with args. +set dummy rmdir; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2205: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RMDIR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RMDIR"; then + ac_cv_prog_RMDIR="$RMDIR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RMDIR="rmdir" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RMDIR="$ac_cv_prog_RMDIR" +if test -n "$RMDIR"; then + echo "$ac_t""$RMDIR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:2243: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:2296: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + + + + # Most operating systems have gethostbyname() in the default searched + # libraries (i.e. libc): + echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 +echo "configure:2323: checking for gethostbyname" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +gethostbyname(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2351: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gethostbyname=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_gethostbyname=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +# Some OSes (eg. Solaris) place it in libnsl: + echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +echo "configure:2370: checking for gethostbyname in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +# Some strange OSes (SINIX) have it in libsocket: + echo $ac_n "checking for gethostbyname in -lsocket""... $ac_c" 1>&6 +echo "configure:2416: checking for gethostbyname in -lsocket" >&5 +ac_lib_var=`echo socket'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +# Unfortunately libsocket sometimes depends on libnsl. + # AC_CHECK_LIB's API is essentially broken so the following + # ugliness is necessary: + echo $ac_n "checking for gethostbyname in -lsocket""... $ac_c" 1>&6 +echo "configure:2464: checking for gethostbyname in -lsocket" >&5 +ac_lib_var=`echo socket'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket -lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lsocket -lnsl $LIBS" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for gethostbyname in -lresolv""... $ac_c" 1>&6 +echo "configure:2502: checking for gethostbyname in -lresolv" >&5 +ac_lib_var=`echo resolv'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lresolv $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +fi + + +fi + + +fi + + +fi + + echo $ac_n "checking for socket""... $ac_c" 1>&6 +echo "configure:2560: checking for socket" >&5 +if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_socket) || defined (__stub___socket) +choke me +#else +socket(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_socket=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_socket=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:2606: checking for socket in -lsocket" >&5 +ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:2651: checking for socket in -lsocket" >&5 +ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket -lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="-lsocket -lnsl $LIBS" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +fi + + +echo $ac_n "checking for cos in -lm""... $ac_c" 1>&6 +echo "configure:2696: checking for cos in -lm" >&5 +ac_lib_var=`echo m'_'cos | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + +# If we find X, set shell vars x_includes and x_libraries to the +# paths, otherwise set no_x=yes. +# Uses ac_ vars as temps to allow command line to override cache and checks. +# --without-x overrides everything else, but does not touch the cache. +echo $ac_n "checking for X""... $ac_c" 1>&6 +echo "configure:2748: checking for X" >&5 + +# Check whether --with-x or --without-x was given. +if test "${with_x+set}" = set; then + withval="$with_x" + : +fi + +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then + # Both variables are already set. + have_x=yes + else +if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=NO ac_x_libraries=NO +rm -fr conftestdir +if mkdir conftestdir; then + cd conftestdir + # Make sure to not put "make" in the Imakefile rules, since we grep it out. + cat > Imakefile <<'EOF' +acfindx: + @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' +EOF + if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering...", which would confuse us. + eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl; do + if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && + test -f $ac_im_libdir/libX11.$ac_extension; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case "$ac_im_incroot" in + /usr/include) ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; + esac + case "$ac_im_usrlibdir" in + /usr/lib | /lib) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;; + esac + fi + cd .. + rm -fr conftestdir +fi + +if test "$ac_x_includes" = NO; then + # Guess where to find include files, by looking for this one X11 .h file. + test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h + + # First, try using that file with no special directory specified. +cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2815: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + # We can compile using X headers with no special include directory. +ac_x_includes= +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + # Look for the header file in a standard set of common directories. +# Check X11 before X11Rn because it is often a symlink to the current release. + for ac_dir in \ + /usr/X11/include \ + /usr/X11R6/include \ + /usr/X11R5/include \ + /usr/X11R4/include \ + \ + /usr/include/X11 \ + /usr/include/X11R6 \ + /usr/include/X11R5 \ + /usr/include/X11R4 \ + \ + /usr/local/X11/include \ + /usr/local/X11R6/include \ + /usr/local/X11R5/include \ + /usr/local/X11R4/include \ + \ + /usr/local/include/X11 \ + /usr/local/include/X11R6 \ + /usr/local/include/X11R5 \ + /usr/local/include/X11R4 \ + \ + /usr/X386/include \ + /usr/x386/include \ + /usr/XFree86/include/X11 \ + \ + /usr/include \ + /usr/local/include \ + /usr/unsupported/include \ + /usr/athena/include \ + /usr/local/x11r5/include \ + /usr/lpp/Xamples/include \ + \ + /usr/openwin/include \ + /usr/openwin/share/include \ + ; \ + do + if test -r "$ac_dir/$x_direct_test_include"; then + ac_x_includes=$ac_dir + break + fi + done +fi +rm -f conftest* +fi # $ac_x_includes = NO + +if test "$ac_x_libraries" = NO; then + # Check for the libraries. + + test -z "$x_direct_test_library" && x_direct_test_library=Xt + test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc + + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS="$LIBS" + LIBS="-l$x_direct_test_library $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + LIBS="$ac_save_LIBS" +# We can link X programs with no special library path. +ac_x_libraries= +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + LIBS="$ac_save_LIBS" +# First see if replacing the include by lib works. +# Check X11 before X11Rn because it is often a symlink to the current release. +for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ + /usr/X11/lib \ + /usr/X11R6/lib \ + /usr/X11R5/lib \ + /usr/X11R4/lib \ + \ + /usr/lib/X11 \ + /usr/lib/X11R6 \ + /usr/lib/X11R5 \ + /usr/lib/X11R4 \ + \ + /usr/local/X11/lib \ + /usr/local/X11R6/lib \ + /usr/local/X11R5/lib \ + /usr/local/X11R4/lib \ + \ + /usr/local/lib/X11 \ + /usr/local/lib/X11R6 \ + /usr/local/lib/X11R5 \ + /usr/local/lib/X11R4 \ + \ + /usr/X386/lib \ + /usr/x386/lib \ + /usr/XFree86/lib/X11 \ + \ + /usr/lib \ + /usr/local/lib \ + /usr/unsupported/lib \ + /usr/athena/lib \ + /usr/local/x11r5/lib \ + /usr/lpp/Xamples/lib \ + /lib/usr/lib/X11 \ + \ + /usr/openwin/lib \ + /usr/openwin/share/lib \ + ; \ +do + for ac_extension in a so sl; do + if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi +rm -f conftest* +fi # $ac_x_libraries = NO + +if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then + # Didn't find X anywhere. Cache the known absence of X. + ac_cv_have_x="have_x=no" +else + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" +fi +fi + fi + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + echo "$ac_t""$have_x" 1>&6 + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$x_includes ac_x_libraries=$x_libraries" + echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 +fi + +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + cat >> confdefs.h <<\EOF +#define X_DISPLAY_MISSING 1 +EOF + + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + case "`(uname -sr) 2>/dev/null`" in + "SunOS 5"*) + echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 +echo "configure:2997: checking whether -R must be followed by a space" >&5 + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_R_nospace=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_R_nospace=no +fi +rm -f conftest* + if test $ac_R_nospace = yes; then + echo "$ac_t""no" 1>&6 + X_LIBS="$X_LIBS -R$x_libraries" + else + LIBS="$ac_xsave_LIBS -R $x_libraries" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_R_space=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_R_space=no +fi +rm -f conftest* + if test $ac_R_space = yes; then + echo "$ac_t""yes" 1>&6 + X_LIBS="$X_LIBS -R $x_libraries" + else + echo "$ac_t""neither works" 1>&6 + fi + fi + LIBS="$ac_xsave_LIBS" + esac + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And karl@cs.umb.edu says + # the Alpha needs dnet_stub (dnet does not exist). + echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 +echo "configure:3062: checking for dnet_ntoa in -ldnet" >&5 +ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldnet $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 +echo "configure:3103: checking for dnet_ntoa in -ldnet_stub" >&5 +ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldnet_stub $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to dickey@clark.net. + echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 +echo "configure:3151: checking for gethostbyname" >&5 +if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +gethostbyname(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_gethostbyname=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_gethostbyname=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_gethostbyname = no; then + echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 +echo "configure:3200: checking for gethostbyname in -lnsl" >&5 +ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnsl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says simon@lia.di.epfl.ch: it contains + # gethostby* variants that don't use the nameserver (or something). + # -lsocket must be given before -lnsl if both are needed. + # We assume that if connect needs -lnsl, so does gethostbyname. + echo $ac_n "checking for connect""... $ac_c" 1>&6 +echo "configure:3249: checking for connect" >&5 +if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +connect(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_connect=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_connect=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_connect = no; then + echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 +echo "configure:3298: checking for connect in -lsocket" >&5 +ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. + echo $ac_n "checking for remove""... $ac_c" 1>&6 +echo "configure:3341: checking for remove" >&5 +if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char remove(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_remove) || defined (__stub___remove) +choke me +#else +remove(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_remove=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_remove=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_remove = no; then + echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 +echo "configure:3390: checking for remove in -lposix" >&5 +ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lposix $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +else + echo "$ac_t""no" 1>&6 +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + echo $ac_n "checking for shmat""... $ac_c" 1>&6 +echo "configure:3433: checking for shmat" >&5 +if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shmat(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shmat) || defined (__stub___shmat) +choke me +#else +shmat(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_shmat=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_shmat=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + + if test $ac_cv_func_shmat = no; then + echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 +echo "configure:3482: checking for shmat in -lipc" >&5 +ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lipc $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +else + echo "$ac_t""no" 1>&6 +fi + + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS="$LDFLAGS" + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. + echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 +echo "configure:3534: checking for IceConnectionNumber in -lICE" >&5 +ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lICE $X_EXTRA_LIBS $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +else + echo "$ac_t""no" 1>&6 +fi + + LDFLAGS="$ac_save_LDFLAGS" + +fi + +for ac_hdr in stdlib.h fcntl.h unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:3581: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3591: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:3619: checking for working const" >&5 +if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:3673: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_const=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_c_const" 1>&6 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking size of int""... $ac_c" 1>&6 +echo "configure:3694: checking size of int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(int)); + exit(0); +} +EOF +if { (eval echo configure:3713: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3733: checking size of long" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long)); + exit(0); +} +EOF +if { (eval echo configure:3752: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long" 1>&6 +cat >> confdefs.h <&6 +echo "configure:3777: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:3787: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +for ac_func in getpagesize +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:3816: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:3844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + +echo $ac_n "checking for working mmap""... $ac_c" 1>&6 +echo "configure:3869: checking for working mmap" >&5 +if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat > conftest.$ac_ext < +#include +#include + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include +# endif + +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +#ifdef __cplusplus +extern "C" { void *malloc(unsigned); } +#else +char *malloc(); +#endif + +int +main() +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize(); + + /* + * First, make a file with some known garbage in it. + */ + data = malloc(pagesize); + if (!data) + exit(1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand(); + umask(0); + fd = creat("conftestmmap", 0600); + if (fd < 0) + exit(1); + if (write(fd, data, pagesize) != pagesize) + exit(1); + close(fd); + + /* + * Next, try to mmap the file at a fixed address which + * already has something else allocated at it. If we can, + * also make sure that we see the same garbage. + */ + fd = open("conftestmmap", O_RDWR); + if (fd < 0) + exit(1); + data2 = malloc(2 * pagesize); + if (!data2) + exit(1); + data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + exit(1); + + /* + * Finally, make sure that changes to the mapped area + * do not percolate back to the file as seen by read(). + * (This is a bug on some variants of i386 svr4.0.) + */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = malloc(pagesize); + if (!data3) + exit(1); + if (read(fd, data3, pagesize) != pagesize) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + exit(1); + close(fd); + unlink("conftestmmap"); + exit(0); +} + +EOF +if { (eval echo configure:4017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_mmap_fixed_mapped=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MMAP 1 +EOF + +fi + +if test "$ac_cv_func_mmap_fixed_mapped" != yes; then + TT_FILE_COMPONENT=ttfile.c +else + TT_FILE_COMPONENT=arch/unix/ttmmap.c +fi + + +for ac_func in memcpy memmove +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:4049: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:4077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi +done + + + + +$srcdir/mkinstalldirs lib/arch/unix test/arch/unix + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile + MakeSub + lib/arch/unix/Makefile + test/arch/unix/Makefile + po/Makefile.in ft_conf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@RANLIB@%$RANLIB%g +s%@CC@%$CC%g +s%@LD@%$LD%g +s%@NM@%$NM%g +s%@LN_S@%$LN_S%g +s%@LIBTOOL@%$LIBTOOL%g +s%@USE_NLS@%$USE_NLS%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@CPP@%$CPP%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@freetype_version@%$freetype_version%g +s%@version_info@%$version_info%g +s%@SET_MAKE@%$SET_MAKE%g +s%@HAVE_LOCALE_H@%$HAVE_LOCALE_H%g +s%@HAVE_LIBINTL_H@%$HAVE_LIBINTL_H%g +s%@HAVE_LIBINTL@%$HAVE_LIBINTL%g +s%@LOCALEDIR@%$LOCALEDIR%g +s%@MSGFMT@%$MSGFMT%g +s%@GMSGFMT@%$GMSGFMT%g +s%@XGETTEXT@%$XGETTEXT%g +s%@MSGMERGE@%$MSGMERGE%g +s%@CATALOGS@%$CATALOGS%g +s%@CATOBJEXT@%$CATOBJEXT%g +s%@INSTOBJEXT@%$INSTOBJEXT%g +s%@DATADIRNAME@%$DATADIRNAME%g +s%@RM@%$RM%g +s%@RMDIR@%$RMDIR%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@X_CFLAGS@%$X_CFLAGS%g +s%@X_PRE_LIBS@%$X_PRE_LIBS%g +s%@X_LIBS@%$X_LIBS%g +s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g +s%@TT_FILE_COMPONENT@%$TT_FILE_COMPONENT%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..100c847 --- /dev/null +++ b/configure.in @@ -0,0 +1,201 @@ +dnl This file is part of the FreeType project. +dnl +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(lib/freetype.h) + +dnl Due to a bug in autoconf we must set $srcdir explicitly to an absolute +dnl path. +srcdir=`cd $srcdir; pwd` + +AM_DISABLE_STATIC +AM_PROG_LIBTOOL + +dnl FreeType version +freetype_version='1.2.0' + +dnl libttf.so version +version_info='4:0:2' + +AC_ARG_ENABLE(nls, + [ --disable-nls don't use NLS], + USE_NLS=no, USE_NLS=yes) +AC_SUBST(USE_NLS) + +dnl Checks for system type. +AC_CANONICAL_SYSTEM + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CPP + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic -ansi" +else + case "$host" in + *-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +dnl at least Digital UNIX 4.0d needs this due to a strange make program + +case "$host" in + *-dec-osf*) + ln -s ../../MakeSub lib/arch + ln -s ../../MakeSub test/arch + ;; +esac + +AC_SUBST(freetype_version) +AC_SUBST(version_info) + +dnl gettext support +if test "$USE_NLS" = "yes"; then + AC_REQUIRE([AC_PROG_MAKE_SET]) + AC_CHECK_HEADERS(locale.h) + AC_CHECK_FUNCS(setlocale) + AC_SUBST(HAVE_LOCALE_H) + + ALL_LINGUAS="de fr cs nl es" + AC_CHECK_HEADERS(libintl.h) + AC_CHECK_LIB(intl,gettext) + AC_SUBST(HAVE_LIBINTL_H) + AC_SUBST(HAVE_LIBINTL) + + dnl Handle localedir + LOCALEDIR='${prefix}/share/locale' + AC_ARG_WITH(locale-dir, + [ --with-locale-dir=DIR Location of the locale file(s) + [PREFIX/share/locale]],[ + if test x$withval = xyes; then + AC_MSG_WARN(Usage is: --with-locale-dir=basedir) + else + if test x$withval = xno; then + AC_MSG_WARN(Usage is: --with-locale-dir=basedir) + else + LOCALEDIR=$withval + fi + fi + ]) + AC_SUBST(LOCALEDIR) + + AC_PATH_PROG(MSGFMT, msgfmt, $MSGFMT) + if test -n "$MSGFMT"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AC_PATH_PROG(XGETTEXT, xgettext, $XGETTEXT) + AC_PATH_PROG(MSGMERGE, msgmerge, $MSGMERGE) + + dnl Test whether we really found GNU xgettext. + if test -n "$XGETTEXT"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT="" + fi + fi + + dnl We add another test for comparing GNU xgettext with openwin xgettext + if test -n "$XGETTEXT"; then + if $XGETTEXT --help > /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT="" + fi + fi + + dnl Test whether we really found GNU msgfmt. + if test -n "$MSGFMT"; then + if $MSGFMT < /dev/null 2> /dev/null; then + AC_MSG_RESULT( + [found msgfmt program is not GNU msgfmt; NLS won't be installed]) + MSGFMT="" + fi + fi + + AC_TRY_LINK(, + [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + + if test -n "$ALL_LINGUAS"; then + for lang in $ALL_LINGUAS; do + CATALOGS="$CATALOGS $lang$CATOBJEXT" + done + fi + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(INSTOBJEXT) + AC_SUBST(DATADIRNAME) +fi + +dnl don't use NLS, when there is no gettext installed +if test x"$MSGFMT" = x; then + USE_NLS=no +fi + + +AC_CHECK_PROG(RM, rm, rm) +AC_CHECK_PROG(RMDIR, rmdir, rmdir) +AC_PROG_INSTALL +AC_PROG_LN_S + +dnl Checks for libraries. +sinclude(net.m4) +AC_LIBRARY_NET +AC_CHECK_LIB(m, cos) + +dnl Checks for header files. +AC_PATH_XTRA +AC_CHECK_HEADERS(stdlib.h fcntl.h unistd.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(long) + +dnl Checks for library functions. + +dnl Here we check whether we can use our mmap file component. +AC_FUNC_MMAP +if test "$ac_cv_func_mmap_fixed_mapped" != yes; then + TT_FILE_COMPONENT=ttfile.c +else + TT_FILE_COMPONENT=arch/unix/ttmmap.c +fi +AC_SUBST(TT_FILE_COMPONENT) + +AC_CHECK_FUNCS(memcpy memmove) + +AC_CONFIG_HEADER(ft_conf.h) + +dnl Another bug: to make --srcdir work correctly we have to create the +dnl directory hierarchy first since autoconf only uses mkdir. +$srcdir/mkinstalldirs lib/arch/unix test/arch/unix + +AC_OUTPUT(Makefile + MakeSub + lib/arch/unix/Makefile + test/arch/unix/Makefile + po/Makefile.in, + [sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile]) + + +dnl end of configure.in diff --git a/contrib/ftos2/DEVELFAQ b/contrib/ftos2/DEVELFAQ new file mode 100644 index 0000000..f8aafbc --- /dev/null +++ b/contrib/ftos2/DEVELFAQ @@ -0,0 +1,38 @@ + + This is a FreeType/2 programmers' mini-FAQ + +Q1: Is the source code available? + +A1: Yes! But if you think you have all you need, you're probably wrong :-) + The source is now actually part of FreeType project, located at + ftp://ftp.physiol.med.tu-muenchen.de/pub/freetype + + We have now the permission to distribute the OS/2 IFI headers with + the FreeType/2 source code. They're all the files beginning with a + "32" in the "ifi" directory. It seems that some people had problems + with the download indicated in the last beta. + + +Q2: What compilers are supported? + +A2: The development of FreeType/2 was done primarily in IBM's VisualAge C++ + version 3.0. It should be possible to build the DLL with Watcom C/C++ but + it's not quite working yet. + It is perhaps possible to build the Font Driver with another compiler, + but you'll have to know the compiler (and OS/2 of course) _quite_ well. + + Note that the FreeType library itself supports also EMX/GCC (and I + believe it was mainly developed in it). + + +Q3: What other tools do I need? + +A3: You'll need a kernel debugger. Check out IBM's ICAT, it's great and + it's free! Actually without ICAT this code would probably never happen. + If you've lived under a rock and don't know what ICAT is, it's actually + an interface to ol' good KDB. It is a source-level debugger and it looks + and feels very much like the VisualAge debugger, IPMD. + + And if you haven't got it yet, you'll need _two_ computers to use ICAT. + But believe me, it's worth it! + diff --git a/contrib/ftos2/FAQ b/contrib/ftos2/FAQ new file mode 100644 index 0000000..d4a7922 --- /dev/null +++ b/contrib/ftos2/FAQ @@ -0,0 +1,260 @@ +This is a FreeType/2 users' mini-FAQ + +Table of Contents: + +Q1: Where can I find the latest FreeType/2 release? +Q2: Now that I have FreeType/2 installed, how do I actually add TrueType +fonts to OS/2? +Q3: When will you add font-smoothing to the DLL? I really want that! +Q4: Why does IBM's TrueType engine do such a poor job? +Q5: But there are still differences with the glyphs produced by Windows or +the Mac, right? +Q6: I've got TrueType Times New Roman installed but the system still seems +to be using the original ATM (Type 1) font. Why this odd behaviour? +Q7: I noticed it takes a second or two before the Font Palette object opens +for the first time. Why? +Q8: I noticed the characters sometimes have odd spacing. When will you fix +it? +Q9: Could you explain the open fonts limit? +Q10: Can you recommend some fonts to use? +Q11: What's a 'broken glyph'? +Q12: Why do some fonts appear twice, once starting with an '@'? +Q13: I've got a Chinese (Japanese, Korean) font but the characters aren't +there! Why? +Q14: I tried to use a DBCS font but I got an exception un UCONV.DLL. What's +wrong? +Q15: My system won't boot after I installed FreeType/2 and the uninstall +script won't work when I boot to command line. What now? +Q16: I'm upgrading from previous version and I don't want to uninstall and +reinstall. Is there any other way? +Q17: What's this stuff about Times New Roman being aliased to Tms Rmn? +Please explain this. + +Questions & Answers: + +Q1: Where can I find the latest FreeType/2 release? + +A1: Links to the latest release can be found at the FreeType/2 homepage at +http://www.freetype.org/ft_os2/index.html. + +Q2: Now that I have FreeType/2 installed, how do I actually add TrueType +fonts to OS/2? + +A2: I thought everyone knew that... It's simple, really. Open the Font +Palette object (in System Setup folder) then click 'Edit font' and 'Add'. +Now type the directory path where your TrueType fonts reside, such as +'C:\WINDOWS\FONTS' if you have Win95 and click 'Add'. You'll be presented a +list of all fonts that OS/2 found in specified directory. Simply select all +fonts you wish to install click 'Add' for the last time. If you wish to +remove fonts, just use the 'Delete' button in the 'Edit Font' dialog. +TIP: If you wish to add font to OS/2 but don't want to actually copy the +file, just type the directory name where the font files already are instead +of 'X:\PSFONTS' in the 'Add New Fonts' dialog. + +Q3: When will you add font-smoothing to the DLL? I really want that! + +A3: Short answer: We can't. +Long answer: The FreeType library already supports font-smoothing (or +antialiasing or grayscaling). The problem is that OS/2's font engine, in +its current incarnation, doesn't know anything about anti-aliased text and +is only able to manage monochrome bitmaps. Font smoothing support would +require some changes of PM/GPI/GRE components, which certainly is out of +our scope, and isn't planned by IBM (to our knowledge) in foreseeable +future, if ever. + +If you really need font smoothing in your application, you can still use +the FreeType library itself. Be warned that it is a rather low-level engine +and that you'll need to add a various number of text features on top of +this code to get the equivalent of PM's font API. + +There is a good chance that FreeType 2.0 will ease the pain for developers +when it's available. + +And if you really want font smoothing in OS/2, ask IBM! + +Q4: Why does IBM's TrueType engine do such a poor job? + +A4: It'd be easy to throw one or two stones at IBM's engineers if this was +the result of lazy coding or bad software engineering. However, the problem +is more complex, and PSP programmers deserve little, if any, blame. + +Trouble is that the TrueType specification, which can be found both on +Microsoft and Apple sites, has severe lacks, as well as particularly fuzzy +definitions. Part of the TT spec is the TrueType bytecode specification. +This bytecode is used to write glyph programs that are used to explicitely +hint each glyph to have it rendered perfectly on the screen (and on +printers). It is made of approximately 200 opcodes, which relate to moving +points on a pixel grid, measuring distances in any kind of direction, +keeping widths and heights consistent across a single font, etc.. + +Some of these opcodes are simply un-documented, or lack precise and +important details related to their exact implementation. As a consequence, +when FreeType started, it's first bytecode interpreter exhibited results +which were very similar to OS/2's one (i.e. bad baseline, incoherent +widths, "swashs" and bad serifs, etc..). There are several commercial +engines which provide the same kind of "erroneous" output, like the one in +the BeOS for instance. + +It took FreeType developers _many_ months and experimentation to discover +the real meaning of some opcodes, and incorporate it into the library. This +"spelunker" work has been painful and slow, which is why few commercial +companies, if any, dared to do it, but it finally pays off ! Moreover, the +FreeType library is released under a BSD-like free license. This means that +_anyone_ is now able to take the work that has been done to rewrite or fix +his own TrueType interpreter. (Of course, another good idea is to use +FreeType as your core TrueType engine, to be able to benefit to ongoing +fixes and "undocumented features" discoveries, etc...) + +Q5: But there are still differences with the glyphs produced by Windows or +the Mac, right? + +A5: Right. Another feature of the TrueType specification is to use fixed +float pixel coordinates. When measuring distances along diagonals, some +rouding error usually occur. Also, some TrueType opcodes have a more or +less "chaotic" behaviour, where a ridiculous difference in inputs can +produce vastly different results. These factors mean that the only way to +match bit-to-bit the glyphs produced by Windows or the Macintosh is to +implement the _exact_ same computation routines, and reproduce all their +rounding errors ! As FreeType is a clean-room implementation, this will +never be possible. Note that the bitmaps match in 95% cases, at least, and +that there are already differences between the Win 3.1 and Win95 TrueType +renderers (i.e. look at the "m" of Arial at size 8 for example). + +The FreeType team tries very hard to "catch" differences, but there is a +point where this just isn't possible... However, we're very satisfied with +its current quality, and we hope you'll be too :-) + +Q6: I've got TrueType Times New Roman installed but the system still seems +to be using the original ATM (Type 1) font. Why this odd behaviour? + +A6: It seems in case of a name clash OS/2 is using the font that was +installed later. Try removing and reinstalling the TrueType font. +Alternately remove the ATM (Type 1) font (not recommended). +Experiments also suggest that different apps behave differently. Some apps +will for example show both fonts but will use only one of them anyway. It +really depends. + +Q7: I noticed it takes a second or two before the Font Palette object opens +for the first time. Why? + +A7: Because FreeType/2 postpones as much work on the fonts as possible +until it's really needed. This means the first opening of a font is a bit +slower. But it also means no resources are unnecessarily wasted. And it's +not really that bad :-) This behaviour is also noticeable when e.g. opening +a document for the first time. Note that subsequent openings are OK because +OS/2 caches as much information as possible. + +Q8: I noticed the characters sometimes have odd spacing. When will you fix +it? + +A8: I won't. It's not really a bug, it's a feature. If they weren't spaced +'oddly', the result might look better, but only at the cost of +Windows-style 'WYSIWYG', i.e. what you see on screen will almost certainly +look totally different on any other device. Anyway, the spacing is +controlled by OS/2 and not by the Font Driver itself, so if you still don't +like it, IBM is the right one to ask :-) + +This problem is particularly visible in Netscape. Most probably this +happens because Netscape tries to use fractional pointsizes, but most +TrueType fonts don't allow that. This means that Netscape sometimes +positions characters as if they were e.g. 8.6 points while their actual +size is only 8 points. + +Q9: Could you explain the open fonts limit? + +A9: Sure. If you install 50 fonts in OS/2, the system opens them all at +startup and keeps them open until shutdown. While many users may want to +have large number of fonts installed (like me), very few of them probably +use all the fonts all the time. This of course wastes lots of memory and +swap space. Just for your information, normal fonts take up 30-50 K of +memory with FreeType/2, but for example Times New Roman MT 30 takes over +500K! + +FreeType/2 overcomes this problem by only actually keeping in memory the +last n most recently used fonts. The actual number is settable via entry in +OS2.INI and there's an simple REXX script to do that. Good default might be +10-15 fonts, depending what you want to do with them. + +Note that this process is totally transparent to the system. You won't have +to do anything, FreeType/2 will take care of everything. The only things +you will notice is dramatically reduced memory consumption and when working +with large numbers of fonts there may be slight delay when reopening a +font. + +Q10: Can you recommend some fonts to use? + +A10: Yes! I recommend to use Micro$oft's (oh no!) Core Fonts - Times New +Roman, Arial and Courier New, plus other MS fonts. There are several +reasons: the fonts have very good quality, stick to the TrueType spec prety +well, support many countries and are widely available. Moreover they're +free. You can certainly find some Win95 or NT machine in your neighbourhood +(all too easily I'm afraid). They should also be available from MS's Web +site. +Note: If you want to copy the fonts from a Win95 machine, they're in +\WINDOWS\FONTS. Watch out, the directory is hidden! + +Q11: What's a 'broken glyph'? + +A11: Some fonts contain buggy or 'broken' glyphs that cannot be reliably +loaded and rendered. Those glyphs are usually very rarely used so you might +never notice. There was a problem with the first Beta of FreeType/2 that if +there was a single broken glyph in a font, the +whole font didn't work. + +Q12: Why do some fonts appear twice, once starting with an '@'? + +A12: It's because of DBCS systems. If you don't have one, you can safely +ignore these fonts. The DBCS characters in them are rotated 90 degrees +counterclockwise. It allows you to write vertical text (e.g. Chinese) with +a normal word processor. You write the text horizontally but if you turn +the resulting page 90 degrees clockwise, you've got vertical text. +It's not working perfectly yet. + +Q13: I've got a Chinese (Japanese, Korean) font but the characters aren't +there! Why? + +A13: Most probably the font and your system settings don't mix. One +possible cause is that your country setting is different than that of the +font and the font contains no information about what language it's meant +for. In that case, FreeType/2 has to guess from your country setting. This +means it might try to treat e.g. Japanese font as a Korean one which means +you won't be able to access the Japanese characters in it. It's all a bit +more complicated but it's a result of how national language support is done +in OS/2. + +Q14: I tried to use a DBCS font but I got an exception un UCONV.DLL. What's +wrong? + +A14: UCONV.DLL it used for character code translation. A likely cause is +that you are missing the required translation table in \LANGUAGE\CODEPAGE +directory on your boot drive. Look for file named 'IBM', where is +the codepage you use, e.g. IBM950 for Taiwan or IBM949 for Korea. + +Q15: My system won't boot after I installed FreeType/2 and the uninstall +script won't work when I boot to command line. What now? + +A15: But you've archived the key files, haven't you? If not, one way out of +this mess is booting to command line and renaming or deleting FREETYPE.DLL +from \OS2\DLL. Your system should boot then. + +Q16: I'm upgrading from previous version and I don't want to uninstall and +reinstall. Is there any other way? + +A16: Yes! There's a little utility called REPMOD.EXE which allows you to +replace files that are in use. In case you don't already have it, it's +included in the FreeType/2 package. You should simply run UPDATE.CMD. The +new version will be used on next reboot. + +Q17: What's this stuff about Times New Roman being aliased to Tms Rmn? +Please explain this. + +A17: OS/2 contains bitmap font called Tms Rmn which is often used in dialog +windows and elsewhere. The bitmap font contains only several pointsizes (8, +10, 12, 14, 18, 24). If you request a missing pointsize, OS/2's graphics +engine (GRE) substitutes it from the (outline) ATM font Times New Roman +which can also be referred to as Roman/Tms Rmn. Now FreeType/2 mimics this +functionality and can fully replace the ATM version. I recommend to +uninstall the ATM font since if both fonts are installed, some apps use the +ATM one, others TrueType one, without any apparent logic. If you uninstall +(via Font Palette) the ATM version, you will always get high-quality +TrueType Times New Roman. diff --git a/contrib/ftos2/ft2.gif b/contrib/ftos2/ft2.gif new file mode 100644 index 0000000000000000000000000000000000000000..b3e9632392a37ab4395f32bdb324540ce3fb3b7f GIT binary patch literal 3817 zcmWkxdpwhi8-L$-?`E@&ZD!_@T!y8&FQnThw_GQ;DQa>Xp}74eJpb)LVze>|V>_xU`3e4pp*y3NJjE({BDfFA(x^XE?p zQWPAW-nMP>ZueYc?X-o(_?y>DVS*`b?NI_jabW+nT>fq5P@T>k);K7_Nrzis3w`5 zf+ZK$#U+R;EFn)2rBY}?$mXC9VzH=n4i;`%qu$D;sx%QO`29_J01b-3Kxj2G$*?aJ zrAA|rvv;8>9So%|==@q5{tQ-CZc3Vd8;Y-Gkl+biG=q=<5|xh-VD(y3I(xmK`nf6` zOdp4&903Fp28-z>|Lc}%pgyuh0;@cfb)YWEGf~R_Z#}Im5M9K{$|5Rbu=8tXuX3rbxIk)Ty0_@X)vryvi{bgL}w;cB2LrnQn;wPWjm z2#Z(6>P50_rC{uD>#QcjjOjg6*X zQ~C(Vbxs)Lm;9FOk#pS9K>($W6JTWL4+NR@RLrbF(rnywehA4H ze>xe~j;wjR`U8;tFMwex5R`83YLyl8N~1#jZ*i(%e-%rl9f9wY(a_7qrw7$xd%pM( z3jU{(O8Ze=#y27fMgmPpvvQ%~c8v$xJq5gOaNj|i?y4oKLZ7J2Bqx<)DIdY-iFa_7 zM^~eH+aop$Rt;vm`*KB6`0}Pwv5M6#5DODF>d9A|vlRgv@6$~jW0n@@G)oOaW~Gq( zjaTFFW<5Qr<&r(%b1WW45JRFsQm*b$A$M^;(n*@yie@)M7d)#w^48pJJoscUX27~M zWbbiKlRI?RP6m2RmAHfVIkUw{=oEVhRvWLEx`bVkOLudtP^fdJMy4{mBW=TF3H+1@ zM>JIRt_2&;9_2VOR@|g`8al#_>{?MTkh`Fn+NiLM9Ogwr4Mv}WkG8!sa&mQj%Cz_F z4N~{sNER@L|JI2@+oBZ07`As9bPtF5i8!AC*xCs2HNfQyEHn+(y_@tOrd%wQ)n@Q8@y?hK2>0+$RnR5JSGa^K7o zm1kH($K?hR8?THue>1?9(pG2IsL0VsSRBnaF%Qq42xv<__nq}pC;3TML@r!-TQ2cT9kwdj zv2s2&vj9Y*KP73iV@26SSd8sb+C3@W z)=;5t@CsY4vh45xHkAYT{0~XS{PW;P1!BOcE1)pX;8o-oVX7eJTJs7Jk~V>;@wj&H z(q5r5t%zN|mCWF^fLW&kQ1Xhgb5i7?wc6H7e$9n`P0`p@-qx&EQ5nhwx6=3I6Bdf}E_< z1$W5N@Ex2cYXIV$B!J*_>+r)7M>9Y`V5>G@E@%8QL^q-`^wbnZ ztO_U>F&*iCAr1C+w&d{p0{T@QvA!=4O#ccgW$NEu>D+bdlttG>4J_cmjCE|MqR*T5 zeQ0oWTc$i*&%IzSE!r?RYTDLVZ`aW1?$49n+uYT?ee;KG;J0tSL}h;|v_(Ai`j_h{ z{~CIKi3iesnVV1*Nv-D?|oj<|ZG*@wX0Vlkel$`b7FhJQ$rh^XAsZ}z#Y zqY*WlnZ+jDRec@@CeOZOH=%D^O5t{yT&El|p!fw>ru6(#u$}GkW<%6(I*PVFuhvcb ze&ba4&8bb;_Y$*neK5ICgR>m|*;>z4{7qD*Xu;*M$Ah%&7sefYJ^S}6V|X<*)z>!4 zO%>>mJ1@#o8o*I}eT7Vx& za62GOJJh3=3A2KmjrTIob8OlUpPvzjK?CunYENvR%q<7qYB2j9@sLxyx8Jw8bncAl*u7E3y0o!rj{_44pn!e}BN2|g#b|fo_D9Oz3WWfe_-pa9_}|GS#7^?v0h2(L?JZ8!to|T|Lm5ughAz z*W&GuW}g$6!W?yLgcCU++BH*uJ)I_}hh{m~wYx)`g_%f2uvvCj{kuWoQon~U@@Gb< zpmuLQV31JaxZKv zwx!rucj%7;{AqTp)=D62{q2c|lzi=X?1l~P{h-_R7pok;cdGMo)ekKzip(}OZP=(4 z>e*3-a@ZyI?f2$irwA{Njeh=<)njxsk1}cLXPbkRV|goMxKI0!UZhT#p_#+bo@LL& zk4?Meeg(B|mrkXy^`NqW7$+-Qz4W&Kq1%F@!z&lAbJkQAF{OxV8z&+Z8)0}=%yoXv z{`%s5Psq+r>0k9(Z_Bp<9ydhyv4L;{io}VGSVwKIqDUFsNvvWXNaXf^8OIUC69)qwE>u(C%hyj4a1LER^T%pU=X% ze1GI8@)oc7))_?MML_fD)*!>!K3@9Rvm-WCFAfcUBUOtEpkI_ha5Uz}DI+i+iW1|P z3mRK^*vjot=UuhyY)`_h$sY@T#`4TsJ5)MkzJumTLwlu{W}G~uWd$C7JVE7J;TNy3 z(x}`Qtxs&8M;IJ*SP=R0GdorNSVM#u!P9;+PnlGtzZ_Hgdor-s7#iqh42&mESm$ms z;vLzq`Vvy|=oWwOB`WK+dw%%_P2}J(j=|kFn{xH>CG7!a#YE+Z0E1g(Z=BH1-)i$| zS+LDh-2lca&mrf^g|$MebHQlps;S&$KCN&#bG4giNaGQ)%==42UR^5Gqkt&^sM{+% z-VYNUk#k1w4WNk}oj)Ggkf=06cKylFzSGT5sn*oe_kJxBn+XB~go%x4_`9PDrj2;i z7u3`D@DoC-jDXAS`iHLC?3b@eq?)(vH+|54f+hD4XfK?IQgJfb_{iD3?Wxbl>-sv0 zhEBz5(Ffe>t<30p2&ZQQC)zHQo%J&>%fJo@vkoWa;dE&{RbRt{M$9Xx_F;2i`!PM4 zlVRPE|D#!dI}#&Mo^LC$9FZO|HFVO#7j8hQ;PmmOy{EG!12@Nqy>%nvrc?VUbcz!_p!f0=AaK zEYv_60xF9KR*mLZ0ueXGVBfG$lSz_r{*9|4Uq~S(1{y9M0Kz*OJcXg zDoJyk%v5;>G%ZRbgD9t1siZa4G++Tl? z_j{2LJt{iASK_=ZUoXgBtvPD*v3;j02UzLn>tw0Xmp3(8f^R3{J_HjeH7L4*R+w^_ zAlOyPx-fu(>wM z)+KwL8>rz?8cQQ_><|5F3w403gAA*mo;~5}P%qFrJ{puQJXAlbL{yIbFS*c==xr4z zKL?&XZ~(A#sj)3@hSDLGZMFB+7MH02Me`sCY@_p~{EwU+1`{C=ULSptCXqR@+94yY+AcN&0i-WN9? zYEdM*?0#BFy@BiI>7Tx)y7k`g9Xl>g>YMC{-IgBA6_wTnjj7((y7V5@ERcKBQ-R@% XOC!tGgCm#zUcRKzYGsljV8j0bh7LU* literal 0 HcmV?d00001 diff --git a/contrib/ftos2/ifi/32fddef.h b/contrib/ftos2/ifi/32fddef.h new file mode 100644 index 0000000..73ae565 --- /dev/null +++ b/contrib/ftos2/ifi/32fddef.h @@ -0,0 +1,53 @@ +/*********************************************************************\ +* Module Name: 32FDDEF.H +* +* OS/2 Intelligent Font Interface +* +* Copyright (c) 1989,1994 IBM Corporation +* Copyright (c) 1989 Microsoft Corporation +* +\*********************************************************************/ +#ifndef __32FDDEF_H__ +#define __32FDDEF_H__ + +/* Typedef the Font Driver 32 Bit entry points */ + +/* FdLoadFontFile */ +typedef HFF (* _syscall PFDLFF)(PSZ pszFileName); + +/* FdQueryFaces */ +typedef LONG (* _syscall PFDQF)(HFF hff, PIFIMETRICS pifim, + ULONG cMetricLen, ULONG cFontCount, + ULONG cStart); +/* FdConvertFontFile */ +typedef LONG (* _syscall PFDCFF)(PSZ pszSrc, PSZ pszDestDir, + PSZ pszName); + +/* FdClaimFontFile */ +typedef LONG (* _syscall PFDCLF)(PSZ pszFileName); + +/* FdUnloadFontFile */ +typedef LONG (* _syscall PFDUFF)(HFF hff); + +/* FdOpenFontContext */ +typedef HFC (* _syscall PFDOFC)(HFF hff, ULONG ulFont); + +/* FdSetFontContext */ +typedef LONG (* _syscall PFDSFC)(HFC hfc, PCONTEXTINFO pci); + +/* FdCloseFontContext */ +typedef LONG (* _syscall PFDCFC)(HFC hfc); + +/* FdQueryFaceAttr */ +typedef LONG (* _syscall PFDQFA)(HFC hfc, ULONG iQuery, PBYTE pBuffer, + ULONG cb, PGLYPH pagi, GLYPH gistart); + +/* FdQueryCharAttr */ +typedef LONG (* _syscall PFDQCA)(HFC hfc, PCHARATTR pCharAttr, + PBITMAPMETRICS pbmm); + +/* FdQueryFullFaces */ +typedef LONG (* _syscall PFDQFF)(HFF hff, PVOID pBuf, PULONG cBufLen, + PULONG cFontCount, ULONG cStart); +#endif + diff --git a/contrib/ftos2/ifi/32fdstrc.h b/contrib/ftos2/ifi/32fdstrc.h new file mode 100644 index 0000000..0db1d72 --- /dev/null +++ b/contrib/ftos2/ifi/32fdstrc.h @@ -0,0 +1,161 @@ +/*********************************************************************\ +* Module Name: 32FDSTRC.H +* +* OS/2 Intelligent Font Interface +* +* Copyright (c) 1989,1994 IBM Corporation +* Copyright (c) 1989 Microsoft Corporation +* +\*********************************************************************/ +#ifndef __32FDSTRC_H__ +#define __32FDSTRC_H__ + +#define FACESIZE 32 +#define GLYPHNAMESIZE 16 + +/* Error codes defined to be returned by IFI */ +/* NOTE: The actual values are subject to change */ + +/*#define PMERR_BUFFER_TOO_SMALL 23003L*/ +#define PMERR_FACENAME_NOT_FOUND 23004L +#define PMERR_FD_ALREADY_INSTALLED 23005L +#define PMERR_INVALID_CONTEXTINFO 23006L +#define PMERR_NOT_A_FONT_FILE 23007L +#define PMERR_INVALID_FONT_SELECTION 23008L +#define PMERR_INVALID_FORMAT 23009L +#define PMERR_BUSY_HFC 230010L +#define PMERR_INVALID_HFC 230011L +#define PMERR_INVALID_INDEX 230012L +#define PMERR_INVALID_QUERY_TYPE 230013L +#define PMERR_CONTEXT_NOT_SET 230014L + +/* Query faces subfunction */ +#define FD_QUERY_CONTEXTMETRICS 1L +#define FD_QUERY_ABC_WIDTHS 2L +#define FD_QUERY_KERNINGPAIRS 3L + +/* Query char subfunction */ +#define FD_QUERY_CHARIMAGE 1L +#define FD_QUERY_OUTLINE 2L +#define FD_QUERY_BITMAPMETRICS 4L + +#define FD_CHARATTR_ALIGNED_8 0x00000001 +#define FD_CHARATTR_ALIGNED_16 0x00000002 +#define FD_CHARATTR_ALIGNED_32 0x00000004 +#define FD_CHARATTR_NO_CACHE 0x00000010 + +typedef struct _ABC_TRIPLETS /*abc*/ +{ + LONG lA; + ULONG ulB; + LONG lC; +} ABC_TRIPLETS; +typedef ABC_TRIPLETS *PABC_TRIPLETS; + +// THIS STRUCTURE NOW RESIDES IN PMDDI.H FOR CRUISER WORLD +// BUT IFI FONT DRIVER DOES NOT INCLUDE PMDDI.H + +#ifndef INCL_IFI +typedef struct _POINTFX { /* ptfx */ + FIXED x; + FIXED y; +} POINTFX; +typedef POINTFX *PPOINTFX; +#endif + +typedef struct _BITMAPMETRICS /* bmm */ +{ + SIZEL sizlExtent; + ULONG cyAscent; +#ifdef OLD_DRIVER + POINTFX *ppfxOrigin; /* Return character origin. */ +#else + POINTFX pfxOrigin; /* Return character origin. */ +#endif +} BITMAPMETRICS; +typedef BITMAPMETRICS *PBITMAPMETRICS; + +typedef struct _MAT2 /* mat */ +{ + FIXED eM11; + FIXED eM12; + FIXED eM21; + FIXED eM22; +} MAT2; + +typedef struct _FD_KERNINGPAIRS /* krnpr */ +{ + GLYPH giFirst; + GLYPH giSecond; + LONG eKerningAmount; +} FD_KERNINGPAIRS; + +typedef struct _CONTEXTINFO /* ci */ +{ + ULONG cb; /* Length in bytes of this structure. */ + ULONG fl; /* Flags. */ + SIZEL sizlPPM; /* Device resolution in pels/meter. */ + POINTFX pfxSpot; /* Spot size in pels. */ + MAT2 matXform; /* Notional to Device transform. */ +} CONTEXTINFO; +typedef CONTEXTINFO *PCONTEXTINFO; + +typedef struct _CHARATTR /* ca */ +{ + ULONG cb; + ULONG iQuery; /* Query type. */ + GLYPH gi; /* Glyph index in font. */ + PBYTE pBuffer; /* Bitmap buffer. */ + ULONG cbLen; /* Size of buffer in bytes. */ +} CHARATTR; +typedef CHARATTR *PCHARATTR; + +typedef struct _CHARATTR2 /* ca2 */ +{ + ULONG cb; + ULONG iQuery; /* Query type. */ + GLYPH gi; /* Glyph index in font. */ + PBYTE pBuffer; /* Bitmap buffer. */ + ULONG cbLen; /* Size of buffer in bytes. */ + ULONG fl; /* Flags */ +} CHARATTR2; +typedef CHARATTR2 *PCHARATTR2; + +typedef struct _CONTEXTMETRICS +{ + SIZEL sizlMax; + ULONG cyMaxAscent; + ULONG cyMaxDescent; + ULONG cxTotal; + ULONG cGlyphs; +} CONTEXTMETRICS; +typedef CONTEXTMETRICS * PCONTEXTMETRICS; + +typedef struct _POLYGONHEADER { + ULONG cb; + ULONG iType; /* Must be FD_POLYGON_TYPE */ +} POLYGONHEADER; +typedef POLYGONHEADER *PPOLYGONHEADER; + +typedef struct _PRIMLINE { + ULONG iType; /* Must be FD_PRIM_LINE */ + POINTFX pte; +} PRIMLINE; +typedef PRIMLINE *PPRIMLINE; + +typedef struct _PRIMSPLINE { + ULONG iType; /* Must be FD_PRIM_SPLINE */ + POINTFX pte[3]; +} PRIMSPLINE; +typedef PRIMSPLINE *PPRIMSPLINE; + +/* + * The names of these were changed to avoid conflict with PRIM_LINE + * which is defined ion some other header file. + */ +#define FD_POLYGON_TYPE 24 +#define FD_PRIM_LINE 1 +#define FD_PRIM_SPLINE 3 + +#endif + diff --git a/contrib/ftos2/ifi/32ifimet.h b/contrib/ftos2/ifi/32ifimet.h new file mode 100644 index 0000000..d965ce0 --- /dev/null +++ b/contrib/ftos2/ifi/32ifimet.h @@ -0,0 +1,118 @@ +/*********************************************************************\ +* Module Name: 32IFIMET.H +* +* OS/2 Intelligent Font Interface +* +* Copyright (c) 1989,1994 IBM Corporation +* Copyright (c) 1989 Microsoft Corporation +* +* Definition and description of IFIMETRICS structure +* This file is included by FDSTRUCS.H +* +\*********************************************************************/ +#ifndef __32IFIMET_H__ +#define __32IFIMET_H__ + +#define FACESIZE 32 +#define GLYPHNAMESIZE 16 + +/* #defines for fsType in IFIMETRICS */ + +#define IFIMETRICS_FIXED 0x0001 /*Fixed pitch */ +#define IFIMETRICS_LICENSED 0x0002 /*Font subject of licensing agreement */ +#define IFIMETRICS_KERNING 0x0004 /*Font has kerning data */ +#define IFIMETRICS_DBCS 0x0010 /*DBCS font */ +#define IFIMETRICS_MBCS 0x0018 /*MBCS (DBCS + SBCS) font */ +/* Reserved 0x8000 */ +#define IFIMETRICS_ATOMS 0x4000 /*The atom name fields are valid */ +#define IFIMETRICS_FAMTRUNC 0x2000 /*Familyname field is truncated */ +#define IFIMETRICS_FACETRUNC 0x1000 /*Facename field is truncated */ +#define IFIMETRICS_ANTIALIASED 0x0020 +#define IFIMETRICS_UNICODE 0x0040 +#define IFIMETRICS_NO_CACHE 0x0080 + +/* #defines for fsDefn in IFIMETRICS */ + +#define IFIMETRICS_OUTLINE 0x0001 /*1 - Outline. 0 - Raster */ +/* Reserved 0x0002 */ +/* Reserved 0x0004 */ +/* Reserved 0x8000 */ +#define IFIMETRICS_UDC_FONT 0x0010 /*User defined font */ +/* Reserved */ + +/* #defines for fsSelection in IFIMETRICS valid for bitmap or outline fonts */ + +#define IFIMETRICS_ITALIC 0x8000 /*Italic */ +#define IFIMETRICS_UNDERSCORE 0x4000 /*Underscored */ +#define IFIMETRICS_OVERSTRUCK 0x2000 /*Overstruck */ + +/* #defines for fsSelection in IFIMETRICS valid for bitmap fonts */ + +#define IFIMETRICS_NEGATIVE 0x1000 /*Negative image */ +#define IFIMETRICS_HOLLOW 0x0800 /*Outline (hollow) */ + +#if defined(__IBMCPP__) || defined(__IBMC__) + #pragma pack(1) +#else + #pragma Align_members(1) +#endif + +typedef struct _IFIMETRICS /* ifim */ +{ /* UNITS */ + UCHAR szFamilyname[FACESIZE]; /*Font Family Name, e.g. Roman */ + UCHAR szFacename[FACESIZE]; /*Face name, e.g. Tms Rmn Bold Italic */ + UCHAR szGlyphlistName[GLYPHNAMESIZE]; /*e.g. PM316, Latin-2, Greek */ + USHORT idRegistry; /*IBM registration number (or zero). I */ + LONG lCapEmHeight; /*Height of uppercase M N */ + LONG lXHeight; /*Nominal height of lowercase N */ + LONG lMaxAscender; /*Maximum height above baseline of any char N */ + LONG lMaxDescender; /*Maximum depth below baseline of any char N */ + LONG lLowerCaseAscent; /*Maximum height above baseline of any a-z N */ + LONG lLowerCaseDescent; /*Maximum depth below basiline of any a-z N */ + LONG lInternalLeading; /*White space within character N */ + LONG lExternalLeading; /*White space between lines N */ + LONG lAveCharWidth; /*Weighted average character width N */ + LONG lMaxCharInc; /*Maximum character increment N */ + LONG lEmInc; /*Increment for Capitals (typically 'M') N */ + LONG lMaxBaselineExt; /*Height of character cell N */ + FIXED fxCharSlope; /*Slope angle, degrees, clockwise D */ + FIXED fxInlineDir; /*Drawing direction, degrees clockwise D */ + FIXED fxCharRot; /*Glyph rotation in cell, degrees clockwise D */ + USHORT usWeightClass; /*Character weight, 1-9 (1=ultra-light) I */ + USHORT usWidthClass; /*Character width, 1-9 (1=ultra condensed) I */ + LONG lEmSquareSizeX; /*Em Square size, x-direction N */ + LONG lEmSquareSizeY; /*Em Square size, y-direction N */ + GLYPH giFirstChar; /*Number of first glyph in font I */ + GLYPH giLastChar; /*Number of last glyph in font I */ + GLYPH giDefaultChar; /*Glyph used if requested glyph invalid I */ + GLYPH giBreakChar; /*Space glyph I */ + USHORT usNominalPointSize; /*Point size for which font was designed N */ + USHORT usMinimumPointSize; /*Minimum point size scaling for font N */ + USHORT usMaximumPointSize; /*Maximum point size scaling for font N */ + USHORT fsType; /*Type indicators (see #defines) B */ + USHORT fsDefn; /*Font definition data (see #defines) B */ + USHORT fsSelection; /*Font selection flags (see #defines) B */ + USHORT fsCapabilities; /*Font capabilities must be 0 B */ + LONG lSubscriptXSize; /*Size in x-direction of subscript N */ + LONG lSubscriptYSize; /*Size in y-direction of subscript N */ + LONG lSubscriptXOffset; /*Offset in x-direction of subscript N */ + LONG lSubscriptYOffset; /*Offset in y-direction of subscript N */ + LONG lSuperscriptXSize; /*Size in x-direction of superscript N */ + LONG lSuperscriptYSize; /*Size in y-direction of superscript N */ + LONG lSuperscriptXOffset; /*Offset in x-direction of superscript N */ + LONG lSuperscriptYOffset; /*Offset in y-direction of superscript N */ + LONG lUnderscoreSize; /*Underscore size N */ + LONG lUnderscorePosition; /*Underscore position N */ + LONG lStrikeoutSize; /*Strikeout size N */ + LONG lStrikeoutPosition; /*Strikeout position N */ + SHORT cKerningPairs; /*Number of kerning pairs in pair table I */ + ULONG ulFontClass; /*IBM font classification B */ +} IFIMETRICS; +typedef IFIMETRICS FAR *PIFIMETRICS; +#if defined(__IBMCPP__) || defined(__IBMC__) + #pragma pack() +#else + #pragma Align_members() +#endif + +#endif diff --git a/contrib/ftos2/ifi/32pmifi.h b/contrib/ftos2/ifi/32pmifi.h new file mode 100644 index 0000000..e0bdb89 --- /dev/null +++ b/contrib/ftos2/ifi/32pmifi.h @@ -0,0 +1,79 @@ +/*********************************************************************\ +* Module Name: 32PMIFI.H +* +* OS/2 Intelligent Font Interface +* +* Copyright (c) 1989,1994 IBM Corporation +* Copyright (c) 1989 Microsoft Corporation +* +\*********************************************************************/ +#ifndef __32PMIFI_H__ +#define __32PMIFI_H__ + +#define INCL_IFD + +typedef PVOID HFF; /* Font file handle */ +typedef PVOID HFC; /* Font context handle */ + +#ifndef INCL_GRE_FONTS +typedef ULONG GLYPH; /* gi */ +typedef ULONG *PGLYPH; /* pgi */ +#endif + +#include "32fdstrc.h" /* Font Driver structures */ +#include "32ifimet.h" /* Pifi Metrics */ +#include "32fddef.h" /* Font Driver entry definitions */ + + +typedef struct _FDDISPATCH16 { /* fdisp */ + PVOID FdLoadFontFile; + PVOID FdQueryFaces; + PVOID FdUnloadFontFile; + PVOID FdOpenFontContext; + PVOID FdSetFontContext; + PVOID FdCloseFontContext; + PVOID FdQueryFaceAttr; + PVOID FdQueryCharAttr; + PVOID FdClaimFontFile; + PVOID FdConvertFontFile; +} FDDISPATCH16; +typedef FDDISPATCH16 FAR *PFDDISPATCH16; + + +typedef struct _FDDISPATCH { /* fdisp */ + PFDLFF FdLoadFontFile; + PFDQF FdQueryFaces; + PFDUFF FdUnloadFontFile; + PFDOFC FdOpenFontContext; + PFDSFC FdSetFontContext; + PFDCFC FdCloseFontContext; + PFDQFA FdQueryFaceAttr; + PFDQCA FdQueryCharAttr; + PFDCLF FdClaimFontFile; + PFDCFF FdConvertFontFile; + PFDQFF FdQueryFullFaces; +} FDDISPATCH; +typedef FDDISPATCH *PFDDISPATCH; + +typedef struct _FDHEADER { /* fdhdr */ + ULONG cbLength; /* Length of FDHEADER */ + UCHAR strId[16]; /* String 'OS/2 FONT DRIVER' */ + UCHAR szTechnology[40]; /* Identifier of Font Driver technology */ + ULONG ulVersion; /* IFI version number (0x0100) */ + ULONG ufDeviceCaps; /* Capabilities of device */ + PFDDISPATCH pfddisp; +} FDHEADER; + +typedef FDHEADER FAR *PFDHEADER; + +#define OK 0 +#define ERROR -1 + +#define IFI_VERSION 10 +#define IFI_VERSION20 20 +#define IFI_VERSION21 21 + +#define FD_DISPATCH_COUNT 11 +#define DISPATCHTABLE "FONT_DRIVER_DISPATCH_TABLE" + +#endif diff --git a/contrib/ftos2/ifi/FreeType.def b/contrib/ftos2/ifi/FreeType.def new file mode 100644 index 0000000..a9e06b2 --- /dev/null +++ b/contrib/ftos2/ifi/FreeType.def @@ -0,0 +1,10 @@ +;LIBRARY FreeType INITGLOBAL TERMGLOBAL +LIBRARY FreeType INITINSTANCE TERMINSTANCE + +PROTMODE + +DATA SINGLE SHARED READWRITE LOADONCALL +;DATA MULTIPLE NONSHARED READWRITE LOADONCALL +CODE LOADONCALL + +DESCRIPTION "FreeType/2, Copyright (C) 1998 Michal Necasek" diff --git a/contrib/ftos2/ifi/FreeType.icc b/contrib/ftos2/ifi/FreeType.icc new file mode 100644 index 0000000..1c9d230 --- /dev/null +++ b/contrib/ftos2/ifi/FreeType.icc @@ -0,0 +1,35 @@ +# Makefile for FTIFI using IBM VisualAge C++ +# +# Explanation of compiler switches used: +# -C compile only, do not link +# -Sp1 pack structures on byte boundaries (quite important) +# -Ss accept double slash (//) comments +# -Ge- build a DLL +# -Rn build a subsystem DLL; means that a special C library is +# linked and some calls cannot be used +# -Fo create object file +# -O+ optimizations on +# -G4 optimize for 486 (should be better for my 6x86MX, produces smaller +# code than Pentium optimization) +# Linker switches used: +# /DE include debug info in executable +# /NOE no extended dictionary search +# /E:2 exepack (for Warp 3 and higher) +# /A:32 align pages of code on 32-byte boundaries (makes smaller file) +# /DBGPACK pack debug info + +# uncomment ICCR and LNKR to build a release version +ICCR=-O+ -G4 +LNKR=/PACKC /PACKD /M /A:32 /E:2 +# uncomment ICCD and LNKD to build a debug version. Note that debug and +# release version is not mutually exclusive in this case. +#ICCD=-Ti+ -DDEBUG +#ICCD=-Ti+ +#LNKD=/DE /DBGPACK /M + + +FreeType.dll: $*.obj $*.def ..\lib\libttf.lib + ilink /NOE $(LNKD) $(LNKR) $*.obj ..\lib\libttf.lib libconv.lib $*.def + +FreeType.obj: ftifi.c ftifi.h FreeType.icc + icc $(ICCD) $(ICCR) -C -Sp1 -Ss -Ge- -Rn -FoFreeType -I..\lib -I..\lib\extend -I..\lib\arch\os2 ftifi.c diff --git a/contrib/ftos2/ifi/FreeType.wat b/contrib/ftos2/ifi/FreeType.wat new file mode 100644 index 0000000..ecb1a6c --- /dev/null +++ b/contrib/ftos2/ifi/FreeType.wat @@ -0,0 +1,29 @@ +# WARNING!! this doesn't quite work yet!!!! +# +# Makefile for FTIFI using Watcom C/C++ +# +# Explanation of compiler switches used: +# -4r register calling convention, generate 486 code. Better than +# Pentium opt. for Cyrix/IBM and AMD +# -otexan maximum optimization for speed +# -zp1 pack structures on byte boundaries (quite important!) +# -bd build a DLL +# -zc +# -d2 include debug info +# +# Important linker options used: +# initglobal call DLL initialization function only once (not for each +# process) +# termglobal call DLL termination function only once +# oneautodata use only one shared data segment + +WCCR=-4r -otexan +#WCCD=-d2 -DDEBUG +#LNKD=debug all + + +FreeType.dll: $*.obj $*.def + wlink system os2v2 dll initglobal termglobal op oneautodata export GetOutline_ export FONT_DRIVER_DISPATCH_TABLE=_fdhdr file $* lib ..\lib\libttf.lib $(LNKD) + +FreeType.obj: ftifi.c ftifi.h + wcc386 $(WCCD) $(WCCR) -zp1 -bd -zc -I..\lib -I..\lib\extend ftifi.c /Fo=freetype.obj diff --git a/contrib/ftos2/ifi/ftifi.c b/contrib/ftos2/ifi/ftifi.c new file mode 100644 index 0000000..9cb6721 --- /dev/null +++ b/contrib/ftos2/ifi/ftifi.c @@ -0,0 +1,3209 @@ +/* */ +/* OS/2 Font Driver using the FreeType library */ +/* */ +/* Copyright (C) 1997, 1998 Michal Necasek */ +/* Copyright (C) 1997, 1998 David Turner */ +/* Copyright (C) 1997, 1998 International Business Machines */ +/* */ +/* Version: 0.9.90 (Beta) */ +/* */ +/* This source is to be compiled with IBM VisualAge C++ 3.0 or possibly */ +/* Watcom C/C++ 10.0 or higher (Wactom doesn't quite work yet). */ +/* Other compilers may actually work too but don't forget this is NOT a */ +/* normal DLL but rather a subsystem DLL. That means it shouldn't use */ +/* the usual C library as it has to run without runtime environment. */ +/* VisualAge provides a special subsystem version of the run-time library. */ +/* All this is of course very compiler-dependent. See makefiles for */ +/* discussion of switches used. */ +/* */ +/* Implemantation Notes: */ +/* */ +/* Note #1: As a consequence of this being a subsystem librarary, I had to */ +/* slightly modify the FreeType source, namely ttmemory.c and ttfile.c. */ +/* FreeType/2 now allocates several chunks of memory and uses them as a */ +/* heap. Note that memory allocation should use TTAlloc(), possibly */ +/* directly SSAllocMem(). malloc() is unusable here and it doesn't work */ +/* at all (runtime library isn't even initialized). See ttmemory.c for */ +/* more info. */ +/* In ttfile.c I had to change all fopen(), fseek()... calls */ +/* to OS/2 API calls (DosOpen, DosSetFilePtr...) because without proper */ +/* runtime environment a subsystem DLL cannot use std C library calls. */ +/* */ +/* Note #2: On exit of each function reading from font file the API */ +/* TT_Flush_Stream() must be called. This is because file handles opened */ +/* by this DLL actually belong to the calling process. As a consequence */ +/* a) it's easy to run out of file handles, which results in really */ +/* very nasty behavior and/or crashes. This could be solved by */ +/* increased file handles limit, but cannot because */ +/* b) it is impossible to close files open by another process and */ +/* therefore the fonts cannot be properly uninstalled (you can't */ +/* delete them while the're open by other process) */ +/* The only solution I found is very simple - just close the file before */ +/* exiting a DLL function. This ensures files are not left open across */ +/* processes and other problems. */ +/* */ +/* Note #3: The whole business with linked lists is aimed at lowering */ +/* memory consumption drastically. If you install 50 TT fonts, OS/2 */ +/* opens all of them at startup. Even if you never use them, they take */ +/* up at least over 1 Meg memory. With certain fonts the consumption can */ +/* easily go over several MB. We limit such waste of memory by only */ +/* actually keeping open several typefaces most recently used. Their */ +/* number can be set via entry in OS2.INI. */ +/* */ +/* For Intelligent Font Interface (IFI) specification please see IFI32.TXT */ + +#ifndef __IBMC__ + #ifndef __WATCOMC__ + #error "This source requires IBM VisualAge C++ or Watcom C/C++" + #endif +#endif + +/* Defining the following uses UCONV.DLL instead of the built-in */ +/* translation tables. This code should work on any Warp 4 and */ +/* Warp 3 w/ FixPak 35(?) and above */ +/* Note: this should be defined before FTIFI.H is #included */ +#undef USE_UCONV + +#define INCL_WINSHELLDATA /* for accessing OS2.INI */ +#define INCL_DOSMISC +#define INCL_DOSNLS +#define INCL_DOSPROCESS +#define INCL_GRE_DCS +#define INCL_GRE_DEVSUPPORT +#define INCL_DDIMISC +#define INCL_IFI +#include +#include /* SSAllocmem(), SSFreemem() and more */ + +#ifdef USE_UCONV /* uconv.h isn't always available */ +#include +#endif /* USE_UCONV */ + +#include +#include /* min and max macros */ + +#define _syscall _System /* the IFI headers don't compile without it */ + +#include "32pmifi.h" /* IFI header */ +#include "freetype.h" /* FreeType header */ +#include "ftxkern.h" /* kerning extension */ +#include "ftxwidth.h" /* glyph width extension */ +#include "ftifi.h" /* xlate table */ + + +/* For the sake of Netscape's text rendering bugs ! */ +#define NETSCAPE_FIX + +/* Create 'fake' Roman face for Times New Roman (to mimic PMATM's */ +/* behaviour */ +#define FAKE_TNR + +/* (indirectly) exported functions */ +LONG _System ConvertFontFile(PSZ pszSrc, PSZ pszDestDir, PSZ pszNewName); +HFF _System LoadFontFile(PSZ pszFileName); +LONG _System UnloadFontFile(HFF hff); +LONG _System QueryFaces(HFF hff, PIFIMETRICS pifiMetrics, ULONG cMetricLen, + ULONG cFountCount, ULONG cStart); +HFC _System OpenFontContext(HFF hff, ULONG ulFont); +LONG _System SetFontContext(HFC hfc, PCONTEXTINFO pci); +LONG _System CloseFontContext(HFC hfc); +LONG _System QueryFaceAttr(HFC hfc, ULONG iQuery, PBYTE pBuffer, + ULONG cb, PGLYPH pagi, GLYPH giStart); +LONG _System QueryCharAttr(HFC hfc, PCHARATTR pCharAttr, + PBITMAPMETRICS pbmm); +LONG _System QueryFullFaces(HFF hff, PVOID pBuff, PULONG buflen, + PULONG cFontCount, ULONG cStart); + +FDDISPATCH fdisp = { /* Font driver dispatch table */ + LoadFontFile, + QueryFaces, + UnloadFontFile, + OpenFontContext, + SetFontContext, + CloseFontContext, + QueryFaceAttr, + QueryCharAttr, + NULL, /* this one is no more used, only the spec fails to mention it */ + ConvertFontFile, + QueryFullFaces +}; + + + +/****************************************************************************/ +/* the single exported entry point; this way is faster than exporting every */ +/* single function and a bit more flexible */ +/* */ +#pragma export (fdhdr, "FONT_DRIVER_DISPATCH_TABLE", 1) +FDHEADER fdhdr = +{ /* Font driver Header */ + sizeof(FDHEADER), + "OS/2 FONT DRIVER", /* do not change */ + "TrueType (Using FreeType Engine)", /* description up to 40 chars */ + IFI_VERSION20, /* version */ + 0, /* reserved */ + &fdisp +}; + + +/****************************************************************************/ +/* some debug macros and functions. the debug version logs system requests */ +/* to the file C:\FTIFI.LOG */ +/* */ +#ifdef DEBUG + HFILE LogHandle = NULLHANDLE; + ULONG Written = 0; + char log[2048] = ""; + char buf[2048] = ""; + + +char* itoa10( int i, char* buffer ) { + char* ptr = buffer; + char* rptr = buffer; + char digit; + + if (i == 0) { + buffer[0] = '0'; + buffer[1] = 0; + return buffer; + } + + if (i < 0) { + *ptr = '-'; + ptr++; rptr++; + i = -i; + } + + while (i != 0) { + *ptr = (char) (i % 10 + '0'); + ptr++; + i /= 10; + } + + *ptr = 0; ptr--; + + while (ptr > rptr) { + digit = *ptr; + *ptr = *rptr; + *rptr = digit; + ptr--; + rptr++; + } + + return buffer; +} + + #define COPY(s) strcpy(log, s) + #define CAT(s) strcat(log, s) + #define CATI(v) strcat(log, itoa10( (int)v, buf )) + #define WRITE DosWrite(LogHandle, log, strlen(log), &Written) + + #define ERET1(label) { COPY("Error at "); \ + CATI(__LINE__); \ + CAT("\r\n"); \ + WRITE; \ + goto label; \ + } + + #define ERRRET(e) { COPY("Error at "); \ + CATI(__LINE__); \ + CAT("\r\n"); \ + WRITE; \ + return(e); \ + } + + +#else + + #define COPY(s) + #define CAT(s) + #define CATI(v) + #define WRITE + + #define ERET1(label) goto label; + + #define ERRRET(e) return(e); + +#endif /* DEBUG */ + + +/****************************************************************************/ +/* */ +/* 'engine' : */ +/* */ +/* The FreeType engine instance. Although this is a DLL, it isn't */ +/* supposed to be shared by apps, as it is only called by the OS/2 GRE. */ +/* This means that there is no need to bother with reentrancy/thread */ +/* safety, which aren't supported by FreeType 1.0 anyway. */ +/* */ +TT_Engine engine; + +/****************************************************************************/ +/* */ +/* TList and TListElement : */ +/* */ +/* simple structures used to implement a doubly linked list. Lists are */ +/* used to implement the HFF object lists, as well as the font size and */ +/* outline caches. */ +/* */ + +typedef struct _TListElement TListElement, *PListElement; + +struct _TListElement +{ + PListElement next; /* next element in list - NULL if tail */ + PListElement prev; /* previous element in list - NULL if head */ + long key; /* value used for searches */ + void* data; /* pointer to the listed/cached object */ +}; + +typedef struct _TList TList, *PList; +struct _TList +{ + PListElement head; /* first element in list - NULL if empty */ + PListElement tail; /* last element in list - NULL if empty */ + int count; /* number of elements in list */ +}; + +static PListElement free_elements = 0; + +#if 0 +/****************************************************************************/ +/* */ +/* TGlyph_Image : */ +/* */ +/* structure used to store a glyph's attributes, i.e. outlines and metrics */ +/* Note that we do not cache bitmaps ourselves for the moment. */ +/* */ +typedef struct _TGlyph_Image TGlyph_Image, *PGlyph_Image; + +struct _TGlyph_Image +{ + PListElement element; /* list element for this glyph image */ + TT_Glyph_Metrics metrics; + TT_Outline outline; +}; +#endif + + +/****************************************************************************/ +/* */ +/* TFontFace : */ +/* */ +/* a structure related to an open font face. It contains data for each of */ +/* possibly several faces in a .TTC file. */ + +typedef struct _TFontFace TFontFace, *PFontFace; + +struct _TFontFace +{ + TT_Face face; /* handle to actual FreeType face object */ + TT_Glyph glyph; /* handle to FreeType glyph container */ + TT_CharMap charMap; /* handle to FreeType character map */ + TT_Kerning directory; /* kerning directory */ + USHORT *widths; /* glyph width cache for large fonts */ + USHORT *kernIndices; /* reverse translation cache for kerning */ + LONG em_size; /* points per em square */ + ULONG flags; /* various FC_* flags (like FC_FLAG_FIXED)*/ +#if 0 /* not now */ + TList sizes; /* list of live child font sizes */ +#endif + LONG charMode; /* character translation mode : */ + /* 0 = Unicode to UGL */ + /* 1 = Symbol (no translation) */ + /* 2 = Unicode w/o translation */ +}; + + +/****************************************************************************/ +/* */ +/* TFontFile : */ +/* */ +/* a structure related to an open font file handle. All TFontFiles are */ +/* kept in a simple linked list. There can be several faces in one font. */ +/* Face(s) information is stored in a variable-length array of TFontFaces. */ +/* A single TFontFile structure exactly corresponds to one HFF. */ + +typedef struct _TFontFile TFontFile, *PFontFile; + +struct _TFontFile +{ + PListElement element; /* list element for this font face */ + HFF hff; /* HFF handle used from outside */ + CHAR filename[260]; /* font file name */ + LONG ref_count; /* number of times this font file is open */ + ULONG flags; /* various FL_* flags */ + ULONG numFaces; /* number of faces in a file (normally 1) */ + TFontFace *faces; /* array of FontFace structures */ +}; + + +/* Flag : The font face has a fixed pitch width */ +#define FC_FLAG_FIXED_WIDTH 1 + +/* Flag : Effectively duplicated FL_FLAG_DBCS_FILE. This info is */ +/* kept twice for simplified access */ +#define FC_FLAG_DBCS_FACE 2 + +/* Flag : This face is an alias */ +#define FL_FLAG_FAKE_ROMAN 8 + +/* Flag : The font file has a live FreeType face object */ +#define FL_FLAG_LIVE_FACE 16 + +/* Flag : A font file's face has a context open - DON'T CLOSE IT! */ +#define FL_FLAG_CONTEXT_OPEN 32 + +/* Flag : This file has been already opened previously*/ +#define FL_FLAG_ALREADY_USED 64 + +/* Flag : This is a font including DBCS characters; this also means */ +/* the font driver presents to the system a second, vertically */ +/* rendered, version of this typeface with name prepended by */ +/* an '@' (used in horizontal-only word processors) */ +/* Note : For TTCs, the whole collection is either DBCS or not. I've */ +/* no idea if there are any TTCs with both DBCS and non-DBCS */ +/* faces. It's possible, but sounds unlikely. */ +#define FL_FLAG_DBCS_FILE 128 + +/* Note, we'll only keep the first max_open_files files with opened */ +/* FreeType objects/instances.. */ +int max_open_files = 10; + +/* number of processes using the font driver; used by the init/term */ +/* routine */ +ULONG ulProcessCount = 0; + +/* the list of live faces */ +static TList liveFiles = { NULL, NULL, 0 }; + +/* the list of sleeping faces */ +static TList idleFiles = { NULL, NULL, 0 }; + +/****************************************************************************/ +/* */ +/* TFontSize : */ +/* */ +/* a structure related to a opened font context (a.k.a. instance or */ +/* transform/pointsize). It exactly corresponds to a HFC. */ +/* */ + +typedef struct _TFontSize TFontSize, *PFontSize; + +struct _TFontSize +{ + PListElement element; /* List element for this font size */ + HFC hfc; /* HFC handle used from outside */ + TT_Instance instance; /* handle to FreeType instance */ + BOOL transformed; /* TRUE = rotation/shearing used (rare) */ + BOOL vertical; /* TRUE = vertically rendered DBCS face */ + TT_Matrix matrix; /* transformation matrix */ + PFontFile file; /* HFF this context belongs to */ + ULONG faceIndex; /* index of face in a font (for TTCs) */ +/* TList outlines;*/ /* outlines cache list */ +}; + +/****************************************************************************/ +/* array of font context handles. Note that there isn't more than one font */ +/* context open at any time anyway, but we want to be safe.. */ +/* */ +#define MAX_CONTEXTS 5 + +static TFontSize contexts[MAX_CONTEXTS]; /* this is rather too much */ + + +/****************************************************************************/ +/* few globals used for NLS */ +/* */ +/* Note: most of the internationalization (I18N) code was kindly provided */ +/* by Ken Borgendale and Marc L Cohen from IBM (big thanks!). I also */ +/* received help from Tetsuro Nishimura from IBM Japan. */ +/* I was also unable to test the I18N code on actual Japanese, Chinese... */ +/* etc. systems. But it might work. */ +/* */ + +static ULONG ScriptTag = -1; +static ULONG LangSysTag = -1; +static ULONG iLangId = TT_MS_LANGID_ENGLISH_UNITED_STATES; /* language ID */ +static ULONG uLastGlyph = 255; /* last glyph for language */ +static PSZ pGlyphlistName = "SYMBOL"; /* PM383, PMJPN, PMKOR.... */ +static BOOL isGBK = TRUE; /* only used for Chinese */ +static ULONG ulCp[2] = {1}; /* codepages used */ +static UCHAR DBCSLead[12]; /* DBCS lead byte table */ + +/* rather simple-minded test to decide if given glyph index is a 'halfchar',*/ +/* i.e. Latin character in a DBCS font which is _not_ to be rotated */ +#define is_HALFCHAR(_x) ((_x) < 0x0400) + + +/****************************************************************************/ +/* */ +/* interfaceSEId: */ +/* */ +/* interfaceSEId (Interface-specific Encoding Id) determines what encoding */ +/* the font driver should use if a font includes a Unicode encoding. */ +/* */ +LONG interfaceSEId(TT_Face face, BOOL UDCflag, LONG encoding); + +/****************************************************************************/ +/* */ +/* LookUpName : */ +/* */ +/* this function tries to find M$ English name for a face */ +/* length is limited to FACESIZE (defined by OS/2); returns NULL if */ +/* unsuccessful. warning: the string gets overwritten on the next */ +/* invocation */ +/* */ +/* TODO: needs enhancing for I18N */ +static char* LookupName(TT_Face face, int index ); + + +/****************************************************************************/ +/* */ +/* GetCharMap : */ +/* */ +/* get suitable charmap from font */ +/* */ +static ULONG GetCharmap(TT_Face face); + + +/****************************************************************************/ +/* */ +/* GetOutlineLen : */ +/* */ +/* get # of bytes needed for glyph outline */ +/* */ +static int GetOutlineLen(TT_Outline *ol); + + +/****************************************************************************/ +/* */ +/* GetOutline : */ +/* */ +/* get glyph outline in PM format */ +/* */ +static int GetOutline(TT_Outline *ol, PBYTE pb); + + + +/****************************************************************************/ +/* */ +/* IsDBCSChar : */ +/* */ +/* Returns TRUE if character is first byte of a DBCS char, FALSE otherwise */ +/* */ +BOOL IsDBCSChar(UCHAR c) +{ + ULONG i; + + for (i = 0; DBCSLead[i] && DBCSLead[i+1]; i += 2) + if ((c >= DBCSLead[i]) && (c <= DBCSLead[i+1])) + return TRUE; + return FALSE; +} + + +/****************************************************************************/ +/* */ +/* TT_Alloc & TT_Free : */ +/* */ +/* The following two functions are declared here because including */ +/* the entire ttmemory.h creates more problems than it solves */ +/* */ +TT_Error TT_Alloc( long Size, void** P ); +TT_Error TT_Free( void** P ); +TT_Error TTMemory_Init(void); + +static TT_Error error; + +#define ALLOC( p, size ) TT_Alloc( (size), (void**)&(p) ) +#define FREE( p ) TT_Free( (void**)&(p) ) + +/****************************************************************************/ +/* */ +/* New_Element : */ +/* */ +/* return a fresh list element. Either new or recycled. */ +/* returns NULL if out of memory. */ +/* */ +static PListElement New_Element( void ) +{ + PListElement e = free_elements; + + if (e) + free_elements = e->next; + else + { + if ( ALLOC( e, sizeof(TListElement) ) ) + return NULL; + } + e->next = e->prev = e->data = NULL; + e->key = 0; + + return e; +} + +/****************************************************************************/ +/* */ +/* Done_Element : */ +/* */ +/* recycles an old list element */ +/* */ +static void Done_Element( PListElement element ) +{ + element->next = free_elements; + free_elements = element; +} + +/****************************************************************************/ +/* */ +/* List_Insert : */ +/* */ +/* inserts a new object at the head of a given list */ +/* returns 0 in case of success, -1 otherwise. */ +/* */ +static int List_Insert( PList list, PListElement element ) +{ + if (!list || !element) + return -1; + + element->next = list->head; + + if (list->head) + list->head->prev = element; + + element->prev = NULL; + list->head = element; + + if (!list->tail) + list->tail = element; + + list->count++; + return 0; +} + +/****************************************************************************/ +/* */ +/* List_Remove : */ +/* */ +/* removes an element from its list. Returns 0 in case of success, */ +/* -1 otherwise. WARNING : this function doesn't check that the */ +/* element is part of the list. */ +/* */ +static int List_Remove( PList list, PListElement element ) +{ + if (!element) + return -1; + + if (element->prev) + element->prev->next = element->next; + else + list->head = element->next; + + if (element->next) + element->next->prev = element->prev; + else + list->tail = element->prev; + + element->next = element->prev = NULL; + list->count --; + return 0; +} + +/****************************************************************************/ +/* */ +/* List_Find : */ +/* */ +/* Look for a given object with a specified key. Returns NULL if the */ +/* list is empty, or the object wasn't found. */ +/* */ +static PListElement List_Find( PList list, long key ) +{ + static PListElement cur; + + for ( cur=list->head; cur; cur = cur->next ) + if ( cur->key == key ) + return cur; + + /* not found */ + return NULL; +} + +/****************************************************************************/ +/* */ +/* Sleep_FontFile : */ +/* */ +/* closes a font file's FreeType objects to leave room in memory. */ +/* */ +static int Sleep_FontFile( PFontFile cur_file ) +{ + int i; + + if (!(cur_file->flags & FL_FLAG_LIVE_FACE)) + ERRRET(-1); /* already asleep */ + + /* is this face in use? */ + if (cur_file->flags & FL_FLAG_CONTEXT_OPEN) { + /* move face to top of the list */ + if (List_Remove( &liveFiles, cur_file->element )) + ERRRET(-1); + if (List_Insert( &liveFiles, cur_file->element )) + ERRRET(-1); + + cur_file = (PFontFile)(liveFiles.tail->data); + } + + /* remove the face from the live list */ + if (List_Remove( &liveFiles, cur_file->element )) + ERRRET(-1); + + /* add it to the sleep list */ + if (List_Insert( &idleFiles, cur_file->element )) + ERRRET(-1); + + /* deactivate its objects - we ignore errors there */ + for (i = 0; i < cur_file->numFaces; i++) { + TT_Done_Glyph( cur_file->faces[i].glyph ); + TT_Close_Face( cur_file->faces[i].face ); + } + cur_file->flags &= ~FL_FLAG_LIVE_FACE; + + return 0; +} + +/****************************************************************************/ +/* */ +/* Wake_FontFile : */ +/* */ +/* awakes a font file, and reloads important data from disk. */ +/* */ +static int Wake_FontFile( PFontFile cur_file ) +{ + static TT_Face face; + static TT_Glyph glyph; + static TT_CharMap cmap; + static TT_Face_Properties props; + static PFontFace cur_face; + ULONG encoding, i; + + if (cur_file->flags & FL_FLAG_LIVE_FACE) + ERRRET(-1); /* already awoken !! */ + + /* OK, try to activate the FreeType objects */ + error = TT_Open_Face(engine, cur_file->filename, &face); + if (error) + { + COPY( "Error while opening " ); CAT( cur_file->filename ); + CAT( ", error code = " ); CATI( error ); CAT( "\r\n" ); WRITE; + return -1; /* error, can't open file */ + /* XXX : should set error condition here! */ + } + + /* Create a glyph container for it */ + error = TT_New_Glyph( face, &glyph ); + if (error) + { + COPY( "Error while creating container for " ); CAT( cur_file->filename ); + CAT( ", error code = " ); CATI( error ); CAT( "\r\n" ); WRITE; + goto Fail_Face; + } + + /* now get suitable charmap for this font */ + encoding = GetCharmap(face); + error = TT_Get_CharMap(face, encoding & 0xFFFF, &cmap); + if (error) + { + COPY( "Error: No char map in " ); CAT( cur_file->filename ); + CAT( "\r\n" ); WRITE; + goto Fail_Glyph; + } + + /* Get face properties. Necessary to find out number of fonts for TTCs */ + TT_Get_Face_Properties(face, &props); + + /* all right, now remove the face from the sleep list */ + if (List_Remove( &idleFiles, cur_file->element )) + ERET1( Fail_Glyph ); + + /* add it to the live list */ + if (List_Insert( &liveFiles, cur_file->element )) + ERET1( Fail_Glyph ); + + /* If the file is a TTC, the first face is now opened successfully. */ + + cur_file->numFaces = props.num_Faces; + + /* Now allocate memory for face data (one struct for each face in TTC). */ + if (cur_file->faces == NULL) { + if (ALLOC(cur_face, sizeof(TFontFace) * cur_file->numFaces)) + ERET1( Fail_Glyph ); + + cur_file->faces = cur_face; + } + else + cur_face = cur_file->faces; + + cur_face->face = face; /* possibly first face in a TTC */ + cur_face->glyph = glyph; + cur_face->charMap = cmap; + cur_file->flags |= FL_FLAG_LIVE_FACE; + + + if (!(cur_file->flags & FL_FLAG_ALREADY_USED)) { + cur_face->charMode = encoding >> 16; /* Unicode, Symbol, ... */ + cur_face->em_size = props.header->Units_Per_EM; + + /* if a face contains over 1024 glyphs, assume it's a DBCS font - */ + /* VERY probable */ + TT_Get_Face_Properties(cur_face->face, &props); + + if (props.num_Glyphs > 1024) { + cur_file->flags |= FL_FLAG_DBCS_FILE; + cur_face->flags |= FC_FLAG_DBCS_FACE; + } + + cur_face->widths = NULL; + cur_face->kernIndices = NULL; + } + /* load kerning directory, if any */ + error = TT_Get_Kerning_Directory(face, &(cur_face->directory)); + if (error) + cur_face->directory.nTables = 0; /* indicates no kerning in font */ + + TT_Flush_Face(face); /* this is important ! */ + + /* open remaining faces if this font is a TTC */ + for (i = 1; i < cur_file->numFaces; i++) { + error = TT_Open_Collection(engine, cur_file->filename, + i, &face); + if (error) + return -1; /* TODO: handle bad TTCs more tolerantly */ + + error = TT_New_Glyph( face, &glyph ); + if (error) + ERET1(Fail_Face); + + encoding = GetCharmap(face); + error = TT_Get_CharMap(face, encoding & 0xFFFF, &cmap); + if (error) + ERET1(Fail_Glyph); + + cur_face = &(cur_file->faces[i]); + + cur_face->face = face; + cur_face->glyph = glyph; + cur_face->charMap = cmap; + + if (!(cur_file->flags & FL_FLAG_ALREADY_USED)) { + cur_face->em_size = props.header->Units_Per_EM; + cur_face->charMode = encoding >> 16; /* 0 - Unicode; 1 - Symbol */ + + if (cur_file->flags & FL_FLAG_DBCS_FILE) + cur_face->flags |= FC_FLAG_DBCS_FACE; + + cur_face->widths = NULL; + cur_face->kernIndices = NULL; + } + + /* load kerning directory, if any */ + error = TT_Get_Kerning_Directory(face, &(cur_face->directory)); + if (error) + cur_face->directory.nTables = 0; /* indicates no kerning in font */ + } + + cur_file->flags |= FL_FLAG_ALREADY_USED; /* indicates some fields need no re-init */ + + error = TT_Flush_Face(face); /* this is important ! */ + if (error) { + COPY("Error flushing face\r\n"); WRITE; + } + + return 0; /* everything is in order, return 0 == success */ + +Fail_Glyph: + /* This line isn't really necessary, because the glyph container */ + /* would be destroyed by the following TT_Close_Face anyway. We */ + /* however use it for the sake of orthodoxy */ + TT_Done_Glyph( glyph ); + +Fail_Face: + TT_Close_Face(face); + + /* note that in case of error (e.g. out of memory), the face stays */ + /* on the sleeping list */ + return -1; +} + +/****************************************************************************/ +/* */ +/* Done_FontFile : */ +/* */ +/* destroys a given font file object. This will also destroy all of its */ +/* live child font sizes (which in turn will destroy the glyph caches). */ +/* This is done for all faces if the file is a collection. */ +/* */ +/* WARNING : The font face must be removed from its list by the caller */ +/* before this function is called. */ +/* */ +static void Done_FontFile( PFontFile *file ) +{ + static PListElement element; + static PListElement next; + ULONG i; + +#if 0 /* this part isn't really used and maybe it never will */ + /* destroy its font sizes */ + element = (*face)->sizes.head; + while (element) + { + next = element->next; + /* XXX : right now, we simply free the font size object, */ + /* because the instance is destroyed automatically */ + /* by FreeType. */ + + FREE( element->data ); + /* Done_FontSize( (PFontSize)element->data ); - later */ + + Done_Element( element ); + element = next; + } +#endif + + /* now discard the font face itself */ + if ((*file)->flags & FL_FLAG_LIVE_FACE) + { + for (i = 0; i < (*file)->numFaces; i++) { + TT_Done_Glyph( (*file)->faces[i].glyph ); + TT_Close_Face( (*file)->faces[i].face ); + + if ((*file)->faces[i].widths) + FREE((*file)->faces[i].widths); + if ((*file)->faces[i].kernIndices) + FREE((*file)->faces[i].kernIndices); + } + } + + FREE( (*file)->faces ); + FREE( *file ); +} + + +/****************************************************************************/ +/* */ +/* New_FontFile : */ +/* */ +/* return the address of the TFontFile corresponding to a given */ +/* HFF. Note that in our implementation, we could simply to a */ +/* typecast like '(PFontFile)hff'. However, for safety reasons, we */ +/* look up the handle in the list. */ +/* */ +static PFontFile New_FontFile( char* file_name ) +{ + static PListElement element; + static PFontFile cur_file; + static TT_CharMap cmap; + + /* first, check if it's already open - in the live list */ + for ( element = liveFiles.head; element; element = element->next ) + { + cur_file = (PFontFile)element->data; + if (strcmp( cur_file->filename, file_name ) == 0) + goto Exit_Same; + } + + /* check in the idle list */ + for ( element = idleFiles.head; element; element = element->next ) + { + cur_file = (PFontFile)element->data; + if (strcmp( cur_file->filename, file_name ) == 0) + goto Exit_Same; + } + + /* OK, this file isn't opened yet. Create a new font face object */ + /* then try to wake it up. This will fail if the file can't be found */ + /* or if we lack memory.. */ + + element = New_Element(); + if (!element) + ERRRET(NULL); + + if ( ALLOC( cur_file, sizeof(TFontFile) ) ) + ERET1( Fail_Element ); + + element->data = cur_file; + element->key = (long)cur_file; /* use the HFF as cur key */ + + cur_file->element = element; + cur_file->ref_count = 1; + cur_file->hff = (HFF)cur_file; + strcpy( cur_file->filename, file_name); + cur_file->flags = 0; + cur_file->faces = NULL; +#if 0 /* not used */ + cur_face->sizes.head = NULL; + cur_face->sizes.tail = NULL; + cur_face->sizes.count= 0; +#endif + + /* add new font face to sleep list */ + if (List_Insert( &idleFiles, element )) + ERET1( Fail_File ); + + /* Make enough room in the live list */ + if ( liveFiles.count >= max_open_files) + { + COPY( "rolling...\n" ); WRITE; + if (Sleep_FontFile( (PFontFile)(liveFiles.tail->data) )) + ERET1( Fail_File ); + } + + /* wake new font file */ + if ( Wake_FontFile( cur_file ) ) + { + COPY( "could not open/wake " ); CAT( file_name ); CAT( "\r\n" ); WRITE; + if (List_Remove( &idleFiles, element )) + ERET1( Fail_File ); + + ERET1( Fail_File ); + } + + return cur_file; /* everything is in order */ + +Fail_File: + FREE( cur_file ); + +Fail_Element: + Done_Element( element ); + return NULL; + +Exit_Same: + cur_file->ref_count++; /* increment reference count */ + + COPY( " -> (duplicate) hff = " ); CATI( cur_file->hff ); + CAT( "\r\n" ); WRITE; + + return cur_file; /* no sense going on */ +} + +/****************************************************************************/ +/* */ +/* getFontFile : */ +/* */ +/* return the address of the TFontFile corresponding to a given */ +/* HFF. If asleep, the file and its face object(s) is awoken. */ +/* */ +PFontFile getFontFile( HFF hff ) +{ + static PListElement element; + + /* look in the live list first */ + element = List_Find( &liveFiles, (long)hff ); + if (element) + { + /* move it to the front of the live list - if it isn't already */ + if ( liveFiles.head != element ) + { + if ( List_Remove( &liveFiles, element ) ) + ERRRET( NULL ); + + if ( List_Insert( &liveFiles, element ) ) + ERRRET( NULL ); + } + return (PFontFile)(element->data); + } + + /* the file may be asleep, look in the second list */ + element = List_Find( &idleFiles, (long)hff ); + if (element) + { + /* we need to awake the font, but before that, we must be sure */ + /* that there is enough room in the live list */ + if ( liveFiles.count >= max_open_files ) + if (Sleep_FontFile( (PFontFile)(liveFiles.tail->data) )) + ERRRET( NULL ); + + if ( Wake_FontFile( (PFontFile)(element->data) ) ) + ERRRET( NULL ); + + COPY ( "hff " ); CATI( hff ); CAT( " awoken\n" ); WRITE; + return (PFontFile)(element->data); + } + + COPY( "Could not find hff " ); CATI( hff ); CAT( " in lists\n" ); WRITE; + +#ifdef DEBUG + + /* dump files lists */ + COPY( "Live files : " ); CATI( liveFiles.count ); CAT( "\r\n" ); WRITE; + + for (element = liveFiles.head; element; element = element->next) + { + COPY( ((PFontFile)(element->data))->filename ); CAT("\r\n");WRITE; + } + + COPY( "Idle files : " ); CATI( idleFiles.count ); CAT( "\r\n" ); WRITE; + for (element = idleFiles.head; element; element = element->next) + { + COPY( ((PFontFile)(element->data))->filename ); CAT("\r\n");WRITE; + } +#endif + + /* could not find the HFF in the list */ + return NULL; +} + + +/****************************************************************************/ +/* */ +/* getFontSize : */ +/* */ +/* return pointer to a TFontSize given a HFC handle, NULL if error */ +/* */ +static PFontSize getFontSize( HFC hfc ) +{ + int i; + for ( i = 0; i < MAX_CONTEXTS; i++ ) + if ( contexts[i].hfc == hfc ) { + return &contexts[i]; + } + + return NULL; +} + +#ifdef USE_UCONV + +/* maximum number of cached UCONV objects */ +#define MAX_UCONV_CACHE 10 + +/* UCONV object used for conversion from UGL to Unicode */ +#define UCONV_TYPE_UGL 1 + +/* UCONV objects used for conversion from local DBCS codepage to Unicode */ +#define UCONV_TYPE_BIG5 2 +#define UCONV_TYPE_SJIS 4 + +/* UCONV objects cache entry */ +typedef struct _UCACHEENTRY { + UconvObject object; /* actual UCONV object */ + PID pid; /* process ID the object is valid for */ + ULONG type; /* type of UCONV object (UGL or DBCS) */ +} UCACHEENTRY, *PUCACHEENTRY; + +/* UCONV globals */ +static UCACHEENTRY UconvCache[MAX_UCONV_CACHE]; /* 10 should do it */ +static int slotsUsed = 0; /* number of cache slots used */ + +/****************************************************************************/ +/* */ +/* getUconvObject : */ +/* */ +/* a function to cache UCONV objects based on current process. The only */ +/* problem is that FT/2 currently doesn't keep track of processes and */ +/* consequently the objects aren't freed when a process ends. But UCONV */ +/* frees the objects itself anyway. */ +int getUconvObject(UniChar *name, UconvObject *ConvObj, ULONG UconvType) { + PPIB ppib; /* process/thread info blocks */ + PTIB ptib; + PID curPid; /* current process ID */ + int i; + + /* query current process ID */ + if (DosGetInfoBlocks(&ptib, &ppib)) + return -1; + + curPid = ppib->pib_ulpid; + + if (slotsUsed == 0) { /* initialize cache */ + if (UniCreateUconvObject(name, ConvObj) != ULS_SUCCESS) + return -1; + UconvCache[0].object = *ConvObj; + UconvCache[0].pid = curPid; + UconvCache[0].type = UconvType; + + for (i = 1; i < MAX_UCONV_CACHE; i++) { + UconvCache[i].object = NULL; + UconvCache[i].pid = 0; + } + slotsUsed = 1; + return 0; + } + + /* search cache for available conversion object */ + i = 0; + while ((UconvCache[i].pid != curPid || UconvCache[i].type != UconvType) + && i < slotsUsed) + i++; + + if (i < slotsUsed) { /* entry found in cache */ + *ConvObj = UconvCache[i].object; + return 0; + } + + /* if cache is full, remove first entry and shift the others 'down' */ + if (slotsUsed == MAX_UCONV_CACHE) { + UniFreeUconvObject(UconvCache[0].object); + for (i = 1; i < MAX_UCONV_CACHE; i++) { + UconvCache[i - 1].object = UconvCache[i].object; + UconvCache[i - 1].pid = UconvCache[i].pid; + UconvCache[i - 1].type = UconvCache[i].type; + } + } + + if (UniCreateUconvObject(name, ConvObj) != ULS_SUCCESS) + return -1; + + if (slotsUsed < MAX_UCONV_CACHE) + slotsUsed++; + + UconvCache[slotsUsed - 1].object = *ConvObj; + UconvCache[slotsUsed - 1].pid = curPid; + UconvCache[slotsUsed - 1].type = UconvType; + + return 0; +} + +/****************************************************************************/ +/* */ +/* CleanUCONVCache : */ +/* */ +/* When process is terminated, removes this process' entries in the UCONV */ +/* object cache. Errors are disregarded at this point. */ +void CleanUCONVCache(void) { + PPIB ppib; /* process/thread info blocks */ + PTIB ptib; + PID curPid; /* current process ID */ + int i = 0, j; + + /* query current process ID */ + if (DosGetInfoBlocks(&ptib, &ppib)) + return; + + curPid = ppib->pib_ulpid; + + while (i < slotsUsed) { + /* if PID matches, remove the entry and shift the others 'down' (or up?) */ + if (UconvCache[i].pid == curPid) { + UniFreeUconvObject(UconvCache[i].object); + for (j = i + 1; j < slotsUsed; j++) { + UconvCache[j - 1].object = UconvCache[j].object; + UconvCache[j - 1].pid = UconvCache[j].pid; + UconvCache[j - 1].type = UconvCache[j].type; + } + slotsUsed--; + } + i++; + } +} +#endif /* USE_UCONV */ + +/****************************************************************************/ +/* */ +/* PM2TT : */ +/* */ +/* a function to convert PM codepoint to TT glyph index. This is the real */ +/* tricky part. */ +/* mode = TRANSLATE_UGL - translate UGL to Unicode */ +/* mode = TRANSLATE_SYMBOL - no translation - symbol font */ +/* mode = TRANSLATE_UNICODE- no translation - Unicode */ +static int PM2TT( TT_CharMap charMap, + ULONG mode, + int index) +{ +#ifdef USE_UCONV + /* Brand new version that uses UCONV.DLL. This should make FreeType/2 */ + /* smaller and at the same time more flexible as it now should use */ + /* the Unicode translation tables supplied with base OS/2 Warp 4. */ + /* Unfortunately there's a complication (again) since UCONV objects */ + /* created in one process can't be used in another. Therefore we */ + /* keep a small cache of recently used UCONV objects. */ + static UconvObject UGLObj = NULL; /* UGL->Unicode conversion object */ + static BOOL UconvSet = FALSE; + char char_data[2], *pin_char_str; + size_t in_bytes_left, uni_chars_left, num_subs; + UniChar *pout_uni_str, uni_buffer[4]; + int rc; + static UniChar uglName[10] = L"OS2UGL"; + static UniChar uglNameBig5[10] = L"IBM-950"; + static UniChar uglNameSJIS[10] = L"IBM-943"; + + switch (mode) { + case TRANSLATE_UGL: + if (UconvSet == FALSE) { + switch (iLangId) { /* select proper conversion table */ + case TT_MS_LANGID_GREEK_GREECE: + strncpy((char*)uglName, (char*)L"OS2UGLG", 16); + break; + case TT_MS_LANGID_HEBREW_ISRAEL: + strncpy((char*)uglName, (char*)L"OS2UGLH", 16); + break; + case TT_MS_LANGID_ARABIC_SAUDI_ARABIA: + strncpy((char*)uglName, (char*)L"OS2UGLA", 16); + break; + } + UconvSet = TRUE; + } + + /* get Uconv object - either new or cached */ + if (getUconvObject(uglName, &UGLObj, UCONV_TYPE_UGL) != 0) + return 0; + + if (index > MAX_GLYPH) + return 0; + + char_data[0] = index; + char_data[1] = index >> 8; + + pout_uni_str = uni_buffer; + pin_char_str = char_data; + in_bytes_left = 2; + uni_chars_left = 1; + + rc = UniUconvToUcs(UGLObj, (void**)&pin_char_str, &in_bytes_left, + &pout_uni_str, &uni_chars_left, + &num_subs); + if (rc != ULS_SUCCESS) + return 0; + else + return TT_Char_Index(charMap, ((unsigned short*)uni_buffer)[0]); + + case TRANSLATE_SYMBOL: + case TRANSLATE_UNICODE: + case TRANSLATE_BIG5: + case TRANSLATE_SJIS: + return TT_Char_Index(charMap, index); + + case TRANSLATE_UNI_BIG5: + case TRANSLATE_UNI_SJIS: + + /* get Uconv object - either new or cached */ + switch (mode) { + /* get proper conversion object */ + case TRANSLATE_UNI_BIG5: + if (getUconvObject(uglNameBig5, &UGLObj, UCONV_TYPE_BIG5) != 0) + return 0; + break; + + case TRANSLATE_UNI_SJIS: + if (getUconvObject(uglNameSJIS, &UGLObj, UCONV_TYPE_SJIS) != 0) + return 0; + break; + } + + /* Note the bytes are swapped here for double byte chars! */ + if (index & 0xFF00) { + char_data[0] = (index & 0xFF00) >> 8; + char_data[1] = index & 0x00FF; + } + else { + char_data[0] = index; + char_data[1] = 0; + } + + pout_uni_str = uni_buffer; + pin_char_str = char_data; + in_bytes_left = 2; + uni_chars_left = 2; + + rc = UniUconvToUcs(UGLObj, (void**)&pin_char_str, &in_bytes_left, + &pout_uni_str, &uni_chars_left, + &num_subs); + if (rc != ULS_SUCCESS) + return 0; + else + return TT_Char_Index(charMap, ((unsigned short*)uni_buffer)[0]); + + default: + return 0; + } +#else + switch (mode) + { + /* convert from PM383 to Unicode */ + case TRANSLATE_UGL: + /* TODO: Hebrew and Arabic UGL */ + if (iLangId == TT_MS_LANGID_GREEK_GREECE) /* use Greek UGL */ + if ((index >= GREEK_START) && (index < GREEK_START + GREEK_GLYPHS)) + return TT_Char_Index(charMap, SubUGLGreek[index - GREEK_START]); + + if (index <= MAX_GLYPH) + return TT_Char_Index(charMap, UGL2Uni[index]); + else + ERRRET(0); + + case TRANSLATE_SYMBOL : + case TRANSLATE_UNICODE: + case TRANSLATE_BIG5: + case TRANSLATE_SJIS: + return TT_Char_Index(charMap, index); + + default: + return 0; + } +#endif +} + +/****************************************************************************/ +/* */ +/* mystricmp : */ +/* */ +/* A simple function for comparing strings without case sensitivity. Just */ +/* returns zero if strings match, one otherwise. I wrote this because */ +/* stricmp is not available in the subsystem run-time library (probably */ +/* because it uses locales). toupper() is unfortunately unavailable too. */ +/* */ + +#define toupper( c ) ( ((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c) ) + +static +int mystricmp(const char *s1, const char *s2) { + int i = 0; + int match = 0; + int len = strlen(s1); + + if (len != strlen(s2)) + return 1; /* no match */ + + while (i < len) { + if (toupper(s1[i]) != toupper(s2[i])) { + match = 1; + break; + } + i++; + } + return match; +} + +/* DBCS enabled strrchr (only looks for SBCS chars though) */ +static +char *mystrrchr(char *s, char c) { + int i = 0; + int lastfound = -1; + int len = strlen(s); + + while (i <= len) { + if (IsDBCSChar(s[i])) { + i += 2; + continue; + } + if (s[i] == c) + lastfound = i; + i++; + } + if (lastfound == -1) + return NULL; + else + return s + lastfound; +} + +/* -------------------------------------------------------------------------*/ +/* here begin the exported functions */ +/* -------------------------------------------------------------------------*/ + +/****************************************************************************/ +/* */ +/* ConvertFontFile : */ +/* */ +/* Install/delete font file */ +/* */ +LONG _System ConvertFontFile( PSZ source, + PSZ dest_dir, + PSZ new_name ) +{ + PSZ source_name; + + COPY("ConvertFontFile: Src = "); CAT(source); + if (dest_dir) { + CAT(", DestDir = "); CAT(dest_dir); + } + CAT("\r\n"); WRITE; + + if (dest_dir && new_name) + { + /* install the font file */ + source_name = mystrrchr( source, '\\' ); /* find the last backslash */ + if (!source_name) + ERRRET(-1); + + source_name++; + strcpy( new_name, source_name ); + + /* check if file is to be copied onto itself */ + if (strncmp(source, dest_dir, strlen(dest_dir)) == 0) + return OK; /* do nothing */ + + if ( DosCopy( source, dest_dir, DCPY_EXISTING) ) /* overwrite file */ + ERRRET(-1); /* XXX : we should probably set the error condition */ + + COPY(" -> Name: "); CAT(new_name); CAT("\r\n"); WRITE; + } + else + { + COPY("Delete file "); CAT(source); CAT("\r\n"); WRITE; + DosDelete(source); /* fail quietly */ + } + + return OK; +} + +/****************************************************************************/ +/* */ +/* LoadFontFile : */ +/* */ +/* open a font file and return a handle for it */ +/* */ +HFF _System LoadFontFile( PSZ file_name ) +{ + PSZ extension; + PFontFile cur_file; + PListElement element; + + COPY( "LoadFontFile " ); CAT( file_name ); CAT( "\r\n" ); WRITE; + + /* first check if the file extension is supported */ + extension = mystrrchr( file_name, '.' ); /* find the last dot */ + if ( extension == NULL || + (mystricmp(extension, ".TTF") && + mystricmp(extension, ".TTC")) ) + return ((HFF)-1); + + /* now actually open the file */ + cur_file = New_FontFile( file_name ); + if (cur_file) + return cur_file->hff; + else + return (HFF)-1; +} + +/****************************************************************************/ +/* */ +/* UnloadFontFile : */ +/* */ +/* destroy resources associated with a given HFF */ +/* */ +LONG _System UnloadFontFile( HFF hff ) +{ + PListElement element; + + COPY("UnloadFontFile: hff = "); CATI((int) hff); CAT("\r\n"); WRITE; + + /* look in the live list first */ + for (element = liveFiles.head; element; element = element->next) + { + if (element->key == (long)hff) + { + PFontFile file = (PFontFile)element->data; + + if (--file->ref_count > 0) /* don't really close, return OK */ + return 0; + + List_Remove( &liveFiles, element ); + Done_Element( element ); + Done_FontFile( &file ); + return 0; + } + } + + /* now look in sleep list */ + for (element = idleFiles.head; element; element = element->next) + { + if (element->key == (long)hff) + { + PFontFile file = (PFontFile)element->data; + + if (--file->ref_count > 0) /* don't really close, return OK */ + return 0; + + List_Remove( &idleFiles, element ); + Done_Element( element ); + Done_FontFile( &file ); + return 0; + } + } + + /* didn't find the file */ + return -1; +} + +/****************************************************************************/ +/* */ +/* QueryFaces : */ +/* */ +/* Return font metrics. This routine has to do a lot of not very */ +/* hard work. */ +/* */ +LONG _System QueryFaces( HFF hff, + PIFIMETRICS pifiMetrics, + ULONG cMetricLen, + ULONG cFontCount, + ULONG cStart) +{ + static TT_Face_Properties properties; + static IFIMETRICS ifi; /* temporary structure */ + PFontFace pface; + TT_Header *phead; + TT_Horizontal_Header *phhea; + TT_OS2 *pOS2; + TT_Postscript *ppost; + PIFIMETRICS pifi2; + PFontFile file; + LONG index, faceIndex, ifiCount = 0; + char *name; + + COPY( "QueryFaces: hff = " ); CATI( hff ); + CAT( ", cFontCount = " ); CATI( cFontCount ); + CAT( ", cStart = " ); CATI( cStart ); + CAT( ", cMetricLen = " ); CATI( cMetricLen ); + CAT( "\r\n"); + WRITE; + + file = getFontFile(hff); + if (!file) + ERRRET(-1) /* error, invalid handle */ + + if (cMetricLen == 0) { /* only number of faces is requested */ + #ifdef FAKE_TNR + /* create an alias for Times New Roman */ + pface = &(file->faces[0]); + name = LookupName(pface->face, TT_NAME_ID_FONT_FAMILY); + if (!strcmp(name, "Times New Roman")) { + file->flags |= FL_FLAG_FAKE_ROMAN; + return 2; + } + #endif + if (file->flags & FL_FLAG_DBCS_FILE) + return file->numFaces * 2; + else + return file->numFaces; + } + + for (faceIndex = 0; faceIndex < file->numFaces; faceIndex++) { + /* get pointer to this face's data */ + pface = &(file->faces[faceIndex]); + + TT_Get_Face_Properties( pface->face, &properties ); + + pOS2 = properties.os2; + phead = properties.header; + phhea = properties.horizontal; + ppost = properties.postscript; + + /* get font name and check it's really found */ + name = LookupName(pface->face, TT_NAME_ID_FONT_FAMILY); + if (name == NULL) + ERET1(Fail); + + strncpy(ifi.szFamilyname, name, FACESIZE); + ifi.szFamilyname[FACESIZE - 1] = '\0'; + + name = LookupName(pface->face, TT_NAME_ID_FULL_NAME); + if (name == NULL) { + ERET1(Fail); + } + strncpy(ifi.szFacename, name, FACESIZE); + ifi.szFacename[FACESIZE - 1] = '\0'; + + /* If Unicode cmap exists in font and it contains more than 1024 glyphs, */ + /* then do not translate from UGL to Unicode and use straight Unicode. */ + /* But first check if it's a DBCS font and handle it properly */ + if ((pface->charMode == TRANSLATE_UGL) && (properties.num_Glyphs > 1024)) + { + LONG specEnc; + BOOL UDCflag = FALSE; /* !!!!TODO: UDC support */ + + specEnc = interfaceSEId(pface->face, UDCflag, PSEID_UNICODE); + switch (specEnc) { + case PSEID_SHIFTJIS: + strcpy( ifi.szGlyphlistName, "PMJPN" ); + pface->charMode = TRANSLATE_UNI_SJIS; + break; + + case PSEID_BIG5: + strcpy( ifi.szGlyphlistName, "PMCHT" ); + pface->charMode = TRANSLATE_UNI_BIG5; + break; + + default: /* do use straight Unicode */ + strcpy( ifi.szGlyphlistName, "UNICODE" ); + pface->charMode = TRANSLATE_UNICODE; /* straight Unicode */ + } +#if 0 + strcpy( ifi.szGlyphlistName, "PMJPN" ); + pface->charMode = TRANSLATE_UNI_SJIS; +#endif + } + else + if (pface->charMode == TRANSLATE_SYMBOL) /* symbol encoding */ + strcpy(ifi.szGlyphlistName, "SYMBOL"); + else + if (pface->charMode == TRANSLATE_BIG5) /* Big5 encoding */ + strcpy(ifi.szGlyphlistName, "PMCHT"); + else + if (pface->charMode == TRANSLATE_SJIS) + strcpy(ifi.szGlyphlistName, "PMJPN"); /* ShiftJIS encoding */ + else + strcpy(ifi.szGlyphlistName, "PM383"); + + ifi.idRegistry = 0; + ifi.lCapEmHeight = phead->Units_Per_EM; /* ??? probably correct */ + ifi.lXHeight = phead->yMax /2; /* IBM TRUETYPE.DLL does */ + ifi.lMaxAscender = pOS2->usWinAscent; + + if ((LONG)pOS2->usWinDescent >= 0) + ifi.lMaxDescender = pOS2->usWinDescent; + else + ifi.lMaxDescender = -pOS2->usWinDescent; + + ifi.lLowerCaseAscent = phhea->Ascender; + ifi.lLowerCaseDescent = -phhea->Descender; + + ifi.lInternalLeading = ifi.lMaxAscender + ifi.lMaxDescender + - ifi.lCapEmHeight; + + ifi.lExternalLeading = 0; + ifi.lAveCharWidth = pOS2->xAvgCharWidth; + ifi.lMaxCharInc = phhea->advance_Width_Max; + ifi.lEmInc = phead->Units_Per_EM; + ifi.lMaxBaselineExt = ifi.lMaxAscender + ifi.lMaxDescender; + ifi.fxCharSlope = -ppost->italicAngle; /* is this correct ? */ + ifi.fxInlineDir = 0; + ifi.fxCharRot = 0; + ifi.usWeightClass = pOS2->usWeightClass; /* hopefully OK */ + ifi.usWidthClass = pOS2->usWidthClass; + ifi.lEmSquareSizeX = phead->Units_Per_EM; + ifi.lEmSquareSizeY = phead->Units_Per_EM; /* probably correct */ + ifi.giFirstChar = 0; /* following values should work */ + ifi.giLastChar = 503; /* either 383 or 503 */ + ifi.giDefaultChar = 0; + ifi.giBreakChar = 32; + ifi.usNominalPointSize = 120; /* these are simply constants */ + ifi.usMinimumPointSize = 10; + ifi.usMaximumPointSize = 10000; /* limit to 1000 pt (like the ATM fonts) */ + ifi.fsType = pOS2->fsType & IFIMETRICS_LICENSED; /* ??? */ + ifi.fsDefn = IFIMETRICS_OUTLINE; /* always with TrueType */ + ifi.fsSelection = 0; + ifi.fsCapabilities = 0; /* must be zero according to the IFI spec */ + ifi.lSubscriptXSize = pOS2->ySubscriptXSize; + ifi.lSubscriptYSize = pOS2->ySubscriptYSize; + ifi.lSubscriptXOffset = pOS2->ySubscriptXOffset; + ifi.lSubscriptYOffset = pOS2->ySubscriptYOffset; + ifi.lSuperscriptXSize = pOS2->ySuperscriptXSize; + ifi.lSuperscriptYSize = pOS2->ySuperscriptYSize; + ifi.lSuperscriptXOffset = pOS2->ySuperscriptXOffset; + ifi.lSuperscriptYOffset = pOS2->ySuperscriptYOffset; + ifi.lUnderscoreSize = ppost->underlineThickness; + if (ifi.lUnderscoreSize == 150) + ifi.lUnderscoreSize = 100; /* little fix for Arial */ + ifi.lUnderscorePosition = -ppost->underlinePosition; + ifi.lStrikeoutSize = pOS2->yStrikeoutSize; + ifi.lStrikeoutPosition = pOS2->yStrikeoutPosition; + +#if 1 + if (pface->directory.nTables != 0 && + pface->directory.tables[0].format == 0) { /* we support only format */ + ifi.cKerningPairs = (pface->directory.tables[0].length - 8) / 6; + ifi.fsType |= IFIMETRICS_KERNING; /* !!! for testing only! */ + } + else +#endif + ifi.cKerningPairs = 0; + + /* Note that the following field seems to be the only reliable method of */ + /* recognizing a TT font from an app! Not that it should be done. */ + ifi.ulFontClass = 0x10D; /* just like TRUETYPE.DLL */ + + /* the following adjustment are needed because the TT spec defines */ + /* usWeightClass and fsType differently */ + if (ifi.usWeightClass >= 100) + ifi.usWeightClass /= 100; + if (ifi.usWeightClass == 4) + ifi.usWeightClass = 5; /* does this help? */ + if (pOS2->panose[3] == 9) { + ifi.fsType |= IFIMETRICS_FIXED; + pface->flags |= FC_FLAG_FIXED_WIDTH; /* we'll need this later */ + } + + switch (pface->charMode) { /* adjustments for var. encodings */ + case TRANSLATE_UNICODE: + ifi.giLastChar = pOS2->usLastCharIndex; + ifi.fsType |= IFIMETRICS_MBCS | IFIMETRICS_DBCS; + break; + + case TRANSLATE_SYMBOL: + ifi.giLastChar = 255; + break; + + case TRANSLATE_BIG5: + case TRANSLATE_UNI_BIG5: + ifi.giLastChar = 383; + ifi.fsType |= IFIMETRICS_MBCS | IFIMETRICS_DBCS; + break; + + case TRANSLATE_SJIS: + case TRANSLATE_UNI_SJIS: + ifi.giLastChar = 890; + ifi.fsType |= IFIMETRICS_MBCS | IFIMETRICS_DBCS; + break; + + } + + /* adjust fsSelection (TT defines this differently) */ + /* Note: Interestingly, the PMATM font driver seems to use the values + defined in TT spec, at least for italic. Strange. Better leave it. */ + if (pOS2->fsSelection & 0x01) { + ifi.fsSelection |= 0x01; + } + if (pOS2->fsSelection & 0x02) { + ifi.fsSelection |= IFIMETRICS_UNDERSCORE; + } + if (pOS2->fsSelection & 0x04) { + ifi.fsSelection |= IFIMETRICS_OVERSTRUCK; + } + + /* copy the right amount of data to output buffer, */ + /* also handle the 'fake' vertically rendered DBCS fonts */ + index = faceIndex * ((file->flags & FL_FLAG_DBCS_FILE) ? 2 : 1); + if ((index >= cStart) && (index < (cStart + cFontCount))) { + memcpy((((PBYTE) pifiMetrics) + ifiCount), &ifi, + sizeof(IFIMETRICS) > cMetricLen ? cMetricLen : sizeof(IFIMETRICS)); + ifiCount += cMetricLen; + } + if ((file->flags & FL_FLAG_DBCS_FILE) && (index + 1 >= cStart) && + (index + 1 < (cStart + cFontCount))) { + + pifi2 = (PIFIMETRICS) (((PBYTE) pifiMetrics) + ifiCount); + memcpy(pifi2, &ifi, + sizeof(IFIMETRICS) > cMetricLen ? cMetricLen : sizeof(IFIMETRICS)); + strcpy(pifi2->szFamilyname + 1, ifi.szFamilyname); + pifi2->szFamilyname[0] = '@'; + strcpy(pifi2->szFacename + 1, ifi.szFacename); + pifi2->szFacename[0] = '@'; + ifiCount += cMetricLen; + } + #ifdef FAKE_TNR + if ((file->flags & FL_FLAG_FAKE_ROMAN) && (index + 1 >= cStart) && + (index + 1 < (cStart + cFontCount))) { + pifi2 = (PIFIMETRICS) (((PBYTE) pifiMetrics) + ifiCount); + memcpy(pifi2, &ifi, + sizeof(IFIMETRICS) > cMetricLen ? cMetricLen : sizeof(IFIMETRICS)); + strcpy(pifi2->szFamilyname, "Roman"); + switch (strlen(ifi.szFacename)) { /* This looks weird but... works */ + case 15: /* Times New Roman */ + strcpy(pifi2->szFacename, "Tms Rmn"); + break; + case 20: /* Times New Roman Bold*/ + strcpy(pifi2->szFacename, "Tms Rmn Bold"); + break; + case 22: /* Times New Roman Italic*/ + strcpy(pifi2->szFacename, "Tms Rmn Italic"); + break; + case 27: /* Times New Roman Bold Italic*/ + strcpy(pifi2->szFacename, "Tms Rmn Bold Italic"); + break; + } + ifiCount += cMetricLen; + } + #endif + } + +Exit: + TT_Flush_Face(pface->face); + return cFontCount; + +Fail: + TT_Flush_Face(pface->face); + return -1; +} + +/****************************************************************************/ +/* */ +/* OpenFontContext : */ +/* */ +/* open new font context */ +/* */ +HFC _System OpenFontContext( HFF hff, + ULONG ulFont) +{ + int i = 0; + static TT_Instance instance; + static PFontFile file; + ULONG faceIndex; + + COPY("OpenFontContext: hff = "); CATI((int) hff); CAT("\r\n"); + COPY(" ulFont = "); CATI((int) ulFont); CAT("\r\n"); + WRITE; + + file = getFontFile(hff); + if (!file) + ERRRET((HFC)-1) /* error, invalid font handle */ + + /* calculate real face index in font file */ + faceIndex = file->flags & FL_FLAG_DBCS_FILE ? ulFont / 2 : ulFont; + + #ifdef FAKE_TNR + if (file->flags & FL_FLAG_FAKE_ROMAN) + /* This font isn't real! */ + faceIndex = 0; + #endif + + if (faceIndex > file->numFaces) + ERRRET((HFC)-1) + + /* OK, create new instance with defaults */ + error = TT_New_Instance( file->faces[faceIndex].face, &instance); + if (error) + ERET1( Fail ); + + /* Instance resolution is set to 72 dpi and is never changed */ + error = TT_Set_Instance_Resolutions(instance, 72, 72); + if (error) + ERRRET((HFC)-1) + + /* find first unused index */ + i = 0; + while ((contexts[i].hfc != 0) && (i < MAX_CONTEXTS)) + i++; + + if (i == MAX_CONTEXTS) + ERET1( Fail ); /* no free slot in table */ + + contexts[i].hfc = (HFC)(i + 0x100); /* initialize table entries */ + contexts[i].instance = instance; + contexts[i].transformed = FALSE; /* no scaling/rotation assumed */ + contexts[i].file = file; + contexts[i].faceIndex = faceIndex; + + /* for DBCS fonts/collections, odd indices are vertical versions*/ + if ((file->flags & FL_FLAG_DBCS_FILE) && (ulFont & 1)) + contexts[i].vertical = TRUE; + else + contexts[i].vertical = FALSE; + + file->flags |= FL_FLAG_CONTEXT_OPEN; /* flag as in-use */ + + COPY("-> hfc "); CATI((int) contexts[i].hfc); CAT("\r\n"); WRITE; + + TT_Flush_Face(file->faces[faceIndex].face); + return contexts[i].hfc; /* everything OK */ + +Fail: + TT_Flush_Face(file->faces[faceIndex].face); + return (HFC)-1; +} + +/****************************************************************************/ +/* */ +/* SetFontContext : */ +/* */ +/* set font context parameters */ +/* */ +LONG _System SetFontContext( HFC hfc, + PCONTEXTINFO pci ) +{ + LONG ptsize, temp, emsize; + PFontSize size; + + COPY("SetFontContext: hfc = "); CATI((int) hfc); + CAT(", sizlPPM.cx = "); CATI((int) pci->sizlPPM.cx); + CAT(", sizlPPM.cy = "); CATI((int) pci->sizlPPM.cy); + CAT("\r\n pfxSpot.x = "); CATI((int) pci->pfxSpot.x); + CAT(", pfxSpot.y = "); CATI((int) pci->pfxSpot.y); + CAT("\r\n eM11 = "); CATI((int) pci->matXform.eM11); + CAT(", eM12 = "); CATI((int) pci->matXform.eM12); + CAT(", eM21 = "); CATI((int) pci->matXform.eM21); + CAT(", eM22 = "); CATI((int) pci->matXform.eM22); + CAT("\r\n"); + WRITE; + + size = getFontSize(hfc); + if (!size) + ERRRET(-1) /* error, invalid context handle */ + + emsize = size->file->faces[size->faceIndex].em_size; + + /* Look at matrix and see if a transform is asked for */ + /* Actually when rotating by 90 degrees hinting could be used */ + + size->transformed = + ( pci->matXform.eM11 != pci->matXform.eM22 || + (pci->matXform.eM12 | pci->matXform.eM21) != 0 || + pci->matXform.eM11 <= 0 ); + + if ( size->transformed ) + { + /* check for simple stretch in one direction */ + if ((pci->matXform.eM11 > 0 && pci->matXform.eM22 > 0) && + (pci->matXform.eM12 | pci->matXform.eM21) == 0) { + + LONG ptsizex, ptsizey; + + size->transformed = FALSE; /* will be handled like nontransformed font */ + + ptsizex = (emsize * pci->matXform.eM11) >> 10; + ptsizey = (emsize * pci->matXform.eM22) >> 10; + + error = TT_Set_Instance_CharSizes(size->instance, ptsizex, ptsizey); + if (error) + ERRRET(-1) /* engine problem */ + + return 0; + } + /* note that eM21 and eM12 are swapped; I have no idea why, but */ + /* it seems to be correct */ + size->matrix.xx = pci->matXform.eM11 * 64; + size->matrix.xy = pci->matXform.eM21 * 64; + size->matrix.yx = pci->matXform.eM12 * 64; + size->matrix.yy = pci->matXform.eM22 * 64; + + /* set pointsize to Em size; this effectively disables scaling */ + /* but enables use of hinting */ + error = TT_Set_Instance_CharSize(size->instance, emsize); + if (error) + ERRRET(-1) /* engine problem */ + + return 0; + } + + /* calculate & set point size */ + ptsize = (emsize * (pci->matXform.eM11 + pci->matXform.eM21)) >> 10; + + if (ptsize <= 0) /* must not allow zero point size ! */ + ptsize = 1; /* !!! should be handled better */ + + error = TT_Set_Instance_CharSize(size->instance, ptsize); + if (error) + ERRRET(-1) /* engine problem */ + + return 0; /* pretend everything is OK */ +} + +/****************************************************************************/ +/* */ +/* CloseFontContext : */ +/* */ +/* destroy a font context */ +/* */ +LONG _System CloseFontContext( HFC hfc) +{ + PFontSize size; + + COPY("CloseFontContext: hfc = "); CATI((int)hfc); CAT("\r\n"); WRITE; + + size = getFontSize(hfc); + if (!size) + ERRRET(-1) /* error, invalid context handle */ + + /* mark table entry as free */ + size->hfc = 0; + + /* !!!!! set flag in TFontFile structure */ + size->file->flags &= ~FL_FLAG_CONTEXT_OPEN; /* reset the in-use flag */ + + if (size->file->flags & FL_FLAG_LIVE_FACE) { + COPY("Closing instance: "); CATI((int)(size->instance.z)); CAT("\r\n"); WRITE; + error = TT_Done_Instance(size->instance); + if (error) + ERRRET(-1) /* engine error */ + } + + COPY("CloseFontContext successful\r\n"); WRITE; + + return 0; /* success */ +} + +#define MAX_KERN_INDEX 504 + +GLYPH ReverseTranslate(PFontFace face, USHORT index) { + ULONG i; + GLYPH newidx = 0; + + /* TODO: enable larger fonts */ + for (i = 0; i < MAX_KERN_INDEX; i++) { + newidx = PM2TT(face->charMap, + face->charMode, + i); + if (newidx == index) + break; + } + if (i < MAX_KERN_INDEX) + return i; + else + return 0; +} + +/****************************************************************************/ +/* */ +/* QueryFaceAttr */ +/* */ +/* Return various info about font face */ +/* */ +LONG _System QueryFaceAttr( HFC hfc, + ULONG iQuery, + PBYTE pBuffer, + ULONG cb, + PGLYPH pagi, + GLYPH giStart ) +{ + int count, i = 0; + PFontSize size; + PFontFace face; + static TT_Face_Properties properties; + TT_OS2 *pOS2; + ABC_TRIPLETS* pt; + + COPY("QueryFaceAttr: hfc = "); CATI((int) hfc); CAT("\r\n"); WRITE; + + size = getFontSize(hfc); + if (!size) + ERRRET(-1) /* error, invalid context handle */ + + face = &(size->file->faces[size->faceIndex]); + + if (iQuery == FD_QUERY_KERNINGPAIRS) + { + TT_Kern_0 kerntab; /* actual kerning table */ + ULONG used = 0; /* # bytes used in output buffer */ + FD_KERNINGPAIRS *kpair; + USHORT *kernIndices, idx; + + count = cb / sizeof(FD_KERNINGPAIRS); + + COPY("QUERY_KERNINGPAIRS, "); CATI((int) count); + CAT("\r\n"); WRITE; +#if 1 + + if (face->directory.tables == NULL) + return 0; /* no kerning info provided */ + /* !!!! could use better error checking */ + /* Only format 0 is supported (which is what M$ recommends) */ + if (face->directory.tables[0].format != 0) /* need only format 0 */ + ERRRET(-1); + + error = TT_Load_Kerning_Table(face->face, 0); + if (error) + ERET1( Fail ); + + kerntab = face->directory.tables[0].t.kern0; + kpair = (PVOID)pBuffer; + + if (face->kernIndices == NULL) { + TT_Get_Face_Properties( face->face, &properties ); + error = ALLOC(face->kernIndices, + properties.num_Glyphs * sizeof (USHORT)); + if (error) + ERET1( Fail ); + + /* fill all entries with -1s */ + memset(face->kernIndices, 0xFF, + properties.num_Glyphs * sizeof (USHORT)); + } + + kernIndices = face->kernIndices; + + while ((i < kerntab.nPairs) && (i < count)) + { + idx = kerntab.pairs[i].left; + if (kernIndices[idx] == (USHORT)-1) + kernIndices[idx] = ReverseTranslate(face, idx); + kpair->giFirst = kernIndices[idx]; + idx = kerntab.pairs[i].right; + if (kernIndices[idx] == (USHORT)-1) + kernIndices[idx] = ReverseTranslate(face, idx); + kpair->giSecond = kernIndices[idx]; + kpair->eKerningAmount = kerntab.pairs[i].value; + kpair++; + i++; + } + + COPY("Returned kerning pairs: "); CATI(i); CAT("\r\n"); WRITE; + return i; /* # items filled */ +#else + return 0; /* no kerning support */ + +#endif + } + + if (iQuery == FD_QUERY_ABC_WIDTHS) + { + count = cb / sizeof(ABC_TRIPLETS); + + COPY("QUERY_ABC_WIDTHS, "); CATI((int) count); + CAT(" items, giStart = "); CATI((int) giStart); + if (pBuffer == NULL) + CAT(" NULL buffer"); + CAT("\r\n"); WRITE; + + /* This call never fails - no error check needed */ + TT_Get_Face_Properties( face->face, &properties ); + + pt = (ABC_TRIPLETS*)pBuffer; + for (i = giStart; i < giStart + count; i++, pt++) + { + int index; + unsigned short wid; + static unsigned short adv_widths [2]; + static unsigned short adv_heights[2]; + + static unsigned short widths[2], heights[2]; + static short lefts [2], tops [2]; + + index = PM2TT( face->charMap, + face->charMode, + i ); + + /* get advances and bearings */ + if (size->vertical && properties.vertical && 0) /* TODO: enable */ + error = TT_Get_Face_Metrics( face->face, index, index, + lefts, adv_widths, tops, adv_heights ); + else + error = TT_Get_Face_Metrics( face->face, index, index, + lefts, adv_widths, NULL, NULL ); + + if (error) + goto Broken_Glyph; + + /* skip complicated calculations for fixed fonts */ + if (face->flags & FC_FLAG_FIXED_WIDTH) { + wid = adv_widths[0] - lefts[0]; + } + else { /* proportianal font, it gets trickier */ + /* store glyph widths for DBCS fonts + - needed for reasonable performance */ + if (face->flags & FC_FLAG_DBCS_FACE) { + if (face->widths == NULL) { + error = ALLOC(face->widths, + properties.num_Glyphs * sizeof (USHORT)); + if (error) + goto Broken_Glyph; /* this error really shouldn't happen */ + + /* tag all entries as unused */ + memset(face->widths, 0xFF, + properties.num_Glyphs * sizeof (USHORT)); + } + if (face->widths[index] == 0xFFFF) { /* get from file if needed */ + error = TT_Get_Face_Widths( face->face, index, index, + widths, heights ); + if (error) + goto Broken_Glyph; + + /* save for later */ + wid = face->widths[index] = widths[0]; + } + else + wid = face->widths[index]; + } + /* 'small' font, no need to remember widths, OS/2 takes care of it */ + else { + /* get width or height - use ftxwidth.c */ + error = TT_Get_Face_Widths( face->face, index, index, + widths, heights ); + if (error) + goto Broken_Glyph; + + wid = widths[0]; + } + } + + if (size->vertical && !is_HALFCHAR(i)) + { + if (properties.vertical && 0) /* TODO: enable */ + { + pt->lA = tops[0]; + pt->ulB = heights[0]; + pt->lC = adv_heights[0] - pt->lA - pt->ulB; + } + else + { + pt->lA = pt->lC = 0; + pt->ulB = properties.os2->usWinAscent + + properties.os2->usWinDescent; + } + + } + else + { + pt->lA = lefts[0]; + pt->ulB = wid; + pt->lC = adv_widths[0] - pt->lA - pt->ulB; + } + +#ifdef NETSCAPE_FIX + if (face->charMode != TRANSLATE_SYMBOL && + !size->vertical) { + if (face->flags & FC_FLAG_FIXED_WIDTH) { + pt->ulB = pt->ulB + pt->lA + pt->lC; + pt->lA = 0; + pt->lC = 0; + } else if (i == 32) { + /* return nonzero B width for 'space' */ + pt->ulB = adv_widths[0] - 2 * lefts[0]; + pt->lC = lefts[0]; + } + } +#endif + continue; + + Broken_Glyph: /* handle broken glyphs gracefully */ + pt->lA = pt->lC = 0; + + if (size->vertical && !is_HALFCHAR(i)) + pt->ulB = properties.os2->usWinAscent + + properties.os2->usWinDescent; + else + pt->ulB = properties.horizontal->xMax_Extent; + + } + } + + TT_Flush_Face(face->face); + return count; /* number of entries filled in */ + +Fail: + TT_Flush_Face(face->face); + return -1; +} + +/****************************************************************************/ +/* */ +/* QueryCharAttr : */ +/* */ +/* Return glyph attributes, basically glyph's bit-map or outline */ +/* some variables are declared static to conserve stack space. */ +/* */ +LONG _System QueryCharAttr( HFC hfc, + PCHARATTR pCharAttr, + PBITMAPMETRICS pbmm ) +{ + static TT_Raster_Map bitmap; + static TT_Outline outline; + static TT_BBox bbox; + + PFontSize size; + PFontFace face; + LONG temp; + PBYTE pb; + int i, j; + ULONG cb; + + size = getFontSize(hfc); + if (!size) + ERRRET(-1) /* error, invalid context handle */ + + face = &(size->file->faces[size->faceIndex]); + + error = TT_Load_Glyph( size->instance, + face->glyph, + PM2TT( face->charMap, + face->charMode, + pCharAttr->gi), + TTLOAD_DEFAULT); + + if (error) + { + if (i == 0) + ERET1( Fail ) /* this font's no good, return error */ + else + { /* try to recover quietly */ + error = TT_Load_Glyph( size->instance, + face->glyph, + 0, + TTLOAD_DEFAULT); + if (error) { + COPY("Error code is "); CATI(error); CAT("\r\n"); WRITE; + ERET1( Fail ); + } + } + } + + TT_Flush_Face( face->face ); + + error = TT_Get_Glyph_Outline( face->glyph, &outline ); + if (error) + ERRRET(-1); + + /* --- Vertical fonts handling----------------------------------- */ + + if (size->vertical && !is_HALFCHAR(pCharAttr->gi)) { + TT_Matrix vertMatrix; + + vertMatrix.xx = 0x00000; + vertMatrix.xy = -0x10000; + vertMatrix.yx = 0x10000; + vertMatrix.yy = 0x00000; + TT_Get_Outline_BBox( &outline, &bbox ); + + /* rotate outline 90 degrees counterclockwise */ + TT_Transform_Outline(&outline, &vertMatrix); + + /* move outline to the right to adjust for rotation */ + TT_Translate_Outline(&outline, bbox.yMax, 0); + /* move outline down a bit */ + TT_Translate_Outline(&outline, 0, bbox.yMin); + } + + if (size->transformed) + TT_Transform_Outline( &outline, &size->matrix ); + + /* --- Outline processing --------------------------------------- */ + + if ( pCharAttr->iQuery & FD_QUERY_OUTLINE ) + { + if (pCharAttr->cbLen == 0) /* send required outline size in bytes */ + return GetOutlineLen( &outline ); + + return GetOutline( &outline, pCharAttr->pBuffer ); + } + + /* --- Bitmap processing ---------------------------------------- */ + + TT_Get_Outline_BBox( &outline, &bbox ); + + /* the following seems to be necessary for rotated glyphs */ + if (size->transformed) { + bbox.xMax = bbox.xMin = 0; + for (i = 0; i < outline.n_points; i++) { + if (bbox.xMin > outline.points[i].x) + bbox.xMin = outline.points[i].x; + if (bbox.xMax < outline.points[i].x) + bbox.xMax = outline.points[i].x; + } + } + /* grid-fit the bbox */ + bbox.xMin &= -64; + bbox.yMin &= -64; + + bbox.xMax = (bbox.xMax+63) & -64; + bbox.yMax = (bbox.yMax+63) & -64; + + if (pCharAttr->iQuery & FD_QUERY_BITMAPMETRICS) + { + /* fill in bitmap metrics */ + /* metrics values are in 26.6 format ! */ + pbmm->sizlExtent.cx = (bbox.xMax - bbox.xMin) >> 6; + pbmm->sizlExtent.cy = (bbox.yMax - bbox.yMin) >> 6; + pbmm->cyAscent = 0; + pbmm->pfxOrigin.x = bbox.xMin << 10; + pbmm->pfxOrigin.y = bbox.yMax << 10; + + if (!(pCharAttr->iQuery & FD_QUERY_CHARIMAGE)) + return sizeof(*pbmm); + } + + /* --- actual bitmap processing here --- */ + if (pCharAttr->iQuery & FD_QUERY_CHARIMAGE) + { + /* values in 26.6 format ?!? */ + bitmap.width = (bbox.xMax - bbox.xMin) >> 6; + bitmap.rows = (bbox.yMax - bbox.yMin) >> 6; + /* width rounded up to nearest multiple of 4 */ + bitmap.cols = ((bitmap.width + 31) / 8) & -4; + bitmap.flow = TT_Flow_Down; + bitmap.bitmap = pCharAttr->pBuffer; + bitmap.size = bitmap.rows * bitmap.cols; + + if (pCharAttr->cbLen == 0) + return bitmap.size; + + if (bitmap.size > pCharAttr->cbLen) + ERRRET(-1) /* otherwise we might overwrite something */ + + /* clean provided buffer (unfortunately necessary) */ + memset(bitmap.bitmap, 0, pCharAttr->cbLen); + + error = TT_Get_Glyph_Bitmap( face->glyph, + &bitmap, + -bbox.xMin, + -bbox.yMin ); + if (error) + ERRRET(-1); /* engine error */ + + return bitmap.size; /* return # of bytes */ + } + ERRRET(-1) /* error */ + +Fail: + TT_Flush_Face(face->face); + return -1; +} + +/****************************************************************************/ +/* */ +/* QueryFullFaces : */ +/* */ +/* Query names of all faces in this file */ +/* */ +LONG _System QueryFullFaces( HFF hff, + PVOID pBuff, + PULONG buflen, + PULONG cFontCount, + ULONG cStart ) +{ + COPY("!QueryFullFaces: hff = "); CATI((int) hff); CAT("\r\n"); WRITE; + ERRRET(-1) /* error ? */ +} + +/*---------------------------------------------------------------------------*/ +/* end of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/****************************************************************************/ +/* LimitsInit reads OS2.INI and sets up max_open_files limit, possibly */ +/* other variables as well. */ +/* */ +static void LimitsInit(void) { + char cBuffer[25]; /* ought to be enough */ + + if (PrfQueryProfileString(HINI_USERPROFILE, "FreeType/2", "OPENFACES", + NULL, cBuffer, sizeof(cBuffer)) > 0) { + max_open_files = atoi(cBuffer); + + if (max_open_files < 8) /* ensure limit isn't too low */ + max_open_files = 8; + } + else + max_open_files = 12; /* reasonable default */ +} + + +/****************************************************************************/ +/* my_itoa is used only in the following function GetUdcInfo. */ +/* Works pretty much like expected. */ +/* */ +void my_itoa(int num, char *cp) { + char temp[10]; + int i = 0; + + do { + temp[i++] = (num % 10) + '0'; + num /= 10; + } while (num); /* enddo */ + + while (i--) { + *cp++ = temp[i]; + } /* endwhile */ + *cp = '\0'; +} + +/****************************************************************************/ +/* GetUdcInfo determines the UDC ranges used */ +/* */ +VOID GetUdcInfo(VOID) { + ULONG ulUdc, ulUdcInfo, i; + PVOID gPtr; + HINI hini; + CHAR szCpStr[10] = "CP"; + + DosQueryCp(sizeof(ulCp), (ULONG*)&ulCp, &i); /* find out default codepage */ + my_itoa((INT) ulCp, szCpStr + 2); /* convert to ASCII */ + +} + +/****************************************************************************/ +/* LangInit determines language used at DLL startup, non-zero return value */ +/* means error. */ +/* This code is crucial, because it determines behaviour of the font driver */ +/* with regard to language encodings it will use. */ +static ULONG LangInit(void) { + COUNTRYCODE cc = {0, 0}; + COUNTRYINFO ci; + ULONG cilen; + + isGBK = FALSE; + + GetUdcInfo(); /* get User Defined Character info */ + + /* get country info; ci.country then contains country code */ + if (DosQueryCtryInfo(sizeof(ci), &cc, &ci, &cilen)) + return -1; + /* get DBCS lead byte values for later use */ + DosQueryDBCSEnv(sizeof(DBCSLead), &cc, DBCSLead); + + uLastGlyph = 383; + switch (ci.country) { + case 81: /* Japan */ + iLangId = TT_MS_LANGID_JAPANESE_JAPAN; + ScriptTag = *(ULONG *) "kana"; + LangSysTag = *(ULONG *) "JAN "; + pGlyphlistName = "PMJPN"; + uLastGlyph = 890; + break; + + case 88: /* Taiwan */ + iLangId = TT_MS_LANGID_CHINESE_TAIWAN; + ScriptTag = *(ULONG *) "kana"; + LangSysTag = *(ULONG *) "CHT "; + pGlyphlistName = "PMCHT"; + break; + + case 86: /* People's Republic of China */ + if (ci.codepage == 1386 || ulCp[0] == 1386 || ulCp[1] == 1386) { + isGBK = TRUE; + } /* endif */ + iLangId = TT_MS_LANGID_CHINESE_PRC; + ScriptTag = *(ULONG *) "kana"; + LangSysTag = *(ULONG *) "CHS "; + pGlyphlistName = "PMPRC"; + break; + + case 82: /* Korea */ + iLangId = TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA; + ScriptTag = *(ULONG *) "hang"; + LangSysTag = *(ULONG *) "KOR "; + pGlyphlistName = "PMKOR"; + uLastGlyph = 949; + break; + + case 30: /* Greece - for Alex! */ + iLangId = TT_MS_LANGID_GREEK_GREECE; + + default: /* none of the above countries */ + ScriptTag = *(ULONG *) ""; + LangSysTag = *(ULONG *) ""; + break; + } /* endswitch */ + + return 0; +} + +/****************************************************************************/ +/* */ +/* FirstInit : */ +/* */ +/* Called when font driver is loaded for the first time. Performs the */ +/* necessary one-time initialization. */ +ULONG FirstInit(void) { + LONG lReqCount; + ULONG ulCurMaxFH; + + #ifdef DEBUG + ULONG Action; + #endif /* DEBUG */ + #ifdef DEBUG + DosOpen("C:\\FTIFI.LOG", &LogHandle, &Action, 0, FILE_NORMAL, + OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS, + OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_WRITE_THROUGH | + OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYWRITE | OPEN_ACCESS_WRITEONLY, + NULL); + COPY("FreeType/2 loaded.\r\n"); + WRITE; + #endif /* DEBUG */ + + /* increase # of file handles by five to be on the safe side */ + lReqCount = 5; + DosSetRelMaxFH(&lReqCount, &ulCurMaxFH); + error = TT_Init_FreeType(&engine); /* turn on the FT engine */ + if (error) + return 0; /* exit immediately */ + error = TT_Init_Kerning_Extension(engine); /* load kerning support */ + COPY("FreeType Init called\r\n"); + WRITE; + + if (LangInit()) /* initialize NLS */ + return 0; /* exit on error */ + COPY("NLS initialized.\r\n"); + WRITE; + + LimitsInit(); /* initialize max_open_files */ + COPY("Open faces limit set to "); CATI(max_open_files); CAT("\r\n"); + WRITE; + + if (error) + return 0; /* exit immediately */ + COPY("Initialization successful.\r\n"); + WRITE; + return 1; +} + + +/****************************************************************************/ +/* */ +/* FinalTerm : */ +/* */ +/* Called when font driver is unloaded for the last time time. Performs */ +/* final clean-up, shuts down engine etc. */ +ULONG FinalTerm(void) { + PListElement cur; + PListElement tmp; + + /* throw away elements from 'free elements' list */ + cur = free_elements; + while (cur != NULL) { + tmp = cur; + cur = cur->next; + FREE(tmp); + } + + /* turn off engine */ + TT_Done_FreeType(engine); + + #ifdef DEBUG + COPY("FreeType/2 terminated.\r\n"); + WRITE; + DosClose(LogHandle); + #endif + return 1; +} +/****************************************************************************/ +/* */ +/* _DLL_InitTerm : */ +/* */ +/* This is the DLL Initialization/termination function. It initializes */ +/* the FreeType engine and some internal structures at startup. It cleans */ +/* up the UCONV cache at process termination. */ +ULONG _System _DLL_InitTerm(ULONG hModule, ULONG ulFlag) { + switch (ulFlag) { + case 0: /* initializing */ + if (++ulProcessCount == 1) + return FirstInit(); /* loaded for the first time */ + else + return 1; + + case 1: { /* terminating */ + int i; + /* clean UCONV cache */ + #ifdef USE_UCONV + CleanUCONVCache(); + #endif + if(--ulProcessCount == 0) + return FinalTerm(); + else + return 1; + } + } + return 0; +} + +/****************************************************************************/ +/* */ +/* interfaceSEId (Interface-specific Encoding Id) determines what encoding */ +/* the font driver should use if a font includes a Unicode encoding. */ +/* */ +LONG interfaceSEId(TT_Face face, BOOL UDCflag, LONG encoding) { + ULONG range1 = 0; + ULONG bits, mask; + TT_OS2 *pOS2; + static TT_Face_Properties props; + + TT_Get_Face_Properties(face, &props); + pOS2 = props.os2; + + if (encoding == PSEID_UNICODE) { + + /* if font is 'small', use PM383; this is done because of DBCS + systems */ + if (!UDCflag && props.num_Glyphs < 1024) { + encoding = PSEID_PM383; + } else if (pOS2->version >= 1) { + /* + * * OS/2 table version 1 and later contains codepage * + * bitfield to support multiple codepages. + */ + range1 = pOS2->ulCodePageRange1; + bits = 0; + + if (range1 & OS2_CP1_ANSI_OEM_JAPANESE_JIS) + bits++; + if (range1 & OS2_CP1_ANSI_OEM_CHINESE_SIMPLIFIED) + bits++; + if (range1 & OS2_CP1_ANSI_OEM_CHINESE_TRADITIONAL) + bits++; + if (range1 & OS2_CP1_ANSI_OEM_KOREAN_WANSUNG) + bits++; + if (range1 & OS2_CP1_ANSI_OEM_KOREAN_JOHAB) + bits++; + + /* Note: if font supports more than one of the following codepages, + * encoding is left at PSEID_UNICODE! + */ + if (bits == 1) { + switch (range1) { + case OS2_CP1_ANSI_OEM_JAPANESE_JIS: + encoding = PSEID_SHIFTJIS; + break; + case OS2_CP1_ANSI_OEM_CHINESE_SIMPLIFIED: + encoding = PSEID_PRC; + break; + case OS2_CP1_ANSI_OEM_CHINESE_TRADITIONAL: + encoding = PSEID_BIG5; + break; + case OS2_CP1_ANSI_OEM_KOREAN_WANSUNG: + encoding = PSEID_WANSUNG; + break; + case OS2_CP1_ANSI_OEM_KOREAN_JOHAB: + encoding = PSEID_JOHAB; + break; + default: + break; + } /* endswitch */ + } /* endif */ + } else { + /* + * The codepage range bitfield is not available. + * Codepage must be assumed from the COUNTRY setting. + * This means the user is on his own. + */ + + switch (iLangId) { + case TT_MS_LANGID_JAPANESE_JAPAN: + encoding = PSEID_SHIFTJIS; + break; + case TT_MS_LANGID_CHINESE_PRC: + case TT_MS_LANGID_CHINESE_SINGAPORE: + encoding = PSEID_PRC; + break; + case TT_MS_LANGID_CHINESE_TAIWAN: + case TT_MS_LANGID_CHINESE_HONG_KONG: + encoding = PSEID_BIG5; + break; + case TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA: + encoding = PSEID_WANSUNG; + break; + case TT_MS_LANGID_KOREAN_JOHAB_KOREA: + encoding = PSEID_JOHAB; + break; + } + + } + } + return encoding; +} + +/****************************************************************************/ +/* */ +/* LookupName : */ +/* */ +/* Look for a TrueType name by index, prefer current language */ +/* */ +static char* LookupName(TT_Face face, int index ) +{ + static char name_buffer[FACESIZE + 2]; + int name_len = 0; + int i, j, n; + + USHORT platform, encoding, language, id; + char* string; + USHORT string_len; + + int found; + + n = TT_Get_Name_Count( face ); + if ( n < 0 ) + return NULL; + + for ( i = 0; i < n; i++ ) + { + TT_Get_Name_ID( face, i, &platform, &encoding, &language, &id ); + TT_Get_Name_String( face, i, &string, &string_len ); + + if ( id == index ) + { + found = 0; + + /* Try to find an appropriate name */ + if ( platform == TT_PLATFORM_MICROSOFT ) + for ( j = 5; j >= 0; j-- ) + if ( encoding == j ) /* Microsoft ? */ + switch (language) + { + case TT_MS_LANGID_CHINESE_TAIWAN: + if (encoding == PSEID_PRC) + found = 1; + break; + + case TT_MS_LANGID_JAPANESE_JAPAN: + if (encoding == PSEID_SHIFTJIS) + found = 1; + break; + + /* these aren't all possibilities; just the most likely ones */ + case TT_MS_LANGID_ENGLISH_UNITED_STATES : + case TT_MS_LANGID_ENGLISH_UNITED_KINGDOM : + case TT_MS_LANGID_ENGLISH_AUSTRALIA : + case TT_MS_LANGID_ENGLISH_CANADA : + case TT_MS_LANGID_ENGLISH_NEW_ZEALAND : + case TT_MS_LANGID_ENGLISH_IRELAND : + case TT_MS_LANGID_ENGLISH_SOUTH_AFRICA : + found = 1; + break; + } + + if ( !found && platform == 0 && language == 0 ) + found = 1; + + if (found) + { + if (language == TT_MS_LANGID_CHINESE_TAIWAN || + language == TT_MS_LANGID_JAPANESE_JAPAN) { + /* it's a DBCS string, copy everything except NULLs */ + int i,j; + if (string_len > FACESIZE - 1) + string_len = FACESIZE - 1; + + for (i=0, j=0; i FACESIZE * 2) + string_len = FACESIZE * 2; + + name_len = 0; + + for ( i = 1; i < string_len; i += 2 ) + name_buffer[name_len++] = string[i]; + + name_buffer[name_len] = '\0'; + + return name_buffer; + } + } + } + } + + /* Not found */ + return NULL; +} + +/****************************************************************************/ +/* */ +/* GetCharMap : */ +/* */ +/* A function to find a suitable charmap, searching in the following */ +/* order of importance : */ +/* */ +/* 1) Windows Unicode */ +/* 2) Apple Unicode */ +/* 3) ROC (Taiwan) */ +/* 4) ShiftJIS (Japan) */ +/* 5) Apple Roman */ +/* 6) Windows Symbol - not really supported */ +/* */ +/* High word of returned ULONG contains type of encoding */ +/* */ +static ULONG GetCharmap(TT_Face face) +{ + int n; /* # of encodings (charmaps) available */ + USHORT platform, encoding; + int i, best, bestVal, val; + + n = TT_Get_CharMap_Count(face); + + if (n < 0) /* no encodings at all; don't yet know what the best course of action would be */ + ERRRET(-1) /* such font should probably be rejected */ + + bestVal = 16; + best = -1; + + for (i = 0; i < n; i++) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + + /* Windows Unicode is the highest encoding, return immediately */ + /* if we find it.. */ + if ( platform == TT_PLATFORM_MICROSOFT && encoding == TT_MS_ID_UNICODE_CS) + return i; + + /* otherwise, compare it to the best encoding found */ + val = -1; + if (platform == TT_PLATFORM_APPLE_UNICODE) + val = 2; + else if (platform == TT_PLATFORM_MICROSOFT + && encoding == TT_MS_ID_BIG_5) + val = 3; + else if (platform == TT_PLATFORM_MICROSOFT + && encoding == TT_MS_ID_SJIS) + val = 4; + else if (platform == TT_PLATFORM_MACINTOSH + && encoding == TT_MAC_ID_ROMAN) + val = 5; + else if (platform == TT_PLATFORM_MICROSOFT + && encoding == TT_MS_ID_SYMBOL_CS) + val = 6; + + if (val > 0 && val <= bestVal) + { + bestVal = val; + best = i; + } + } + + if (i < 0) + return 0; /* we didn't find any suitable encoding !! */ + + if (bestVal == 3) /* Taiwanese font */ + best |= ( TRANSLATE_BIG5 << 16 ); + + if (bestVal == 4) /* Japanese font */ + best |= ( TRANSLATE_SJIS << 16 ); + + if (bestVal == 5) /* for Apple Roman encoding only, this */ + best |= ( TRANSLATE_SYMBOL << 16 ); /* means no translation should be performed */ + + return best; +} + +/****************************************************************************/ +/* */ +/* GetOutlineLen : */ +/* */ +/* Used to compute the size of an outline once it is converted to */ +/* OS/2's specific format. The translation is performed by the later */ +/* function called simply "GetOultine". */ +/* */ +static int GetOutlineLen(TT_Outline *ol) +{ + int index; /* current point's index */ + BOOL on_curve; /* current point's state */ + int i, start = 0; + int first, last; + ULONG cb = 0; + + /* loop thru all contours in a glyph */ + for ( i = 0; i < ol->n_contours; i++ ) { + + cb += sizeof(POLYGONHEADER); + + first = start; + last = ol->contours[i]; + + on_curve = (ol->flags[first] & 1); + index = first; + + /* process each contour point individually */ + while ( index < last ) { + index++; + + if ( on_curve ) { + /* the previous point was on the curve */ + on_curve = ( ol->flags[index] & 1 ); + if ( on_curve ) { + /* two successive on points => emit segment */ + cb += sizeof(PRIMLINE); + } + } + else { + /* the previous point was off the curve */ + on_curve = ( ol->flags[index] & 1 ); + if ( on_curve ) { + /* reaching an `on' point */ + cb += sizeof(PRIMSPLINE); + } + else { + /* two successive `off' points => create middle point */ + cb += sizeof(PRIMSPLINE); + } + } + } + + /* end of contour, close curve cleanly */ + if ( ol->flags[first] & 1 ) + { + if ( on_curve ) + cb += sizeof(PRIMLINE); + else + cb += sizeof(PRIMSPLINE); + } + else + if (!on_curve) + cb += sizeof(PRIMSPLINE); + + start = ol->contours[i] + 1; + + } + return cb; /* return # bytes used */ +} + +/****************************************************************************/ +/* */ +/* a few global variables used in the following functions */ +/* */ +static ULONG cb = 0, polycb; +static LONG lastX, lastY; +static PBYTE pb; +static POINTFX Q, R; +static POLYGONHEADER hdr = {0, FD_POLYGON_TYPE}; +static PRIMLINE line = {FD_PRIM_LINE}; +static PRIMSPLINE spline = {FD_PRIM_SPLINE}; + +/****************************************************************************/ +/* */ +/* LineFrom : */ +/* */ +/* add a line segment to the PM outline that GetOultine is currently */ +/* building. */ +/* */ +static void Line_From(LONG x, LONG y) { + line.pte.x = x << 10; + line.pte.y = y << 10; + /* store to output buffer */ + memcpy(&(pb[cb]), &line, sizeof(line)); + cb += sizeof(PRIMLINE); + polycb += sizeof(PRIMLINE); +} + + +/****************************************************************************/ +/* */ +/* BezierFrom : */ +/* */ +/* add a bezier arc to the PM outline that GetOutline is currently */ +/* buidling. The second-order Bezier is trivially converted to its */ +/* equivalent third-order form. */ +/* */ +static void Bezier_From( LONG x0, LONG y0, LONG x2, LONG y2, LONG x1, LONG y1 ) { + spline.pte[0].x = x0 << 10; + spline.pte[0].y = y0 << 10; + /* convert from second-order to cubic Bezier spline */ + Q.x = (x0 + 2 * x1) / 3; + Q.y = (y0 + 2 * y1) / 3; + R.x = (x2 + 2 * x1) / 3; + R.y = (y2 + 2 * y1) / 3; + spline.pte[1].x = Q.x << 10; + spline.pte[1].y = Q.y << 10; + spline.pte[2].x = R.x << 10; + spline.pte[2].y = R.y << 10; + /* store to output buffer */ + memcpy(&(pb[cb]), &spline, sizeof(spline)); + cb += sizeof(PRIMSPLINE); + polycb += sizeof(PRIMSPLINE); +} + + +/****************************************************************************/ +/* */ +/* GetOutline : */ +/* */ +/* Translate a FreeType glyph outline into PM format. The buffer is */ +/* expected to be of the size returned by a previous call to the */ +/* function GetOutlineLen(). */ +/* */ +/* This code is taken right from the FreeType ttraster.c source, and */ +/* subsequently modified to emit PM segments and arcs. */ +/* */ +static int GetOutline(TT_Outline *ol, PBYTE pbuf) { + LONG x, y; /* current point */ + LONG cx, cy; /* current Bezier control point */ + LONG mx, my; /* current middle point */ + LONG x_first, y_first; /* first point's coordinates */ + LONG x_last, y_last; /* last point's coordinates */ + + int index; /* current point's index */ + BOOL on_curve; /* current point's state */ + int i, start = 0; + int first, last; + ULONG polystart; + + pb = pbuf; + cb = 0; + + /* loop thru all contours in a glyph */ + for ( i = 0; i < ol->n_contours; i++ ) { + + polystart = cb; /* save this polygon's start offset */ + polycb = sizeof(POLYGONHEADER); /* size of this polygon */ + cb += sizeof(POLYGONHEADER); + + first = start; + last = ol->contours[i]; + + x_first = ol->points[first].x; + y_first = ol->points[first].y; + + x_last = ol->points[last].x; + y_last = ol->points[last].y; + + lastX = cx = x_first; + lastY = cy = y_first; + + on_curve = (ol->flags[first] & 1); + index = first; + + /* check first point to determine origin */ + if ( !on_curve ) { + /* first point is off the curve. Yes, this happens... */ + if ( ol->flags[last] & 1 ) { + lastX = x_last; /* start at last point if it */ + lastY = y_last; /* is on the curve */ + } + else { + /* if both first and last points are off the curve, */ + /* start at their middle and record its position */ + /* for closure */ + lastX = (lastX + x_last)/2; + lastY = (lastY + y_last)/2; + + x_last = lastX; + y_last = lastY; + } + } + + /* now process each contour point individually */ + while ( index < last ) { + index++; + x = ( ol->points[index].x ); + y = ( ol->points[index].y ); + + if ( on_curve ) { + /* the previous point was on the curve */ + on_curve = ( ol->flags[index] & 1 ); + if ( on_curve ) { + /* two successive on points => emit segment */ + Line_From( lastX, lastY ); /*x, y*/ + lastX = x; + lastY = y; + } + else { + /* else, keep current control point for next bezier */ + cx = x; + cy = y; + } + } + else { + /* the previous point was off the curve */ + on_curve = ( ol->flags[index] & 1 ); + if ( on_curve ) { + /* reaching an `on' point */ + Bezier_From(lastX, lastY, x, y, cx, cy ); + lastX = x; + lastY = y; + } + else { + /* two successive `off' points => create middle point */ + mx = (cx + x) / 2; + my = (cy + y)/2; + + Bezier_From( lastX, lastY, mx, my, cx, cy ); + lastX = mx; + lastY = my; + + cx = x; + cy = y; + } + } + } + + /* end of contour, close curve cleanly */ + if ( ol->flags[first] & 1 ) { + if ( on_curve ) + Line_From( lastX, lastY); /* x_first, y_first );*/ + else + Bezier_From( lastX, lastY, x_first, y_first, cx, cy ); + } + else + if (!on_curve) + Bezier_From( lastX, lastY, x_last, y_last, cx, cy ); + + start = ol->contours[i] + 1; + + hdr.cb = polycb; + memcpy(&(pb[polystart]), &hdr, sizeof(hdr)); + + } + return cb; /* return # bytes used */ +} + diff --git a/contrib/ftos2/ifi/ftifi.h b/contrib/ftos2/ifi/ftifi.h new file mode 100644 index 0000000..e8be787 --- /dev/null +++ b/contrib/ftos2/ifi/ftifi.h @@ -0,0 +1,305 @@ +/* + Conversion from OS/2 UGL to Unicode + + Copyright (C) 1997 Robert Muchsel + Copyright (C) 1997,1998 Michal Necasek + + All entries that were previously 0xFFFF were changed to 0x0000 because + TrueType 'missing glyph' has index 0 +*/ + +#ifndef _FTIFI_H_INCLUDED_ +#define _FTIFI_H_INCLUDED_ + +/* Platform-specific Encoding IDs for MS platform */ +#define PSEID_SYMBOL 0 +#define PSEID_UNICODE 1 +#define PSEID_SHIFTJIS 2 +#define PSEID_BIG5 3 +#define PSEID_PRC 4 +#define PSEID_WANSUNG 5 +#define PSEID_JOHAB 6 +/* defined by me! */ +#define PSEID_PM383 100 + +/* bit masks for determining supported codepages */ +#define OS2_CP1_ANSI_OEM_JAPANESE_JIS (1 << 17) +#define OS2_CP1_ANSI_OEM_CHINESE_SIMPLIFIED (1 << 18) +#define OS2_CP1_ANSI_OEM_CHINESE_TRADITIONAL (1 << 19) +#define OS2_CP1_ANSI_OEM_KOREAN_WANSUNG (1 << 20) +#define OS2_CP1_ANSI_OEM_KOREAN_JOHAB (1 << 21) + +/* defines for character translation */ +/* from Unicode to UGL */ +#define TRANSLATE_UGL 0 +/* Symbol - no translation */ +#define TRANSLATE_SYMBOL 1 +/* Unicode - no translation */ +#define TRANSLATE_UNICODE 2 +/* Big5 - no translation */ +#define TRANSLATE_BIG5 4 +/* ShiftJIS - no translation */ +#define TRANSLATE_SJIS 5 +/* from Unicode to Big5 */ +#define TRANSLATE_UNI_BIG5 16 +/* from Unicode to ShiftJIS */ +#define TRANSLATE_UNI_SJIS 17 + + +#define MAX_GLYPH 504 +/* I suppose more than 949 is never used */ +/* 504 should be OK for (most) European and American countries */ + +#ifndef USE_UCONV +static const int UGL2Uni[MAX_GLYPH + 1] = { + + /* PM383 UGL mapping */ + + /* 0..9 */ + 0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25d8, 0x25cb, + /* 10..19 */ + 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c, 0x25ba, 0x25c4, 0x2195, 0x203c, + /* 20..29 */ + 0xb6, 0xa7, 0x25ac, 0x21a8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, + /* 30..39 */ + 0x25b2, 0x25bc, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + /* 40..49 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + /* 50..59 */ + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + /* 60..69 */ + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + /* 70..79 */ + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + /* 80..89 */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + /* 90..99 */ + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + /* 100..109 */ + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + /* 110..119 */ + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + /* 120..129 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x2302, 0xc7, 0xfc, + /* 130..139 */ + 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7, 0xea, 0xeb, 0xe8, 0xef, + /* 140..149 */ + 0xee, 0xec, 0xc4, 0xc5, 0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, + /* 150..159 */ + 0xfb, 0xf9, 0xff, 0xd6, 0xdc, 0xf8, 0xa3, 0xd8, 0xd7, 0x192, + /* 160..169 */ + 0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba, 0xbf, 0xae, + /* 170..179 */ + 0xac, 0xbd, 0xbc, 0xa1, 0xab, 0xbb, 0x2591, 0x2592, 0x2593, 0x2502, + /* 180..189 */ + 0x2524, 0xc1, 0xc2, 0xc0, 0xa9, 0x2563, 0x2551, 0x2557, 0x255d, 0xa2, + /* 190..199 */ + 0xa5, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0xe3, 0xc3, + /* 200..209 */ + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0xa4, 0xf0, 0xd0, + /* 210..219 */ + 0xca, 0xcb, 0xc8, 0x131, 0xcd, 0xce, 0xcf, 0x2518, 0x250c, 0x2588, + /* 220..229 */ + 0x2584, 0xa6, 0xcc, 0x2580, 0xd3, 0xdf, 0xd4, 0xd2, 0xf5, 0xd5, + /* 230..239 */ + 0xb5, 0xfe, 0xde, 0xda, 0xdb, 0xd9, 0xfd, 0xdd, 0xaf, 0xb4, + /* 240..249 */ + 0xad, 0xb1, 0x2017, 0xbe, 0xb6, 0xa7, 0xf7, 0xb8, 0xb0, 0xa8, + /* 250..259 */ + 0xb7, 0xb9, 0xb3, 0xb2, 0x25a0, 0xa0, 0x20a7, 0x2310, 0x2561, 0x2562, + /* 260..269 */ + 0x2556, 0x2555, 0x255c, 0x255b, 0x255e, 0x255f, 0x2567, 0x2568, 0x2564, 0x2565, + /* 270..279 */ + 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x258c, 0x2590, 0x3b1, 0x393, + /* 280..289 */ + 0x3c0, 0x3a3, 0x3c3, 0x3c4, 0x3a6, 0x398, 0x3a9, 0x3b4, 0x221e, 0x3c6, + /* 290..299 */ + 0x3b5, 0x2229, 0x2261, 0x2265, 0x2264, 0x2320, 0x2321, 0x2248, 0x2219, 0x221a, + /* 300..309 */ + 0x207f, 0x2c9, 0x2d8, 0x2d9, 0x2da, 0x2dd, 0x2db, 0x2c7, 0x2018, 0x2019, + /* 310..318*/ + 0x201c, 0x201d, 0x2013, 0x2014, 0x2c6, 0x2dc, 0x201a, 0x201e, 0x2026, + + /* 319..329 */ + 0x2020, 0x2021, 0x2c6, 0x2030, 0x160, 0x2039, 0x152, 0x303, 0x2122, 0x161, 0x203a, + /* 330..339 */ + 0x153, 0x178, 0x11f, 0x11e, 0x130, 0x15f, 0x15e, 0x103, 0x102, 0x105, + /* 340..349 */ + 0x104, 0x107, 0x106, 0x10d, 0x10c, 0x10f, 0x10e, 0x111, 0x11b, 0x11a, + /* 350..359 */ + 0x119, 0x118, 0x13a, 0x139, 0x13e, 0x13d, 0x142, 0x141, 0x144, 0x143, + /* 360..369 */ + 0x148, 0x147, 0x151, 0x150, 0x155, 0x154, 0x159, 0x158, 0x15b, 0x15a, + /* 370..379 */ + 0x165, 0x164, 0x163, 0x162, 0x171, 0x170, 0x16f, 0x16e, 0x17a, 0x179, + /* 380..383 */ + 0x17e, 0x17d, 0x17c, 0x17b, + + /* I don't know whether the following are used by PM, but they are in + the I18N unicode library */ + /* yes they ARE used (for Cyrillic systems) */ + + /* 384..389 */ + 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, + /* 390..399 */ + 0x407, 0x408, 0x409, 0x40a, 0x40b, 0x40c, 0x40e, 0x40f, 0x410, 0x411, + /* 400..409 */ + 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41a, 0x41b, + /* 410..419 */ + 0x41c, 0x41d, 0x41e, 0x41f, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, + /* 420..429 */ + 0x426, 0x427, 0x428, 0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f, + /* 430..439 */ + 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, + /* 440..449 */ + 0x43a, 0x43b, 0x43c, 0x43d, 0x43e, 0x43f, 0x440, 0x441, 0x442, 0x443, + /* 450..459 */ + 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44a, 0x44b, 0x44c, 0x44d, + /* 460..469 */ + 0x44e, 0x44f, 0x2116, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, + /* 470..479 */ + 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0x45e, 0x45f, 0x490, 0x491, 0x156, + /* 480..489 */ + 0x12e, 0x100, 0x112, 0x116, 0x122, 0x136, 0x12a, 0x1eb, 0x145, 0x14c, + /* 490..499 */ + 0x172, 0x16a, 0x157, 0x12f, 0x101, 0x113, 0x117, 0x123, 0x137, 0x12b, + /* 500..504 */ + 0x13c, 0x146, 0x14d, 0x173, 0x16b + +#if MAX_GLYPH > 504 + , 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 510..519 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 520..529 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 530..539 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 540..549 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 550..559 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 560..569 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 570..579 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 580..589 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 590..599 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 600..609 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 610..619 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 620..629 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 630..639 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 640..649 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 650..659 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 660..669 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 670..679 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 680..689 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 690..699 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 700..709 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 710..719 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 720..729 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 730..739 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 740..749 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 750..759 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 760..769 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x303f, 0x21b5, + /* 770..779 */ + 0x3002, 0x300c, 0x300d, 0x3001, 0x0000, 0x30f2, 0x30a1, 0x30a3, 0x30a5, 0x30a7, + /* 780..789 */ + 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, + /* 790..799 */ + 0x30aa, 0x30ab, 0x30ad, 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, + /* 800..809 */ + 0x30bd, 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, 0x30cd, + /* 810..819 */ + 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, 0x30df, 0x30e0, 0x30e1, + /* 820..829 */ + 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, + /* 830..839 */ + 0x30f3, 0x309b, 0x309c, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049, 0x3083, 0x3085, + /* 840..849 */ + 0x3049, 0x3063, 0x3042, 0x3044, 0x3046, 0x3048, 0x304a, 0x304b, 0x304d, 0x304f, + /* 850..859 */ + 0x3051, 0x3053, 0x3055, 0x3057, 0x3059, 0x305b, 0x305d, 0x305f, 0x3061, 0x3064, + /* 860..869 */ + 0x3066, 0x3068, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3072, 0x3075, + /* 870..879 */ + 0x3078, 0x307b, 0x307e, 0x307f, 0x3080, 0x3081, 0x3082, 0x3084, 0x3086, 0x3088, + /* 880..889 */ + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308f, 0x3092, 0x3093, 0x300e, 0x300f, + /* 890..899 */ + 0x30f6, 0x3005, 0x0000, 0x0000, 0x0000, 0x0000, 0x3131, 0x3132, 0x3133, 0x3134, + /* 900..909 */ + 0x3135, 0x3136, 0x3137, 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, + /* 910..919 */ + 0x313f, 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, + /* 920..929 */ + 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, 0x3151, 0x3152, + /* 930..939 */ + 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, + /* 940..949 */ + 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163, 0x20a9, 0x0000, 0x3164, + /* 950..959 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 960..969 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 970..979 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 980..989 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 990..999 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 1000..1009 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 1010..1019 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + /* 1020..1023 */ + 0x0000, 0x0000, 0x0000, 0x0000 +#endif /* MAX_GLYHP > 504 */ +}; + + +/* on Greek systems, the UGL is a bit different */ +/* and changes the entries 319-383 inclusive */ + +/* # of Greek glyphs in UGL */ +#define GREEK_GLYPHS 65 +/* start of Greek glyphs in UGL */ +#define GREEK_START 319 + +static const int SubUGLGreek[GREEK_GLYPHS] = { + /* 319..328 */ + 0x0391, 0x0392, 0x0395, 0x0396, 0x0397, 0x0399, 0x039a, 0x039c, 0x039d, 0x039f, + /* 329..338 */ + 0x03a1, 0x03a4, 0x03a5, 0x03a7, 0x03b7, 0x03bd, 0x03c7, 0x03bf, 0x0384, 0x0308, + /* 339..348 */ + 0x0385, 0x0390, 0x0020, 0x00A6, 0x0386, 0x0388, 0x0389, 0x038a, 0x038c, 0x038e, + /* 349..358 */ + 0x038f, 0x0394, 0x0398, 0x039b, 0x039e, 0x03a0, 0x03a8, 0x03aa, 0x03ab, 0x03ac, + /* 359..368 */ + 0x03ad, 0x03ae, 0x03af, 0x03b0, 0x03b2, 0x03b3, 0x03b6, 0x03b8, 0x03b9, 0x03ba, + /* 369..378 */ + 0x03bb, 0x03bc, 0x03be, 0x03c1, 0x03c2, 0x03c5, 0x03c6, 0x03c8, 0x03c9, 0x03ca, + /* 379..383 */ + 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000 +}; +#endif /* USE_UCONV */ + +#endif /* _FTIFI_H_INCLUDED_ */ diff --git a/contrib/ftos2/ifi/ftmem.c b/contrib/ftos2/ifi/ftmem.c new file mode 100644 index 0000000..f0f15f3 --- /dev/null +++ b/contrib/ftos2/ifi/ftmem.c @@ -0,0 +1,184 @@ +/* */ +/* ** This is part of the FreeType/2 project! ** */ +/* A small utility to display online memory usage stats for FreeType/2 */ +/* */ +/* The method used to keep the window float on top may be completely */ +/* stupid but I found no other way (except putting WinSetWindowPos() */ +/* in the timer code which looks odd). */ +/* */ +/* Copyright (C) 1998 by M. Necasek */ + +#define INCL_DOSMISC +#define INCL_WINTIMER +#define INCL_PM +#include +#include + +#define ID_TIMER 42 +#define IDM_FLOAT 155 + + +/* name of shared memory used for memory usage reporting */ +#define MEM_NAME "\\sharemem\\freetype" + +typedef struct _INFOSTRUCT { + ULONG signature; /* signature (0x46524545, 'FREE') */ + ULONG used; /* bytes actually used */ + ULONG maxused; /* maximum amount ever used */ + ULONG num_err; /* number of (de)allocation errors */ +} INFOSTRUCT, *PINFOSTRUCT; + +/* structure (in named shared memory) pointing to the above struct */ +typedef struct _INFOPTR { + PINFOSTRUCT address; /* pointer to actual memory info */ +} INFOPTR, *PINFOPTR; + +HAB hab; +HWND hwndFrame; +PINFOSTRUCT meminfo; +PINFOPTR memptr; +ULONG bFloat = TRUE; +HWND hwndSysSubmenu; + +VOID AddFloat(HWND hwndFrame) { + MENUITEM mi; + HWND hwndSysMenu; + SHORT sMenuID; + + /* add Float option to system menu */ + hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU); + sMenuID = (SHORT)WinSendMsg(hwndSysMenu, MM_ITEMIDFROMPOSITION, + MPFROMSHORT(0), MPVOID); + WinSendMsg(hwndSysMenu, MM_QUERYITEM, MPFROMSHORT(sMenuID), + MPFROMP(&mi)); + hwndSysSubmenu = mi.hwndSubMenu; + mi.iPosition = MIT_END; + mi.afStyle = MIS_SEPARATOR; + mi.afAttribute = 0; + mi.id = -1; + mi.hwndSubMenu = 0; + mi.hItem = 0; + WinSendMsg(hwndSysSubmenu, MM_INSERTITEM, MPFROMP (&mi), NULL); + mi.afStyle = MIS_TEXT; + mi.afAttribute = MIA_CHECKED; + mi.id = IDM_FLOAT; + WinSendMsg(hwndSysSubmenu, MM_INSERTITEM, MPFROMP (&mi), "~Float on top"); +} + +MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) +{ + HPS hps; + RECTL rcl; + static ULONG i = 1; + ULONG ulMem; + char szBuf[200]; + + switch (msg) { + case WM_CREATE: + /* use smaller text */ + WinSetPresParam(hwnd, PP_FONTNAMESIZE, 7, (PVOID)"8.Helv"); + /* start the timer (ticks each 0.5 sec.) */ + AddFloat(WinQueryWindow(hwnd, QW_PARENT)); + WinStartTimer(hab, hwnd, ID_TIMER, 500); + break; + + /* make window always stay on top (if desired) */ + case WM_VRNENABLED: + if (bFloat) + WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER); + break; + + case WM_COMMAND: /* why doesn't WM_SYSCOMMAND work? */ + if (LOUSHORT(mp1) == IDM_FLOAT) { + bFloat = !bFloat; + WinCheckMenuItem(hwndSysSubmenu, IDM_FLOAT, bFloat); + } + break; + + case WM_TIMER: + if (++i > 13) + i = 1; + WinInvalidateRect(hwnd, NULL, FALSE); + return FALSE; + + case WM_PAINT: + hps = WinBeginPaint(hwnd, NULLHANDLE, &rcl); + /* necessary to avoid incorrectly repainting window */ + WinQueryWindowRect(hwnd, &rcl); + +/* sprintf(szBuf, " Current use %dK Maximum ever used %dK Errors %d", + meminfo->used / 1024, + meminfo->maxused / 1024, meminfo->num_err);*/ + sprintf(szBuf, " Current use %dB Maximum ever used %dK Errors %d", + meminfo->used, + meminfo->maxused / 1024, meminfo->num_err); + WinDrawText(hps, -1, szBuf, &rcl, CLR_BLACK, CLR_WHITE, + DT_CENTER | DT_VCENTER | DT_ERASERECT); + + WinEndPaint(hps); + break; + } + + return WinDefWindowProc(hwnd, msg, mp1, mp2); +} + +void main (void) +{ + QMSG qmsg; + HMQ hmq; + HWND hwndClient; + ULONG flFrameFlags; + + WinInitialize(0); + hmq = WinCreateMsgQueue(hab, 0); + + /* get access to shared memory */ + DosGetNamedSharedMem((PVOID*)&memptr, MEM_NAME, PAG_READ); + if (!memptr) + WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, + " FreeType/2 is not running!", + "Error", 0, MB_OK | MB_ERROR); + + else { + meminfo = memptr->address; + if (meminfo->signature != 0x46524545) + WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, + " FreeType/2 is not running!", + "Error", 0, MB_OK | MB_ERROR); + else { + flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | + FCF_TASKLIST ; + + WinRegisterClass(hab, "MyClass", + (PFNWP) ClientWndProc, + CS_SIZEREDRAW, 0); + + hwndFrame = WinCreateStdWindow(HWND_DESKTOP, + WS_VISIBLE, + &flFrameFlags, + "MyClass", "FreeType/2 Heap Usage", + 0, (HMODULE) NULL, + 0, &hwndClient); + + WinSetVisibleRegionNotify(hwndClient, TRUE); + + /* make titlebar text look better */ + WinSetPresParam(WinWindowFromID(hwndFrame, FID_TITLEBAR), + PP_FONTNAMESIZE, 9, (PVOID)"8.Helv"); + + WinSetWindowPos(hwndFrame, NULLHANDLE, 0, 0, 350, 42, + SWP_MOVE | SWP_SIZE | SWP_SHOW); + + while (WinGetMsg(hab, &qmsg, (HWND) NULL, 0, 0)) + WinDispatchMsg(hab, &qmsg); + + WinSetVisibleRegionNotify(hwndClient, FALSE); + } + } + /* free shared memory block */ + DosFreeMem(memptr); + + WinDestroyWindow(hwndFrame); + WinDestroyMsgQueue(hmq); + WinTerminate(hab); +} diff --git a/contrib/ftos2/ifi/ftmem.icc b/contrib/ftos2/ifi/ftmem.icc new file mode 100644 index 0000000..c9991f4 --- /dev/null +++ b/contrib/ftos2/ifi/ftmem.icc @@ -0,0 +1,4 @@ +ftmem.exe: $*.obj + ilink /PM:PM /ST:0x8000 /BAS:0x10000 /E:2 /A:4 $*.obj +ftmem.obj: $*.c + icc -C $*.c diff --git a/contrib/ftos2/ifi/ftmem.ico b/contrib/ftos2/ifi/ftmem.ico new file mode 100644 index 0000000000000000000000000000000000000000..ab730f5c91b8ac557a89de47eb2e9b0a28e312c6 GIT binary patch literal 2692 zcmeHFOHRZv40T~7vO+|fMVGTe9Ag+(Y!C-v$w88x57%SN3AjLcw$s7=i53ZvU|hxZ z_xY0??q7)L4M*tV@d^9}-?1XvL*C)Yzrr^~7gI)OYunbNB76_;uAGWCkk(U@6tGl; zRFnjRRBXi$22lmIKxvwW4mz>eQT);--qMzi8|&>3j%OS{@$EH{9HHeC3+n6D2dW_Z zi9M=9&#=_lA$(=xF8#m$c|eIdaAG3;aWGxDn4LcK_jRISe5VH{PJ)DA0A3;{*ierG zCd*Oo$AXC_I@RA9a-L) zpEvM38(8;Rmqgc`nd=;DHc4_!5 + +#include +#include +#include +#include "32pmifi.h" + +//#define USE_ORIG +#ifdef USE_ORIG + #pragma import (fdhdr, "FONT_DRIVER_DISPATCH_TABLE", "TRUETYPE", 0) +#else + #if defined USE_ATM + #pragma import (fdhdr, "FONT_DRIVER_DISPATCH_TABLE", "PMATM", 0) + #else + #pragma import (fdhdr, "FONT_DRIVER_DISPATCH_TABLE", "FREETYPE", 0) + #endif +#endif + +extern FDHEADER fdhdr; + +char *fontnames[20] = { + "G:\\OS2\\MDOS\\WINOS2\\SYSTEM\\SYMBOL.TTF", + "G:\\OS2\\MDOS\\WINOS2\\SYSTEM\\WINGDING.TTF", + "G:\\PSFONTS\\ARIALB.ttf", + "G:\\PSFONTS\\ARIALI.ttf", + "G:\\PSFONTS\\ARIALZ.ttf", + "G:\\PSFONTS\\COUR.TTF", + "G:\\PSFONTS\\COURB.TTF", + "G:\\PSFONTS\\COURI.TTF", + "G:\\PSFONTS\\COURZ.TTF", + "G:\\PSFONTS\\ARIAL.ttf", + "G:\\PSFONTS\\TIMESB.TTF", + "G:\\PSFONTS\\TIMESI.ttf", + "G:\\PSFONTS\\TIMESZ.ttf", + "G:\\PSFONTS\\TIMES.TTF", + "G:\\PSFONTS\\ARIBLK.ttf", + "G:\\CHINESE\\AVSV.TTF", + "G:\\CHINESE\\MINGLI.TTC", + "D:\\PSFONTS\\TNRMT30.TTF" +}; + +#define FNTNAME1 "\\PSFONTS\\TIMES.TTF" +#ifdef USE_ATM + #define FNTNAME2 "\\PSFONTS\\helv.ofm" +#else + #define FNTNAME2 "\\PSFONTS\\symbol.tTf" +#endif + +#define BUFSIZE 32768 + +void ShowChar(PCHARATTR pca, PBITMAPMETRICS pbmm) { + int i, j; + int bufwidth = ((pbmm->sizlExtent.cx + 31) & -32) / 8; + + for (i =0; i < pbmm->sizlExtent.cy; i++) { + for (j = 0; j < bufwidth * 8; j++) + if (pca->pBuffer[i * bufwidth + j / 8] & (1 << (7-(j % 8)))) + printf("*"); + else + printf(" "); + printf("\n"); + } +} + +void main(int argc, char **argv) +{ + char fname[260]; + PFDDISPATCH pfdisp; + LONG rc; + HFF hff, hff2; /* font file */ + HFC hfc, hfc2; /* font context */ + static IFIMETRICS ifimet[12]; /* IFI metrics */ + CONTEXTINFO ci; + CHARATTR charattr; /* character attributes */ + BITMAPMETRICS bmm; /* bit-map metrics */ + PBYTE buf; + int glyph = 0, i, j; + int numFaces; + int faceIndex = 0; + + switch (argc) { + case 4: + strcpy(fname, argv[1]); + glyph = atoi(argv[2]); + faceIndex = atoi(argv[3]); + break; + + case 2: + glyph = atoi(argv[1]); + case 1: + strcpy(fname, FNTNAME1); + break; + + default: + strcpy(fname, argv[1]); + glyph = atoi(argv[2]); + } + + buf = (PBYTE)malloc(BUFSIZE); + if (strncmp("OS/2 FONT DRIVER", fdhdr.strId, 16)) { + printf("Invalid Font Driver\n"); + return; + } + printf("Font Driver OK, "); + printf("Version %d\n", fdhdr.ulVersion); + printf("Technology: %s\n", fdhdr.szTechnology); + + hff = fdhdr.pfddisp->FdLoadFontFile(fname); + printf("Loading font... HFF = %X\n", hff); + if (hff == (HFF)0xFFFFFFFF) + return; + +/* rc = fdhdr.pfddisp->FdConvertFontFile("G:\\PSFONTS\\TIMES.TTF", + "G:\\PSFONTS", buf); */ + +#if 0 + for (i = 0; i < 18; i++) { + hff = fdhdr.pfddisp->FdLoadFontFile(fontnames[i]); + if (hff == (HFF)-1) { + printf("x"); + continue; + } + numFaces = fdhdr.pfddisp->FdQueryFaces(hff, NULL, 0, -1, 0); + if (numFaces < 0) { + printf("x"); + continue; + } + for (j = 0; j < numFaces; j++) { + rc = fdhdr.pfddisp->FdQueryFaces(hff, &ifimet[0], 238, 1, j); + if (rc < 0) { + printf("x"); + continue; + } + } + + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + if (rc) + printf("x"); + else + printf("."); + } + printf("\n"); +#endif + + hff = fdhdr.pfddisp->FdLoadFontFile(FNTNAME2); + hff = fdhdr.pfddisp->FdLoadFontFile(fname); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + + hff = fdhdr.pfddisp->FdLoadFontFile(fname); + printf("Loading font... HFF = %X\n", hff); + if (hff == (HFF)0xFFFFFFFF) + return; + numFaces = fdhdr.pfddisp->FdQueryFaces(hff, NULL, 0, -1, 0); + printf("Number of faces = %d\n", numFaces); + rc = fdhdr.pfddisp->FdQueryFaces(hff, &ifimet[0], sizeof(IFIMETRICS), numFaces, 0); + printf("Querying faces... RC = %X\n", rc); + hfc = fdhdr.pfddisp->FdOpenFontContext(hff, faceIndex); + printf("Opening context... HFC = %X\n", hfc); + if (hfc == (HFC)0xFFFFFFFF) { + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + printf("Unloading font... RC = %X\n", rc); + } + ci.cb = sizeof(ci); + ci.fl = 0; +/* ci.sizlPPM.cx = 3618; + ci.sizlPPM.cy = 3622; + ci.pfxSpot.x = 46340; + ci.pfxSpot.y = 46340; + ci.matXform.eM11 = 511; + ci.matXform.eM12 = 0; + ci.matXform.eM21 = 0; + ci.matXform.eM22 = 511; */ + ci.sizlPPM.cx = 3622; + ci.sizlPPM.cy = 3622; + ci.pfxSpot.x = 46340; + ci.pfxSpot.y = 46340; + ci.matXform.eM11 = 768; + ci.matXform.eM12 = 0; + ci.matXform.eM21 = 0; + ci.matXform.eM22 = 768; + + rc = fdhdr.pfddisp->FdQueryFaceAttr(hfc, FD_QUERY_ABC_WIDTHS, buf, + sizeof(ABC_TRIPLETS), NULL, glyph); + printf("Querying face attrs... RC = %d\n", rc); + rc = fdhdr.pfddisp->FdQueryFaceAttr(hfc, FD_QUERY_KERNINGPAIRS, buf, + ifimet[0].cKerningPairs * sizeof(FD_KERNINGPAIRS), + NULL, 0); + + + rc = fdhdr.pfddisp->FdSetFontContext(hfc, &ci); + printf("Setting context... rc = %X\n", rc); + + charattr.cb = sizeof(charattr); + charattr.iQuery = FD_QUERY_BITMAPMETRICS | FD_QUERY_CHARIMAGE; +// charattr.iQuery = FD_QUERY_OUTLINE; + charattr.gi = glyph; + charattr.pBuffer = buf; + charattr.cbLen = BUFSIZE; + if (rc == -1) + return; + rc = fdhdr.pfddisp->FdQueryCharAttr(hfc, &charattr, &bmm); + printf("Querying char attrs... bytes = %d\n", rc); + ShowChar(&charattr, &bmm); + +// rc = fdhdr.pfddisp->FdQueryCharAttr(hfc, &charattr, &bmm, NULL); +// printf("Querying char attrs... bytes = %d\n", rc); + + hff2 = fdhdr.pfddisp->FdLoadFontFile(FNTNAME2); + printf("Loading font... HFF = %X\n", hff2); + if (hff2 == (HFF)0xFFFFFFFF) + return; + + charattr.cbLen = 0; + rc = fdhdr.pfddisp->FdQueryCharAttr(hfc, &charattr, &bmm); + printf("Querying char attrs... bytes = %d\n", rc); + rc = fdhdr.pfddisp->FdQueryFaces(hff2, &ifimet[0], sizeof(ifimet), 1, 0); + printf("Querying faces... RC = %X\n", rc); + hfc2 = fdhdr.pfddisp->FdOpenFontContext(hff2, 0); + printf("Opening context... HFC = %X\n", hfc2); + if (hfc2 == (HFC)0xFFFFFFFF) { + rc = fdhdr.pfddisp->FdUnloadFontFile(hff2); + printf("Unloading font... RC = %X\n", rc); + } + rc = fdhdr.pfddisp->FdCloseFontContext(hfc); + printf("Closing context... RC = %X\n", rc); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + printf("Unloading font... RC = %X\n", rc); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff); + printf("Unloading font... RC = %X\n", rc); + + rc = fdhdr.pfddisp->FdCloseFontContext(hfc2); + printf("Closing context... RC = %X\n", rc); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff2); + printf("Unloading font... RC = %X\n", rc); + rc = fdhdr.pfddisp->FdUnloadFontFile(hff2); + printf("Unloading font... RC = %X\n", rc); +} diff --git a/contrib/ftos2/ifi/test.icc b/contrib/ftos2/ifi/test.icc new file mode 100644 index 0000000..36a8f0d --- /dev/null +++ b/contrib/ftos2/ifi/test.icc @@ -0,0 +1,6 @@ +test.exe: $*.obj freetype.lib + ilink /DE /PM:VIO /ST:0x1000 $*.obj freetype.lib +test.obj: $*.c + icc -Ti+ -C -Ss -Sp1 $*.c +freetype.lib: $*.dll + implib $*.lib $*.dll diff --git a/contrib/ftos2/ifi/test.wat b/contrib/ftos2/ifi/test.wat new file mode 100644 index 0000000..20dca18 --- /dev/null +++ b/contrib/ftos2/ifi/test.wat @@ -0,0 +1,4 @@ +test.exe: $*.obj + wlink file $*.obj lib freetype.lib import _fdhdr freetype.FONT_DRIVER_DISPATCH_TABLE +test.obj: $*.c + wcc386 -d2 -zp1 $*.c diff --git a/contrib/ftos2/install.cmd b/contrib/ftos2/install.cmd new file mode 100644 index 0000000..44e7a29 --- /dev/null +++ b/contrib/ftos2/install.cmd @@ -0,0 +1,30 @@ +/* */ +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + + +say "Warning: This is your last chance to back out. If you do not wish to" +say "continue, please just press ENTER. Otherwise please type ""yes""" + +pull letter +if letter <> "YES" then exit + +/* Find drive where OS/2 is installed */ +bootdrive = SysSearchPath('PATH', 'OS2.INI') +/* say os2path */ +bootdrive = left(bootdrive, 2) + +copy "FREETYPE.DLL " || bootdrive || "\os2\dll" +if rc <> 0 then do + say "Error: Could not copy file!" + pause + exit +end + +app = "PM_Font_Drivers" +key = "TRUETYPE" +val = "\OS2\DLL\FREETYPE.DLL" || d2c(0) + +SysIni('BOTH', app, key, val) +say "Font Driver is installed. Please reboot." +pause diff --git a/contrib/ftos2/lib/arch/os2/Makefile.icc b/contrib/ftos2/lib/arch/os2/Makefile.icc new file mode 100644 index 0000000..7d83f33 --- /dev/null +++ b/contrib/ftos2/lib/arch/os2/Makefile.icc @@ -0,0 +1,72 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for IBM VisualAge C++ under OS/2. +# +# You will need nmake. +# +# Use this file while in the lib directory with the following statement: +# +# nmake -f arch\os2\Makefile.icc +# + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.icc +FT_MAKE = $(MAKE) -nologo + +CC = icc +CFLAGS = -Wcnd- -Wpro- -Ss -Sp1 -Rn -Ge- -O+ -G4 -Q+ -Iarch\os2 -I. -Iextend +#CFLAGS = -Wcnd- -Wpro- -Ss -Sp1 -Rn -Ge- -Ti+ Q+ -Iarch\os2 -I. -Iextend + +# NOTE: Optimizations are discarded, as it seems that Visual Age +# is buggy when producing ttraster.obj. The resulting code +# crashes under some circumstances (performing vertical dropout +# control when rendering smoothed outlines)! + +TTFILE = $(ARCH)\os2file.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c \ + extend\ftxcmap.c extend\ftxwidth.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c \ + ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +all: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_S)" libttf.lib + +debug: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_M)" libttf.lib + + +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +$(OBJS_X): + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +$(ARCH)\os2file.obj: + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +libttf.lib: $(LIB_FILES) + !ilib /nologo /noignorecase /nobackup $@ -+$?,, + +clean: + -del *.obj + -del extend\*.obj + -del arch\os2\*.obj + +distclean: clean + -del libttf.lib + +# end of Makefile.icc diff --git a/contrib/ftos2/lib/arch/os2/Makefile.wat b/contrib/ftos2/lib/arch/os2/Makefile.wat new file mode 100644 index 0000000..3a4cef6 --- /dev/null +++ b/contrib/ftos2/lib/arch/os2/Makefile.wat @@ -0,0 +1,41 @@ +# This file is part of the FreeType project. +# Modified for FTIFI - Mike +# +# It builds the library and test programs using Watcom C/C++ under OS/2. +# +# You will need nmake!! +# If you can change this makefile to work with wmake, please +# inform me. +# +# Use this file while in the lib directory with the following statement: +# +# nmake -f arch\os2\Makefile.icc + +CC = wcc386 +CFLAGS = -4r -Otexan -zp1 -bd -zc -Iarch\os2 -I. -Iextend + +SRC = ttapi.c ttcache.c ttcalc.c ttcmap.c tterror.c \ + ttfile.c ttgload.c ttinterp.c ttlists.c ttload.c \ + ttmemory.c ttmutex.c ttobjs.c ttraster.c ttextend.c \ + \ + extend\ftxgasp.c extend\ftxkern.c + +OBJ = $(SRC:.c=.obj) + +.c.obj: + $(CC) $(CFLAGS) $*.c + +all: libttf.lib + +libttf.lib: $(OBJ) + -move ft*.obj extend + !wlib -c $@ -+$? + +clean: + -del *.obj + -del extend\*.obj + +distclean: clean + -del libttf.lib + +# end of Makefile.wcc diff --git a/contrib/ftos2/lib/ttmemory.c b/contrib/ftos2/lib/ttmemory.c new file mode 100644 index 0000000..38fd979 --- /dev/null +++ b/contrib/ftos2/lib/ttmemory.c @@ -0,0 +1,385 @@ +/******************************************************************* + * + * ttmemory.c 1.2 + * + * Memory management component (body). + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Portions Copyright 1998 by Michal Necasek + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 1.1 and 1.2: + * + * - the font pool is gone. + * + * - introduced the FREE macro and the Free function for + * future use in destructors. + * + * - Init_FontPool() is now a macro to allow the compilation of + * 'legacy' applications (all four test programs have been updated). + * + * Note: This code was slightly adapted for use in the OS/2 + * Font Driver (FreeType/2). + * + ******************************************************************/ + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +#define INCL_DEV +#include +#include + +#include + +#undef DEBUG_MEM + +/* -------------------- debugging defs ----------------------- */ +/* DEBUG_MEM creates a file and logs all actions to it */ + +#ifdef DEBUG_MEM + static HFILE MemLogHandle = NULLHANDLE; + static ULONG Written = 0; + static char log[2048] = ""; + static char buf[2048] = ""; + + +char* itoa10( int i, char* buffer ) { + char* ptr = buffer; + char* rptr = buffer; + char digit; + + if (i == 0) { + buffer[0] = '0'; + buffer[1] = 0; + return buffer; + } + + if (i < 0) { + *ptr = '-'; + ptr++; rptr++; + i = -i; + } + + while (i != 0) { + *ptr = (char) (i % 10 + '0'); + ptr++; + i /= 10; + } + + *ptr = 0; ptr--; + + while (ptr > rptr) { + digit = *ptr; + *ptr = *rptr; + *rptr = digit; + ptr--; + rptr++; + } + + return buffer; +} + +static const char* hexstr = "0123456789abcdef"; + +char* itohex2( int i, char* buffer ) + { + buffer[0] = hexstr[ (i >> 12) & 0xF ]; + buffer[1] = hexstr[ (i >> 8 ) & 0xF ]; + buffer[2] = hexstr[ (i >> 4 ) & 0xF ]; + buffer[3] = hexstr[ (i ) & 0xF ]; + buffer[4] = '\0'; + return buffer; +} + +char* itohex4( long i, char* buffer ) +{ + itohex2( (i >> 16) & 0xFFFF, buffer ); + /* We separate the high and low part with a dot to make it */ + /* more readable */ + buffer[4] = '.'; + itohex2( i & 0xFFFF, buffer+5 ); + return buffer; +} + + #define COPY(s) strcpy(log, s) + #define CAT(s) strcat(log, s) + #define CATI(v) strcat(log, itoa10( (int)v, buf )) + #define CATH(v) strcat(log, itohex4( (long)v, buf )) + #define CATW(v) strcat(log, itohex2( (short)v, buf )) + #define WRITE DosWrite(MemLogHandle, log, strlen(log), &Written) + #define ERRRET(e) { COPY("Error at "); \ + CATI(__LINE__); \ + CAT("\r\n"); \ + WRITE; \ + return(e); \ + } + +#else + + #define COPY(s) + #define CAT(s) + #define CATI(v) + #define CATH(v) + #define CATW(v) + #define WRITE + #define ERRRET(e) return(e); + +#endif /* DEBUG_MEM */ + + +#undef TRACK_MEM +/* TRACK_MEM allows online tracking of memory usage online (via shared */ +/* memory). It is used in conjunction with the FTMEM utility. */ + +#ifdef TRACK_MEM + /* name of shared memory used for memory usage reporting */ + #define MEM_NAME "\\sharemem\\freetype" + + /* structure containing memory usage information */ + typedef struct _INFOSTRUCT { + ULONG signature; /* signature (0x46524545, 'FREE') */ + ULONG used; /* bytes actually used */ + ULONG maxused; /* maximum amount ever used */ + ULONG num_err; /* number of (de)allocation errors */ + } INFOSTRUCT, *PINFOSTRUCT; + + /* structure (in named shared memory) pointing to the above struct */ + typedef struct _INFOPTR { + PINFOSTRUCT address; /* pointer to actual memory info */ + } INFOPTR, *PINFOPTR; + + PINFOSTRUCT meminfo; /* struct in shared memory holding usage info */ + PINFOPTR memptr; +#endif + +/* ----------------------------------------------------------------- + + A brief explanation of the memory allocator : + + - We store the block's size in front of it. The size implies the nature + of the block, and selects a de-allocation scheme.. + + - A note on the memory debugging schemes: logging and online tracking + are independent of each other and none, either or both may be used. + + ----------------------------------------------------------------- */ + + /****************************************************************/ + /* */ + /* Allocate a block of memory */ + /* */ + static + void* ft2_malloc( long size ) + { + long* head; + void* base; + int rc; + + /* add header size */ + size += sizeof(long); + + /* Allocate memory accessible from all processes */ + if (( rc = SSAllocMem( (PVOID)&head, size, 0 ))) + { + COPY( "ft2_malloc: block SSAllocMem failed with rc = " ); + CATH( rc ); + CAT ( "\r\n" ); + WRITE; + return NULL; + } + *head = size; + base = (void*)(head + 1); + #ifdef TRACK_MEM + meminfo->used += size; + if (meminfo->used > meminfo->maxused) + meminfo->maxused = meminfo->used; + #endif + return base; + } + + /****************************************************************/ + /* */ + /* Release a block of memory */ + /* */ + int ft2_free( void* block ) + { + long* head; + long size, offset; + int rc, h; + + if (!block) + return -1; + + head = ((long*)block) - 1; + size = *head; + + if (size <= 0) + { + COPY( "ft2_free: negative size !!\r\n" ); + WRITE; + return -1; + } + + rc = SSFreeMem( (PVOID)head ); + if (rc) + { + COPY( "ft2_free: block SSFreeMem failed with rc = " ); + CATI( rc ); + CAT ( "\r\n" ); + WRITE; + } + #ifdef TRACK_MEM + meminfo->used -= size; + #endif + return rc; + } + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE: The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + TT_Error TT_Alloc( long Size, void** P ) + { + if ( Size ) + { + *P = ft2_malloc( Size ); + if (!*P) { + #ifdef TRACK_MEM + meminfo->num_err++; + #endif + return TT_Err_Out_Of_Memory; + } + + /* MEM_Set( *P, 0, Size); */ /* not necessary, SSAllocMem does it */ + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + TT_Error TT_Free( void** P ) + { + if ( !P || !*P ) + return TT_Err_Ok; + + if (ft2_free( *P )) { + #ifdef TRACK_MEM + meminfo->num_err++; + #endif + } + *P = NULL; + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + TT_Error TTMemory_Init() + { + int rc; + + #ifdef DEBUG_MEM + ULONG Action; + + DosOpen("C:\\FTMEM.LOG", &MemLogHandle, &Action, 0, FILE_NORMAL, + OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS, + OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_WRITE_THROUGH | + OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYWRITE | OPEN_ACCESS_WRITEONLY, + NULL); + + COPY("FTMEM Init.\r\n"); + WRITE; + + #endif /* DEBUG */ + + #ifdef TRACK_MEM + /* allocate named shared memory and global shared memory */ + + SSAllocMem(&meminfo, 4096, 0); + DosAllocSharedMem((PVOID*)&memptr, MEM_NAME, 4096, fALLOC); + memptr->address = meminfo; + meminfo->signature = 0x46524545; /* 'FREE' */ + meminfo->maxused = 0; + meminfo->used = 0; + #endif /* TRACK */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + TT_Error TTMemory_Done() + { + /* Never called by the font driver (beats me why). We do not + release the heaps */ + + #ifdef TRACK_MEM + DosFreeMem(memptr); /* free shared memory */ + SSFreeMem(meminfo); + #endif + #ifdef DEBUG_MEM + COPY("FTMEM Done.\r\n"); + WRITE; + DosClose(MemLogHandle); + #endif + return TT_Err_Ok; + } + + +/* END */ diff --git a/contrib/ftos2/limit.cmd b/contrib/ftos2/limit.cmd new file mode 100644 index 0000000..807deda --- /dev/null +++ b/contrib/ftos2/limit.cmd @@ -0,0 +1,63 @@ +/* */ +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + +Parse Upper Arg a1 a2 + +app = "FreeType/2" +key = "OPENFACES" + +if Arg() = 0 then call usage + +if a1 = 'Q' then call query + +if a1 = 'S' then call set +call usage + +set: + +val = a2 + +if val = '' then do + say 'Invalid limit!' + exit +end + +if val < 8 then do + say 'The lowest acceptable limit is 8!' + pause + exit +end + +szval = val || d2c(0) + +rc = SysIni('USER', app, key, szval) +say rc +if rc = 'ERROR:' then do + say 'Error updating OS2.INI!' + pause + exit +end + +say "Open faces limit updated to " || val || ". Please reboot to activate changes." +pause +exit + +query: +val = SysIni('USER', app, key) +if val = "ERROR:" then val = "not set" +/* strip the terminating NULL character */ +else val = substr(val, 1, pos(d2c(0), val) - 1) + +say 'The current open faces limit is ' || val +pause +exit + +usage: +say 'This program is used to set the limit of concurrently open typefaces for' +say 'FreeType/2. Use lower numbers to limit memory consumption and higher to' +say 'improve performance if you use lots of fonts.' +say +say 'Usage: LIMIT q - query the current limit' +say ' LIMIT s - set limit to (effective on next reboot).' +pause diff --git a/contrib/ftos2/query.cmd b/contrib/ftos2/query.cmd new file mode 100644 index 0000000..532c8e6 --- /dev/null +++ b/contrib/ftos2/query.cmd @@ -0,0 +1,15 @@ +/* */ +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + +app = "PM_Font_Drivers" +key = "TRUETYPE" + +val = SysIni('USER', app, key) + +if val = "ERROR:" then val = "none" +/* strip the terminating NULL character */ +else val = substr(val, 1, pos(d2c(0), val) - 1) + +say 'The current TrueType driver is ' || val +pause diff --git a/contrib/ftos2/readme.1st b/contrib/ftos2/readme.1st new file mode 100644 index 0000000..ea5f403 --- /dev/null +++ b/contrib/ftos2/readme.1st @@ -0,0 +1,87 @@ +This is the source code from the FreeType/2 OS/2 font driver. +Copyright (C) 1997-1998 Michal Necasek (mike@mendelu.cz). + +Here's a description of the files in this package : + + readme.1st This file + + readme.txt The FreeType/2 Readme + + FAQ The FreeType/2 user faq + + DEVELFAQ The FreeType/2 developer faq. Read it before trying to + compile this program + + install.cmd The FreeType/2 installation script + uninstall.cmd The FreeType/2 uninstallation script + query.cmd A script used to query the name of the current font driver + + limit.cmd The driver controls the number of font files it keeps + opened at the same time, in order to save system resources + and memory (of course, this _doesn't_ limit the number of + opened fonts in PM, it just saves a _lot_ of memory when + many fonts are installed on your system). + + This script let you change this limit. It can be useful + if you use font-intensive applications (like DTP) and + want better performance (to the sake of memory). + + update.cmd The FreeType/2 update script + ifi/ Source code of the FreeType/2 font driver proper + + + lib/ files that must be added to the standard FreeType 1.1 + release. They take the place of the files located in + the corresponding "lib" file. + + lib/ttmemory.c replacement for the FreeType memory + manager component. This one uses the GRE + shared memory segment allocater, and is + required. + + lib/arch/makefile.icc Makefile to compile the FreeType library for + FreeType/2 with Visual Age. You'll need nmake. + + lib/arch/makefile.wat Makefile to compile with Watcom. NOTE that + you'll ALSO need nmake (wmake won't work !!) + + +Here's how to compile the font driver. + +0. Read the DEVELFAQ ! Now ! Then make a WPS backup ! + +1. Get the FreeType library, and copy the "lib" hierarchy into it to + replace the related files (i.e. ttmemory.c and makefiles). + +2. Compile FreeType with the new files, simply go to "freetype/lib" + and type : + + nmake -f arch\os2\makefile.icc for VisualAge + nmake -f arch\os2\makefile.wat for Watcom + +3. Adjust the makefiles in "ifi" to reflect the location of the + library file "libttf.lib" that was generated previously. + +5. Compile the font driver. Go to the "ft_os2/ifi" directory, then type + + nmake -f freetype.icc for VisualAge + nmake -f freetype.wat for Watcom + + You should have created a file called "FreeType.dll". Copy it to + your "ft_os2" directory.. + +6. Run the "install.cmd" script, then reboot after closing all + applications. + +7. When your desktop is back, go to the font palette and try to + install some new TrueType fonts. Enjoy the difference :-) + +8. You can also compile a small memory usage dumper called "ftmem.c" + to know how much memory the driver is using. Simply do + + nmake -f ftmem.icc for VisualAge + nmake -f ftmem.wat for Watcom + + Then launch it. A small window will appear with the current amount + of memory allocated by the driver. + diff --git a/contrib/ftos2/readme.txt b/contrib/ftos2/readme.txt new file mode 100644 index 0000000..a03fd2b --- /dev/null +++ b/contrib/ftos2/readme.txt @@ -0,0 +1,113 @@ + + * * * FreeType/2 * * * + + (Version 1.0, 5. November 1998) + + Copyright (C) 1997,1998 Michal Necasek + Copyright (C) 1997,1998 The FreeType Development Team + + + Motto: "OS/2 is dead? Again? Thanks for telling me, I'd never notice!" + + + *** if you are upgrading from previous version, please see the FAQ (Q15) *** + + +- First a short Q&A: + +Q1: What's this? +A1: This is what OS/2 users have been waiting for only too long - a free, + high-quality TrueType renderer a.k.a. Font Driver conforming to the + OS/2 Intelligent Font Interface specification. It is based on FreeType - + a free portable library for using TrueType fonts. + Please note that although this code is free the FreeType team and + I will cheerfully accept any donations by happy users ;-) (not that I + expect to get any) + +Q2: How do I use this? +A2: Go to OS/2 command line and run INSTALL.CMD from the directory containing + FREETYPE.DLL. This will replace the original IBM TrueType driver if it is + installed. + +Q3: Where's the disclaimer? +A3: No, don't worry, I didn't forget that. I of course provide NO WARRANTY + that this code will work as you expect. Use only at your OWN RISK! + +Q4: What should I do RIGHT NOW? +A4: Before attempting to install this driver, you are STRONGLY advised + to archive your current configuration (Set Desktop Properties/Archive/ + Create archive at each startup, then reboot. Then of course switch archiving + off). It is always possible your system won't boot with the font driver + installed. You can risk it, but I warned you! You know how nasty the + computers can be ;-) + +Q5: What about the license? +A5: This code is distributed under the FreeType license. + It is free and the source code is available as part of the FreeType + distribution. + +Q6: How do I get rid of this? +A6: Ah, right question. Just run UNINSTALL.CMD. That removes the font driver + (not physically, it just isn't used on next startup) and restores the + original TRUETYPE.DLL if it exists. + +Q7: Is there something else? +A7: Yes, be prepared that the fonts just kick ass! You will no longer have + to envy those poor souls still using the so-called 95% OS from THAT + unspeakable company starting with the letter M ;-) + + +- Current features/bugs/limitations: + + Features : - outlines + - scaled/rotated text + - supports printed output + - works with TTCs (TrueType collections) + - national characters (if provided in the font, of course); + should work with all Latin codepages, Cyrillic and Greek. + - partial DBCS support - Traditional Chinese should work about + 98%. Fonts like Times New Roman MT30 should work on all + systems. If you want your language to be supported, you can + apply at and become a Beta tester. + + Bug/feature: - unharmonious glyph spacing in some applications. This seems + to come from OS/2's WYSIWYG glyph placement policy. This + is more or less visible depending on the application. We + can't do a lot about this... At least it's true WYSIWYG and + no nasty surprises when printing. + + + Limitations: - no grayscaling (a.k.a. antialiasing) - this is a limitation + of OS/2, not my code. If OS/2 starts supporting it, I'll + implement it the moment I lay my hands on the specs :) + Unfortunately it most probably won't happen any too soon. + Anyway, you have to bug IBM about this one, not me! + +- Planned features and features under consideration: + - possibly adding even support for Type 1 fonts, but that depends on + further FreeType engine development. Looks quite probable now. + +And finally, thanks go to: + - the FreeType team, the makers of FreeType. Without them, my work would be + impossible. + - especially David Turner of FreeType for his help, advice and support + - Robert Muchsel, I used one or two ideas from his code + - Marc L Cohen, Ken Borgendale and Tetsuro Nishimura from IBM. They provided + me with lots of extremely valuable 'inside' information. + - and last but not least - IBM, for providing us with the wonderful OS/2. + And for giving out the necessary docs for free. If all companies did + that, the world would be a better place. + + +Information on FreeType is available at + http://www.freetype.org + +Please send bug reports/suggestions and comments to : + + freetype-os2@physiol.med.tu-muenchen.de + + +Greetings can also be sent directly to the author at : mike@mendelu.cz + +And if you didn't know, IBM and OS/2 are registered trademarks of the +International Business Machines Corporation. diff --git a/contrib/ftos2/uninst.c b/contrib/ftos2/uninst.c new file mode 100644 index 0000000..da3380b --- /dev/null +++ b/contrib/ftos2/uninst.c @@ -0,0 +1,60 @@ +/* */ +/* UNINST - FreeType/2 uninstaller */ +/* */ +/* Copyright 1998 Michal Necasek */ +/* */ +/* UNINSTALL.CMD rewritten in C - apparently the REXX version fails */ +/* when OS/2 is booted to command line. This causes problems if */ +/* FreeType/2 prevents PM from starting successfully. */ +/* */ +/* Note: This can be compiled as 16-bit app to keep the size down. */ + +#define INCL_NOXLATE_WIN16 +#define INCL_NOXLATE_DOS16 +#define INCL_WINSHELLDATA +#define INCL_DOSMISC +#include + +#include +#include +#include + +char szApp[] = "PM_Font_Drivers"; +char szKey[] = "TRUETYPE"; +char szBuffer[300]; + +void main(void) { + ULONG ulBootDrv; + USHORT usLen = 0; + APIRET rc; + char c; + + usLen = PrfQueryProfileString(HINI_USERPROFILE, szApp, szKey, NULL, + (PVOID)szBuffer, 260L); + + if (!strcmp("\\OS2\\DLL\\FREETYPE.DLL", szBuffer)) { + if(!PrfWriteProfileString(HINI_USERPROFILE, szApp, szKey, NULL)) + goto err; + + printf("FreeType/2 successfully removed.\n"); + printf("Do you wish to restore TRUETYPE.DLL (y/n)? "); + c = getch(); + if (c != 'y' && c != 'Y') + return; + + if(!PrfWriteProfileString(HINI_USERPROFILE, szApp, szKey, + "\\OS2\\DLL\\TRUETYPE.DLL")) + goto err; + + printf("\nTRUETYPE.DLL successfully restored"); + } + else { + printf("FreeType/2 not installed!"); + return; + } + + return; + +err: + printf("Uninstallation failed!"); +} diff --git a/contrib/ftos2/uninstall.cmd b/contrib/ftos2/uninstall.cmd new file mode 100644 index 0000000..bf13f68 --- /dev/null +++ b/contrib/ftos2/uninstall.cmd @@ -0,0 +1,34 @@ +/* */ +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + + +say "This utility will remove the FreeType/2 font driver and install " +say "the original TRUETYPE.DLL if it exists. If you do not wish to" +say "continue, please just press ENTER. Otherwise please type ""y""" + +pull letter +if letter <> "Y" then exit + +/* Find drive where OS/2 is installed */ +bootdrive = SysSearchPath('PATH', 'OS2.INI') +bootdrive = left(bootdrive, 1) + +app = "PM_Font_Drivers" +key = "TRUETYPE" + +/* look for TRUETYPE.DLL */ +rc = SysFileTree(left(bootdrive,1) || ":\OS2\DLL\TRUETYPE.DLL", "file", "F") + +if file.0 = 1 then do + say "Restoring TRUETYPE.DLL..." + val = "\OS2\DLL\TRUETYPE.DLL" || d2c(0) + SysIni('BOTH', app, key, val) +end +else do + say "Uninstalling FREETYPE.DLL..." + SysIni('BOTH', app, key, "DELETE:") +end + +say "FTIFI is uninstalled. Please reboot." +pause diff --git a/contrib/mac/mac.hqx b/contrib/mac/mac.hqx new file mode 100644 index 0000000000000000000000000000000000000000..cd33ac5ff7ca9f821f953d3f348efd614940b9cb GIT binary patch literal 45034 zcmbTd1ymhfuP}UYcXwJ!p*W@Z0g4wWR@@zmySux)yE_zjio0`gcXx;X^yz!=d++_e zyZ*JlEGEfhCzCysIeQk#j+~hMI{*X#PS11~5jh=w)> z26oO?1`PjqxBO-Q!^1!GgaLx3xPSb}3oFYDDv1e00IGMj9RC~u00h_u79C850RSk7 zBwl`^zt_lx#Q?w)n_0u_{>)5*RLkVDc@rtd)A-W5=DR1oxcQ5sf@@xD)93Vt&`eXi zg~xJeT1$o|P^6fVautdcp7I8{?sSqD!P|z^ZNF;m47gy#^mWWf>L|DTj{B|aT5Z-E zW~eP=tJP-|mDlz6Fk|EKW_lzo@TD_HRC9TKKe{2Z@!=b9)$4_t#;xK>`YBMqCEaF4 zwPZW&XsFFy{VWA7ZqfFv#gV7@dAPE^rNVYnX%ltyW$I;ohVukt94ehV!)fV0{RhLE z&Gvb1DVwYNa()9TFYB9ieoHLDQaz8jB!?W3`@Z5wq`J+~i{;uTa*hu>xf9XYHk@8B zDO~jg!e!PlFxT*6&AG<1r3vEdnxvZ84Rx<5$xH(`v3>0tF_jz9zryR;JL`8=RflM) zVnja~i@{j=IU_#(&tF?2NXF)v005%YL3A!OL8pE=@Z`hwd7Kpmbyix&cb`2`H0emI z5Gv8o?~0JEkkDbC4;$m50Jkrc`=U(fo%TFBeuD?X9Lb-37}{ghU~XFh3{u5rb%m;q z0{47XNcyIT1=HqTG{c^-b%Bl>yKh1Lc|?oc>+@SA}UHe z%!qd9nJ`mplb~w7u25K188%e>i4a=iNR}em2y(umfnbL<-0<*6dOn*R3VLSc&v`E% zdfaP%qnOFs*;!FlOI^fBje&hxKPi(W3~iCQj1P11&~xc)NIyJGIqb@0tmuOn;9f<8M)k=)IP7_# z=bM(-)5G>ljt66@b0j8qH3LXJrYq^QUY<{q<`y5mE*4poeV99e_%58seQ^g%OhT%y z^nL47VM6IQ@j5fYA~PM>Bw>UzW%H(umRpsCclU{5`^xh&5y$WY@XZ<5YAYP1s^!mm z>*TUSSb}x6JpNwHmnxz6P|Y>*z-n8<0ll_}*p2L+ViaZXEjBrwufW}IvBOwGU=}-i z&tO)|FzvCT=7@wao*i95_ia@zK8{n+fV8%QQKsIod1<3i?B%;J={tz*q}?KjR(Gb$ z>>ot?cjKQTZLW=LOgi!^zr|#Pa+Srg+Rrf*VH9zss>%l9TBvT8w}qlRO(d(jb;yD~ zK3LBd-{ocmHsp%W>0LRnKAgLJA-ZtMN0Di}TQtx}d!@c*ROu(B|FL@gAt>~Ko#XIs z>mFjsN(Hz}wl;sHmgv##X5~dHePMtu;6}3nt#h41*=C>0?(~AcZBSsHrupvdbqvb1 z@rcc+2WM{K)`_+inwj*fLp0V9gR!{uY17uD)?I?WBW`%prH;>$^01D>+^v6*5kHLQ+6!2>I z-{H>+Npt}A1q6JBfRL1wvH817Rywh~fc-iA)eiOfOL0a40AIVm{AUQ%d!S2lcq=da zlWxpPhVI441ElxGCMbX5Yq-u{Dw&s-0LRj4q>zn2Ni0UaDsBQlC>(A4|#`b-jg9 z|2E>1et3xUFG^Ki{$Vd^tnARK2-!` zjoEKlkWxt!@W`4dIidI+s9|f2MOT^^@(FeMVR|T67DU#^Ly0Xh*Y*14)W>Qdr0ezb zX)&upJ;KwcWq*hCWd4*yh*U+rk80j+s31G;pOoI_P;5|9D0C2J1@X+joe_XkoY4N@ zm(NuTH}rEJ+GtR;&6K#p9_<~lit2hNPzALPwrt64n+Fo!qcDDp`#7DuBwu`StC*^W zH<{-|JgKT4XjVnN+J;csvOFFOz38j9mM|pVAglbV_0j7l-w;4KStOYebJVa7&aJa_ z(Dk^W(k=g+fk6?ik4<-!%*81Qf(>;SHxm9ol2VXTPUu)a4`w}7yDnqy}C`A^4d+UktepDF{o zR;lVyVUNU)C7CoUnXG(7v~(T2oP4`G^;Cn64Yw zzv%Asmw(scgYdQgcq_p);M>EC*Y57&l>7aErO6qt*ZH;24j=egCb`OwP zD&X6G3`FNH`T|p(>CZ3q@wSC21^X6_2~-#dTSjmL%e>q3h^{B;NE^oKZ3J`6!la5V zBBjfR`J{%wtuG!%z;sI!1{7`+3VZpAB5>TV6BQb?f(G@-ubt@~{R5<=-72YDJCJMa zU)=yI>;aWdKtblBHKl;ybdKflS>b+#car+^M^Mh8ZhfuPze49Y7Q7{Uig@YcHO#D8 z0~sAN-f})Az4W?NOO>IyhPCx(=rUFZg1C}DHk02)-@8%(L#IQJQ=WN{D%m_?Pao{~w+9;4x3rgj(!#Ewb zmOG>ClhhDi5or@i7cmzI7f0cD7im}aNqvlL4s!|P3Ud=(5vKo|F6=Jco|BOik>inL zk)xU8QK*7GB?SpJR#V{4K#n2 zXe;$B`(1u|`KD?XJ7ekB_ZlBC8yu7moW7t>njDtCbOC%G*aMU_$d>9DT2#~~hRn>tZ4NcHmpG_Vuwb^Y^dk8CCB%@*6pZ z6au*kTOAuxk6G>L2jk!Mj{TdTHEov>B@*#nMFZ^IF%7%L$)aRvH<5Zw7Gp8Ka;5Qq z``U8C7SDjrlCIezB`~@XW@9q;i%m?wGFeKzM?4u(Ooc%0{ga+-i?AX!X{?m-^e?nL z<#HjX$|i17i!taQ(Fs_Ry`%_9=AX*#C?MIGv}tfK!VL?Klj7-UTkPewc5Bj87I0PO zW@dhwo)DV5Pl%KJtn#@~E*V5D%r)p*Y(&65j$qalDEd%BSdzTDbtNk%X1+awR%{Tq z8z!tFHtPGJvt2Yr_rOb>|5DWJRJ2qy=v2f?VlE=7(inw>Urd!fnNlRd8JI>|j{P7j zIvynM|8gZ>dtp^Ca?*FTH)AEu$6$BDUc8fXi;g)xp=-X8iJAMFTTjs^K0dp+l-=Pz zqkc7U48Nain7^xseE8jjPj_Zy!s|UL>pA3!)LdVG3ElVL#rxHAyLZ)S)b8JobC1h7 z1_(iw5^YXczv?4x188?mg{fmAuZk$KlRDdlUV?4y7nj^0SCtYSD%>)nS4kdJF z{D(b4r`042Ez~VSjRU1L+PWK`3Q3{+GSrd>Koh52th{!`-U~6W(*l_l;$K^i(!7fv zvd5gwg6#*mpu<>O6kFcV4G|tKC00rVD-Y8!WIF_?j?#Ea9w17UA|rH~Ph@Q$RUz1%yrURA(v$!m=_qa-OWm)k?Bs^MkJd};;>|@pe;T-h zz#Jk;E4@+WvKz$yq~ir2y}1mTk7XBPW#0gf@69iv7=t2X*hNN=LTnVF(VWF5%8XJK9H;MWt+{$nwV$jA zg>Qu7yASYYp%oAdwe;Dfs)}d^>eGJ8UdSHE_C|*nuNMVzNN#-ylVhggH0ri@sS#G> z;a-W!>6hEc$_AlHC}8EvajPyL$RJcPCP?<^tW^y6ao)g+_UUxA>AXjEt+E57>u@Y< z&^)_T&pWb}FBpNu_E$p0m!prt9NQ6>V3df0Wj(+*O!b&RT<7$DY~j(Vs8>ZxM*+WD zSTr0IE_$&YKsa0}X{>_7JUp~2ui0cE@$)y^&Ra05r)S%2iXn2?_8je-DA#lG?`G8J zj`$l(kFTT0G~Eu3-}^d>;a|gAU|&0!fo-&(bzR9sTUn)-rFe??f}GNhIk3Kn7?Orb zUFM1$JM&LI*lhYIVwwE4^9K$u7IvC82Z(n(GPI!KpcF~kEPmdOK z+`3ZoX}FKcU(%GYvx?mIxXc3jxa{cAzdN7JqRvOS>5fi_IoP&QHXPWu~8$KZ;h1*QY#1 zIns|yO|0}#E{|?XORnZOHB{a^oZBg;{(kD#50oEI{WkAhrQPl7Dp{EuXCLDvu#rb_ zhLW8jhpM0kgHOZWyQ-avNXao(K$3G6#z<;=%Z>WW*A16T#;P@iq~aF!d9up}^}eCJ zMW+a4M@miUo*wdPi4jyyXo)M$>qA0m2#f#T&?OR`1qvC9WhF2udDXY)m;=qe6>GyT zm80E=Q0+@E6SL9FQCH_A{55#Os*S- z)fDtueAgmqGDkY5XA~*nZhxIuNs3U)k-~L#B~9-kWp3j9kVp?coDgar4s-nHIf)>gHjkfVBVCk<*I( zrTM()0r|4G9S6zQTUknbbxAWO={!v;V^d2_#{>^4Kw<9UG?j6P2jWq9b-I4eg1)jC zS)Q$=lG`=nepEDw6@Tc|ojVZkp!QR#uXP09XK!ET8zlYP<1)kt_C(9Q4w@03j*5E4 zm)7D%J-HRO8~efpJ}5m>Pxqm)9*6$>yPRoH%AxiG3gy)=Bh%+3c)aJjrBVv-D&%h! zhBQl#4Tdx;j&X)Gi;opZiVtdg;33G0o4&8h=@{DkU5x5CapmHpN>g)Z9nV5}kV0$d zU=NIA35^07n|q6Mr*TSWmAun)x}D)^ET?`@@a|nYpyQ0AiEHMG?M<^wH^|9pDX7qS zlzrbs5HL`qvB=kQD%bL7L?gh}B74;)+*b?B2S8}(!`si{Pea>*wF$eHVJVN~rg1mcV87@s{7?k_zjt zXTE(JXTLM}9tHb;w^%^Ga$K|u);S&O6RW5c(7zkIS0*V=e?6PJTakELTh`72M@j3X{q#J4ac|J|1xH`3&+Xujh$m9Ri^?+2-G=Fbau8bSj*46xOX1ed6yz?^S4BJ?cl(#FJ*;$|A*?;o!(t5E|&PFeG(7=tNMT=Twd2 z`AkHepaXffe5}^;?85{pzX?i4?tA<~dJgEoF04J)iKAGWdA=U9}zw zTV2PxK55rt%Z!wtAl&d!brl7(&qdgxyVd8&QP-&!s76m^CB(QC5`HwVmlhD2{f)gz zVdWr@kcNl|Qqp(HK4`j*QR@xE`4=cyDMf3$+UOV2_+9CMUKn@Nn%3#LYopS=FLEnO z!jC5vsX0~?;hC|BSoh4ayjiK(Sm$%-_s>uanvEgpyliqGtpR&Fz^ zMj2h;y^e7%kc-pW4`N*Gh$b_psJ3ZAS01tADH*=>>Fx{24=4FE!kgLi4ZWp?=p?IZJi_1-Gi{~Pw zn|uAncYe^+_rB<|n}*X(C2l3K@Tn28*L8DNVCK2Q(PshpkpQGHq!;qka&zA9{GuJn z$4bJd3^-_>f8?%b=USLqlY{=IpO?${$>##dK=TKEerN(RFgY_sO4OFT0yWbVP;j<6 zcSm-tqdA|Z?|E$_z;jldO$oX30RN>{9*VR$1O!E*>zrJM?(G$8`rlHL(-%JUye= zQD^ed5#mv*h>(cEB=e0zd)Z4hO>!9kj1t$w+*rEw&|Y>DO`|^(T$4wT)_CK{ZNynm zICTEJn_HAqOUbEgqmpefbycb!-}lm^k5tMk>EZ$YxUdoQ6P{@KUw9lmfXq8*G`EuQ zZA-64r>;`ViWhB&jbD`OOky>ksYY+BwG%whS%el@!Lns0e7xS>i1Nh5XW8xFMQyP zE;%{g|Cu}{7t*o&SE?BRi1PZI`280KXQuxosJSoxNge};RsNBC0U*F7w&i+{>P@W7 zznWEDe<@kgzbwH7ZxIEBkY7qpj9idh(9*)z(#(KdMn;fa==*mDJN>^IW{0qU>;L8c zB&s>UMY=x}0FW2r|EHt}`0H<1)gGJ~Cj|hqg}@X703eht4onB9)BgZjD7d6oGwIY$ zLRRj$BAI$!Dp#}^h6~5Ha5tl2D`n17zH!8^ej~Ge+|1o>)f<2?*mc{;YB8$vQM!-= z{bx89xBcZ{)$ukn&aWOnnIqDZSVM&xaBa_OY!0=p-}rGES4$>8u8 z0~!(NO#ZTh1P)!9*?nL|%rLxpoz&z7^a%Y%1PfplVf z*(oI@!?FU7)4gHMAoI^S)biVBIOPYQ^sJ%NC0)b$J{N0DyX5Qvn*Y)oDwd z&&z#2{H6ayO=e&=J#>96=W%`6=rCE2bf!!@ePqxeb^92<6YXyI)Mo5^JUDj6RdY^D z(eR7UW3m@qCpybQ-SlJEernC26UA+J!d*ZKI}SajXrLJOI*y>Dg6f0hxPX|Rs~;N8 zUNEmOTH3^05M^7?k0rUQ2Mj}?dqL4;na-)v?dDLML_KlJUXK+Hx*KA%O2J4EQ1IH~ zIX1A?vDM)s#p^Om&&mr4+93d)f;Ko`YM;_zzQ2{g@T6Wm3S%RbXJM7OG;TMZj3hx=@NBNzUNUls!r=@ zv$>d@QE|$skyewhk!VRnZA&o)1@9*dwSnz=_a4_sqNcmM<)FJpqKi}2DyxQv#>7Ea z3raqQgP0N8Q8YmoDk%i1xioKE?`5&x^F)ze4~bK;5chAVgCQ^R%YmOr%rbJ4w#g>3 zd)Ke!do|xhYRMu?#pH4vM{Zx(^}hZf4RkGo(C|>G)=GqHLRJn0M#z*=M^fOl$dZbF zVxx;R4tZ$;7Qj)up=ot%os+o1YW2*Y6SxVx_dLAk^|4&Xx`*WTy8Rh3_mlYP%-fgo z%V5J>0mEyR;b>1dmK0nr zyvkQ&DwG_kJLD(j*P1HI?`TBl%|rNisY_)f-k|0UjeSi=BbVDB$3-W1knErBh3My_ zR4GHuO6g@dAm8&qwU*jL-z#{%@_4I5f{rLhBZ(-FM0hV(NB7WHYrO&82}ji5*HpLX zKkX_skiuFab7jw%3C#!~i~sti4`A%&TA9lSf4Po6OY@4u9PK*ZDSa3GQ?Sx^l3(E z1cUqj>+f&FH3AOdt(2ufP{Th^aAUR$YiG@>qlUylpSZQM6M9-GTG(PwquvK-r>_i` zETq+jq*tdEW5W&q=<+Exz-$-Vq|lfNfV#9^0p z8zPwx-W~XZ2FvYpiqtI1v4ne+z-Y$$mlSsVc7!Q;WsKU9(B!O*X*#t_>9Q(SND-NF zI`w1TAC{M@VJFK7bqI#C?k)=!cn7*jKyvdCmsKB?Be{K zqI(Z*|G8>u`@*bul@{&LP5T~E)!SX@1@CzJ(y2lhZ9p$U_w9Y;p7Y4;Rz@ZMA}ejc z%cqdhg#O}?jl056BBQ5vy)N6{kzN>3dD2}v*Nm-StB1F(6Lc#lL68oyz;*arHs{uF z%-0sO$8W~Z5Uw4-F~wsB=k-W!Pnt+u>=q?bM%iNz=d@DL+JIh#?%E6otVr6=8|4@d zW-VsjImq51ihFMScJ~b3`_=co=izL<6Z>wx_o2<7loNrAI22OrqS`&dy&*e0lg0QR zzcaP(QLJIZII4x1O)7hIn4S%bbA1 z-@ZroG1vh`S5RzdxOXbdglgm zrK?kSCM!WpJIq<2vtf!-e3!}}$9k8_O%W9>v86NxzMJenx$|-6GI~vow zP`QialosUThVrQb-x;ksL5RQL{`S{czq(GX($`XJk0YHQ{EvgJzRLM3kTqbKNrFcb$0d7)5p4PVV55rAuxeu_M))igo?E7KCMMj-1KR zpgmP45f4_{8~Z@lYf8}t&3*7_19aljMa$Gx%WSaWvxPa~j^j}ib4OxjG(&?CZl#Qe zl8Z+}2GP;{@^Tv1^N$@-Ji_OFSQD>I(1qne%d^FASdYO5-Zzo1)uLxo84o)S;gYq6 zo!9+ImP}WPORV$?3G}tE><@?B;K`n+yXOR6xQfnH>8z-=dN%s4T*OXQ(!T1FNorXe zZp}y)Dm{0c+h{lpO8=T%5wYhyxN+()9(y%>n1A!EC|X)oZhKi7OtpLtSl2k0Ftf7m z-0`nS%y+HoS@%o$W~X_VCcSy5xu?ck=0V673MB>(MTH#$xfNzREe8fkeWUUOL%+F} zy`3ElV3%YP+SS8E(!>#N1*0ABVB%fX@C5Ej4X`J-?#kt4dD&WD8>Rd7HJ4SX*bl-f zt)palp6(8-IVQ{Q`j<)K#k)7 z4^4v2T%?sF7Lkl_PWSJJ2ktxI#;rGkzZd4_YV2Vgb5O9f3N4loIo6$pGrjdv;74WK zjd6QwZ66;ll!|7(pI*S?Hnp9tFD1N6%D>{w*k)!J$OSsUt-tLuV+?kT`$8ym0C`z> zwk!2dBl<~M&HPqTb$HN{eF)*#-(j`CiYlpg>yfs+pUee{x71D}XqW-`Na8M9Hj?v8z()&YMsnHMhYP_6u!00A8n$OeZU$>EI zg-TwG&d`(2MI}Y^R!W|?Skp;>-5(Y9pz4xNRxff@M>I(zXLN5bo$_#NBm3`6nX!P~ zNOei&F3(_rAgKS3fV8;REdOHbk1m`Evs#cJyb1G`=YG|}N}$*bmO8s+smDGvp9$9z z)MTUy7dM3mQ&s^BbHmBN+^qpu*EwF`Ys$G0o-jw&(>uE<^C+V6R(&h7bm1jMz9Iwa zjo=D@yIt+ftP2ioZ`0(#m69^k5m&UNJFKj^89^3>#$Lv-eJH9srYbw zf7ov>983E*b9OPa_;(FzQ@1Kt{|{8kNk8_7cF5t9l2L2(79YB9*=h14@ml>I8xZX69l6)_W8g zwCQb*0$TT`fn4IQ8iWYuTH>BC=-)*(Gwp(aRImB+BRFE$8>DU+AN6mYTC6>Y`NO0Q1v<5 z(=diH)%K9|_}7wEDA0A5Y!ceJ(Djm_M*hAomgk+m%u_t{j~rz(?|5Biez|>l9;2-k zOQRmAJ(W(wMp^TCYQP-79DkTRZ}D`M)#d;4ToL=KoY05g?l$!je3f&Td0xClIk5cT zy`Y6j7PqI=+jjcgnP%IQy5pR{kq2bN(IWO(rzoUU&D~IHdsqo}2-1w-zZ}n>Jhv}Q z#2f~4T@$+L$-Yl<03AHvX3)E&ZPam1d&)l9J^m8V7U;>%ypR|}J8FDS*k0`7x%obl zmu6Vv#kShhq1&q3&oPkUVm!ynWu7xQ#ebW~PoPbS;<$Ixz9Py_(%CD z%dp7Ak=?mm)`A7eLIdVR9m^g!`*X9$g&d#9nwuskjHX>LlbFM zyY@mi!}OYL88+;p0D%P=Y9d4f!ECdANa+U{`~NDTjzjUU$wuPYsXhFM`)>y0S8+!3 zS5RQXziR&)oDj~q4E?{TFS+5){3!hIx?sM<3fGDQ#---v<=`yzHni*f9Z{&;gqGk^wfZ>Ho447?$}- z(A+b9STz0TBLAEs(hIh<`L;Hmk_T*(|Ch%Go`S~Vr}1*R|Nb=ph<87Ym;RsPHtH1Q zXkq*J0RlaLr-d;#u_FuVYryK8_$afWm^dz@OoV7EsAIk#@)J`lQ|WC{hL;69_)p}g zHFK~`VBKY*V0m%}qq|;en9y*CO>s+s{(7d^imtv}Ca|2AOl^iyk(eAe#jL&pah;WT zbI2jGP>_rjuD;onma8i4?AJJ}t)&(gKNnK9l-b#TVNzNpQ?mMIXN#%c&(s|KY^%%M z8}4BQi5?l;9+|cl!n48DjmE@8XTw`kcjJes5rupY*xU}tNy=_q3c^%!hD$TSRdNlr zsBP?1qhk%7cL}8!*|cBX{8sDK*1$1DS8;kL7^@$yeN@p=+9qs^gQrc5qyF|+)9A5!8kH~!-@VrsekJBT zy6DQt_{|%s;=HUybHc4vUZRsvuEq1-V`x8z_>v5|SFQ!-zKhjw81Rl1zWFC0q0&0_ zi5)*6qFFZUD4%qzkR*e%$!5^tvcpszl8 zLXtl2hs1HH7&T_Z_9R}`h1HIUma3Z|*!Wd+MR)4Kpb>mqq6fP+V5L45iR66dKG~Eo zU+^?jCD=Rk!gB4H;2<~-6Oue?r?tH+_ivLK*b(t&DD7e;3-=63egjycR-&eNv^F5M zCQmpuD!BS&AG`mU4@f=_VHO;fI{3C$MuGWO{3{F@Z-Q;qV8JR>OqxqrE;0rJ zq*a(L`{kn*glPSjy{P#>@Z7JA2amv^*%C|JzR@E#fD}jf+KO5pLD1t(Eai)lP-gtS zvedrnwC^opp|&H}IKkTgjxl*=a!!wcweJw4An< z`iF;6p%OQY!{Ypw{v^cLrED2IB992UKQK2-Y$z*LyccQH;w-sktK1EzPsykI$9JU>W-I=~sN^e9B zF-N9k$h(Lf9OSV_ETT4%*h9ID6je_TOKSm~^?*ky^05T-Bf%fpsmAr@*lVkkDFjXj z+{|{}nbiDLsp`Hxsw907EDu-3ucL9X-#;ka6_-X~f!^;ZJq}_g zyZ&9}-Lav!?;p8Nc8{Q%O{SXj&chpR)AMJL;(n0g&)|Tc{;&6xyxy7XruQnxdiOYs zn{xM9yuOSZqW46Exr~cBw2wKg&0A3S#IIgto3Z!sydh*;(?ok)TWa?TKqA<+_ZH}U zL6ki>ZY&Y(PkOA?-i_CO9g~js!D@G2-U3zr2G1f8NiBEhiB#_HzXQ-}etUYIet6%J z<8ChIiu-M;@mvV7^G$kT8HH%|H9bo*3O+3@BE$J}7E9LGL}KerULhIjB5GAX9_i0~ z;fKlc^Mtu>`CK)u3ZMBDTndPKKQn(wpjaXa$+v@+dgSr0TK=Unp#Q+)5}`a*sQ7dR zUwki_5b;<@J-*Fun&2oQCPPQ1_X#*^Q}V^%Q9_{{LSlpSvTy{Tc0={U=Si`Bu|HEQ zl0GsfVu|PseO6re6Un)u^S0+VqQ)8A^!yPFrs3i#dWWlUlTUKIBbV^iX&)Db8g@#J z7jP&a>QZ*d`WAOfi!mfT3z$=PKtEJ&2~us>TwzLgH2dMlDH6GdYgs(0VA!Ow~JUh@4n%MJ?1p@BpSI4BY_5*6UN7~67Pyv zFQM7>$_*cIorzBsT6QvFO6|i(of3hk7YUw{E3wV_+$;x9X(#l2UvJ_}3L5m+jtiYL z5@kyBNspykls~o?CCKv>!#?q?8F{j0k>BW9iW!}XTQ+T%@5^6NA687aLVEI(eY!EU z6q}u+<=Nv)Uj1SEOKs%P-O-gT-xD+J@fUacCPr{>o59mr2n3F)WAlFTohHW~*KUG!Hi}xy4^~2cKKF7TxR(()Ut(iB><>o%ea-M+rZkG=Tf| z000y;K_zlI13Noo3nNptQa9i`H{;@r!|QufaTwj+eQ-9*{-g z^}5N=FoM>;87Pm&pu`f7;vWo)LEsS>Od?H|@j-Qg7LFqZiz8wnWbP$u9JW6tGuwnQ zeb$B+a}w}Iu=+YD=4Bg~f*$RyNk!9+9^Z};%(^e^EvlMYo3(dmu(miwgIH$nNEkz6 zO#d=*czrDsFf(d zeHayKW#kvo*4fiFi$ft!&OF<)N0d2`vTeWIS-TkSpm3aOaBvwLcrm)><5xMOoJ&<< zZOUSB-kftP0!g+^R+;U0){~dRKBL{gJbu<3ZWV_Cw)cG?h%Da2EEv;M{H%AWQ~{5&mv=z_ z2H*@(75ir7ud&Gq6-6a8jL_r?g;GcZzpu{ z_n%M$V8rw+El~dVm*_$8?+fs6{HFxW?foAwkulg@l3!5nE8tJb8GK~@Ed&3fU;PK4 ztp3A;k#6+A%D@S(tV^yfcrEOfoVVZgidIXV+4$^s9U`#_I~*f!Kc)3L8}3l9(&67n zk9u@m{fwrl!TF(jSDLa+^?AkT*Y9HP}G=0b~+CjgOQd730 z8BByi|I0WtL60%zKud*9{nu$2m?yOr$v_e1a?z@O@93`<(WYO($5gvUMdrLcx?;rf z7}(JMTy9L?ugPVLX8Lyj9b25%09?g>_wN6%)%Ks8`**7?*yhhK><|1?C;#7CZ6O5z zH1mRii|F62whRI&{|^EA;|IJg@=p^P82*odfcF9XsmuQZZGZ6e#@`bFU;^?#1G3ZR zzqV50He8+DC)1{+uGp}s-;$uWVz2UFV{-oAVv=gpjo?~WG-Y#K#obcJt;;9+ z=9?Re!&9*XDmT1Mta->Tf4p0JE&i3@igVGb+)-}E>Cp52ZASCyq-oeR;?)~fNvla= zxGiLt?3Z3;xmpAX=X7Svk!(Y~)K5+a`KfYaQPP8bEndqjfppb~6~kT9xz~$i>Nv$A z$p5$C{Mj(^2mX0j|7&oBN&ad9ss9}u-e3Q-qtMJ)_pjQ2Vp{NnhNuF3fs}*{1`Gde z(f|j=ks8e7f`jz>kBA=7^skP>EfwZ}Od*s-|6YQV=HDHK+#CP1qY&(mq3*wJ()hLd z*Y4l=PxqpH|36)fU;i&1g+Kmk{zpe4F8G7+aqX{cJo`^aVVaGW#r4pLS*G8;K)lO(jAl zc*g=oC;?R{!#JL1-%%?po7GobkKtq#H#{i|=bH0~XTz^>R-2XWwZZ9`hR!?mZq6A> z`p!1o?GyAKaAADfsi2+Sse?Qn{Ex4-$XhFXfp27lA_t;g<7i(OsJuaxp}72>;rDrT zoohpNnWWwxNUxNNo5|w>9Vl;8!Lt_}*LPceqh*kJ7UfFhzN!s~E6J3#ckHT{gicyD)YwuBVpCEKrz&d!? z2(akZBtW%f^^SFA)j1Rke6&%*2HEdA;CQX>%fbS6j$9dM|mu5LC_A6nMEq zJ@%5Vs<)u#vy*@*o9QHW`J3dc45IsI_yBq{`UW0iMckF%K5r$ZO+_8r02)R$(sLR}SudGGlY1HT=|%IwF2l(M1(znNlX&mi^@mSUMPW4{JRLnXq4dkXQ6ePt35Z`dDN%O1Fg0^H<=|EciO=5bn%4F&9K9Oy&l2%N8UW})sA1^;bAPHz`Xc&^FmNkfV2dhOZz^?iq`s6*DDwHD3|WT zVT%yiuvU|K+mvb_b51N#A0x>ORQKF|UC60sVf5<;Vo?;DVTE0ENLFdctTNzp25^43 zwLe$^aY_37cnIojcX31O(XV_0q4Dc@3LPtDwMtYKX1A*8#c!)#QZe6RZX@b$N04EM zF|W~sC}d7Cj?uEBh=O0RurGo7L(Vez+{~9}?u1v&7?;r|;0BJqM7=BrgF+nXLk=+Ap=I zDregymxxE{_G6ER8nqcJ{bgEn^hfdPJ*&a2!gSJWIeBe?r2XWHdIeUx2(rTpx@Qf@A|74b@+aS@HI6czfE841?56}Uhl#_ zVceo&U*b4t^33VSyhjL!7OLrbqkA3$ z*F<;5Cym>tW2k2+zvqxuL&SUE;{y&&oMa%+7B%1nO8BWOqcOoLLMbA zccy%#s>)DV+D2@ULYt*(+EosZA$rF0BM#B*5~%F4vD!m@g2u5U;_ib=A%Mp(JlG&b zf3|bJtdt?l7LO}7B{@en{<>E-#Zauds!rCk&X6dz*yVi1PG}!&Hip2qWd4b0y0zpd z^~wQ0O7NVvJ5B5u*Ln5G&#k84!cw&<0OQkA+hDK|c>8dh$Vx9ih!y~m4+z@S zN|zuo?UuCH#G!6+lcg?Z5Y{d;Z(~1MMFEMG|H`-{OqyHakZvj=ulP&z>BoH9M-8Hxc zhv4oO+}+(RxE|cygPq{+?(XjH?(by&Gk0e0ox8sGzV&)RRrRi2bXD)}wTi0#?M>PN z5rq=ow`9d1%ZQMliv`_tIyd$$a3Kw^*}rC!{TN036iAyAWgZ7*A=-Rnso?xIV>LHN z=0R1g$w^QKe9;t<4!qpun`FcH6U)1!M{M)(y`Ey)`Nfi$Nas31lEVmEG4c!tmMW?* zE=x{9u^+ACYpqNqgBB%(*_MvuChIgQQ7qO~mC9nGTR9ArW;^xZ@r;=mwM==?^Q-;I zg4~Bhsx>0=@npz5&M?o5CZvC@5i$@FJnqST#fBezIQ2c)hdsIBhM%<-d)GgDBiY~; zjBe|`StG;6a4zCcKu^)4)+0Dn=TDh1HCaBdJ8uPaMuro5xn;rTG!%;Av*KIL@^J};#){E_st=XC^8y=jXx$h_E&f+YC z$2TGf?12W^2-^lal9dSr9Q$PF6POJ6rx&m#=Dzxfos!R(OeDa5R7t+s0ruw^T z`yeXcEt7bPtau=vO|I{(0OU;Nho;}OQJiw&Yu|Cc>dLk|=)F(oO_PWPCM-OlzKp&e z(WXD806GbD+#B5rRAcc)wObX}&JHV{eauRR&2lLYt)3KPk}6EiW7(M1M|!DMhVpRo zYH;JSbRGIYxHbiQE!*)Cj``qwuFm9cnV~*yKb#E2D2pNmoi@png>d_i8%d#drJG@) zEUG7(EdLc|MkzRyE<=VdQV=K|8z~xx4v4ckvfmNii`QpF=e1mm`}+D+=dqxxOKX7Kn`!H2v#SmCHn9oetip^NkU! z=6uKl;=(NO!#5+)7x0!msIyZC2gRe$D(aC0P-$!cBD2)H~DmXMHsJllBL$GIMSC?@0wdVxXj~hzH=DO$5 zMP^VhAbX^a!SxGo8TAXj_!yh}L=_jMM__}lMME0Idh-mq1^R^r@C$bs73e0e7#InP z_O^GpzmE(5>pjtZerT6x z&)SceYOrUP+8ye*<5aZ{i?2xkG~IM1pY1%}%W&-K{WLsqEk{#8JnQ0yWvFnvOSwyZ zthc1f+gGf^!71~;Y8@6zT?3vOUYUz)4$F|WImSyP7m%hvo<7_v<1PueMqg{c49Au$6*gb;(2!BYU9k@PPWraO%fH!2*XEG> z!uV$5eN0tb9*E=oRh{j#e#pRbqozHIZN1UwZTN=j2p*5$F+?4a$cmRrxQLJ|`JMOj zH=WWHo)p3nX}TBM5|7))Nr!z}BhtQV9Bg^^C>ze`ZlY+e1gO@%gm>VS`xKWm1Pk=w z-QOZ{e)E%eoC;&eFn^8C2dmfA%AfxM#fwB1^8J#I`hr!rDnTj%e;up((_><|O=xK6 zTEmWNBgz;RgOT07GF1GY zl$A14jX|ll*R=Ar4J>kpZ~Y6c2paSwI*>tZ)#P<{$t&EwE|so|#`bwBmSoKDxM85Q zF+sd8Hf5yXj{q7ZP_!{KqE6|px2Q@O(Z?H7VG3UsG6V^viT(&afs!p4ltl?+yY5I! zvg#lGe*`K7e*}2|kYIoZBoG)|EjL8BP_K(s+hO}trI84#@>Xkz!aV*_2mDdy-*!sq z&CA5mPHCi6gYnvx#nNppblCooP^%l5HaPO;D9~0s4Nq88EX`M|i(uKEN{0jCwMN>} zO7gS()5!-Z1|!&PCXuY4?FcoI3XRLVT$?u_)Sb`neig zGd&pD+BZI1SB1N?k+nHXtY=|WUb#=!y>)Uz>pD6o+haSJyy-hoEEr3v(X`QSY8nI| z>B_Zx*H%j=NERyi55k!YY~cZ86%lxz?}o*{T-{!$Bv}rlOuSa}D;wMD6s!u5J2di^ zMpFzqpB3tr0JFx9;bh~(yP+Xb{`~3E&6Zf+Sz4BL;Ft4#xeDv zN+vK8Bd)$T42k7e8(6Xd(|;Nfv~$k!LXh_DH7vMH z_S*jRr>KO`Lh`7^I4d4Y&v(@@5m02g3z74+uaTr8ay%bH$~twNMu*e`T|$I&2I-4Jl?{%9ttb1#T_K757!TE8Bf? zpg4D>hMVth9U?H?s0|$%Am6EM>6>P3T(oOBt8Oe?Vd21sB}3h&3%zV9VTWs`lpxC-VIFL(4r{x(-_dvSfqTxl$7-Mj` z!$o38?YC_7yq#r-`{+g#MFjD7&mJcA=84;aeD0CUHGS!Bv|q7>Io7wv^#%4irn41` z7u;^6q3wN?y56zT4%Z+TV{71(Q&De=yWInXjL^nz?BEAQzjl_6*nxHdBFMvqLUUr!= z{iuM;D;i_cD8=gJw(l<=j2WQ`?3GTUFSZu+%btO;Jd|w&%o*OqPj^x#(U)Eznz7e| zq%Z(SWyoq{9jy&`ndK_HNpSJhdA?K2Up3*jx$&uuhSQxiZa(KhwnaT;`TbsofuNrq z(j()_w*M9Qc+u|mx)H(6iuVOK!g=)gr`CMtDgDv=!H3TSa>7|hA4Im;7r#XG*u@S4 z`Y*ZTFt*uQOF5DIU5u3>Kf1+mgxjSXj*;lKjHH7`ma2RUz17Re9mS7(MBHq^>xg>< zm*K7V*;yv_o}cdxj2RWJ-_PrYXNolj(~zadkEA`ScXFmlj}(#G3H@7~)Vot=YoJF{ z6DKM)YheA7fvm{l>F*PFalL}VpEg6bib>*<+JWmND4TI?t{g2y>(^?2ICVpt^+H=U zZ*$c>6PAcfa>RDdYWi^lLh;hyw?;Hnww@{^9%xt;YvzS&Y&xyr0TKD~x7M!(NweAuZJNHQI!zgEJw2_0lI zw#cn}!KD_qM(pmi& z;Hm~+w)IU#`v|xrvO;ujJnEgibE2+2>N%pCXq2T}?!KZr7_|Ax>e1}X?b2C##6XjC z+UO{g4Tw}M1VcJ)WRvRyc-XfCt6$B*pNF*#|-@iXH-`vxrep?OVRvVJcg!j^FZpVcBHjcx-3O zYTdkF>1adUi`rSW{Id_`x4Jzjz6#o;N(Uq5uT=ZDww#a%?=M9iYny6UG7X1I_S9H` z_rqqAxlPvC_&tncC2G@&EqYc}buB3_RjZroL4%C4ro((&WOgo1iD)MpPSR{ATgq?e zH#ChH#hMy0-k6vkU&vU0xD!0I)M-N8F}qHu-aY2Dj28`hpI@3s-q+Qd4>$8dp3sf& z_h(DZCLT9_!_=gI+}ZiT)cRcSyLzfV$BVFQXXOTa&%U~S$?_D{!D8h$?ZvQgratHO zIZSDjM3c@DnB*txu`+q#+&6%;7f;iP=32OOz5fml6LRpEE53iH8~?tL{V#N5f5JbP zut6oz!ug-Yawq@4Eo6f!v;D2s7wjK&sp+)H(}x7bOC*-hj=Kwi!wC+6}OXSw?wOT2KS)L zdgC-*({l`p#p#ekRNKbGyv@>HjK;ETB*$0ptBmfk^^Mw>?mNrd@3a2lTI+Xn-R{b1 zm0mcqyp@kJqE;8{MA@|J0}_pru*H6&1j*{fWKIJtnLmjgF)o74Ha zn@4FL`>vRK00~HX=a8S_hUQM}zHcMlVQGy!M}90qEgfiAt7IE$7p_Da^oiBiNqElO+Kzz zc!tm%i8WYVFfvC*o}?IZ2Fe_qH3<9XTQRt47Pe3%|FbE6d7fQOWZ@(ewn(#j5(G5C z?S?>12RH2^(j4sITlhKbf}?rZwrQ*n%LigUdZPP$Ffy^3U4b}LB2K5dpKW7vQ3{pn zLnay~Bbuu!*k!MxOLWmTDmFl+BiGd_Cn7Mcjv_?5C><18>n7u!AXk#%!B`1o?#5{C z47`CNRi)**I<%=*tN15a-uE#HZDnnuJ6uUtx5%DB6q>Lm`(X_(_+5p9xuxahFQYR1 z*98idPTt>iqMDLwoYN=mo(}00I@TO(`7&G%x=!FpIL1rRa|`fzuJ;fe4lLUmZY_Xxm1v|p}u3mab|F&WCrf7{AI^{fb+PHDrq~B83qgAQt zrHvTIcyhQS`@62n??aBg(8Uj6RlR79#2>}-4;z{|Hy(Ig zm~N9KXQ6EaJ1TDrx+`y4`KOdhcfv?jhClk!e~XHY1JRKOJj8~y*i71s>tWV(fJAs z5+)7vKUY^e3dFuyYR3EDnQYhEPrO-rX5iNF;jEMX(J&Qwu4a7I2bFyOoHyaugR}s} z-krQeu&3?4_d}Z?yjcxV_B#34pHGX?e!dX%(uDGxBBIIHptGzT%+{-FR1IQS76=i9 z=tr<%MmF0D{hKxu$~)w8T3uiwByQ(h7H;M*%tve06QtTV-&R$`eX2Wtj%?B2?eX1@ zVP5KpOMVtl793)-Q+htsuuliN>rEvTBrGY5T z1EmODtujm(Mj+T6HLNj2M={F5hX~Hf@0CAs-BAVERz3z<7c=Y5ga(E&UVq1f5o8NT z^(ewcrxwX*kg9Cn@ip!&21=qmQ*%V4{H7oFdj$Ip9Ny#zdyT`*EXCwm-ghfYX?pkU zEp{136?~_c`{Y%KCW!NdZ$mD+LlE&0p+5sC)3?}R$X>A6{Vh<*HprirKk7phoUXs) zk)ZEG6g(Sd6%E8;;UY|oXn?NlAJfnb;xo`lx6$g_I zD4dv0wepe+SZT|zmVf^y`y1M|&1g9PRO4~8N7{G8p_-19P)IfJ*V^*Z^W{{WTROVi zaD&JkBz^m+EWBBIy~`&RivodTvc*#1S7oNz^7)aYBz!03K67*G`qfHGEwz~P+B>7e zN69qrVOGaJqnSL-HMhZ&PEFovP8V8#D2?-E#%tuzK|}f>bQf(#3RP*<(#4;jRFs_8 z^62aE*ltuLN~>OLtrYAb#inZLC4=g}T-MWwtA=r1uQLKQFl{2wG#8c>6TiS>u`l*b z^9eUs=ZeQzF{Z7%f7$0@vfmFjWVyLmwe$a^bqcp$&cruV%T>U1RVx|%RJf-45?k5_ zuWLUpD9q4kp8J^`BNC%~CzA)-?jhBV6=}UzYqGokB-%>L8U@;Zr!Ygf%6qy_AZ3L? zny0c9TZrC;UGFZILCzaMirCnoWCB@(>m1DcM&Ucpl&mZ&eLWo-ZoIM!+y z(jI3iqx9ZPabqLQy}uA_v{RRCOVc=$9+nmFX@=O^8xjT$LR)t$W~71Mk=z_-GON`m z+@0+(Yo5{oDXgNoEN8tNA=|Td9o{VQxxQ{p3Q)i5f1C&?SJZY4kcdh9cP+|9Fq z$A|T5->uUlI-Qs?&0WyHOWmmB+DP?0Bg&OxZPG-udu_LzLibi{4{U!I7_?S(IE`}2 z*M2Usfm?%bfACg?U1^?>mbgJkWRx)nkd7Z`T`@YIUwaM*D;Mcib4JH3c4UUf$lGFY0n@eqVH}S;!Ig4j z^d}!`n~*E=riswJFL7}AM{Us=q!!(a&t0%E=a||DuIQUO{uD^O!Vfr`W&tipZG0_l z7k8Z|u(ISWE*Az}upj8jJ>4!=JHtQn5qc(HtaXkDA^N%ZvV#^MZ7=#e4Pf4}Jj*VU zyKrEE)Sh;lMc?1JpDznK`NGWvnot`QHar6OklMstw>SL#DP*<~Bx!q};l>F(fftOq zkbdWAc%M9@FRHr2KLCkef+$H`wKow0*3o#m90e{&y7u9K#GdXKja_N50BX_9QZl;nVkB2@)%<@7t%3IxUwAYRo!lv!Q!+BAPo5dsMwdl~C#OP=;Ftdlk2xu;Zz{i4jr2`Le7`c*zQS;My z0H=`@xPuazEm|YSJBY(UX0yY3nIz*`FbSK=?_x?fiGxitegJQkL*N)#IDy|tI=_>G z8)tD91v3HpB#2{*?3Igg6IK|!?mzRvF{p0>S6#?t=Ck=nr$FpDSLmquqkP^D*2njk zJQ?2kT6S9%e_EP2W-Q-Eu3>7i87HVHXYeNawN3gj67n4xK0bjrCWWOo`XQ&`t8q8D z8Q>wSd1G>!B|%pQ%<&XuIo!qw88~=j!*?t0U^Y7cgYt6Ayo!MNLyi3#fi)4%y_<3i z4)=GW>|g4}?&Gr-v;SQi#A_{K{lTvM|0j#anaIxYpr7Su!pfveiNz5A2~z^*6B%Ss zEV$sHZw?(KjLw#ki#EwW1cn`Q|Il07rP7%wHu-l#>kr13i%zMtl5Ir!cQ~x3AEhy$ z=pzUUqZIlS7?RVf4TbSdNSBhB0YroeOo3QAIB~%*emO}ZaoH=g|7-{1!RT&knsENf zmrq%S4-!>O)9FbEnr2NRhvaRT7&!bCdPOLjPusyJWR^P zgf-7e(A9c|J$vNQ?fe1kOT^k|BvF+iI9@$U;jV!I_CaFpLlU~`kXzm@_V9*5QK|Zn zG_RgZ^h-N}ONj7?0KkCy28#nz`EnSI>>OPndY|MhY{pub%-?nQ1ff z-p>@_HPH)NE{;2;vkYK>a8+fPr5ztaU<8B{{o%wZEaIVo-nzhQ@y2I>utO4^xkj56 zJoY`SO3LCD2R^k$V1LiKYuQqHpO-s`%b$@^0b;#Z9GuLa5_`uWeZ4?ytg^1Rr39uZ zyz63qzfUk1W)ooV@duXk(W6%dUmdx&Fw~c~o$POp>I8ZEv3XMjQD}3nu4*+=^xoN+ z))R`KCXU=YODiRxUw?pUk#jfJX{oorqe~eO&E6`gE^?l`=UGae4d_4YUKV(X?LQ0P z9x_k`eP+y=qfj@@?m)UH=e^uwq(T$n zi(bKWo%P2Cf^BvcX>|w7FVKAMoXc>NvhJK*UqN(!5p$c_)Fhr(xKnkBj_1gH07W5X z7x*+%PMn$l%UMzq`xS#)jZ=Hv6FeC=V{P;x{?bgz*tQ&WMSJ{xOM_1|;9~Sf&`N*C zaZ4kXI@3$#cqxUsjyJvVMdamCxGV^bCU?#*#!y2=O^&Ect#JX++MbAXEJ<8 z>b=Bd&9wFu#0$kklXe}*&Ej&qq0wRO6kI_E#Q1DMFGgsi(;sLaC03#Z-*Byap57uA zB)&cc)my9%*p<9ocIAg7(`~Rzzqwk)4uhyLgI$0Nc_Z$wYk&KY2n;w_RR16WK*k=6 zZeZK-aa&x1t{d8oTl>v56Qs?LFB{F5S-8Wb*>OqwxSbK^Vlhk}b?=?TgG;bo+$_hL zHHV7JmFU={gSB$z4IyPI!2u5 z8=$_#-LrZ3=DCA(*1te)B#$)5jLS!zyOy5CyG7@nRe(JDiE^}^&LBa7vy)GMXz3GO zL$+;cBKsug?=&y7Pu6-!d$|_JSMi)|{e0I-hTOWz%5$gv*h~o4-!qKEcQT6Gn?el* z>J*|=+oA!ki=z$*WjtisKIG|RWYp&9U`$Esh4s8%K2vu#_A0A5Xe*Fm{?qsVU(+MW zDzUh@6B1KF1{0K;(W0wdvxlI2CV#Kygntjx8Dzm&yUN2oe+@Zf^8odA{mAnS)Yq%B zOO9DDTqmGvd$`T-@6=87Wga+z@K4B19%aM(Kk&Q3cpz8J=33jkpw%b6Ojb3V;H|iZR$6b5HUXDq zGkpm!!R%Xr;r{0Qg63ue?+g;R7m4dO?bC`!l+D-~yDK!h;_H*;QBfpP%?Tu#BX*u> z+fI#VBe+VSSi^T}Hp-qgLfG0W|LtM4E+Y=j=zbiuu4WFb5z@xI{L)Mm(L54~-0eJGdTNt?EuH(5A^p8^s z+0bfc_kWBs;0`_uBx!yRkY}&*L(&P2ytp7bIy<$HeiB0R8MSp>-h5s9b@9r1{JVb9 zi>KY`{nZEm!vYH9$gLB73N5uTH0r^X2<|%paj{Nuu{soAd!a!gdU_ncXBcxopMv=tfvhNYgNH4*_!;X@s#NvyfGh|v!4e}c0fKl z`$DEmeZUZ>>PY@@lS*(#uhqFH1A)o2X2v$KSclWfoRJ}>#~|y1dJJjDE~VNql>Yi4 z&#ZBU0OP>`z-HStlL!A=xwC?@RmG=$2te~GGr4U*QT9eM6jgiU-u{{_T3wRjL0J0r z3z`&<-?S_u$^g?wcK^2Q3@4_0v3u%!3{=UDh<#Zokm4fXP3^WKj%a^l&of`yjEe3CTsK%$y6wy~g%rnH3#f0k@X8j_HG@Hc8am^OWA*=F-n!d4+ASQWz zN@lDeCNofm6U5}FPgzYF)U>h)-nTL9t+h;=Vbg9dgLJ2XUSdW7dBwf~IT#O~XW(@#8@;Y&st6 z7lxwFkqHOShZPtOL9Q3#fPFS5Q%WqB_)mXaI1FZk92S6zoc)S*tGpnW4L}|AW&c7r z(N$WixWV!6Jb~J8HDnP&Tk3?rilTuPb`X_$Eoo}!uTZeyZ2%8UG?y_;AbzvPZ?d+ zug9@zRYGCFU&8pbG9ULt<0`{ZU4Ddfi(EZg4*G_pp6}&wy-SA$3yIWYm}4z=kdlqu zjP(E+zs^hv#=NDyDNlcotu1^x?qR-w7!+{KzaX8eB2W9ONqF{&b|1rhHit_XFW0X= z9HXa(gn99*5btJ57 zrsQFb)yQ*)>YO}M+;H5bCw02KedPevE#6(-D2eFuJW&4@sT(>k?HI*g-Piv#z>h0r3vRdG zSUW&Z_aGT;wzUUs<2&yW)% zcm)l35@O>M>&Hz<2La07@EliucjCq^c*n)vYg@X1<0Jp5ROG8=aWA}Fv8hI9X_o_=V36$! z#X@-?G3hexUj+pni|3~_9%!>;isiBfO)4Ce<$%5+&P@1`m+q!gw;3wqE;@KO+5Zgw{p&+yd;Q-ZqCeZ!PALC)i2euo zm;Eo`U*n&)h)MtW3y%!{1^)e?NKD**6;V?$Q#?x!Y7dpoZdU2XK9J{K^_>vQ!1%dW zbCbK~`-q$ByR)4GfaW~Sdm;#-WT^Jh+CJ^8ai5s9k!&cWv1nA?5)p*AS}NLI2seIG zO+>&b=gI?>`_p4gx?`f&RLcgmHbIPL$|2Io$^D=xzMI26R@B>OIlYgC`fz2^*h=>j zA1_Mal!V&=u0{>w1`FNjRs{eQI$3CrJY)3ft?j(62&=p)6+Y_7y`W%t?1 z+*!yg?kiFhoytu^qCtJ?qR!A>aNW_m&vVg~`k8Xiwf<{e)$YO<=2u0J)B1fnAjcCd zr>57g3hn*ZRG*2c);enr=N&1ZvkKAGCC;4P1$puMLOi$pJfFvwQFteF4(GHKj~~zd zCb@FzRPg^-M*8!y$DiYG@fZJBBV`!=rRCK1Pa_fABOrVgI(nS%3xBGvlQ5Sq;V)mrErWTd|$)DB;t zxzV0qNU9SQXL=kYz)-np;d&p2z8F3k`_r9zUn-}JJ6+u+c`2|TpG#h|+o>yz|IL5( zXUcuX?lL5v?Q@sR69>i)7#VI3v$%dF*XPl-`}`9}{gaECv`2Y1JZBeTJe8xy({Glo z@0mDwUwmE_k+i2u&335(7(S-kOgyqH=JZ#lx11<+Yd-BHU-4Q-XKsSC^f;_XlD`7V z?Di{!-HW6+taRVlqC$2Wo?b)%1iuUR8yzGckW#r@k1ckOP#2pz<2FM*=FH|=g#41= zY`(cyH)-weBB8goDS4TEMr#4@T(%|W!=%1r4+*5mjx=E&53FWizVvhZ;wnl5o7Md# ziTUgIirtaScq%iHPJYYnivn<)=1=f7~2=*xoi$f$D{CiZ4 z&LWCCll=+t_(zI#TYHP3qN)U39{Q>v6KxEvGF;tT-%C6&6d!GK-K()7+|%1|I53(7N*wToabF!Pe)R8}L= zZ*Mz_%+9@$%rT$EqjYE^88dS;v;3+cC}X+}Ei>Lse9&`@RFciiUB_5B2}LET7#i3@ zNYvdeG2SaHOf(#2E4lycbLhymh)mwD+c`@rKHhDV4@x(T*STkEshZ2B|Bq;?K^RvR z1?+DB#5mV?+XgnTH-3Oo39>yR7>5mwlyUQA!3*&L&8KuH^9tocV z#qfaGuoa3HOMC^2!xLzj0#4lLz8zYAWG(EDnB3$9Pfbc1SBz_7>is1 zalS%Jt${6C0nh!uozLUjaOaC^iZ&4MR8}TIF+GPWgQ%EB&w+z!xdS1S8v6kmPZ3xZ zL1X44Emak*LXNLz`)g`q=`+dt7`C=x!CVzssz8fC0|uHp4l0SPgGoT?5b~F5WRgHp zeA|km_?^$_SD}HRAUTShcHEJNChLBLm{g@J4kn^^Ws5p&oAtCI>yg@hqo?RlB@Kg` zxs~=mN5z>H16HI37fqHCM1nXUpiW3n1w^cS$}(oT^i?(~O^<#cBmQWRBFg(RDs?W! zDU?g%kuy=)sH9VjI*-FRN*(#*tSi-4!@%(e{C?NU1Tt=m^#_eLLA4L~bKL?WNv4Ok zWT*x0*Y#Ku*u4;zcl~+(o4TC5Q6Q6`X6MGs=1uCd!}ZqE{+w@27}g4&g%YoE5Dq-a zbTPsZFLj_~^$r2xOwvefHA7(cv?H&2sZIxiwslAeBvTKg0K8F2QHs@{uMhX+>K znSXEYK6Q?VDC&<6(=|aAjmI3w?SknM3r$Xiv;}vD(E#RoRM8OhbDL}<1X;GOCIDEm zkSA1yZUT4nDbJQ1d1J`66Nc1Cos3jlRhWuN0Z^O&_%;XSTJAf z57$i5y=Nd{vm8+!B}SCkF2AaURToD$!0m&Ko79lXHPpmw zg_Yjq7kxH%bq^x^Z*nK19`rEN-3Kh3>3wn9eC{(<8z0}3*9%wjbh9gTH3p&8;5UA^ zuxFOD{oe9`-t!>KMyA)R;a4u+546zbst9V7_G{p@@g}27mFkQ82D5dS7PRK8gz@N* zJH@(?GL+QNg&@iKiTN09S46xjd*>xb* z9OoeQ0y5z;!U+r4@Yku-P+eC16{=rx$l`snIfg|6C0(oejBm^lv`}YJeRemsLp2Qf zz9H87?^a3MkLIE)eh7bKR@9#m1B6+g$9tFGgisb;^14#I{D2$sO6WHSno@kg$`ctjGs5&Uzm{lCu^ z2rB+LPx!0!$A^RO9|t)gKMwzGN|yohdXn)kbM3!*J^8u!S3A(>s1yG+rIY!Zb{tuR zXzJ!l5Au3)eQD|aymwM2K+(5nn$@M2Zla>SH45?ccLy8Ye{*``VQt(#MkjuHA8FCJ zUjrH5cjjt8+zmT&@;)W?UbpbYrj=IX?9n+g4X1C%#*IDg(C2Z(!iLUHY`D9T?`6h% zkhVYD^SPbzX|tF=jqfN^*@I9kNnS6D(VDuh7RTdh9NC2DE3z<>&jIqu|L0m=~03r z)BiaTK_M~x#s4aU$02}eIa|;5l&=q*o3`T7IvDLcJ*vrg0tj|fRYieg`WoO5shbA% z)^&(m$M;@&W8#po(l2W-E$KV?p&1#F%_GAxtaj0E+8hHT{Cf=T2H#;XZq+6&J=W&v zx?l~{wBzHJ4gdTQQFxGnf$!#9XS^?5vn}H+Y-P2B_rq20Z3_H=8pr7J#$4|X_>dmr zfS^l&OzfEY`B=}oW3q#vWdrlI+`EV4zMa5{eOW~bInV6w12H)Bscr60F$O?D2qmv7 zV;9kjdyLagU4SW$k43C0X-w@%&(fYpM$5!nK3<`tS3|L}mf#Epu$F$cc*U8e(mTwI zXR@eer7GytGGki!PRsA4D1^~J@%lnaIKpoCK;6@1y< zpm-~-RI5RwAVgXmRdSL|ip2(bIQt}yh2d()^0u%Ie!RRZFf!6k2d2o1)J z_dKp;rr@NT0#ooUW2b=3+9^_;d9HOV+#0*oIot$_$fya*=0+O(*Szt{Oy)h#U;CGT zON*#PVete}sv~`zmqt}V|AdNTey!)Fw2a8InyQ!^l-K-pZ zHr%ePEY+8OE_OEQfikeVp^U#rlsY}?$8wC5B_yx2AWD_r43tkw7G#2g$BT?&f zW)^9=DL#b`tD)r_Us#TI1N`+-vbMPOQ)v_>XP3Lvyn)Xmzg&}Y#lo<4Iv`04{D-h0 zP^3Mme-G6FAxfpesclu2J0FB+$bTPh^`gH(Pl(k(ii(-PqoJ2HxPo`tGHhx7s`Eg# zjracTLuU-uTZkM9w_ti)YQKC}p1L5tbDuX&17fSh_wos;A!3v|eSLWR=h0Ylm+~YXTDCjzR zs2Bj2xW2 zNC(->Kkcj&m=rFnKTE`o{AdDqGg|bo1^(n=6FD{iEs%>%b_~wKDtyhVG`9@^M zHO8@;-`hv^q(zhEX}-6WUN7MX2iD4$T~sh6=C)B188C($aJ_NHZGj=VoWL6Lgvdxc zP*(iT;>{3Ht0A|g$Bv{!Brn>ZVHZx=&dk8bHYuKjvT*S%8}Wu%@T_b)*~O^S22 z5Fo{1#0s|knhe* zJg21M2sX>~xeX1gg*wxU$8#o@6>YsdRe548TbtF`HPg%JC~Mz2vz*}+Vsb=LV@0LQ zn}4mfupVz@Zg%l1WrpX9-Y;WIw6hSsO1H{C?)&YW8@#{qVhp(6SxB)TJGDkBogtia zmEcC&e*~_tB=Z>cjv|Ot$X!EgrJ{6Ag@=wSN@v1L-fqO2sZM#q@7J$~(mb~LUpJQ? z_mt#3oue^V43@8QxX6#UY859UdJ^m-X*c_QE!?Y>-qBCz)BM$Qrm%%^19)NQFwfZ- zAS-PlT`d@%gV2_2Z$j6+TT}m>ECrzN=kV!G5G6vvYc2!m_+1a7t;&6XYV?k{E}`>? zU{f!}XLqr7&{4-NogwYwIB_cfGA~;akjpW+n#8XpKI@n1`wkmg|gL z7W(fS=ZXdexs_LTpL_dyAui(Qsi6Mz6x0i_vGw<7CSCMj-RuOK#+D`@wr;MG3RZ<$ zwbDl$gH^O-W6m~>j&rOh6aeZUt9Y*7(o#q{2wukx;Hjne_?($xlbDkpPH7$qJow;z z)Ehl(8M6S}o?Ex|U|Q#@oGyM8cD%I`embXqjVuR;Q_w%%53i+uLC*|S7a%BW1>lJt zj&HtPTd-mH=rpkVd=};gTnC~xkHp>zp;>q@`+V8gaWB3ed^t{Yae$38sXTmuXjY_l z7)(@xk~RHiQCyNric@m&)3Pi+4#(Wc%4@ZP+o*enO7ZC4GTxQVDLH;nOsR0QzctLZ zOR2@#gP&j72_>*LD878r)x0o(l71OE)ScKh;jNCYv?5DEnS$b+NqWIE4J&JZ5Lao@ zAm0*DB%-2_43Qo*!|wYn;mBBB)Wa7#>5;P+8KZ4y7x>Z@NK8wM@+P zWn3X)I^5Cog=%zI4GvwV{U~**q)Cfhm5L-C!N3)pCcXNRRGD3HHg2+b=4ZN|lcI%P zD0}MHfNG4)#lq!QsftKM_GxS!B0YtKvaG2eiaHcH=Fu40+b+P=3CeVf{0It-sg!h; zfT9*N;qPqy4K8yRrr|zB7zX5>wJZShU;jSAk_Q zEODdlDzaE{X>1Q=VbQMiOSrK$N2M1)GIB*4)^T1XrjrU!x_S z_{-U4kPOrr1Wo?S2J*azmwwL$GXTh zCC*^YX8jf=W;VjX&o`}N$1euZ7Ym1sie@6<7(v?iwCmu3a~u?NsJ4|KCWZN!>CGmZ zw)gS=TSPvw^uUuTn)UzF*;fYD)oj~t*tom91b26L2?TeS5FmIq64RhQnk+oB9p^*->iMH=)&q>h2hNDcs^fKw? z5xGwL8LvvI1Z4w-L|mIky;^w-P<1HH$dN?Qg23&FHeoRDCuOM_qJERii%$&+_P6jb z5lhn(MAGWl*9UojSfuEc>a(N7+*+<~mtv^epO#3x8-*s^ zd*t6l{el640<`wvV{=CBK2kE?Fn3xHMGUS!RjkGt)+6A$Y8k0sYPvY$C-=U#zDX3f z%#8Dzu)Mk^Bx32FV0%Yx4eJ=EVTClcFn87i@E_q%38l@k6jxTR2)D|=uzUHnMF>9sLP%Hkctzotv>8gJO{jx4SAbd=MIKM;ZhMS`Wnacdqw~R*-Ms(p%L$wL= z8U!?y&u)lP=hphG1?lbAUMFja)jlUGbpDLUN z>%bP~(LKZDA+X=mcA+V?n?f0VuXgI>rO3%|QO@2^7e!LWmcE6p9}KZ*RUI;yA9k+I zOcCcGBbWy-E*;sb)imoPs^K_(uAsBSbc*3^k1F+DorTnCp4H%dq`As74hU{{T%_2f zEHp5p0Dt(>ehta-u{^{~oY3A7wPqw|^PkPb8!mcRlY*tVDa&Q2t!zm&h_@gh-P>%X zf>v#YhDspV2ROkt^Yf*w4x@62=U2pxE=b|j)aK3_EqeCvDRmOd&T?o2<)k{+otvSy z_(>4&w75k+>nbC;#wz zKRNv5{}yQel{Wr;{>{kaeBWO103rZvO&Q&PT2lTk+U#?vT^+#q7l#jc6I%htZcST~WVD>=qc>lKMY7OiYBWi{M~zVcKfbypq#r~U6?pal za|^O_=S7z31VlniGwuZsxnF$u{Kq&+ypn%D*m|hM9@Gm@WTXuRXC8RE(v5zwTJ}j% zQ~-6!QOCOt|NPNc=_w0mwvpCF${p#L%+POCSKd*oup0Kx+1Z(=`~h2^ZbO-&?n6O+ z5Ylh(x&!~uO{UmDf<-*uGmQ5`%r8RdhN8mWa=>UIbAdaOm=Vjvx|UuYGzRaie6@X~ z5po1U6r@M*2D=^56Ng4px>mAZudPHrDWAUlr^L74Rd4L*Lh&1cH>@(&HWIR6Ywx#e zTJb7ObEst5Zd;fy`GWZAUMibn@7lk}?C84RvgrP8S5Z;nKFCN&tH`|30RQiZ5P$z? zGymi9mjd{<`t|`2pav-XpNPEW*v4#cs>)wA_*$-p88sAF3R*tS-FNdjkbCbT#R+6%kfG*P>Pc)go z_-|OLEb-Pi7`4*Z7u?9&0_;~_hDK^L_|7m&euHa z-W%KW+tf{WP$vgYZiFc}u|_JbefA0-C;h(#mb}@Dx+i2=WTNAiX-WMI7yyzgp(h{! z#kB6tli7u-Uqh9^QAFB)NCWuVHD^raVR#!`Sa14fE07{gx-!;JZ3fle7 zj@D3;dSqL)$J5JQ%*CoM_&`v|x2EvU(3bHY`L=QfJo$VSczF=NJaU!GzQ%^FarS6F zCMghKIN5Ytx+9qWYl+L^9dp9Ql8}d+xA#{hZkG)fszwdw?{}AP{j_5|(O9$0l0G&J zy2H7N%kDQwz1u_P+}`vYm)PSYZ*CxTaWed~n@8QIp!`*J{6VvKhroa;UBj5dUVKqS zV-1RWX*hSNk=?0kA#P2vuwE_j-WMvf74By{M|F2Fr=j z&UR@x0TBJx0jj^J@FR{wkW5ePp!u=uC{feGaY)lw%?OB*p}+_vPdML=sdD_n#E}z| z&M3LmUYPz-jtl3ulFM%gC^nWPZOGBX!oj+O!| z?SENq^x!r5gfiAhp5(CZ(Yz;xqlR~B`d}_Qrl8~B$ZN9UXRY}Sn{n|njNg+bHJnHA znv!~(z1Y|`%w9)Im!S)yXYVT);H&ALBvu*M39a8QiB`f`Q_UnObN(w}C$;A+_++6Cm9 z#t7Vyvg-r`mzTxse6=6fD8wI-BQ>e;$i9>fmMfmA8t4h>NdJOL@*}yHS0FnE2z-LG zf!CN=a~JC!v6}2Qf`r2$rOTg2rsxYg#rH+KUg9y_e*bDly)B9o1! zie4RxLePu!iS>1H@hGL2gI7?7gAER0ZBabrsF&32+y+f!6stzuC@|$GT#X|&bIR2M zh~Mk{Iy}xZ%HsUBYSfi)eG3&GBbCo{pvIo8C>_Ea*kF}0FPVHej)P0S0K)$F0|!k+C5JSr-Jo124! znG>tU|AMYC|J>U64{-hGtgH6=i>|M4yX>;7g^_#m0Lr}_BU@6r0bY51JqmLG0c4zu)kg6idB+n*Xpi^+5ao0A9$Y5pjE zKLf){Du_r`dN;gxNf_rll$!httdGJ-6d8h*v8tV|t6{$PMeeOz5&H1>B6+7*9r&KE zvl#>n!Z-KWc{(_rt}{#vs~*?B_}xyPTk!8mZ#T()zB6j{oQy0x_R;kx`jVtjdbJ+j zCB-X_uI;^ZA*7n+d@>O4P5$O;@ae>>b73p`M9^{d6CHkgZSU6OXB;n1$NiQ=z7fHO zqj@{EwaQU@$O)Nxn|2P#{i8afDty7p3HE(Brg0U%&^T1@^s=Rq6|n`Tf8twC33`Vb`Cs9gfDES*Af#WuO~I z!U3LanWM=Qg2dg5Gp1FP@(?iVO1nRD-oO@zEfsGw=Amp{;Mr#EM zYo4p-YkiXrZ))`xvcZUTJ9RUO-Uw8jl@%QsXcNZNeH!k}`&Fd(6*-5~9&wv?-F<;u};Qs3YI#C~@;HHv7qq!WK+R9k5 z;E8wbGRzB^pe?b7%uI?oSHi`e3;iHF(ksm`>1YloRvCi3lugYD?qpJ)0g5A#5js;L z9x0nD)hV~inFy*NLHdw_C3o0o8x4)SY^Fe6-hqi5uTQ5XjV@2yAQ>OuaAHI(Hu+8n zT|(TDV@Y^zLI%@fIWiDQ; zm_ozPu%=bMzSap3cVS;Sl^1ii#&JS4_F_IUkw?70;2rBb2$E_G7B>!yiRv`2AyP6- zPXw8PVQJMD6^yvg0-ny^lrF%N_L|@6^XKmg1@fgM&$(;G98)VPu_$ zSXmy-iI~Weij{by+PSB^InkvRQNiD~pTCXI0Gb!ovE@mOQ_^FW9ji`BPovsAeo>qc zt3>{pDh?#6rcH28l?5wyrnz(*ft8@0HlC9|6;pAO=(ulxEOX4QNRXIBwx&h_aJ{$D zLOJ}&DZ29_jO{-s;~$Lqo0jraqNILXamX|?3?GDqZN6?l<&33F+t$N>(DKY-)G`c2 znD%n1@dK^?7G5$ap5#B~#~jYsZzL1|B7(&nPodhDJ-He*l-dLvJO+& zMjAnM(2j_n-=m9N$ygC$ah@J_YEYaczqPrV5Wsww;_n(U2&{ll-MODMB>}34(ktFo z6zHzmRlX{DU)Hp)l!dcqNl3xu`3g;v+mbHc>wG38|ANc~hXx4xeCfC+; z;089S)tya*4EJ=e^l?T5i_5AL{CbpPXZw?5JpP1Q6@if#l30bE z{J=plefa!Zv+vSo&kvlH1XC6`QY}Xbm^Nu%e$(HJ&sEt1;sHg|#j+vUU1tzS-JPwBZ&=f3xgCI2yBSZ;Axd~!o@&Gp~ z*z{;gcSI~HDVM%OX#b^q0f&=)xwki7j@Sg^a`lqRnNYtq8iu__-V)_?4!`m81_+C} zO=|xHzx;R?_DGp3uqJWjE}FH4*(Bs99D-EJ0_i>s*!>+9cm*HalHk z9KST~Mh8G^_(ZPQERJ1IK0{nX>l#7}0vor-^I2l?h?r1@m@&7oEi-Bs9g^n8cHyZX znfeIG&}uugpID&n?cdeRt$uY{)UOUN_TkCX_Ne;IbIa?Yf6PW=!m}P|h6aR%)*x$M zxV`0VCU3q)k7>TWT^=?du+9HEy9!gu;WLg!fu_q0=SkQ4ai0{uj_&5X8zVF?*w1^D zz$E>NPd;Q37v3D+y}hj|{Iyw2?o+Sq5si+)x`>6lx5(DHz~*i4-ay}ZE+Yh;8%<8Z z6<>{%6W5gByDOWr#eNj&!GkJ{PsqCz5G#YPh?uauPx2UJBY4~2KIm0IlMA{5BT5d* zl*C&xFs!d(VQ-wpHaN^yO30wM4;17|ccI(WQ%BVrg%%&^%C90~C?WMdg+c}q&j?K? z26Eda9yo+NCr#-kPhn!=gV%P%kIURYVDnazN_{j*Xih5Bo$<$Eh_3}PH2htNJ7!C*AJPi{^ z3;ZKUs(FT87L&a8)NKntUSQYT8Y;k1As1j5i2d6FXNQj?wT#J>Q#`Dttfw z-YdJiu`2H+A8INOCJrOX+l$|j>Q&lsS+<5&P9c)*^ceaqNieMvpy_HC< zQs?L8s(3vdmm>gU6_hcv^?LSXxzg~uNyONoQ36{K4z=Nmu06+?ADqfOj6GG*S6J21 znG`4N4yXbWFJ`25j=mTq!H6BaMUFlwSfKu$Si*Yn!#1(<9tsA1>QwO=Q?Ka?dU*}o z6EOJp2bL3Ia-_tIQdu|Ic9v(4T@B{r$eifHyke8Z6t~6#lEg)0i?)HKSx_`D->AOq zxuYddKcBrQ)%*3{Uc)o^F5D8iKUttYF?w)M{_{A|ehL0fvrOrvbxC~-_-m5W0wUS7xi zI4OlS3vqGpgmES*o=FsPM&UBWv)9??rJi-7<_t>o%m^IgE)VTktSPCHuVuw|B_*$J zPZ2^@@`y*hJtpoV$z>=RS>Y9N2Glgf3yb;~`7a&1k-=^$Yo~%~74=21G=zjPC>LS} zPB%ETXx(4(7V0JDDQk~6b1tsC;y0M#iEE<_E8hzFKR(3OOSEVi4sg{DUQtL&Obg(M zPDS_mU*slyt%TqS`12!RmW!uJQGOW@gzx#yBQ;6yxu7rpy-_9R07Ry5inlzpm+rE! zWhrBvqQggyX{e&3=&8~?p~rN0upDM!{nG$zq;Mm8 zO+rF~Wob`A4MJLg0^>&RNfpMYZhAL72FD6O!!X8<6dR-O*eD`6A=0@K$BOhliV6;b ztuJ+vv&oEOtxaZ7(1w;b+h*sJF#WLFJvvn4R5(MQoN`^sm8V&_$wiL~C*<~7dofbmWNPn>9@~BFK2d~S09V#rZu2_aZ>n<1}a7`$$aLDvlol;#xnB_w_mE&%i zSHUA4ed6w1`vR3dKPV!~iQ32`X)sm9oAy&P35VU&dxDgqi5t7Fg+u8KQ<^&6}FL~ zWjcGOQnn#`K0-B)1Gct&RBimuDBhiLXoiGFr0B3HF$ubcAO&(vM{v?zq9+^iqb#=*61yj)X3QBa)Nx`6RsY|Bs9&}d3W70l%0QI(0dJp)r0|Ef$AbNeCDtgS3 zQL2Y&2xTLISn+0qnx`*)yEnsA3coWBTOtl;s08`bE}y1qXmhB$1}>M_EOT3bh;G4a z`yVX4_}!8f-zQ3U0>kud@e(pEift=zi@ZJCVM%MK=P&(zx=)jLBD^}`N+CiQskfXG z5Xg0erpS*>gc_}*FDs1MntTf{2wFeqc@f9EcrH7+?Dn(lCI?9P1tsF&$__O~T*T#i zZlGtQHpQ7(Opoow)V}g|+*MFcfGD(-?(<5(EjcA>uv+sNTCgbobpo3 z@$<#bMsu7o85%{S|C8G_*)QLuH@XT>8?Q#GM5aSY)HEsz`NU)J38_wIPbRQu3Q_Z6 zW|agKp38^Sgr+jYg3OJ>8}^)4WVByUMjM;+$#K6+=4rCTnNXQik;)~7t&Xzo+-wi< zvFp!#@$csYN=u2Pg(T{ zuy97qqdd+VNTlye*n*Y#fi5v$ESg+`5}v{GgO)$SeMW(Y!G!6B$+AkL;R9i8weC@2 zK(09jhmXXM24oZkv#VU=-~{Y#&Z^6apybNPEL+#=0s}XQ*blS3y;UX#J|O(D8?nZe zJJzS=xVdj|62GpjqOMG`1@{WP2ld>Klf5wdK{gp&=H}z)Y?)(= zlBQxHO2X(&r)n%UM$ElNM~FV2EIenI?LIetWtGqNEHp~b zmG(ALM+p+O@QkuNteVpkG^0I$@tRo?_IJwj7M|TL#x+Se>v0*DqdfOshwKnX7W?}N zltOFG1YX!WsVLx8q=)!r!;)E^)av+gYM6WRACU{b1uetJfl0k?8+@=NUPKp{Vamd@ z2th!;nCAry;yE#0dwVzjN;|wz<*)hQ&WU$MMW7|(8pbu_jKwo#SG;36h6goaFN`8E zCp9+vfX)NLJW6Y1jP33Q#M@@^uw#ge=*r+-Lt>?Pb5I2+qGMBCyy&_osG2iW4qj8> z>@|_dh=UrBGW8(}c5^jjB6lJEvnv^BZm(-J@*==>K%Za$jx5b3vFW1%g{<5MNk2ek zs|=A{9I>1-n5$f0jc@Te^v6B>F3K}82FIWea2stL$t~>Gw^*dX5^y9#y6tXlrCI=8h#ok93Ki>HApQBM^1acO zzYLTf#n*0WJZ=hNNw*D(ET1TLK6%O57`1RFKtfWsrUXHca3BW5kobZwmXb8Ji9{AH z6zdOM!+x2jNi5cj#4HI^_;)H3zNM-CWln1}Zm&CCrBI~|j$)`2jIrb&;cBeaP*77D zSarm9HXe2x-Lm&aN&-IqM$Y(nP`p$_3E?Jl3|>n!o2DRKa)?$76sg>$8DWs4$m12G zCE-d^i+)M*o6_gBlNbVdktmEGS!}A5lX0+<5xtZZevhEP4%R6xy>tsi*8&Q`v~B<$ z-ifW}KnvHA4@n)A-KIZDr_{3zIP}2opK2iX6&Qcu^zUhw_ms)?l^BJlcU`Hlf}*^J zGS(J3Q{__29wtN)3Lmii{{0xXqZ=)z1ZWB8G~ge|RDe~8st6%6J;tz*ix zNQ^g@5%`@&^FwOD&TZi9O9+myaeyH}?_h&lz~?2s@$9od{eD0ZrQYg~aZlCp`{i5{ zLHvg1-q1v!xx)2$tqE5DR^X6R`nfgSowVo2eOJU3`X>yKLu`}N_Gb>zs-UCT*9T3j zXl0ub*VB#c^RkpfoHD`lW8#NG<4&i<8dnR%++tXWHZ6|jVKD|YJ(HqS?ov{KSs!o& zP;S_rh)d)jk~0E%*z$2V5Vi!9jY0~D^zlsQuMzCBKtE7A>Ji9GHc**B@+w5dnYwY_ zAA+QiM0PXKFa!3zYEGoyJcNn)jVLF`tt{o%Q)sWE@2p-Np`&+NeK@C0TD))02ppI? zwe)W=99VnTN{Y$+EPXN=1cmSYkOdc9ca?q;$Yc+#{$O7@=x=76bi+BO@1g&Bev;%U zFX6?)i!jlq8hi1P4>*F^#M%Z!Z49BByfXU5QT!dv_1&PH4l~s&WoU40pnMu`fX27? zD-RwDmKY>8uP@L-yX_)at1e%^d5>|j_($Y&FBge2AE7HnI-#z;g@lB3?=C+04Az7>&-caAb@NjkrVrV z&@$|(=l;V6ECx*^d>QoQ5yHSVA?ZCjlF&~UqvJcwK8?|qlIZpkx$fVHANx{gz)vb=79gd8L z(AsV)BR0g&DKwCgmfFg1L|P&L-n*4@0w?=!{zfwxvV<+KB!lkib&+4jiw1QcY&>NV z*amZpKL9n8YKh;Xufpn?c9>ib^x7k8oewz6i;!#6AGg^Z*VZ`cJEt}AGom=Gc+3xF zTVacC?^Xk78TQ)`2zP8eE>tX%I3?iFv;_)*?L}lRAdzlx+eeT|SBa=wPxwR{kWMUF z+jP<_M0|Z(ls;_(0kw-pBGz?te@;~28f^KqUmQ5A=1VTj2%<;-@ECQ+^?^VhCof8? z5H3DkiS64SWqKKNcp4aL`!|(9kgh%lyf|v$mU{rsgpLTgD#nHpW@8Zn=)82G{R!d5 za82X02BS6D1fdLqwc8^=8R$+bJ!=Qij0Hoh8`q)@WK(#_t>gOYB>7jx96(bA5@0!& zN?so|q1+IeJA~Mv)Lt)d263>m;2JMq=zYb5spvgN3-gAKlCpZq#5luGqE--)CGKG%w7K#yiW zp<17>%A1mCeCJr#hhxVhl+vb-d)DSs=a1{HeDH~EE=nT>IL$G4Q=K?y5CgXL@n}dc zzCVpP36v~qgPXb2Wx{8yvwZ_}A3(@8WtcG`6PNIA&$dBTQTQ-b+`}vlqIdg92A>V8 zoW~kt{T%Pbq4@3jxnTT$U-YM(Jx}BM90F?@F?Msr+tWSO2Gi5%2uJ0A~bFQUCw| literal 0 HcmV?d00001 diff --git a/contrib/ttf2bdf/.cvsignore b/contrib/ttf2bdf/.cvsignore new file mode 100644 index 0000000..f910b83 --- /dev/null +++ b/contrib/ttf2bdf/.cvsignore @@ -0,0 +1,5 @@ +ttf2bdf +config.status +config.cache +config.log +Makefile diff --git a/contrib/ttf2bdf/Makefile.in b/contrib/ttf2bdf/Makefile.in new file mode 100644 index 0000000..e5d5a39 --- /dev/null +++ b/contrib/ttf2bdf/Makefile.in @@ -0,0 +1,74 @@ +# +# $Id: Makefile.in,v 1.4 1998/12/06 18:50:22 mleisher Exp $ +# + +# +# Copyright 1996, 1997, 1998 Computing Research Labs, New Mexico State +# University +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +# OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +# THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +RM = @RM@ +MKINSTALLDIRS = ../../mkinstalldirs + +CC = @CC@ +CFLAGS = @XX_CFLAGS@ @CFLAGS@ + +SRCS = remap.c ttf2bdf.c +OBJS = remap.o ttf2bdf.o + +# +# Point these at the FreeType source directories. +# +INCS = @CPPFLAGS@ +LIBS = @LIBS@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ + +all: ttf2bdf + +ttf2bdf: $(OBJS) + $(PURIFY) $(CC) $(STATIC) $(CFLAGS) -o ttf2bdf $(OBJS) $(LIBS) + +clean: + $(RM) -f *.o *BAK *CKP *~ a.out core + +realclean: clean + $(RM) -f ttf2bdf + +distclean: clean + $(RM) -f ttf2bdf config.* Makefile + +.c.o: + $(CC) $(CFLAGS) $(INCS) -c $< -o $@ + +install: ttf2bdf + @$(MKINSTALLDIRS) $(bindir) $(mandir)/man1 + @cp ttf2bdf $(bindir)/ttf2bdf + @cp ttf2bdf.man $(mandir)/man1/ttf2bdf.1 + +uninstall: + @$(RM) -f $(bindir)/ttf2bdf + @$(RM) -f $(mandir)/man1/ttf2bdf.1 + +# end of Makefile diff --git a/contrib/ttf2bdf/README b/contrib/ttf2bdf/README new file mode 100644 index 0000000..f5ac32e --- /dev/null +++ b/contrib/ttf2bdf/README @@ -0,0 +1,315 @@ +# +# $Id: README,v 1.18 1999/08/19 16:30:24 mleisher Exp $ +# + +# +# Copyright 1996, 1997, 1998, 1999 Computing Research Labs, +# New Mexico State University +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +# OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +# THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +This is version 2.7 of a program to convert TrueType fonts to BDF fonts using +the FreeType renderer. + +BDF fonts can be edited using the XmBDFEditor which is available from (replace +the with the most current version number): + + [Sources] + ftp://crl.nmsu.edu/CLR/multiling/General/xmbdfed.tar.gz + + [Binaries: Linux/Pentium, Solaris, SunOS] + ftp://crl.nmsu.edu/CLR/multiling/General/xmbdfed--ELF.tar.gz + ftp://crl.nmsu.edu/CLR/multiling/General/xmbdfed--SOLARIS.tar.gz + +COMPILING ttf2bdf +----------------- + +1. Pick up the latest FreeType distribution from: + +ftp://ftp.physiol.med.tu-muenchen.de/pub/freetype/devel/freetype-current.tar.gz + +2. Unpack FreeType and build it. + +3. Go into the "contrib/ttf2bdf/" directory and type "make" to build "ttf2bdf". + +RUNNING ttf2bdf +--------------- + +Type the following to get a list of command line options: + + % ttf2bdf -h + +ACKNOWLEDGEMENTS +---------------- + +Thanks go to the following people: + + Robert Wilhelm for pointing out a + crucial problem with the pre-1.0 code. + + Lho Li-Da for pointing out a problem with Big5 and + GB2312 encoding ids being documented incorrectly in the TT docs and a + problem with glyphs that are height 1 or width 1, and a font name problem. + + Adrian Havill for unintentionally pointing out a + missing feature. + + Richard Verhoeven for pointing out a font names problem, + problem with bitmaps missing their last byte in each row, and an invalid + FONT_DESCENT property value. + + Choi Jun Ho for his inspiration from his + implementation that changed some character set names, and added a + number of new command line parameters. + + Pavel Kankovsky for providing some + critical grid fitting and metrics fixes when generating the bitmaps, + adding the code to "auto-detect" bold and italic fonts, removing the + dependency on ttobjs.h, finding some remapping bugs, and other fixes. + + Matti Koskinen for pointing out a problem with using + the code 0xffff. + + Eugene Bobin for contributing the Cyrillic mapping + tables (iso8859.5, koi8.r, windows.1251) and the sample shell scripts for + generating sets of BDF fonts. + + Oleg N. Yakovlev for alerting me to the + problem of certain codes not being loaded correctly in the mapping tables. + + Bertrand Petit for providing additional command line + parameters to allow more control over the XLFD name generated. + + Roman Czyborra for pointing out the need for a + change from UNICODE-2.0 to ISO10646-1 in the font XLFD name. + + Mike Blazer for pointing out the include changes + needed to compile on Windows. + + Solofo Ramangalahy for contributing the ISO8859.1 and + ISO8859.3 mapping tables. + + Antoine Leca for suggesting the exchange of + columns in the mapping table to better fit the mapping table format used by + many. + + Robert Brady for pointing out a problem with the + length of _XFREE86_GLYPH_RANGES properties and an Exceed font compiler. + +CHANGES +------- +Version 2.7 +=========== + 1. Swapped all the columns in the mapping files. + + 2. Changed the mapping table loader to index on the second column instead of + the first. + + 3. Reduced the line length of _XFREE86_GLYPH_RANGES properties to 256 + instead of 512. + +Version 2.6 +=========== + 1. Changed the includes to deal with compilation on Windows. + + 2. Added some new mapping tables. + +Version 2.5 +=========== + 1. Updated the copyright dates. + + 2. Fixed an incorrect parameter for Traditional C compilers. + + 3. Added generation of the _XFREE86_GLYPH_RANGES properties. + +Version 2.4 +=========== + 1. Change all CRLF's, CR's, or LF's in copyright strings to double spaces. + + 2. Changed it so gcc 2.8.1 likes the return type of main() again. + +Version 2.3 +=========== + 1. Changed Makefile.in a bit to make installation more consistent. + + 2. Changed the lower limit for the vertical and horizontal resolutions to be + 10dpi instead of 50dpi. + +Version 2.2 +=========== + 1. Added missing documentation in the manual page. + + 2. Added the `-u' parameter to allow setting the character used to replace + dashes or spaces in the font name. + + 3. Changed the CHARSET_REGISTRY and CHARSET_ENCODING to be "ISO10646-1" + instead of "Unicode-2.0". + + 4. The numGlyphs property comes back incorrect for some fonts, so the loop + cycles through all 65536 possibilities every time now. + +Version 2.1 +=========== + 1. Added patches provided by Bertrand Petit. + + 2. Insured compatibility with FreeType 1.1. + +Version 2.0 +=========== + 1. Created two new subdirectories. One for mapping tables and one for any + other contributed code, scripts, or data. + + 2. Updated Cyrillic mapping files sent by Eugene Bobin. + + 3. Minor fixes to make compatible with the latest version of FreeType. + +Version 1.9 +=========== + 1. Fixed a problem with the first code of a mapping table being lost. + +Version 1.8 +=========== + 1. Added the Unicode->Cyrillic mapping tables provided by Eugene Bobin. + + 2. Created a shell script based on Eugene Bobin's scripts to generate sets + of BDF fonts at one time. + +Version 1.7 +=========== + 1. If a remapping table is provided, code ranges are now expected to be + specified in terms of the codes in the mapping table. + + 2. The glyph generation loop is improved a bit. + +Version 1.6 +=========== + 1. Added two expected keywords REGISTRY and ENCODING in the remap files. + These values are used when the font's XLFD name is generated. + + 2. Added TTF2BDF_VERSION macro used for adding the "Converted by" comment. + + 3. Handle the case of no glyphs being generated. No BDF font is produced. + + 4. Updated for new API with TT_Engine. + +Version 1.5 +=========== + 1. Fixed a problem with updating the average width field of the XLFD + font name. + + 2. Changed things so bitmaps are generated to a temporay file so an + accurate count and metrics can be calculated. + + 3. Changed things so the font header is not generated until the bitmaps + have been generated. This allows accurate calculations of the various + fields needed. + + 4. Added the '-l' command line parameter that allows specification of a + subrange of glyphs to generate. The syntax is the same as that used in + X11 for subranges. See the X11 XLFD documentation, page 9 for more + detail. + + Example: + + % ttf2bdf -l '60 70 80_90' font.ttf -o font.bdf + + The command above will only generate the glyphs for codes 60, 70, + and 80 through 90 inclusive. + + 5. Added the ability to load a mapping table that will remap a font to + another character set. The mapping table should have two columns. + + The first column should be the hexadecimal code of the glyph in the + "cmap" table ttf2bdf is using. The second column should have the + code which should be used in the BDF font. An example mapping file + is provided which will map fonts from Unicode (default cmap table) to + ISO8859-2. + + 6. Fixed grid fitting to avoid dropout in some cases. + + 7. Removed dependency on ttobjs.h by using the new API function for + retrieving strings. + + 8. Removed warning about getpid() on Solaris. + + 9. Rearranged the man page a bit to be more useful. Minor + improvements also done. + + 10. Changed the loop so it does not include 0xffff as a code because + it causes crashes when converting some fonts. + +Version 1.4 [Never released as binaries] +=========== + 1. Changed the names of two MS encodings (Wansung and Johab) to + KSC5601.1987 and KSC5601.1992. + + 2. Added the '-n' command line flag to turn hinting off. + + 3. Added the '-c' command line flag to set the font spacing. + + 4. Added the '-t', '-w', and '-s' command line options to override the + default typeface, weight and slant names. + +Version 1.3 +=========== + 1. Converted to use the new FreeType API. + + 2. Added the '-rh' and '-rv' command line parameters to allow both the + horizontal and vertical resolutions to be set individually. + + 3. Fixed a problem with ignoring undefined glyphs. All undefined were + being rendered which caused missing glyphs on the end. + + 4. Fixed a problem with offset calculations needed to render glyph + bitmaps. + +Version 1.2 +=========== + 1. Fixed a problem with dashes that appear in the font family name causing + parse problems with the XLFD font names. + + 2. Fixed a problem with certain bitmaps missing their final byte on each + row. + + 3. Fixed an incorrect FONT_DESCENT value. + + 4. Changed things around so names can be retrieved in a more general way. + + 5. Fixed a problem with bitmaps not being generated after a certain point. + +Version 1.1 +=========== + 1. Fixed the actual glyph count for the CHARS line. + + 2. Swapped the Big5 and GB2312 XLFD encoding strings because of incorrect TT + specifications. + + 3. Fixed a problem with bitmap generation for glyphs that are width 1 or + height 1. + + 4. Added command line parameters to set the font and render pool memory + sizes in Kilobytes from the command line. + +Version 1.0 +=========== + 1. Initial release. + +mleisher@crl.nmsu.edu (Mark Leisher) +15 October 1997 diff --git a/contrib/ttf2bdf/configure b/contrib/ttf2bdf/configure new file mode 100644 index 0000000..197aaa7 --- /dev/null +++ b/contrib/ttf2bdf/configure @@ -0,0 +1,1357 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=../../lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:529: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:559: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:610: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:642: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 653 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:684: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:689: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:717: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="$CPPFLAGS -I../../lib" +echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 +echo "configure:753: checking for TT_Init_FreeType in -lttf" >&5 +ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lttf $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lttf" +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find ttf library! Compile FreeType first." 1>&2; exit 1; } +fi + + + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:814: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:842: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:863: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:880: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:897: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:922: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:935: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1002: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1029: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1039: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 +echo "configure:1067: checking for 8-bit clean memcmp" >&5 +if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_memcmp_clean=no +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_memcmp_clean=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_memcmp_clean=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6 +test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@RM@%$RM%g +s%@CPP@%$CPP%g +s%@LIBOBJS@%$LIBOBJS%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/contrib/ttf2bdf/configure.in b/contrib/ttf2bdf/configure.in new file mode 100644 index 0000000..dfe17a2 --- /dev/null +++ b/contrib/ttf2bdf/configure.in @@ -0,0 +1,40 @@ +dnl $Id: configure.in,v 1.1 1998/01/14 21:45:26 mleisher Exp $ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(../../lib/freetype.h) + +AC_PROG_CC + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="$CPPFLAGS -I../../lib" +AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[ + AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])]) +AC_SUBST(LIBS) + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +AC_CHECK_PROG(RM, rm, rm) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) + +dnl Checks for library functions. +AC_FUNC_MEMCMP + +AC_OUTPUT(Makefile) diff --git a/contrib/ttf2bdf/contrib/KOI2iso_pcf b/contrib/ttf2bdf/contrib/KOI2iso_pcf new file mode 100644 index 0000000..b88caa7 --- /dev/null +++ b/contrib/ttf2bdf/contrib/KOI2iso_pcf @@ -0,0 +1,28 @@ +#!/usr/local/bin/perl +# +# hack a XFLD info - alias all fonts, declared as koi8*, to iso8859-1 +# +# usage: +# cd fontdir; ../ISO2koi < fonts.dir >> fonts.alias +# +# 1996/08/29 - vsv +# +while (<>) { + chop; + ($z, $koi8) = split /[ \t]+/; + $iso = $koi8; + $iso =~ s/-koi8r-1/-iso8859-1/g; + $iso =~ s/-koi8-1/-iso8859-1/g; + $iso =~ s/-koi8-r/-iso8859-1/g; + $iso =~ s/-cronyx-/-adobe-/g; + $iso =~ s/-cronix-/-adobe-/g; + ## $iso =~ s/-cronix-/-hack-/g; + ## $iso =~ s/-cronyx-/-hack-/g; + # Elvis+ fonts... + ## $iso =~ s/-adobe-/-hack-/g; + ## $iso =~ s/-dec-/-hack-/g; + next if ("$iso" !~ /-iso8859-/); + @z = split (/-/, $iso); + # no matter, 10 or 12, must be more then 3-4 ;) + printf ("\"%s\"\t\"%s\"\n", $iso, $koi8) if (@z > 10); +} diff --git a/contrib/ttf2bdf/contrib/creatett b/contrib/ttf2bdf/contrib/creatett new file mode 100644 index 0000000..4dc27c7 --- /dev/null +++ b/contrib/ttf2bdf/contrib/creatett @@ -0,0 +1,60 @@ +#!/bin/csh +# -*- mode:SH; -*- +# +# This script creates series of bdf files from TTF file. +# +# +# Please set up parameters +# +# Font dpi: +set DPI=96 + +# +# TrueType files dir. +set ttf_dir=~/ttf + +# TTF files, please specify only base name +# Script will try to use BolD, Italic and BoldItalic versions of face +set FACES="ARIAL ARIBLK ARIALN TAHOMA TIMES VERDANA" + + +# Output codepage +# koi8.r +# windows.1251 +# iso8859.5 +# iso8859.2 +set LANG_ID=koi8.r + +foreach x ( 7 8 9 10 11 12 14 16 18 20 24 30 50 100 150) +foreach z ( $FACES ) +set y = ${ttf_dir}/${z} +# +# Simple face + if( -e ${y}.TTF ) then + echo ${y} at ${x}pt + ./ttf2bdf -m $LANG_ID -p $x -r $DPI ${y}.TTF | bdftopcf | compress > ${DPI}dpi/${z}${x}.pcf.Z + endif +# +# Bold face + if( -e ${y}BD.TTF ) then + echo Bold ${y} at ${x}pt + ./ttf2bdf -m $LANG_ID -p $x -r $DPI -w bold ${y}BD.TTF | bdftopcf | compress > ${DPI}dpi/${z}bd${x}.pcf.Z + endif +# +# Italic face + if( -e ${y}I.TTF ) then + echo Italic ${y} at ${x}pt + ./ttf2bdf -m $LANG_ID -p $x -r $DPI -s o ${y}I.TTF | bdftopcf | compress >${DPI}dpi/${z}i${x}.pcf.Z + endif +# +# Bold Italic face + if( -e ${y}BI.TTF ) then + echo Bold Italic ${y} at ${x}pt + ./ttf2bdf -m $LANG_ID -p $x -r $DPI -w bold -s o ${y}BI.TTF | bdftopcf | compress > ${DPI}dpi/${z}bi${x}.pcf.Z + endif +end +end + +echo Creating fonts directory... +cd ${DPI}dpi +mkfontdir diff --git a/contrib/ttf2bdf/contrib/creatett.m b/contrib/ttf2bdf/contrib/creatett.m new file mode 100644 index 0000000..da9d6a1 --- /dev/null +++ b/contrib/ttf2bdf/contrib/creatett.m @@ -0,0 +1,59 @@ +#!/bin/csh +# -*- mode:SH; -*- +# +# This script creates series of bdf files from TTF file. +# +# +# Please set up parameters +# +# Font dpi: +set DPI=96 + +# +# TrueType files dir. +set ttf_dir=~/ttf + +# TTF files, please specify only base name +# Script will try to use BolD, Italic and BoldItalic versions of face +set FACES="COUR MONOTYPE" + +# Output codepage +# koi8.r +# windows.1251 +# iso8859.5 +# iso8859.2 +set LANG_ID=koi8.r + +foreach x ( 7 8 9 10 11 12 14 16 18 20 24 30 50 100 150) +foreach z ( $FACES ) +set y = ${ttf_dir}/${z} +# +# Simple face + if( -e ${y}.TTF ) then + echo ${z} at ${x}pt + ./ttf2bdf -c m -m $LANG_ID -p $x -r $DPI ${y}.TTF | bdftopcf | compress > ${DPI}dpi/${z}${x}.pcf.Z + endif +# +# Bold face + if( -e ${y}BD.TTF ) then + echo Bold ${z} at ${x}pt + ./ttf2bdf -c m -m $LANG_ID -p $x -r $DPI -w bold ${y}BD.TTF | bdftopcf | compress > ${DPI}dpi/${z}bd${x}.pcf.Z + endif +# +# Italic face + if( -e ${y}I.TTF ) then + echo Italic ${z} at ${x}pt + ./ttf2bdf -c m -m $LANG_ID -p $x -r $DPI -s o ${y}I.TTF | bdftopcf | compress >${DPI}dpi/${z}i${x}.pcf.Z + endif +# +# Bold Italic face + if( -e ${y}BI.TTF ) then + echo Bold Italic ${z} at ${x}pt + ./ttf2bdf -c m -m $LANG_ID -p $x -r $DPI -w bold -s o ${y}BI.TTF | bdftopcf | compress > ${DPI}dpi/${z}bi${x}.pcf.Z + endif +end +end + +#echo Creating fonts directory... +#cd ${DPI}dpi +#mkfontdir diff --git a/contrib/ttf2bdf/maps/iso8859.1 b/contrib/ttf2bdf/maps/iso8859.1 new file mode 100644 index 0000000..8cc68d4 --- /dev/null +++ b/contrib/ttf2bdf/maps/iso8859.1 @@ -0,0 +1,278 @@ +# +# $Id: iso8859.1,v 1.2 1999/06/16 16:13:11 mleisher Exp $ +# +# SAMPLE TTF2BDF MAPPING TABLE +# +# Mapping table from Unicode to ISO8859-1. Names are from the Unicode +# Character Database on ftp.unicode.org. +# +# Two keywords are used to specify the character set registry and encoding: +# REGISTRY and ENCODING. These will be used when creating the XLFD name +# for the font. +# +# Column 1 is the ISO8859-1 value, and column 2 is the Unicode value. The +# columns can be separated by tabs or whitespace, and only the first two +# columns are used. +# +# Empty lines and lines starting with '#' are ignored. +# +# NOTE: made with material from "The ISO 8859 Alphabet Soup" --solofo +# +REGISTRY ISO8859 +ENCODING 1 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/contrib/ttf2bdf/maps/iso8859.2 b/contrib/ttf2bdf/maps/iso8859.2 new file mode 100644 index 0000000..52af12a --- /dev/null +++ b/contrib/ttf2bdf/maps/iso8859.2 @@ -0,0 +1,276 @@ +# +# $Id: iso8859.2,v 1.2 1999/06/16 16:13:11 mleisher Exp $ +# +# SAMPLE TTF2BDF MAPPING TABLE +# +# Mapping table from Unicode to ISO8859-2. Names are from the Unicode +# Character Database on ftp.unicode.org. +# +# Two keywords are used to specify the character set registry and encoding: +# REGISTRY and ENCODING. These will be used when creating the XLFD name +# for the font. +# +# Column 1 is the ISO8859-2 value, and column 2 is the Unicode value. The +# columns can be separated by tabs or whitespace, and only the first two +# columns are used. +# +# Empty lines and lines starting with '#' are ignored. +# +REGISTRY ISO8859 +ENCODING 2 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x02D8 # BREVE +0xA3 0x0141 # LATIN CAPITAL LETTER L WITH STROKE +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x013D # LATIN CAPITAL LETTER L WITH CARON +0xA6 0x015A # LATIN CAPITAL LETTER S WITH ACUTE +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x0164 # LATIN CAPITAL LETTER T WITH CARON +0xAC 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xB2 0x02DB # OGONEK +0xB3 0x0142 # LATIN SMALL LETTER L WITH STROKE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x013E # LATIN SMALL LETTER L WITH CARON +0xB6 0x015B # LATIN SMALL LETTER S WITH ACUTE +0xB7 0x02C7 # CARON +0xB8 0x00B8 # CEDILLA +0xB9 0x0161 # LATIN SMALL LETTER S WITH CARON +0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x0165 # LATIN SMALL LETTER T WITH CARON +0xBC 0x017A # LATIN SMALL LETTER Z WITH ACUTE +0xBD 0x02DD # DOUBLE ACUTE ACCENT +0xBE 0x017E # LATIN SMALL LETTER Z WITH CARON +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x0154 # LATIN CAPITAL LETTER R WITH ACUTE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 # LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x0139 # LATIN CAPITAL LETTER L WITH ACUTE +0xC6 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x011A # LATIN CAPITAL LETTER E WITH CARON +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x010E # LATIN CAPITAL LETTER D WITH CARON +0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0147 # LATIN CAPITAL LETTER N WITH CARON +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0150 # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x0158 # LATIN CAPITAL LETTER R WITH CARON +0xD9 0x016E # LATIN CAPITAL LETTER U WITH RING ABOVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x0170 # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x0162 # LATIN CAPITAL LETTER T WITH CEDILLA +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x0155 # LATIN SMALL LETTER R WITH ACUTE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 # LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x013A # LATIN SMALL LETTER L WITH ACUTE +0xE6 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x011B # LATIN SMALL LETTER E WITH CARON +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x010F # LATIN SMALL LETTER D WITH CARON +0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0148 # LATIN SMALL LETTER N WITH CARON +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0151 # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x0159 # LATIN SMALL LETTER R WITH CARON +0xF9 0x016F # LATIN SMALL LETTER U WITH RING ABOVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x0171 # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x0163 # LATIN SMALL LETTER T WITH CEDILLA +0xFF 0x02D9 # DOT ABOVE diff --git a/contrib/ttf2bdf/maps/iso8859.3 b/contrib/ttf2bdf/maps/iso8859.3 new file mode 100644 index 0000000..548b3ca --- /dev/null +++ b/contrib/ttf2bdf/maps/iso8859.3 @@ -0,0 +1,271 @@ +# +# $Id: iso8859.3,v 1.2 1999/06/16 16:13:11 mleisher Exp $ +# +# SAMPLE TTF2BDF MAPPING TABLE +# +# Mapping table from Unicode to ISO8859-3. Names are from the Unicode +# Character Database on ftp.unicode.org. +# +# Two keywords are used to specify the character set registry and encoding: +# REGISTRY and ENCODING. These will be used when creating the XLFD name +# for the font. +# +# Column 1 is the ISO8859-3 value, and column 2 is the Unicode value. The +# columns can be separated by tabs or whitespace, and only the first two +# columns are used. +# +# Empty lines and lines starting with '#' are ignored. +# +# NOTE: prepared with material from "The ISO 8859 Alphabet Soup" +# +REGISTRY ISO8859 +ENCODING 3 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0126 # LATIN CAPITAL LETTER H WITH STROKE +0xA2 0x02D8 # BREVE +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA6 0x0124 # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0130 # LATIN CAPITAL LETTER I WITH DOT ABOVE +0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x011E # LATIN CAPITAL LETTER G WITH BREVE +0xAC 0x0134 # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0xAD 0x00AD # SOFT HYPHEN +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0127 # LATIN SMALL LETTER H WITH STROKE +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x0125 # LATIN SMALL LETTER H WITH CIRCUMFLEX +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x0131 # LATIN SMALL LETTER DOTLESS I +0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x011F # LATIN SMALL LETTER G WITH BREVE +0xBC 0x0135 # LATIN SMALL LETTER J WITH CIRCUMFLEX +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x010A # LATIN CAPITAL LETTER C WITH DOT ABOVE +0xC6 0x0108 # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0120 # LATIN CAPITAL LETTER G WITH DOT ABOVE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x011C # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x016C # LATIN CAPITAL LETTER U WITH BREVE +0xDE 0x015C # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x010B # LATIN SMALL LETTER C WITH DOT ABOVE +0xE6 0x0109 # LATIN SMALL LETTER C WITH CIRCUMFLEX +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0121 # LATIN SMALL LETTER G WITH DOT ABOVE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x011D # LATIN SMALL LETTER G WITH CIRCUMFLEX +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x016D # LATIN SMALL LETTER U WITH BREVE +0xFE 0x015D # LATIN SMALL LETTER S WITH CIRCUMFLEX +0xFF 0x02D9 # DOT ABOVE diff --git a/contrib/ttf2bdf/maps/iso8859.5 b/contrib/ttf2bdf/maps/iso8859.5 new file mode 100644 index 0000000..69eac5a --- /dev/null +++ b/contrib/ttf2bdf/maps/iso8859.5 @@ -0,0 +1,265 @@ +#/* +# * Unicode 2.0 -> iso8859-5 +# * +# * 04 Jan 98 | Eugene Bobin, +# * +# * Modified 16 June 99 Mark Leisher +# */ +REGISTRY ISO8859 +ENCODING 5 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0401 # CYRILLIC CAPITAL LETTER IO /* ³ */ +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x0410 # CYRILLIC CAPITAL LETTER A /* á */ +0xB1 0x0411 # CYRILLIC CAPITAL LETTER BE /* â */ +0xB2 0x0412 # CYRILLIC CAPITAL LETTER VE /* ÷ */ +0xB3 0x0413 # CYRILLIC CAPITAL LETTER GHE /* ç */ +0xB4 0x0414 # CYRILLIC CAPITAL LETTER DE /* ä */ +0xB5 0x0415 # CYRILLIC CAPITAL LETTER IE /* å */ +0xB6 0x0416 # CYRILLIC CAPITAL LETTER ZHE /* ö */ +0xB7 0x0417 # CYRILLIC CAPITAL LETTER ZE /* ú */ +0xB8 0x0418 # CYRILLIC CAPITAL LETTER I /* é */ +0xB9 0x0419 # CYRILLIC CAPITAL LETTER SHORT I /* ê */ +0xBA 0x041A # CYRILLIC CAPITAL LETTER KA /* ë */ +0xBB 0x041B # CYRILLIC CAPITAL LETTER EL /* ì */ +0xBC 0x041C # CYRILLIC CAPITAL LETTER EM /* í */ +0xBD 0x041D # CYRILLIC CAPITAL LETTER EN /* î */ +0xBE 0x041E # CYRILLIC CAPITAL LETTER O /* ï */ +0xBF 0x041F # CYRILLIC CAPITAL LETTER PE /* ð */ +0xC0 0x0420 # CYRILLIC CAPITAL LETTER ER /* ò */ +0xC1 0x0421 # CYRILLIC CAPITAL LETTER ES /* ó */ +0xC2 0x0422 # CYRILLIC CAPITAL LETTER TE /* ô */ +0xC3 0x0423 # CYRILLIC CAPITAL LETTER U /* õ */ +0xC4 0x0424 # CYRILLIC CAPITAL LETTER EF /* æ */ +0xC5 0x0425 # CYRILLIC CAPITAL LETTER HA /* è */ +0xC6 0x0426 # CYRILLIC CAPITAL LETTER TSE /* ã */ +0xC7 0x0427 # CYRILLIC CAPITAL LETTER CHE /* þ */ +0xC8 0x0428 # CYRILLIC CAPITAL LETTER SHA /* û */ +0xC9 0x0429 # CYRILLIC CAPITAL LETTER SHCHA /* ý */ +0xCA 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN /* ÿ */ +0xCB 0x042B # CYRILLIC CAPITAL LETTER YERU /* ù */ +0xCC 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN /* ø */ +0xCD 0x042D # CYRILLIC CAPITAL LETTER E /* ü */ +0xCE 0x042E # CYRILLIC CAPITAL LETTER YU /* à */ +0xCF 0x042F # CYRILLIC CAPITAL LETTER YA /* ñ */ +0xD0 0x0430 # CYRILLIC SMALL LETTER A /* Á */ +0xD1 0x0431 # CYRILLIC SMALL LETTER BE /* Â */ +0xD2 0x0432 # CYRILLIC SMALL LETTER VE /* × */ +0xD3 0x0433 # CYRILLIC SMALL LETTER GHE /* Ç */ +0xD4 0x0434 # CYRILLIC SMALL LETTER DE /* Ä */ +0xD5 0x0435 # CYRILLIC SMALL LETTER IE /* Å */ +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE /* Ö */ +0xD7 0x0437 # CYRILLIC SMALL LETTER ZE /* Ú */ +0xD8 0x0438 # CYRILLIC SMALL LETTER I /* É */ +0xD9 0x0439 # CYRILLIC SMALL LETTER SHORT I /* Ê */ +0xDA 0x043A # CYRILLIC SMALL LETTER KA /* Ë */ +0xDB 0x043B # CYRILLIC SMALL LETTER EL /* Ì */ +0xDC 0x043C # CYRILLIC SMALL LETTER EM /* Í */ +0xDD 0x043D # CYRILLIC SMALL LETTER EN /* Î */ +0xDE 0x043E # CYRILLIC SMALL LETTER O /* Ï */ +0xDF 0x043F # CYRILLIC SMALL LETTER PE /* Ð */ +0xE0 0x0440 # CYRILLIC SMALL LETTER ER /* Ò */ +0xE1 0x0441 # CYRILLIC SMALL LETTER ES /* Ó */ +0xE2 0x0442 # CYRILLIC SMALL LETTER TE /* Ô */ +0xE3 0x0443 # CYRILLIC SMALL LETTER U /* Õ */ +0xE4 0x0444 # CYRILLIC SMALL LETTER EF /* Æ */ +0xE5 0x0445 # CYRILLIC SMALL LETTER HA /* È */ +0xE6 0x0446 # CYRILLIC SMALL LETTER TSE /* Ã */ +0xE7 0x0447 # CYRILLIC SMALL LETTER CHE /* Þ */ +0xE8 0x0448 # CYRILLIC SMALL LETTER SHA /* Û */ +0xE9 0x0449 # CYRILLIC SMALL LETTER SHCHA /* Ý */ +0xEA 0x044A # CYRILLIC SMALL LETTER HARD SIGN /* ß */ +0xEB 0x044B # CYRILLIC SMALL LETTER YERU /* Ù */ +0xEC 0x044C # CYRILLIC SMALL LETTER SOFT SIGN /* Ø */ +0xED 0x044D # CYRILLIC SMALL LETTER E /* Ü */ +0xEE 0x044E # CYRILLIC SMALL LETTER YU /* À */ +0xEF 0x044F # CYRILLIC SMALL LETTER YA /* Ñ */ +0xF0 0x00F0 # LATIN SMALL LETTER ETH +0xF1 0x0451 # CYRILLIC SMALL LETTER IO /* £ */ +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/contrib/ttf2bdf/maps/koi8.r b/contrib/ttf2bdf/maps/koi8.r new file mode 100644 index 0000000..aa16705 --- /dev/null +++ b/contrib/ttf2bdf/maps/koi8.r @@ -0,0 +1,232 @@ +#/* +# * Unicode 2.0 -> KOI8-R +# * +# * 11 Jan 97 | Eugene Bobin, +# * +# * Modified 16 June 99 Mark Leisher +# */ +REGISTRY KOI8 +ENCODING R +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x0451 # CYRILLIC SMALL LETTER IO /* £ */ +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO /* ³ */ +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x044E # CYRILLIC SMALL LETTER YU /* À */ +0xC1 0x0430 # CYRILLIC SMALL LETTER A /* Á */ +0xC2 0x0431 # CYRILLIC SMALL LETTER BE /* Â */ +0xC3 0x0446 # CYRILLIC SMALL LETTER TSE /* Ã */ +0xC4 0x0434 # CYRILLIC SMALL LETTER DE /* Ä */ +0xC5 0x0435 # CYRILLIC SMALL LETTER IE /* Å */ +0xC6 0x0444 # CYRILLIC SMALL LETTER EF /* Æ */ +0xC7 0x0433 # CYRILLIC SMALL LETTER GHE /* Ç */ +0xC8 0x0445 # CYRILLIC SMALL LETTER HA /* È */ +0xC9 0x0438 # CYRILLIC SMALL LETTER I /* É */ +0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I /* Ê */ +0xCB 0x043A # CYRILLIC SMALL LETTER KA /* Ë */ +0xCC 0x043B # CYRILLIC SMALL LETTER EL /* Ì */ +0xCD 0x043C # CYRILLIC SMALL LETTER EM /* Í */ +0xCE 0x043D # CYRILLIC SMALL LETTER EN /* Î */ +0xCF 0x043E # CYRILLIC SMALL LETTER O /* Ï */ +0xD0 0x043F # CYRILLIC SMALL LETTER PE /* Ð */ +0xD1 0x044F # CYRILLIC SMALL LETTER YA /* Ñ */ +0xD2 0x0440 # CYRILLIC SMALL LETTER ER /* Ò */ +0xD3 0x0441 # CYRILLIC SMALL LETTER ES /* Ó */ +0xD4 0x0442 # CYRILLIC SMALL LETTER TE /* Ô */ +0xD5 0x0443 # CYRILLIC SMALL LETTER U /* Õ */ +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE /* Ö */ +0xD7 0x0432 # CYRILLIC SMALL LETTER VE /* × */ +0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN /* Ø */ +0xD9 0x044B # CYRILLIC SMALL LETTER YERU /* Ù */ +0xDA 0x0437 # CYRILLIC SMALL LETTER ZE /* Ú */ +0xDB 0x0448 # CYRILLIC SMALL LETTER SHA /* Û */ +0xDC 0x044D # CYRILLIC SMALL LETTER E /* Ü */ +0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA /* Ý */ +0xDE 0x0447 # CYRILLIC SMALL LETTER CHE /* Þ */ +0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN /* ß */ +0xE0 0x042E # CYRILLIC CAPITAL LETTER YU /* à */ +0xE1 0x0410 # CYRILLIC CAPITAL LETTER A /* á */ +0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE /* â */ +0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE /* ã */ +0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE /* ä */ +0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE /* å */ +0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF /* æ */ +0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE /* ç */ +0xE8 0x0425 # CYRILLIC CAPITAL LETTER HA /* è */ +0xE9 0x0418 # CYRILLIC CAPITAL LETTER I /* é */ +0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I /* ê */ +0xEB 0x041A # CYRILLIC CAPITAL LETTER KA /* ë */ +0xEC 0x041B # CYRILLIC CAPITAL LETTER EL /* ì */ +0xED 0x041C # CYRILLIC CAPITAL LETTER EM /* í */ +0xEE 0x041D # CYRILLIC CAPITAL LETTER EN /* î */ +0xEF 0x041E # CYRILLIC CAPITAL LETTER O /* ï */ +0xF0 0x041F # CYRILLIC CAPITAL LETTER PE /* ð */ +0xF1 0x042F # CYRILLIC CAPITAL LETTER YA /* ñ */ +0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER /* ò */ +0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES /* ó */ +0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE /* ô */ +0xF5 0x0423 # CYRILLIC CAPITAL LETTER U /* õ */ +0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE /* ö */ +0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE /* ÷ */ +0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN /* ø */ +0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU /* ù */ +0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE /* ú */ +0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA /* û */ +0xFC 0x042D # CYRILLIC CAPITAL LETTER E /* ü */ +0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA /* ý */ +0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE /* þ */ +0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN /* ÿ */ diff --git a/contrib/ttf2bdf/maps/windows.1251 b/contrib/ttf2bdf/maps/windows.1251 new file mode 100644 index 0000000..ec3e34c --- /dev/null +++ b/contrib/ttf2bdf/maps/windows.1251 @@ -0,0 +1,233 @@ +#/* +# * Unicode 2.0 -> Windows CP_1251 (Must Die ;) +# * +# * 11 Jan 97 | Eugene Bobin, +# * +# * Modified 16 June 99 Mark Leisher +# */ +# +REGISTRY WINDOWS +ENCODING 1251 +0x00 0x0000 # +0x01 0x0001 # +0x02 0x0002 # +0x03 0x0003 # +0x04 0x0004 # +0x05 0x0005 # +0x06 0x0006 # +0x07 0x0007 # +0x08 0x0008 # +0x09 0x0009 # +0x0A 0x000A # +0x0B 0x000B # +0x0C 0x000C # +0x0D 0x000D # +0x0E 0x000E # +0x0F 0x000F # +0x10 0x0010 # +0x11 0x0011 # +0x12 0x0012 # +0x13 0x0013 # +0x14 0x0014 # +0x15 0x0015 # +0x16 0x0016 # +0x17 0x0017 # +0x18 0x0018 # +0x19 0x0019 # +0x1A 0x001A # +0x1B 0x001B # +0x1C 0x001C # +0x1D 0x001D # +0x1E 0x001E # +0x1F 0x001F # +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x0451 # CYRILLIC SMALL LETTER IO /* £ */ +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO /* ³ */ +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x044E # CYRILLIC SMALL LETTER YU /* À */ +0xC1 0x0430 # CYRILLIC SMALL LETTER A /* Á */ +0xC2 0x0431 # CYRILLIC SMALL LETTER BE /* Â */ +0xC3 0x0446 # CYRILLIC SMALL LETTER TSE /* Ã */ +0xC4 0x0434 # CYRILLIC SMALL LETTER DE /* Ä */ +0xC5 0x0435 # CYRILLIC SMALL LETTER IE /* Å */ +0xC6 0x0444 # CYRILLIC SMALL LETTER EF /* Æ */ +0xC7 0x0433 # CYRILLIC SMALL LETTER GHE /* Ç */ +0xC8 0x0445 # CYRILLIC SMALL LETTER HA /* È */ +0xC9 0x0438 # CYRILLIC SMALL LETTER I /* É */ +0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I /* Ê */ +0xCB 0x043A # CYRILLIC SMALL LETTER KA /* Ë */ +0xCC 0x043B # CYRILLIC SMALL LETTER EL /* Ì */ +0xCD 0x043C # CYRILLIC SMALL LETTER EM /* Í */ +0xCE 0x043D # CYRILLIC SMALL LETTER EN /* Î */ +0xCF 0x043E # CYRILLIC SMALL LETTER O /* Ï */ +0xD0 0x043F # CYRILLIC SMALL LETTER PE /* Ð */ +0xD1 0x044F # CYRILLIC SMALL LETTER YA /* Ñ */ +0xD2 0x0440 # CYRILLIC SMALL LETTER ER /* Ò */ +0xD3 0x0441 # CYRILLIC SMALL LETTER ES /* Ó */ +0xD4 0x0442 # CYRILLIC SMALL LETTER TE /* Ô */ +0xD5 0x0443 # CYRILLIC SMALL LETTER U /* Õ */ +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE /* Ö */ +0xD7 0x0432 # CYRILLIC SMALL LETTER VE /* × */ +0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN /* Ø */ +0xD9 0x044B # CYRILLIC SMALL LETTER YERU /* Ù */ +0xDA 0x0437 # CYRILLIC SMALL LETTER ZE /* Ú */ +0xDB 0x0448 # CYRILLIC SMALL LETTER SHA /* Û */ +0xDC 0x044D # CYRILLIC SMALL LETTER E /* Ü */ +0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA /* Ý */ +0xDE 0x0447 # CYRILLIC SMALL LETTER CHE /* Þ */ +0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN /* ß */ +0xE0 0x042E # CYRILLIC CAPITAL LETTER YU /* à */ +0xE1 0x0410 # CYRILLIC CAPITAL LETTER A /* á */ +0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE /* â */ +0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE /* ã */ +0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE /* ä */ +0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE /* å */ +0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF /* æ */ +0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE /* ç */ +0xE8 0x0425 # CYRILLIC CAPITAL LETTER HA /* è */ +0xE9 0x0418 # CYRILLIC CAPITAL LETTER I /* é */ +0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I /* ê */ +0xEB 0x041A # CYRILLIC CAPITAL LETTER KA /* ë */ +0xEC 0x041B # CYRILLIC CAPITAL LETTER EL /* ì */ +0xED 0x041C # CYRILLIC CAPITAL LETTER EM /* í */ +0xEE 0x041D # CYRILLIC CAPITAL LETTER EN /* î */ +0xEF 0x041E # CYRILLIC CAPITAL LETTER O /* ï */ +0xF0 0x041F # CYRILLIC CAPITAL LETTER PE /* ð */ +0xF1 0x042F # CYRILLIC CAPITAL LETTER YA /* ñ */ +0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER /* ò */ +0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES /* ó */ +0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE /* ô */ +0xF5 0x0423 # CYRILLIC CAPITAL LETTER U /* õ */ +0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE /* ö */ +0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE /* ÷ */ +0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN /* ø */ +0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU /* ù */ +0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE /* ú */ +0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA /* û */ +0xFC 0x042D # CYRILLIC CAPITAL LETTER E /* ü */ +0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA /* ý */ +0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE /* þ */ +0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN /* ÿ */ diff --git a/contrib/ttf2bdf/remap.c b/contrib/ttf2bdf/remap.c new file mode 100644 index 0000000..3555a0f --- /dev/null +++ b/contrib/ttf2bdf/remap.c @@ -0,0 +1,690 @@ +/* + * Copyright 1996, 1997, 1998, 1999 Computing Research Labs, + * New Mexico State University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef lint +#ifdef __GNUC__ +static char rcsid[] __attribute__ ((unused)) = "$Id: remap.c,v 1.9 1999/06/16 16:13:11 mleisher Exp $"; +#else +static char rcsid[] = "$Id: remap.c,v 1.9 1999/06/16 16:13:11 mleisher Exp $"; +#endif +#endif + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#endif + +/* + * Structure for managing simple lists in place. + */ +typedef struct { + unsigned char *bfield; + unsigned long bsize; + unsigned long bused; + unsigned char **field; + unsigned long size; + unsigned long used; +} list_t; + +/* + * Callback type used with the high speed text file reader function. + */ +typedef int (*scanlines_callback_t)( +#ifdef __STDC__ + unsigned char *line, + unsigned long linelen, + unsigned long lineno, + void *client_data +#endif +); + +/* + * Various utility routines. + */ + +#define setsbit(m, cc) (m[(cc) >> 3] |= (1 << ((cc) & 7))) +#define sbitset(m, cc) (m[(cc) >> 3] & (1 << ((cc) & 7))) + +/* + * An empty string for empty fields. + */ +static unsigned char empty[1] = { 0 }; + +/* + * Assume the line is NULL terminated and that the `list' parameter was + * initialized the first time it was used. + */ +static void +#ifdef __STDC__ +splitline(unsigned char *separators, unsigned char *line, + unsigned long linelen, list_t *list) +#else +splitline(separators, line, linelen, list) +unsigned char *separators, *line; +unsigned long linelen; +list_t *list; +#endif +{ + int mult, final_empty; + unsigned char *sp, *ep, *end; + unsigned char seps[32]; + + /* + * Initialize the list. + */ + list->used = list->bused = 0; + + /* + * If the line is empty, then simply return. + */ + if (linelen == 0 || line[0] == 0) + return; + + /* + * If the `separators' parameter is NULL or empty, split the list into + * individual bytes. + */ + if (separators == 0 || *separators == 0) { + if (linelen > list->bsize) { + if (list->bsize) + list->bfield = (unsigned char *) malloc(linelen); + else + list->bfield = (unsigned char *) realloc(list->bfield, linelen); + list->bsize = linelen; + } + list->bused = linelen; + (void) memcpy(list->bfield, line, linelen); + return; + } + + /* + * Prepare the separator bitmap. + */ + (void) memset((char *) seps, 0, 32); + + /* + * If the very last character of the separator string is a plus, then set + * the `mult' flag to indicate that multiple separators should be + * collapsed into one. + */ + for (mult = 0, sp = separators; sp && *sp; sp++) { + if (*sp == '+' && *(sp + 1) == 0) + mult = 1; + else + setsbit(seps, *sp); + } + + /* + * Break the line up into fields. + */ + for (final_empty = 0, sp = ep = line, end = sp + linelen; + sp < end && *sp;) { + /* + * Collect everything that is not a separator. + */ + for (; ep < end && *ep && !sbitset(seps, *ep); ep++) ; + + /* + * Resize the list if necessary. + */ + if (list->used == list->size) { + if (list->size == 0) + list->field = (unsigned char **) + malloc(sizeof(unsigned char *) << 3); + else + list->field = (unsigned char **) + realloc((char *) list->field, + sizeof(unsigned char *) * (list->size + 8)); + + list->size += 8; + } + + /* + * Assign the field appropriately. + */ + list->field[list->used++] = (ep > sp) ? sp : empty; + + sp = ep; + if (mult) { + /* + * If multiple separators should be collapsed, do it now by + * setting all the separator characters to 0. + */ + for (; ep < end && *ep && sbitset(seps, *ep); ep++) + *ep = 0; + } else + /* + * Don't collapse multiple separators by making them 0, so just + * make the one encountered 0. + */ + *ep++ = 0; + final_empty = (ep > sp && *ep == 0); + sp = ep; + } + + /* + * Finally, NULL terminate the list. + */ + if (list->used + final_empty + 1 >= list->size) { + if (list->used == list->size) { + if (list->size == 0) + list->field = (unsigned char **) + malloc(sizeof(unsigned char *) << 3); + else + list->field = (unsigned char **) + realloc((unsigned char *) list->field, + sizeof(char *) * (list->size + 8)); + list->size += 8; + } + } + if (final_empty) + list->field[list->used++] = empty; + + if (list->used == list->size) { + if (list->size == 0) + list->field = (unsigned char **) + malloc(sizeof(unsigned char *) << 3); + else + list->field = (unsigned char **) + realloc((char *) list->field, + sizeof(unsigned char *) * (list->size + 8)); + list->size += 8; + } + list->field[list->used] = 0; +} + +static int +#ifdef __STDC__ +scanlines(int fd, scanlines_callback_t callback, void *client_data, + unsigned long *lineno) +#else +scanlines(fd, callback, client_data, lineno) +int fd; +scanlines_callback_t callback; +void *client_data; +unsigned long *lineno; +#endif +{ + unsigned long lno; + int n, res, done, refill, bytes, hold; + char *ls, *le, *pp, *pe, *hp; + char buf[65536]; + + if (callback == 0) + return -1; + + lno = 1; + (void) memset(buf, 0, 65536); + res = done = 0; + pp = ls = le = buf; + bytes = 65536; + while (!done && (n = read(fd, pp, bytes)) > 0) { + /* + * Determine the new end of the buffer pages. + */ + pe = pp + n; + + for (refill = 0; done == 0 && refill == 0; ) { + while (le < pe && *le != '\n' && *le != '\r') + le++; + + if (le == pe) { + /* + * Hit the end of the last page in the buffer. + * Need to find out how many pages to shift + * and how many pages need to be read in. + * Adjust the line start and end pointers down + * to point to the right places in the pages. + */ + pp = buf + (((ls - buf) >> 13) << 13); + n = pp - buf; + ls -= n; + le -= n; + n = pe - pp; + (void) memcpy(buf, pp, n); + pp = buf + n; + bytes = 65536 - n; + refill = 1; + } else { + /* + * Temporarily NULL terminate the line. + */ + hp = le; + hold = *le; + *le = 0; + + if (callback && *ls != '#' && *ls != 0x1a && le > ls && + (res = (*callback)((unsigned char *) ls, le - ls, lno, + client_data)) != 0) + done = 1; + else { + ls = ++le; + /* + * Handle the case of DOS CRLF sequences. + */ + if (le < pe && hold == '\n' && *le =='\r') + ls = ++le; + } + + /* + * Increment the line number. + */ + lno++; + + /* + * Restore the character at the end of the line. + */ + *hp = hold; + } + } + } + + /* + * Return with the last line number processed. + */ + *lineno = lno; + + return res; +} + +static unsigned char a2i[128] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char odigits[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char ddigits[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char hdigits[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, + 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define isdigok(m, d) (m[(d) >> 3] & (1 << ((d) & 7))) + +static unsigned short +#ifdef __STDC__ +my_atous(unsigned char *s, unsigned char **end, int base) +#else +my_atous(s, end, base) +unsigned char *s, **end; +int base; +#endif +{ + unsigned short v; + unsigned char *dmap; + + if (s == 0 || *s == 0) + return 0; + + /* + * Make sure the radix is something recognizable. Default to 10. + */ + switch (base) { + case 8: dmap = odigits; break; + case 16: dmap = hdigits; break; + default: base = 10; dmap = ddigits; break; + } + + /* + * Check for the special hex prefix. + */ + if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) { + base = 16; + dmap = hdigits; + s += 2; + } + + for (v = 0; isdigok(dmap, *s); s++) + v = (v * base) + a2i[(int) *s]; + + if (end != 0) + *end = s; + + return v; +} + +/******************************************************************** + * + * Routines to load, unload, and use mapping tables to remap BDF fonts + * generated using ttf2bdf. + * + ********************************************************************/ + +/* + * Strings used to store the registry and encoding values specified + * in the mapping table. + */ +static char *registry; +static char *encoding; + +/* + * Trie node structure. + */ +typedef struct { + unsigned short key; /* Key value. */ + unsigned short val; /* Data for the key. */ + unsigned long sibs; /* Offset of siblings from trie beginning. */ + unsigned long kids; /* Offset of children from trie beginning. */ +} node_t; + +/* + * The trie used for remapping codes. + */ +static node_t *nodes; +static unsigned long nodes_size = 0; +static unsigned long nodes_used = 0; + +/* + * Gets the next available node in the trie. + */ +static unsigned long +#ifdef __STDC__ +getnode(unsigned short key) +#else +getnode(key) +unsigned short key; +#endif +{ + unsigned long loc; + node_t *np; + + if (nodes_used == nodes_size) { + if (nodes_size == 0) + nodes = (node_t *) malloc(sizeof(node_t) << 7); + else + nodes = (node_t *) realloc((char *) nodes, sizeof(node_t) * + (nodes_size + 128)); + np = nodes + nodes_size; + nodes_size += 128; + (void) memset((char *) np, 0, sizeof(node_t) << 7); + } + + loc = nodes_used++; + np = nodes + loc; + np->kids = np->sibs = 0; + np->key = key; + return loc; +} + +/* + * Inserts a node in the trie. + */ +static void +#ifdef __STDC__ +trie_insert(unsigned short key, unsigned short val) +#else +trie_insert(key, val) +unsigned short key, val; +#endif +{ + unsigned long i, n, t, l; + unsigned short codes[2]; + + /* + * Convert the incoming key into two codes to make the trie lookup more + * efficient. + */ + codes[0] = (key >> 8) & 0xff; + codes[1] = key & 0xff; + + for (i = t = 0; i < 2; i++) { + if (nodes[t].kids == 0) { + n = getnode(codes[i]); + nodes[t].kids = t = n; + } else if (nodes[nodes[t].kids].key == codes[i]) + t = nodes[t].kids; + else if (nodes[nodes[t].kids].key > codes[i]) { + n = getnode(codes[i]); + nodes[n].sibs = nodes[t].kids; + nodes[t].kids = t = n; + } else { + t = nodes[t].kids; + for (l = t; nodes[t].sibs && nodes[t].key < codes[i]; ) { + l = t; + t = nodes[t].sibs; + } + if (nodes[t].key < codes[i]) { + n = getnode(codes[i]); + nodes[t].sibs = t = n; + } else if (nodes[t].key > codes[i]) { + n = getnode(codes[i]); + nodes[n].sibs = t; + nodes[l].sibs = t = n; + } + } + } + + /* + * Set the value in the leaf node. + */ + nodes[t].val = val; +} + +/* + * List used by the routine that parses the map lines. + */ +static list_t list; + +/* + * Routine to parse each line of the mapping file. + */ +static int +#ifdef __STDC__ +add_mapping(unsigned char *line, unsigned long linelen, unsigned long lineno, + void *client_data) +#else +add_mapping(line, linelen, lineno, client_data) +unsigned char *line; +unsigned long linelen, lineno; +void *client_data; +#endif +{ + unsigned short key, val; + + /* + * Split the line into parts separted by one or more spaces or tabs. + */ + splitline((unsigned char *) " \t+", line, linelen, &list); + + /* + * Check to see if the line starts with one of the keywords. + */ + if (memcmp((char *) list.field[0], "REGISTRY", 8) == 0) { + /* + * Collect the XLFD CHARSET_REGISTRY value. + */ + if (registry != 0) + free((char *) registry); + if ((val = strlen((char *) list.field[1])) == 0) + registry = 0; + else { + registry = (char *) malloc(val + 1); + (void) memcpy(registry, (char *) list.field[1], val + 1); + } + return 0; + } + + if (memcmp((char *) list.field[0], "ENCODING", 8) == 0) { + /* + * Collect the XLFD CHARSET_ENCODING value. + */ + if (encoding != 0) + free((char *) encoding); + if ((val = strlen((char *) list.field[1])) == 0) + encoding = 0; + else { + encoding = (char *) malloc(val + 1); + (void) memcpy(encoding, (char *) list.field[1], val + 1); + } + return 0; + } + + /* + * Get the second field value as the key (the Unicode value). Always + * assume the values are in hex. + */ + key = my_atous(list.field[1], 0, 16); + val = my_atous(list.field[0], 0, 16); + + trie_insert(key, val); + + return 0; +} + +/******************************************************************** + * + * API for mapping table support. + * + ********************************************************************/ + +int +#ifdef __STDC__ +ttf2bdf_load_map(FILE *in) +#else +ttf2bdf_load_map(in) +FILE *in; +#endif +{ + unsigned long lineno; + + /* + * Allocate some nodes initially. + */ + if (nodes_size == 0) { + nodes = (node_t *) malloc(sizeof(node_t) << 7); + nodes_size = 128; + } + + /* + * Reset the trie in case more than one gets loaded for some reason. + */ + if (nodes_size > 0) + (void) memset((char *) nodes, 0, sizeof(node_t) * nodes_size); + nodes_used = 1; + + return scanlines(fileno(in), add_mapping, 0, &lineno); +} + +/* + * Routine that deallocates the mapping trie. + */ +void +#ifdef __STDC__ +ttf2bdf_free_map(void) +#else +ttf2bdf_free_map() +#endif +{ + if (registry != 0) + free((char *) registry); + if (encoding != 0) + free((char *) encoding); + registry = encoding = 0; + + if (list.size > 0) + free((char *) list.field); + list.size = list.used = 0; + + if (nodes_size > 0) + free((char *) nodes); + nodes_size = nodes_used = 0; +} + +/* + * The routine that actually remaps the code by looking it up in the trie. + */ +int +#ifdef __STDC__ +ttf2bdf_remap(unsigned short *code) +#else +ttf2bdf_remap(code) +unsigned short *code; +#endif +{ + unsigned long i, n, t; + unsigned short c, codes[2]; + + /* + * If no mapping table was loaded, then simply return the code. + */ + if (nodes_used == 0) + return 1; + + c = *code; + codes[0] = (c >> 8) & 0xff; + codes[1] = c & 0xff; + + for (i = n = 0; i < 2; i++) { + t = nodes[n].kids; + if (t == 0) + return 0; + for (; nodes[t].sibs && nodes[t].key != codes[i]; t = nodes[t].sibs); + if (nodes[t].key != codes[i]) + return 0; + n = t; + } + + *code = nodes[n].val; + return 1; +} + +void +#ifdef __STDC__ +ttf2bdf_remap_charset(char **registry_name, char **encoding_name) +#else +ttf2bdf_remap_charset(registry_name, encoding_name) +char **registry_name, **encoding_name; +#endif +{ + if (registry_name != 0) + *registry_name = registry; + if (encoding_name != 0) + *encoding_name = encoding; +} diff --git a/contrib/ttf2bdf/remap.h b/contrib/ttf2bdf/remap.h new file mode 100644 index 0000000..15ded54 --- /dev/null +++ b/contrib/ttf2bdf/remap.h @@ -0,0 +1,64 @@ +/* + * Copyright 1996, 1997, 1998, 1999 Computing Research Labs, + * New Mexico State University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _h_remap +#define _h_remap + +/* + * $Id: remap.h,v 1.4 1999/05/03 17:07:04 mleisher Exp $ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ttf2bdf_load_map( +#ifdef __STDC__ + FILE *in +#endif +); + +extern void ttf2bdf_free_map( +#ifdef __STDC__ + void +#endif +); + +extern int ttf2bdf_remap( +#ifdef __STDC__ + unsigned short *code +#endif +); + +extern void ttf2bdf_remap_charset( +#ifdef __STDC__ + char **registry_name, + char **encoding_name +#endif +); + +#ifdef __cplusplus +} +#endif + +#endif /* _h_remap */ diff --git a/contrib/ttf2bdf/ttf2bdf.c b/contrib/ttf2bdf/ttf2bdf.c new file mode 100644 index 0000000..903fc18 --- /dev/null +++ b/contrib/ttf2bdf/ttf2bdf.c @@ -0,0 +1,1581 @@ +/* + * Copyright 1996, 1997, 1998, 1999 Computing Research Labs, + * New Mexico State University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef lint +#ifdef __GNUC__ +static char rcsid[] __attribute__ ((unused)) = "$Id: ttf2bdf.c,v 1.25 1999/10/21 16:31:54 mleisher Exp $"; +#else +static char rcsid[] = "$Id: ttf2bdf.c,v 1.25 1999/10/21 16:31:54 mleisher Exp $"; +#endif +#endif + +#include + +#ifdef WIN32 +#include +#else +#include +#include +#endif + +#include + +#include "freetype.h" + +/* + * Include the remapping support. + */ +#include "remap.h" + +/************************************************************************** + * + * Macros. + * + **************************************************************************/ + +/* + * The version of ttf2bdf. + */ +#define TTF2BDF_VERSION "2.8" + +/* + * Set the default values used to generate a BDF font. + */ +#ifndef DEFAULT_PLATFORM_ID +#define DEFAULT_PLATFORM_ID 3 +#endif + +#ifndef DEFAULT_ENCODING_ID +#define DEFAULT_ENCODING_ID 1 +#endif + +#ifndef DEFAULT_POINT_SIZE +#define DEFAULT_POINT_SIZE 12 +#endif + +#ifndef DEFAULT_RESOLUTION +#define DEFAULT_RESOLUTION 100 +#endif + +/* + * Used as a fallback for XLFD names where the character set/encoding can not + * be determined. + */ +#ifndef DEFAULT_XLFD_CSET +#define DEFAULT_XLFD_CSET "-FontSpecific-0" +#endif + +/* + * nameID macros for getting strings from the TT font. + */ +#define TTF_COPYRIGHT 0 +#define TTF_TYPEFACE 1 +#define TTF_PSNAME 6 + +#ifndef MAX +#define MAX(h,i) ((h) > (i) ? (h) : (i)) +#endif + +#ifndef MIN +#define MIN(l,o) ((l) < (o) ? (l) : (o)) +#endif + +/************************************************************************** + * + * General globals set from command line. + * + **************************************************************************/ + +/* + * The program name. + */ +static char *prog; + +/* + * The flag indicating whether messages should be printed or not. + */ +static int verbose = 0; + +/* + * Flags used when loading glyphs. + */ +static int load_flags = TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH; + +/* + * The default platform and encoding ID's. + */ +static int pid = DEFAULT_PLATFORM_ID; +static int eid = DEFAULT_ENCODING_ID; + +/* + * Default point size and resolutions. + */ +static int point_size = DEFAULT_POINT_SIZE; +static int hres = DEFAULT_RESOLUTION; +static int vres = DEFAULT_RESOLUTION; + +/* + * The user supplied foundry name to use in the XLFD name. + */ +static char *foundry_name = 0; + +/* + * The user supplied typeface name to use in the XLFD name. + */ +static char *face_name = 0; + +/* + * The user supplied weight name to use in the XLFD name. + */ +static char *weight_name = 0; + +/* + * The user supplied slant name to use in the XLFD name. + */ +static char *slant_name = 0; + +/* + * The user supplied width name to use in the XLFD name. + */ +static char *width_name = 0; + +/* + * The user supplied additional style name to use in the XLFD name. + */ +static char *style_name = 0; + +/* + * The user supplied spacing (p = proportional, c = character cell, + * m = monospace). + */ +static int spacing = 0; + +/* + * The dash character to use in the names retrieved from the font. Default is + * the space. + */ +static int dashchar = ' '; + +/* + * Flag, bitmask, and max code for generating a subset of the glyphs in a font. + */ +static int do_subset = 0; +static unsigned short maxcode; +static unsigned long subset[2048]; + +/* + * The flag that indicates the remapping table should be used to + * reencode the font. + */ +static int do_remap = 0; + +/************************************************************************** + * + * Internal globals. + * + **************************************************************************/ + +/* + * Structure used for calculating the font bounding box as the glyphs are + * generated. + */ +typedef struct { + short minlb; + short maxlb; + short maxrb; + short maxas; + short maxds; + short rbearing; +} bbx_t; + +static bbx_t bbx; + +/* + * The buffer used to transfer the temporary file to the actual output file. + */ +#define TTF2BDF_IOBUFSIZ 8192 +static char iobuf[TTF2BDF_IOBUFSIZ]; + +/* + * The Units Per Em value used in numerous places. + */ +static TT_UShort upm; + +/* + * A flag indicating if a CMap was found or not. + */ +static TT_UShort nocmap; + +/* + * The scaling factor needed to compute the SWIDTH (scalable width) value + * for BDF glyphs. + */ +static double swscale; + +/* + * Mac encoding names used when creating the BDF XLFD font name. + */ +static char *mac_encodings[] = { + "-MacRoman-0", "-MacJapanese-0", "-MacChinese-0", "-MacKorean-0", + "-MacArabic-0", "-MacHebrew-0", "-MacGreek-0", "-MacRussian-0", + "-MacRSymbol-0", "-MacDevanagari-0", "-MacGurmukhi-0", "-MacGujarati-0", + "-MacOriya-0", "-MacBengali-0", "-MacTamil-0", "-MacTelugu-0", + "-MacKannada-0", "-MacMalayalam-0", "-MacSinhalese-0", "-MacBurmese-0", + "-MacKhmer-0", "-MacThai-0", "-MacLaotian-0", "-MacGeorgian-0", + "-MacArmenian-0", "-MacMaldivian-0", "-MacTibetan-0", "-MacMongolian-0", + "-MacGeez-0", "-MacSlavic-0", "-MacVietnamese-0","-MacSindhi-0", + "-MacUninterp-0" +}; +static int num_mac_encodings = sizeof(mac_encodings) / + sizeof(mac_encodings[0]); + +/* + * ISO encoding names used when creating the BDF XLFD font name. + */ +static char *iso_encodings[] = { + "-ASCII-0", "-ISO10646-0", "-ISO8859-1" +}; +static int num_iso_encodings = sizeof(iso_encodings) / + sizeof(iso_encodings[0]); + +/* + * Microsoft encoding names used when creating the BDF XLFD font name. + */ +static char *ms_encodings[] = { + "-Symbol-0", "-ISO10646-1", "-ShiftJIS-0", "-GB2312.1980-0", "-Big5-0", + "-KSC5601.1987-0", "-KSC5601.1992-0" +}; +static int num_ms_encodings = sizeof(ms_encodings) / + sizeof(ms_encodings[0]); + +/* + * The propery names for all the XLFD properties. + */ +static char *xlfd_props[] = { + "FOUNDRY", + "FAMILY_NAME", + "WEIGHT_NAME", + "SLANT", + "SETWIDTH_NAME", + "ADD_STYLE_NAME", + "PIXEL_SIZE", + "POINT_SIZE", + "RESOLUTION_X", + "RESOLUTION_Y", + "SPACING", + "AVERAGE_WIDTH", + "CHARSET_REGISTRY", + "CHARSET_ENCODING", +}; + +/************************************************************************** + * + * Freetype globals. + * + **************************************************************************/ + +static TT_Engine engine; +static TT_Face face; +static TT_Face_Properties properties; + +static TT_Instance instance; + +static TT_Glyph glyph; +static TT_Glyph_Metrics metrics; +static TT_Instance_Metrics imetrics; + +static TT_Raster_Map raster; + +static TT_CharMap cmap; + +/************************************************************************** + * + * Freetype related code. + * + **************************************************************************/ + +/* + * A generic routine to get a name from the TT name table. This routine + * always looks for English language names and checks three possibilities: + * 1. English names with the MS Unicode encoding ID. + * 2. English names with the MS unknown encoding ID. + * 3. English names with the Apple Unicode encoding ID. + * + * The particular name ID mut be provided (e.g. nameID = 0 for copyright + * string, nameID = 6 for Postscript name, nameID = 1 for typeface name. + * + * If the `dash' flag is non-zero, all dashes (-) in the name will be replaced + * with the character passed. + * + * Returns the number of bytes added. + */ +static int +#ifdef __STDC__ +ttf_get_english_name(char *name, int nameID, int dash) +#else +ttf_get_english_name(name, nameID, dash) +char *name; +int nameID, dash; +#endif +{ + TT_UShort slen; + int i, j, encid, nrec; + unsigned short nrPlatformID, nrEncodingID, nrLanguageID, nrNameID; + char *s; + + nrec = TT_Get_Name_Count(face); + + for (encid = 1, j = 0; j < 2; j++, encid--) { + /* + * Locate one of the MS English font names. + */ + for (i = 0; i < nrec; i++) { + TT_Get_Name_ID(face, i, &nrPlatformID, &nrEncodingID, + &nrLanguageID, &nrNameID); + if (nrPlatformID == 3 && + nrEncodingID == encid && + nrNameID == nameID && + (nrLanguageID == 0x0409 || nrLanguageID == 0x0809 || + nrLanguageID == 0x0c09 || nrLanguageID == 0x1009 || + nrLanguageID == 0x1409 || nrLanguageID == 0x1809)) { + TT_Get_Name_String(face, i, &s, &slen); + break; + } + } + + if (i < nrec) { + /* + * Found one of the MS English font names. The name is by + * definition encoded in Unicode, so copy every second byte into + * the `name' parameter, assuming there is enough space. + */ + for (i = 1; s != 0 && i < slen; i += 2) { + if (dash) + *name++ = (s[i] == '-' || s[i] == ' ') ? dash : s[i]; + else if (s[i] == '\r' || s[i] == '\n') { + if (s[i] == '\r' && i + 2 < slen && s[i + 2] == '\n') + i += 2; + *name++ = ' '; + *name++ = ' '; + } else + *name++ = s[i]; + } + *name = 0; + return (slen >> 1); + } + } + + /* + * No MS English name found, attempt to find an Apple Unicode English + * name. + */ + for (i = 0; i < nrec; i++) { + TT_Get_Name_ID(face, i, &nrPlatformID, &nrEncodingID, + &nrLanguageID, &nrNameID); + if (nrPlatformID == 0 && nrLanguageID == 0 && + nrNameID == nameID) { + TT_Get_Name_String(face, i, &s, &slen); + break; + } + } + + if (i < nrec) { + /* + * Found the Apple Unicode English name. The name is by definition + * encoded in Unicode, so copy every second byte into the `name' + * parameter, assuming there is enough space. + */ + for (i = 1; s != 0 && i < slen; i += 2) { + if (dash) + *name++ = (s[i] == '-' || s[i] == ' ') ? dash : s[i]; + else if (s[i] == '\r' || s[i] == '\n') { + if (s[i] == '\r' && i + 2 < slen && s[i + 2] == '\n') + i += 2; + *name++ = ' '; + *name++ = ' '; + } else + *name++ = s[i]; + } + *name = 0; + return (slen >> 1); + } + + return 0; +} + +/************************************************************************** + * + * General code. + * + **************************************************************************/ + +/* + * Create an XLFD name. Assumes there is enough space in the string passed + * to fit a reasonably long XLFD name into, up to the 256 byte maximum. + */ +static void +#ifdef __STDC__ +make_xlfd_name(char *name, TT_Long awidth, int ismono) +#else +make_xlfd_name(name, awidth, ismono) +char *name; +TT_Long awidth; +int ismono; +#endif +{ + TT_Long i; + TT_ULong val; + char *r, *e; + double dr, dp; + + /* + * Default the foundry name to "FreeType" in honor of the project and + * because the foundry name is too difficult to automatically determine + * from the names in TT fonts. But the user can provide his own. + */ + if (foundry_name == 0) { + (void) strcpy(name, "-FreeType"); + name += 9; + } else { + *(name++)='-'; + strcpy(name,foundry_name); + name+=strlen(foundry_name); + } + + /* + * Add the typeface name from the font. The fallback default will be + * "Unknown". + */ + *name++ = '-'; + if (face_name == 0) { + if((i = ttf_get_english_name(name, TTF_TYPEFACE, dashchar))) + name += i; + else { + (void) strcpy(name, "Unknown"); + name += 7; + } + } else { + (void) strcpy(name, face_name); + name += strlen(face_name); + } + + /* + * Add the weight name. The default will be "Medium". + */ + if (weight_name != 0) { + sprintf(name, "-%s", weight_name); + name += strlen(weight_name) + 1; + } else { + if (properties.os2->fsSelection & 0x20) { + (void) strcpy(name, "-Bold"); + name += 5; + } else { + (void) strcpy(name, "-Medium"); + name += 7; + } + } + + /* + * Add the slant name. The default will be 'R'. + */ + if (slant_name) { + sprintf(name, "-%s", slant_name); + name += strlen(slant_name) + 1; + } else { + *name++ = '-'; + if (properties.os2->fsSelection & 0x01) + *name++ = 'I'; + else + *name++ = 'R'; + } + + /* + * Default the setwidth name to "Normal" but user can specify one. + */ + if (width_name == 0) { + (void) strcpy(name, "-Normal"); + name += 7; + } else { + *(name++)='-'; + strcpy(name,width_name); + name+=strlen(width_name); + } + + /* + * Default the additional style name to NULL but user can specify one. + */ + *name++ = '-'; + if (style_name != 0) { + strcpy(name,style_name); + name+=strlen(style_name); + } + + /* + * Determine the pixel size from the point size and resolution. + */ + dr = (double) vres; + dp = (double) (point_size * 10); + val = (unsigned long) (((dp * dr) / 722.7) + 0.5); + + /* + * Set the pixel size, point size, and resolution. + */ + sprintf(name, "-%ld-%d-%d-%d", val, point_size * 10, hres, vres); + name += strlen(name); + + switch (spacing) { + case 'p': case 'P': spacing = 'P'; break; + case 'm': case 'M': spacing = 'M'; break; + case 'c': case 'C': spacing = 'C'; break; + default: spacing = 0; break; + } + + /* + * Set the spacing. + */ + if (!spacing) + spacing = (ismono) ? 'M' : 'P'; + *name++ = '-'; + *name++ = spacing; + + /* + * Add the average width. + */ + sprintf(name, "-%ld", awidth); + name += strlen(name); + + /* + * Check to see if the remapping table specified a registry and encoding + * and use those if they both exist. + */ + ttf2bdf_remap_charset(&r, &e); + if (r != 0 && e != 0) { + sprintf(name, "-%s-%s", r, e); + return; + } + + /* + * If the cmap for the platform and encoding id was not found, or the + * platform id is unknown, assume the character set registry and encoding + * are the XLFD default. + */ + if (nocmap || pid > 3) + (void) strcpy(name, DEFAULT_XLFD_CSET); + else { + /* + * Finally, determine the character set registry and encoding from the + * platform and encoding ID. + */ + switch (pid) { + case 0: + /* + * Apple Unicode platform, so "Unicode-2.0" is the default. + */ + (void) strcpy(name, "-Unicode-2.0"); + break; + case 1: + /* + * Macintosh platform, so choose from the Macintosh encoding + * strings. + */ + if (eid < 0 || eid >= num_mac_encodings) + (void) strcpy(name, DEFAULT_XLFD_CSET); + else + (void) strcpy(name, mac_encodings[eid]); + break; + case 2: + /* + * ISO platform, so choose from the ISO encoding strings. + */ + if (eid < 0 || eid >= num_iso_encodings) + (void) strcpy(name, DEFAULT_XLFD_CSET); + else + (void) strcpy(name, iso_encodings[eid]); + break; + case 3: + /* + * Microsoft platform, so choose from the MS encoding strings. + */ + if (eid < 0 || eid >= num_ms_encodings) + (void) strcpy(name, DEFAULT_XLFD_CSET); + else + (void) strcpy(name, ms_encodings[eid]); + break; + } + } +} + +static int +#ifdef __STDC__ +generate_font(FILE *out, char *iname, char *oname) +#else +generate_font(out, iname, oname) +FILE *out; +char *iname, *oname; +#endif +{ + int eof, ismono, i; + FILE *tmp; + TT_Short maxx, maxy, minx, miny, xoff, yoff, dwidth, swidth; + TT_Short y_off, x_off; + TT_UShort sx, sy, ex, ey, wd, ht; + TT_Long code, idx, ng, aw; + TT_UShort remapped_code; + unsigned char *bmap; + double dw; + char *xp, xlfd[256]; + char *tmpdir, tmpfile[BUFSIZ]; + + /* + * Open a temporary file to store the bitmaps in until the exact number + * of bitmaps are known. + */ + if ((tmpdir = getenv("TMPDIR")) == 0) + tmpdir = "/tmp"; + sprintf(tmpfile, "%s/ttf2bdf%ld", tmpdir, (long) getpid()); + if ((tmp = fopen(tmpfile, "w")) == 0) { + fprintf(stderr, "%s: unable to open temporary file '%s'.\n", + prog, tmpfile); + return -1; + } + + /* + * Calculate the scale factor for the SWIDTH field. + */ + swscale = ((double) vres) * ((double) point_size); + + /* + * Calculate the font bounding box again so enough storage for the largest + * bitmap can be allocated. + */ + minx = (properties.header->xMin * imetrics.x_ppem) / upm; + miny = (properties.header->yMin * imetrics.y_ppem) / upm; + maxx = (properties.header->xMax * imetrics.x_ppem) / upm; + maxy = (properties.header->yMax * imetrics.y_ppem) / upm; + + maxx -= minx; ++maxx; + maxy -= miny; ++maxy; + + /* + * Initialize the flag that tracks if the font is monowidth or not and + * initialize the glyph width variable that is used for testing for a + * monowidth font. + */ + wd = 0xffff; + ismono = 1; + + /* + * Use the upward flow because the version of FreeType being used when + * this was written did not support TT_Flow_Down. This insures that this + * routine will not mess up if TT_Flow_Down is implemented at some point. + */ + raster.flow = TT_Flow_Up; + raster.width = maxx; + raster.rows = maxy; + raster.cols = (maxx + 7) >> 3; + raster.size = raster.cols * raster.rows; + raster.bitmap = (void *) malloc(raster.size); + + for (ng = code = 0, eof = 0, aw = 0; eof != EOF && code < 0xffff; code++) { + + /* + * If a remap is indicated, attempt to remap the code. If a remapped + * code is not found, then skip generating the glyph. + */ + remapped_code = (TT_UShort) code; + if (do_remap && !ttf2bdf_remap(&remapped_code)) + continue; + + /* + * If a subset is being generated and the code is greater than the max + * code of the subset, break out of the loop to avoid doing any more + * work. + */ + if (do_subset && remapped_code > maxcode) + break; + + /* + * If a subset is being generated and the index is not in the subset + * bitmap, just continue. + */ + if (do_subset && + !(subset[remapped_code >> 5] & (1 << (remapped_code & 31)))) + continue; + + if (nocmap) { + if (code >= properties.num_Glyphs) + + /* + * At this point, all the glyphs are done. + */ + break; + idx = code; + } else + idx = TT_Char_Index(cmap, code); + + /* + * If the glyph could not be loaded for some reason, or a subset is + * being generated and the index is not in the subset bitmap, just + * continue. + */ + + if (idx <= 0 || TT_Load_Glyph(instance, glyph, idx, load_flags)) + continue; + + (void) TT_Get_Glyph_Metrics(glyph, &metrics); + + /* + * Clear the raster bitmap. + */ + (void) memset((char *) raster.bitmap, 0, raster.size); + + /* + * Grid fit to determine the x and y offsets that will force the + * bitmap to fit into the storage provided. + */ + xoff = (63 - metrics.bbox.xMin) & -64; + yoff = (63 - metrics.bbox.yMin) & -64; + + /* + * If the bitmap cannot be generated, simply continue. + */ + if (TT_Get_Glyph_Bitmap(glyph, &raster, xoff, yoff)) + continue; + + /* + * Determine the DWIDTH (device width, or advance width in TT terms) + * and the SWIDTH (scalable width) values. + */ + dwidth = metrics.advance >> 6; + dw = (double) dwidth; + swidth = (TT_Short) ((dw * 72000.0) / swscale); + + /* + * Determine the actual bounding box of the glyph bitmap. Do not + * forget that the glyph is rendered upside down! + */ + sx = ey = 0xffff; + sy = ex = 0; + bmap = (unsigned char *) raster.bitmap; + for (miny = 0; miny < raster.rows; miny++) { + for (minx = 0; minx < raster.width; minx++) { + if (bmap[(miny * raster.cols) + (minx >> 3)] & + (0x80 >> (minx & 7))) { + if (minx < sx) + sx = minx; + if (minx > ex) + ex = minx; + if (miny > sy) + sy = miny; + if (miny < ey) + ey = miny; + } + } + } + + /* + * If the glyph is actually an empty bitmap, set the size to 0 all + * around. + */ + if (sx == 0xffff && ey == 0xffff && sy == 0 && ex == 0) + sx = ex = sy = ey = 0; + + /* + * Increment the number of glyphs generated. + */ + ng++; + + /* + * Test to see if the font is going to be monowidth or not by + * comparing the current glyph width against the last one. + */ + if (ismono && (ex - sx) + 1 != wd) + ismono = 0; + + /* + * Adjust the font bounding box. + */ + wd = (ex - sx) + 1; + ht = (sy - ey) + 1; + x_off = sx - (xoff >> 6); + y_off = ey - (yoff >> 6); + + bbx.maxas = MAX(bbx.maxas, ht + y_off); + bbx.maxds = MAX(bbx.maxds, -y_off); + bbx.rbearing = wd + x_off; + bbx.maxrb = MAX(bbx.maxrb, bbx.rbearing); + bbx.minlb = MIN(bbx.minlb, x_off); + bbx.maxlb = MAX(bbx.maxlb, x_off); + + /* + * Add to the average width accumulator. + */ + aw += wd; + + /* + * Print the bitmap header. + */ + fprintf(tmp, "STARTCHAR %04lX\nENCODING %ld\n", code, + (long) remapped_code); + fprintf(tmp, "SWIDTH %hd 0\n", swidth); + fprintf(tmp, "DWIDTH %hd 0\n", dwidth); + fprintf(tmp, "BBX %hd %hd %hd %hd\n", wd, ht, x_off, y_off); + + /* + * Check for an error return here in case the temporary file system + * fills up or the file is deleted while it is being used. + */ + eof = fprintf(tmp, "BITMAP\n"); + + /* + * Now collect the bits so they can be printed. + */ + for (miny = sy; eof != EOF && miny >= ey; miny--) { + for (idx = 0, minx = sx; eof != EOF && minx <= ex; minx++) { + if (minx > sx && ((minx - sx) & 7) == 0) { + /* + * Print the next byte. + */ + eof = fprintf(tmp, "%02lX", idx & 0xff); + idx = 0; + } + if (bmap[(miny * raster.cols) + (minx >> 3)] & + (0x80 >> (minx & 7))) + idx |= 0x80 >> ((minx - sx) & 7); + } + if (eof != EOF) + /* + * Because of the structure of the loop, the last byte should + * always be printed. + */ + fprintf(tmp, "%02lX\n", idx & 0xff); + } + if (eof != EOF) + fprintf(tmp, "ENDCHAR\n"); + } + + fclose(tmp); + + /* + * If a write error occured, delete the temporary file and issue an error + * message. + */ + if (eof == EOF) { + (void) unlink(tmpfile); + fprintf(stderr, "%s: problem writing to temporary file '%s'.\n", + prog, tmpfile); + if (raster.size > 0) + free((char *) raster.bitmap); + return -1; + } + + /* + * If no characters were generated, just unlink the temp file and issue a + * warning. + */ + if (ng == 0) { + (void) unlink(tmpfile); + fprintf(stderr, "%s: no glyphs generated from '%s'.\n", prog, iname); + if (raster.size > 0) + free((char *) raster.bitmap); + return -1; + } + + /* + * Reopen the temporary file so it can be copied to the actual output + * file. + */ + if ((tmp = fopen(tmpfile, "r")) == 0) { + /* + * Unable to open the file for read, so attempt to delete it and issue + * an error message. + */ + (void) unlink(tmpfile); + fprintf(stderr, "%s: unable to open temporary file '%s' for read.\n", + prog, tmpfile); + if (raster.size > 0) + free((char *) raster.bitmap); + return -1; + } + + /* + * Free up the raster storage. + */ + if (raster.size > 0) + free((char *) raster.bitmap); + + /* + * Calculate the average width. + */ + aw = (TT_Long) ((((double) aw / (double) ng) + 0.5) * 10.0); + + /* + * Generate the XLFD font name. + */ + make_xlfd_name(xlfd, aw, ismono); + + /* + * Start writing the font out. + */ + fprintf(out, "STARTFONT 2.1\n"); + + /* + * Add the vanity comments. + */ + fprintf(out, "COMMENT\n"); + fprintf(out, "COMMENT Converted from TrueType font \"%s\" by \"%s %s\".\n", + iname, prog, TTF2BDF_VERSION); + fprintf(out, "COMMENT\n"); + + fprintf(out, "FONT %s\n", xlfd); + fprintf(out, "SIZE %d %d %d\n", point_size, hres, vres); + + /* + * Generate the font bounding box. + */ + fprintf(out, "FONTBOUNDINGBOX %hd %hd %hd %hd\n", + bbx.maxrb - bbx.minlb, bbx.maxas + bbx.maxds, + bbx.minlb, -bbx.maxds); + + /* + * Print the properties. + */ + fprintf(out, "STARTPROPERTIES %hd\n", 19); + + /* + * Print the font properties from the XLFD name. + */ + for (i = 0, xp = xlfd; i < 14; i++) { + /* + * Print the XLFD property name. + */ + fprintf(out, "%s ", xlfd_props[i]); + + /* + * Make sure the ATOM properties are wrapped in double quotes. + */ + if (i < 6 || i == 10 || i > 11) + putc('"', out); + + /* + * Skip the leading '-' in the XLFD name. + */ + xp++; + + /* + * Skip until the next '-' or NULL. + */ + for (; *xp && *xp != '-'; xp++) + putc(*xp, out); + + /* + * Make sure the ATOM properties are wrapped in double quotes. + */ + if (i < 6 || i == 10 || i > 11) + putc('"', out); + + putc('\n', out); + } + + /* + * Make sure to add the FONT_ASCENT and FONT_DESCENT properties + * because X11 can not live without them. + */ + fprintf(out, "FONT_ASCENT %hd\nFONT_DESCENT %hd\n", + (properties.horizontal->Ascender * imetrics.y_ppem) / upm, + -((properties.horizontal->Descender * imetrics.y_ppem) / upm)); + + /* + * Get the copyright string from the font. + */ + (void) ttf_get_english_name(xlfd, TTF_COPYRIGHT, 0); + fprintf(out, "COPYRIGHT \"%s\"\n", xlfd); + + /* + * Last, print the two user-defined properties _TTF_FONTFILE and + * _TTF_PSNAME. _TTF_FONTFILE provides a reference to the original TT + * font file which some systems can take advantage of, and _TTF_PSNAME + * provides the Postscript name of the font if it exists. + */ + (void) ttf_get_english_name(xlfd, TTF_PSNAME, 0); + fprintf(out, "_TTF_FONTFILE \"%s\"\n_TTF_PSNAME \"%s\"\n", iname, xlfd); + + fprintf(out, "ENDPROPERTIES\n"); + + /* + * Print the actual number of glyphs to the output file. + */ + eof = fprintf(out, "CHARS %ld\n", ng); + + /* + * Copy the temporary file to the output file. + */ + while (eof != EOF && (ng = fread(iobuf, 1, TTF2BDF_IOBUFSIZ, tmp))) { + if (fwrite(iobuf, 1, ng, out) == 0) + eof = EOF; + } + + /* + * Close the temporary file and delete it. + */ + fclose(tmp); + (void) unlink(tmpfile); + + /* + * If an error occured when writing to the output file, issue a warning + * and return. + */ + if (eof == EOF) { + fprintf(stderr, "%s: problem writing to output file '%s'.\n", + prog, oname); + if (raster.size > 0) + free((char *) raster.bitmap); + return -1; + } + + /* + * End the font and do memory cleanup on the glyph and raster structures. + */ + eof = fprintf(out, "ENDFONT\n"); + + return eof; +} + +static int +#ifdef __STDC__ +generate_bdf(FILE *out, char *iname, char *oname) +#else +generate_bdf(out, iname, oname) +FILE *out; +char *iname, *oname; +#endif +{ + TT_Long i; + TT_UShort p, e; + + /* + * Get the requested cmap. + */ + for (i = 0; i < TT_Get_CharMap_Count(face); i++) { + if (!TT_Get_CharMap_ID(face, i, &p, &e) && + p == pid && e == eid) + break; + } + if (i == TT_Get_CharMap_Count(face) && pid == 3 && eid == 1) { + /* + * Make a special case when this fails with pid == 3 and eid == 1. + * Change to eid == 0 and try again. This captures the two possible + * cases for MS fonts. Some other method should be used to cycle + * through all the alternatives later. + */ + for (i = 0; i < TT_Get_CharMap_Count(face); i++) { + if (!TT_Get_CharMap_ID(face, i, &p, &e) && + p == pid && e == 0) + break; + } + if (i < TT_Get_CharMap_Count(face)) { + if (!TT_Get_CharMap(face, i, &cmap)) + eid = 0; + else + nocmap = 1; + } + } else { + /* + * A CMap was found for the platform and encoding IDs. + */ + if (i < TT_Get_CharMap_Count(face) && TT_Get_CharMap(face, i, &cmap)) + nocmap = 1; + else + nocmap = 0; + } + + if (nocmap && verbose) { + fprintf(stderr, + "%s: no character map for platform %d encoding %d. ", + prog, pid, eid); + fprintf(stderr, "Generating all glyphs.\n"); + } + + /* + * Now go through and generate the glyph bitmaps themselves. + */ + return generate_font(out, iname, oname); +} + +#define isdig(cc) ((cc) >= '0' && (cc) <= '9') + +/* + * Routine to parse a subset specification supplied on the command line. + * The syntax for this specification is the same as the syntax used for + * the XLFD font names (XLFD documentation, page 9). + * + * Example: + * + * "60 70 80_90" means the glyphs at codes 60, 70, and between 80 and + * 90 inclusive. + */ +static void +#ifdef __STDC__ +parse_subset(char *s) +#else +parse_subset(s) +char *s; +#endif +{ + long l, r; + + /* + * Make sure to clear the flag and bitmap in case more than one subset is + * specified on the command line. + */ + maxcode = 0; + do_subset = 0; + (void) memset((char *) subset, 0, sizeof(unsigned long) * 2048); + + while (*s) { + /* + * Collect the next code value. + */ + for (l = r = 0; *s && isdig(*s); s++) + l = (l * 10) + (*s - '0'); + + /* + * If the next character is an '_', advance and collect the end of the + * specified range. + */ + if (*s == '_') { + s++; + for (; *s && isdig(*s); s++) + r = (r * 10) + (*s - '0'); + } else + r = l; + + /* + * Add the range just collected to the subset bitmap and set the flag + * that indicates a subset is wanted. + */ + for (; l <= r; l++) { + do_subset = 1; + subset[l >> 5] |= (1 << (l & 31)); + if (l > maxcode) + maxcode = l; + } + + /* + * Skip all non-digit characters. + */ + while (*s && !isdig(*s)) + s++; + } +} + +static void +#ifdef __STDC__ +usage(int eval) +#else +usage(eval) +int eval; +#endif +{ + fprintf(stderr, "Usage: %s [options below] font.ttf\n", prog); + fprintf(stderr, "-h\t\tThis message.\n"); + fprintf(stderr, "-v\t\tPrint warning messages during conversion.\n"); + fprintf(stderr, + "-l \"subset\"\tSpecify a subset of glyphs to generate.\n"); + fprintf(stderr, "-m mapfile\tGlyph reencoding file.\n"); + fprintf(stderr, "-n\t\tTurn off glyph hinting.\n"); + fprintf(stderr, + "-c c\t\tSet the character spacing (default: from font).\n"); + fprintf(stderr, + "-f name\t\tSet the foundry name (default: freetype).\n"); + fprintf(stderr, + "-t name\t\tSet the typeface name (default: from font).\n"); + fprintf(stderr, "-w name\t\tSet the weight name (default: Medium).\n"); + fprintf(stderr, "-s name\t\tSet the slant name (default: R).\n"); + fprintf(stderr, "-k name\t\tSet the width name (default: Normal).\n"); + fprintf(stderr, + "-d name\t\tSet the additional style name (default: empty).\n"); + fprintf(stderr, "-u char\t\tSet the character to replace '-' in names "); + fprintf(stderr, "(default: space).\n"); + fprintf(stderr, + "-pid id\t\tSet the platform ID for encoding (default: %d).\n", + DEFAULT_PLATFORM_ID); + fprintf(stderr, + "-eid id\t\tSet the encoding ID for encoding (default: %d).\n", + DEFAULT_ENCODING_ID); + fprintf(stderr, "-p n\t\tSet the point size (default: %dpt).\n", + DEFAULT_POINT_SIZE); + fprintf(stderr, "-r n\t\tSet the horizontal and vertical resolution "); + fprintf(stderr, "(default: %ddpi).\n", DEFAULT_RESOLUTION); + fprintf(stderr, "-rh n\t\tSet the horizontal resolution "); + fprintf(stderr, "(default: %ddpi)\n", DEFAULT_RESOLUTION); + fprintf(stderr, "-rv n\t\tSet the vertical resolution "); + fprintf(stderr, "(default: %ddpi)\n", DEFAULT_RESOLUTION); + fprintf(stderr, + "-o outfile\tSet the output filename (default: stdout).\n"); + exit(eval); +} + +int +#ifdef __STDC__ +main(int argc, char *argv[]) +#else +main(argc, argv) +int argc; +char *argv[]; +#endif +{ + int res; + char *infile, *outfile, *iname, *oname; + FILE *out, *mapin; + + if ((prog = strrchr(argv[0], '/'))) + prog++; + else + prog = argv[0]; + + out = stdout; + infile = outfile = 0; + + argc--; + argv++; + + while (argc > 0) { + if (argv[0][0] == '-') { + switch (argv[0][1]) { + case 'v': case 'V': + verbose = 1; + break; + case 'l': case 'L': + argc--; + argv++; + parse_subset(argv[0]); + break; + case 'n': case 'N': + load_flags &= ~TTLOAD_HINT_GLYPH; + break; + case 'c': case 'C': + argc--; + argv++; + spacing = argv[0][0]; + break; + case 't': case 'T': + argc--; + argv++; + face_name = argv[0]; + break; + case 'w': case 'W': + argc--; + argv++; + weight_name = argv[0]; + break; + case 's': case 'S': + argc--; + argv++; + slant_name = argv[0]; + break; + case 'k': case 'K': + argc--; + argv++; + width_name = argv[0]; + break; + case 'd': case 'D': + argc--; + argv++; + style_name = argv[0]; + break; + case 'f': case 'F': + argc--; + argv++; + foundry_name = argv[0]; + break; + case 'u': case 'U': + argc--; + argv++; + dashchar = argv[0][0]; + break; + case 'p': case 'P': + res = argv[0][2]; + argc--; + argv++; + if (res == 'i' || res == 'I') + /* + * Set the platform ID. + */ + pid = atoi(argv[0]); + else + /* + * Set the point size. + */ + point_size = atoi(argv[0]); + break; + case 'e': case 'E': + /* + * Set the encoding ID. + */ + argc--; + argv++; + eid = atoi(argv[0]); + break; + case 'r': + /* + * Set the horizontal and vertical resolutions. + */ + if (argv[0][2] == 'h') + hres = atoi(argv[1]); + else if (argv[0][2] == 'v') + vres = atoi(argv[1]); + else + hres = vres = atoi(argv[1]); + argc--; + argv++; + break; + case 'm': case 'M': + /* + * Try to load a remap table. + */ + argc--; + argv++; + + /* + * Always reset the `do_remap' variable here in case more than + * one map file appears on the command line. + */ + do_remap = 0; + if ((mapin = fopen(argv[0], "r")) == 0) + fprintf(stderr, "%s: unable to open the remap table '%s'.\n", + prog, argv[0]); + else { + if (ttf2bdf_load_map(mapin) < 0) { + fprintf(stderr, + "%s: problem loading remap table '%s'.\n", + prog, argv[0]); + do_remap = 0; + } else + do_remap = 1; + fclose(mapin); + } + break; + case 'o': case 'O': + /* + * Set the output file name. + */ + argc--; + argv++; + outfile = argv[0]; + break; + default: + usage(1); + } + } else + /* + * Set the input file name. + */ + infile = argv[0]; + + argc--; + argv++; + } + + /* + * Validate the values passed on the command line. + */ + if (infile == 0) { + fprintf(stderr, "%s: no input file provided.\n", prog); + usage(1); + } + /* + * Set the input filename that will be passed to the generator + * routine. + */ + if ((iname = strrchr(infile, '/'))) + iname++; + else + iname = infile; + + /* + * Check the platform and encoding IDs. + */ + if (pid < 0 || pid > 255) { + fprintf(stderr, "%s: invalid platform ID '%d'.\n", prog, pid); + exit(1); + } + if (eid < 0 || eid > 65535) { + fprintf(stderr, "%s: invalid encoding ID '%d'.\n", prog, eid); + exit(1); + } + + /* + * Arbitrarily limit the point size to a minimum of 2pt and maximum of + * 256pt. + */ + if (point_size < 2 || point_size > 256) { + fprintf(stderr, "%s: invalid point size '%dpt'.\n", prog, point_size); + exit(1); + } + + /* + * Arbitrarily limit the resolutions to a minimum of 10dpi and a maximum + * of 1200dpi. + */ + if (hres < 10 || hres > 1200) { + fprintf(stderr, "%s: invalid horizontal resolution '%ddpi'.\n", + prog, hres); + exit(1); + } + if (vres < 10 || vres > 1200) { + fprintf(stderr, "%s: invalid vertical resolution '%ddpi'.\n", + prog, vres); + exit(1); + } + + /* + * Open the output file if specified. + */ + if (outfile != 0) { + /* + * Attempt to open the output file. + */ + if ((out = fopen(outfile, "w")) == 0) { + fprintf(stderr, "%s: unable to open the output file '%s'.\n", + prog, outfile); + exit(1); + } + /* + * Set the output filename to be passed to the generator routine. + */ + if ((oname = strrchr(outfile, '/'))) + oname++; + else + oname = outfile; + } else + /* + * Set the default output file name to . + */ + oname = ""; + + /* + * Intialize Freetype. + */ + if ((res = TT_Init_FreeType(&engine))) { + /* + * Close the output file. + */ + if (out != stdout) { + fclose(out); + (void) unlink(outfile); + } + fprintf(stderr, "%s[%d]: unable to initialize renderer.\n", + prog, res); + exit(1); + } + + /* + * Open the input file. + */ + if ((res = TT_Open_Face(engine, infile, &face))) { + if (out != stdout) { + fclose(out); + (void) unlink(outfile); + } + fprintf(stderr, "%s[%d]: unable to open input file '%s'.\n", + prog, res, infile); + exit(1); + } + + /* + * Create a new instance. + */ + if ((res = TT_New_Instance(face, &instance))) { + (void) TT_Close_Face(face); + if (out != stdout) { + fclose(out); + (void) unlink(outfile); + } + fprintf(stderr, "%s[%d]: unable to create instance.\n", + prog, res); + exit(1); + } + + /* + * Set the instance resolution and point size and the relevant + * metrics. + */ + (void) TT_Set_Instance_Resolutions(instance, hres, vres); + (void) TT_Set_Instance_CharSize(instance, point_size*64); + (void) TT_Get_Instance_Metrics(instance, &imetrics); + + /* + * Get the face properties and set the global units per em value for + * convenience. + */ + (void) TT_Get_Face_Properties(face, &properties); + upm = properties.header->Units_Per_EM; + + /* + * Create a new glyph container. + */ + if ((res = TT_New_Glyph(face, &glyph))) { + (void) TT_Done_Instance(instance); + (void) TT_Close_Face(face); + if (out != stdout) { + fclose(out); + (void) unlink(outfile); + } + fprintf(stderr, "%s[%d]: unable to create glyph.\n", + prog, res); + exit(1); + } + + /* + * Generate the BDF font from the TrueType font. + */ + res = generate_bdf(out, iname, oname); + + /* + * Free up the mapping table if one was loaded. + */ + ttf2bdf_free_map(); + + /* + * Close the input and output files. + */ + (void) TT_Close_Face(face); + if (out != stdout) { + fclose(out); + if (res < 0) + /* + * An error occured when generating the font, so delete the + * output file. + */ + (void) unlink(outfile); + } + + /* + * Shut down the renderer. + */ + (void) TT_Done_FreeType(engine); + + exit(res); + + return 0; +} diff --git a/contrib/ttf2bdf/ttf2bdf.man b/contrib/ttf2bdf/ttf2bdf.man new file mode 100644 index 0000000..8ae0554 --- /dev/null +++ b/contrib/ttf2bdf/ttf2bdf.man @@ -0,0 +1,196 @@ +.\" +.\" $Id: ttf2bdf.man,v 1.14 1999/10/21 16:31:54 mleisher Exp $ +.\" +.TH TTF2BDF 1 "21 October 1999" "X Version 11" +.SH NAME +ttf2bdf \- TrueType to BDF font converter + +.SH SYNOPSIS +.B ttf2bdf +[\fIoptions\fP] [\fIfont.ttf\fP] + +.SH DESCRIPTION +.I ttf2bdf +will convert a TrueType font to a BDF font using the FreeType renderer. + +.SH OPTIONS +.I ttf2bdf +accepts the following command line arguments: + +.PP +.TP 8 +.I -v +print warning messages when the font is converted. +.PP +.TP 8 +.I -p n +set the desired point size (see default value by running the program with the +-h option). +.PP +.TP 8 +.I -r n +set both the horizontal and the vertical resolution (see default value by +running the program with the -h option). The minimum is 10dpi and the maximum +is 1200dpi. +.PP +.TP 8 +.I -rh n +set the horizontal resolution (see default value by running the program with +the -h option). The minimum is 10dpi and the maximum is 1200dpi. +.PP +.TP 8 +.I -rv n +set the vertical resolution (see default value by running the program with +the -h option). The minimum is 10dpi and the maximum is 1200dpi. +.PP +.TP 8 +.I -o outfile +sets the output filename (default output is to stdout). +.PP +.TP 8 +.I -pid id +set the platform id for selecting the character map (see default value by +running the program with the -h option). +.PP +.TP 8 +.I -eid id +set the encoding id for selecting the character map (see default value by +running the program with the -h option). +.PP +.TP 8 +.I -c c +set the character spacing. This should be one of `P' for proportional, +`M' for monospace, or `C' for character cell. By default, the spacing +of a font will be automatically determined to be either `M' or `P' +according to values provided in the font. +.PP +.TP 8 +.I -f name +set the foundry name used in the XLFD name. The default value is +`Freetype'. +.PP +.TP 8 +.I -t name +set the typeface name used in the XLFD name. By default, +.I ttf2bdf +will attempt to get a name from the font first and then it will use the +name supplied with this command line option, and if all else fails, it +will use the name `Unknown'. +.PP +.TP 8 +.I -w name +set the weight name used in the XLFD name. If this value is not +supplied, the default value is assumed to be `Medium'. Some common +values for this are `Thin', `Delicate', `ExtraLight', `Light', `Normal', +`Medium', `SemiCondensed', `Condensed', `SemiBold', `Bold', `Heavy', +`ExtraBold', and `ExtraHeavy'. +.PP +.TP 8 +.I -s name +set the slant name used in the XLFD name. If this value is not +supplied, the default value is assumed to be `R', for Roman. Some common +values for this are `R' for Roman, `I' for Italic, `O' for Oblique, `RI' +for Reverse Italic, and `RO' for Reverse Oblique. +.PP +.TP 8 +.I -k name +set the width name used in the XLFD name. The default is `Normal'. +.PP +.TP 8 +.I -d name +set the additional style name used in the XLFD name. The default is an empty +string. +.PP +.TP 8 +.I -u char +set the character used to replace the dashes/spaces in a font name. The +default is the space character. +.PP +.TP 8 +.I -l subset +define a list of character codes which will be used to select a subset +of glyphs from the font. The syntax of the subset string is the same +as the syntax for selecting subsets in X11 XLFD font names. Example: +.sp +% ttf2bdf -l '60 70 80_90' font.ttf -o font.bdf +.sp +The command above will only generate the glyphs for codes 60, 70, and 80 +through 90 inclusive. Glyphs that are not in the subset are not +generated. +.PP +.TP 8 +.I -m mapfile +specifies a mapping file which will reencode the BDF font when it is +generated. Any glyphs with codes that do not have a mapping will not +be generated. +.sp +The remapping file should begin with two lines, one which starts with +REGISTRY followed by the character set registry and one which starts +with ENCODING followed by the encoding. An example from the +iso8859.2 file: +.sp +REGISTRY ISO8859 +.br +ENCODING 2 +.sp +The remapping data should be two columns of hexadecimal numbers, separated by +spaces or tabs. The first column should have the code which should be used in +the BDF font. The second column should be the hexadecimal code of the glyph +in the "cmap" table ttf2bdf is using. An example mapping file is provided +which will map fonts from Unicode (the default "cmap" table) to ISO8859-2. +.sp +Unicode is not the only option. If you choose another platform and +encoding ID on the command line, then the remapping is assumed to map +from the chosen platform and encoding to some other character set. + +.SH "SEE ALSO" +xmbdfed(1), xfed(1), bdftopcf(1), bdftosnf(1) +.br +\fIGlyph Bitmap Distribution Format (BDF) Specification\fP, Application +Note 5005, Adobe System Inc, 1993 +.br +\fIX Logical Font Description Conventions\fP, X Consortium + +.SH ACKNOWLEDGMENTS + +The FreeType project for providing the renderer! +.br +Robert Wilhelm for pointing out a +crucial problem with the pre-1.0 code. +.br +Lho Li-Da for problem reports. +.br +Adrian Havill for unintentionally pointing out a +missing feature. +.br +Richard Verhoeven for problem reports and patches. +.br +Choi Jun Ho whose implementation provided some +nice new features. +.br +Pavel Kankovsky for providing some +critical metrics fixes and other improvements. +.br +Matti Koskinen for pointing out a problem. +.br +Eugene Bobin for mapping tables and shell scripts. +.br +Oleg N. Yakovlev for pointing out a problem. +.br +Bertrand Petit for additional functionality. +.br +Roman Czyborra for pointing out some problems. +.br +Mike Blazer for some Window's compilation advice. +.br +Solofo Ramangalahy for contributing some mapping +tables. +Antoine Leca for mapping table suggestions. +.SH AUTHOR +Mark Leisher +.br +Computing Research Lab +.br +New Mexico State University +.br +Email: mleisher@crl.nmsu.edu diff --git a/contrib/ttf2pfb/.cvsignore b/contrib/ttf2pfb/.cvsignore new file mode 100644 index 0000000..bcb2ec2 --- /dev/null +++ b/contrib/ttf2pfb/.cvsignore @@ -0,0 +1,3 @@ +t1asm +ttf2pfb +Makefile diff --git a/contrib/ttf2pfb/Makefile.emx b/contrib/ttf2pfb/Makefile.emx new file mode 100644 index 0000000..72968c8 --- /dev/null +++ b/contrib/ttf2pfb/Makefile.emx @@ -0,0 +1,16 @@ +# Makefile for ttf2pfb and t1asm + +all: ttf2pfb.exe t1asm.exe + + +ttf2pfb.exe: ttf2pfb.o + gcc -O -o ttf2pfb.exe ttf2pfb.o -lttf + +ttf2pfb.o: ttf2pfb.c + gcc -O -c ttf2pfb.c + +t1asm.exe: t1asm.o + gcc -O -o t1asm.exe t1asm.o -lttf + +t1asm.o: t1asm.c + gcc -O -c t1asm.c diff --git a/contrib/ttf2pfb/Makefile.in b/contrib/ttf2pfb/Makefile.in new file mode 100644 index 0000000..a6d42c8 --- /dev/null +++ b/contrib/ttf2pfb/Makefile.in @@ -0,0 +1,74 @@ +# Makefile for ttf2pfb +# +# This Makefile assumes that you've already built and installed +# the FreeType library. + +VPATH = @srcdir@ +srcdir = @srcdir@ + +RM = @RM@ +RMF = @RM@ -f + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = ../../libtool +MKINSTALLDIRS = $(srcdir)/../../mkinstalldirs + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ + +CFLAGS = @CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ @DEFS@ +FT_CFLAGS = $(CFLAGS) $(CPPFLAGS) +LDFLAGS = @LDFLAGS@ @LIBS@ +LIBDIR = ../../lib + +SRC = t1asm.c ttf2pfb.c + +PROGRAMS = t1asm ttf2pfb + +default all: $(PROGRAMS) + +t1asm: t1asm.c + $(CC) $(CFLAGS) -o $@ $< + +ttf2pfb: ttf2pfb.o $(LIBDIR)/libttf.la + $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o $@ $< \ + $(LIBDIR)/libttf.la $(LDFLAGS) + +clean: + $(RMF) *.o *BAK *CKP *~ a.out core + +realclean: clean + $(RMF) $(PROGRAMS) + $(RM) -rf .libs/ + +distclean: realclean + $(RMF) *~ *.orig core *.core + $(RMF) config.cache config.log config.status Makefile + +.c.o: + $(CC) -c $(FT_CFLAGS) $< + +install: $(PROGRAMS) + $(MKINSTALLDIRS) $(bindir) + for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$P $(bindir)/$$P ; \ + done + $(INSTALL_PROGRAM) $(srcdir)/getafm $(bindir)/getafm + +uninstall: + -for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=uninstall $(RM) $(bindir)/$$P ; \ + done + +.PHONY: all clean realclean distclean install uninstall + +# end of Makefile diff --git a/contrib/ttf2pfb/TODO b/contrib/ttf2pfb/TODO new file mode 100644 index 0000000..57dda25 --- /dev/null +++ b/contrib/ttf2pfb/TODO @@ -0,0 +1,40 @@ +ttf2pfb is oriented towards support for CJK fonts containing several +thousand glyphs to be splitted into subfonts with 256 characters each usable +by TeX. Nevertheless, it is quite generic and works with normal ttf files +too. + +Some features are still missing or should be added for convenience: + +. Documentation. ttf2pbf explains itself; t1asm is a filter which converts + the (disassembled) pseudo font created by ttf2pfb into a real PFA font + (or PFB if you use the `-b' command line switch). + + Example for an ordinary font: + + ttf2pfb -v -m -enc Uni-T1.enc -f FooBar -o foobar.ps foobar.ttf + t1asm -b < foobar.ps > foobar.pfb + printafm foobar.pfb > foobar.afm + afm2tfm foobar.afm + + Example for a CJK font in Big 5 encoding to be used with the CJK package + for LaTeX (note that the call creates just the first subfont): + + ttf2pfb -c -pid 3 -eid 4 -plane 1 -f FooBar01 -o foobar01.ps foobar.ttf + t1asm -b < foobar01.ps > foobar01.pfb + printafm foobar01.pfb > foobar01.afm + afm2tfm foobar01.afm + +. Inclusion of t1asm and t1binary into ttf2pfb so that ttf2pfb can directly + produce PFA and PFB files. + +. Overlapping outlines produce incorrect shapes: The overlapping areas + appear white instead of black. + +. A more flexible encoding file format (maybe similar to ttf2tfm) which can + handle glyph names. + +. [t1asm has been slightly patched to allow partial font downloading with + dvips.] + +. Note that compiling ttf2pfb with `-O2' doesn't work, most probably due to + a compiler bug (we've tested with gcc 2.7.2.1 and 2.7.2.3). diff --git a/contrib/ttf2pfb/Uni-T1.enc b/contrib/ttf2pfb/Uni-T1.enc new file mode 100644 index 0000000..2eaddb6 --- /dev/null +++ b/contrib/ttf2pfb/Uni-T1.enc @@ -0,0 +1,397 @@ +# +# This file is a hack to provide some mapping for standard (non-CJK) +# TrueType fonts. It is intended as an intermediate step towards a +# `correct' implementation as in ttf2tfm. +# +# Here, we have Unicode to LaTeX's T1 encoding. An example call would be +# +# ttf2pfb -m -enc Uni-T1.enc ... +# +# Glyph names which can't be represented in Unicode have the character code +# 0xfffe. + + +# 0x00 + +0x00: + 0x60 # /grave + 0xb4 # /acute +0x02: + 0xc6 # /circumflex + 0xdc # /tilde + +0x00: + 0xa8 # /dieresis +0x02: + 0xdd # /hungarumlaut + 0xda # /ring + 0xc7 # /caron + + 0xd8 # /breve + 0xc9 # /macron + 0xd9 # /dotaccent +0x00: + 0xb8 # /cedilla + +0x02: + 0xdb # /ogonek +0x20: + 0x1a # /quotesinglbase + 0x39 # /guilsinglleft + 0x3a # /guilsinglright + +# 0x10 + + 0x1c # /quotedblleft + 0x1d # /quotedblright + 0x1e # /quotedblbase +0x00: + 0xab # /guillemotleft + + 0xbb # /guillemotright +0x20: + 0x13 # /endash + 0x14 # /emdash +0xff: + 0xfe # /compwordmark + + 0xfe # /perthousandzero +0x01: + 0x31 # /dotlessi +0xff: + 0xfe # /dotlessj + 0xfe # /ff + +0xf0: + 0x01 # /fi + 0x02 # /fl +0xff: + 0xfe # /ffi + 0xfe # /ffl + +# 0x20 + + 0xfe # /visualspace +0x00: + 0x21 # /exclam + 0x22 # /quotedbl + 0x23 # /numbersign + + 0x24 # /dollar + 0x25 # /percent + 0x26 # /ampersand +0x20: + 0x19 # /quoteright + +0x00: + 0x28 # /parenleft + 0x29 # /parenright + 0x2a # /asterisk + 0x2b # /plus + + 0x2c # /comma + 0x2d # /hyphen + 0x2e # /period + 0x2f # /slash + +# 0x30 + + 0x30 # /zero + 0x31 # /one + 0x32 # /two + 0x33 # /three + + 0x34 # /four + 0x35 # /five + 0x36 # /six + 0x37 # /seven + + 0x38 # /eight + 0x39 # /nine + 0x3a # /colon + 0x3b # /semicolon + + 0x3c # /less + 0x3d # /equal + 0x3e # /greater + 0x3f # /question + +# 0x40 + + 0x40 # /at + 0x41 # /A + 0x42 # /B + 0x43 # /C + + 0x44 # /D + 0x45 # /E + 0x46 # /F + 0x47 # /G + + 0x48 # /H + 0x49 # /I + 0x4a # /J + 0x4b # /K + + 0x4c # /L + 0x4d # /M + 0x4e # /N + 0x4f # /O + +# 0x50 + + 0x50 # /P + 0x51 # /Q + 0x52 # /R + 0x53 # /S + + 0x54 # /T + 0x55 # /U + 0x56 # /V + 0x57 # /W + + 0x58 # /X + 0x59 # /Y + 0x5a # /Z + 0x5b # /bracketleft + + 0x5c # /backslash + 0x5d # /bracketright + 0x5e # /asciicircum + 0x5f # /underscore + +# 0x60 + +0x20: + 0x18 # /quoteleft +0x00: + 0x61 # /a + 0x62 # /b + 0x63 # /c + + 0x64 # /d + 0x65 # /e + 0x66 # /f + 0x67 # /g + + 0x68 # /h + 0x69 # /i + 0x6a # /j + 0x6b # /k + + 0x6c # /l + 0x6d # /m + 0x6e # /n + 0x6f # /o + +# 0x70 + + 0x70 # /p + 0x71 # /q + 0x72 # /r + 0x73 # /s + + 0x74 # /t + 0x75 # /u + 0x76 # /v + 0x77 # /w + + 0x78 # /x + 0x79 # /y + 0x7a # /z + 0x7b # /braceleft + + 0x7c # /bar + 0x7d # /braceright + 0x7e # /asciitilde + 0x2d # /hyphen + +# 0x80 + +0x01: + 0x02 # /Abreve + 0x04 # /Aogonek + 0x06 # /Cacute + 0x0c # /Ccaron + + 0x0e # /Dcaron + 0x1a # /Ecaron + 0x18 # /Eogonek + 0x1e # /Gbreve + + 0x39 # /Lacute + 0x3d # /Lcaron + 0x41 # /Lslash + 0x43 # /Nacute + + 0x47 # /Ncaron + 0x4a # /Eng + 0x50 # /Odblacute + 0x54 # /Racute + +# 0x90 + + 0x58 # /Rcaron + 0x5a # /Sacute + 0x60 # /Scaron + 0x5e # /Scedilla + + 0x64 # /Tcaron + 0x62 # /Tcedilla + 0x70 # /Udblacute + 0x6e # /Uring + + 0x78 # /Ydieresis + 0x79 # /Zacute + 0x7d # /Zcaron + 0x7b # /Zdot + + 0x32 # /IJ + 0x30 # /Idot + 0x11 # /dmacron +0x00: + 0xa7 # /section + +# 0xA0 + +0x01: + 0x03 # /abreve + 0x05 # /aogonek + 0x07 # /cacute + 0x0d # /ccaron + + 0x0f # /dcaron + 0x1b # /ecaron + 0x19 # /eogonek + 0x1f # /gbreve + + 0x3a # /lacute + 0x3e # /lcaron + 0x42 # /lslash + 0x44 # /nacute + + 0x48 # /ncaron + 0x4b # /eng + 0x51 # /odblacute + 0x55 # /racute + +# 0xB0 + + 0x59 # /rcaron + 0x5b # /sacute + 0x61 # /scaron + 0x5f # /scedilla + + 0x65 # /tcaron + 0x63 # /tcedilla + 0x71 # /udblacute + 0x6f # /uring + +0x00: + 0xff # /ydieresis +0x01: + 0x7a # /zacute + 0x7e # /zcaron + 0x7c # /zdot + + 0x33 # /ij +0x00: + 0xa1 # /exclamdown + 0xbf # /questiondown + 0xa3 # /sterling + +# 0xC0 + + 0xc0 # /Agrave + 0xc1 # /Aacute + 0xc2 # /Acircumflex + 0xc3 # /Atilde + + 0xc4 # /Adieresis + 0xc5 # /Aring + 0xc6 # /AE + 0xc7 # /Ccedilla + + 0xc8 # /Egrave + 0xc9 # /Eacute + 0xca # /Ecircumflex + 0xcb # /Edieresis + + 0xcc # /Igrave + 0xcd # /Iacute + 0xce # /Icircumflex + 0xcf # /Idieresis + +# 0xD0 + + 0xd0 # /Eth + 0xd1 # /Ntilde + 0xd2 # /Ograve + 0xd3 # /Oacute + + 0xd4 # /Ocircumflex + 0xd5 # /Otilde + 0xd6 # /Odieresis +0x01: + 0x52 # /OE + +0x00: + 0xd8 # /Oslash + 0xd9 # /Ugrave + 0xda # /Uacute + 0xdb # /Ucircumflex + + 0xdc # /Udieresis + 0xdd # /Yacute + 0xde # /Thorn +0xff: + 0xfe # /Germandbls + +# 0xE0 + +0x00: + 0xe0 # /agrave + 0xe1 # /aacute + 0xe2 # /acircumflex + 0xe3 # /atilde + + 0xe4 # /adieresis + 0xe5 # /aring + 0xe6 # /ae + 0xe7 # /ccedilla + + 0xe8 # /egrave + 0xe9 # /eacute + 0xea # /ecircumflex + 0xeb # /edieresis + + 0xec # /igrave + 0xed # /iacute + 0xee # /icircumflex + 0xef # /idieresis + +# 0xF0 + + 0xf0 # /eth + 0xf1 # /ntilde + 0xf2 # /ograve + 0xf3 # /oacute + + 0xf4 # /ocircumflex + 0xf5 # /otilde + 0xf6 # /odieresis +0x01: + 0x53 # /oe + +0x00: + 0xf8 # /oslash + 0xf9 # /ugrave + 0xfa # /uacute + 0xfb # /ucircumflex + + 0xfc # /udieresis + 0xfd # /yacute + 0xfe # /thorn + 0xdf # /germandbls + +#eof diff --git a/contrib/ttf2pfb/configure b/contrib/ttf2pfb/configure new file mode 100644 index 0000000..7ec8072 --- /dev/null +++ b/contrib/ttf2pfb/configure @@ -0,0 +1,1553 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=../../lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:573: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:594: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:612: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:638: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:668: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:719: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:751: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 762 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:793: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:798: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:826: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:858: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:879: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:896: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + +CFLAGS="-g -O -DDEBUG" +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 +echo "configure:943: checking for TT_Init_FreeType in -lttf" >&5 +ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lttf $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lttf" +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find ttf library! Compile FreeType first." 1>&2; exit 1; } +fi + +LIBS=$OLDLIBS + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -ansi -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1004: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1042: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 +echo "configure:1096: checking whether struct tm is in sys/time.h or time.h" >&5 +if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +int main() { +struct tm *tp; tp->tm_sec; +; return 0; } +EOF +if { (eval echo configure:1109: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_struct_tm=time.h +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_struct_tm=sys/time.h +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_struct_tm" 1>&6 +if test $ac_cv_struct_tm = sys/time.h; then + cat >> confdefs.h <<\EOF +#define TM_IN_SYS_TIME 1 +EOF + +fi + + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1131: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1144: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_hdr in unistd.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1238: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1248: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@RM@%$RM%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + diff --git a/contrib/ttf2pfb/configure.in b/contrib/ttf2pfb/configure.in new file mode 100644 index 0000000..3b02f0a --- /dev/null +++ b/contrib/ttf2pfb/configure.in @@ -0,0 +1,45 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(../../lib/freetype.h) + +AC_CANONICAL_SYSTEM + +AC_PROG_CC +AC_PROG_CPP + +CFLAGS="-g -O -DDEBUG" +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[ + AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])]) +LIBS=$OLDLIBS + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -ansi -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +AC_CHECK_PROG(RM, rm, rm) +AC_PROG_INSTALL + +AC_STRUCT_TM + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS(unistd.h) + +AC_OUTPUT(Makefile) + +dnl end of configure.in diff --git a/contrib/ttf2pfb/getafm b/contrib/ttf2pfb/getafm new file mode 100644 index 0000000..fc35c1c --- /dev/null +++ b/contrib/ttf2pfb/getafm @@ -0,0 +1,364 @@ +#!/bin/sh + +if [ $# -ne 1 ]; then + echo "usage: $0 font-name | gsnd -q - >font-name.afm" >&2 + exit 1 +fi + +cat << EOF +%! +% produce .afm for $1 +% (c) 1993 by Robert Joop +% inspired by two other versions of this theme which are +% getafm 1.00 (c) AJCD +% and getafm.ps by an unknown author, +% modified by J. Daniel Smith +% +% modified by Joachim H. Kaiser : +% - suggest a quiet gs run in usage +% - get font version info (from 'version', not 'Version') +% - add copyright field to output + +% Metrics dictionary code added by AJCD, 7/6/93 + +/getafmdict 100 dict dup begin + + /buf 256 string def + /buf2 16 string def + + /prany % dict dictname printname -> dict + { + 2 index 2 index cvn known + { + print % printname + ( ) print + 1 index exch cvn get = + } + { + (Comment /FontInfo contains no /) print + 2 copy eq + { + = % printname + pop % dictname + } + { + exch + print % dictname + (, therefore no ) print + = % printname + } + ifelse + } + ifelse + } + bind def + + /printfontname + { + (FontName)dup prany + } + bind def + + /printfontinfo + { + dup /FontInfo known + { + dup /FontInfo get + (FullName)dup prany + (FamilyName)dup prany + (Weight)dup prany + (ItalicAngle)dup prany + (isFixedPitch)(IsFixedPitch) prany + (UnderlinePosition)dup prany + (UnderlineThickness)dup prany + (version)(Version) prany + (Notice)dup prany + (Copyright)dup prany + pop + } + { + (Comment Font lacks a /FontInfo!)= + } + ifelse + } + bind def + + /prbbox % llx lly urx ury -> - + { + 4 1 roll 3 1 roll exch % swap top 4 elements + 4 { ( ) print buf cvs print } repeat + } + bind def + + /getbbox % fontdict chardict character -> fontdict chardict llx lly urx ury + { + gsave + 2 index setfont 0 0 moveto + false charpath flattenpath pathbbox + grestore + } + bind def + + /printmiscinfo + { + dup /FontBBox known + { + (FontBBox) print + dup /FontBBox get aload pop prbbox ()= + } + { + (Comment missing required /FontBBox)= + quit + } + ifelse + 2 copy exch get + dup /H known + 1 index /x known and + 1 index /d known and + 1 index /p known and + dup /looksRoman exch def + { + (CapHeight ) print + (H) getbbox + ceiling cvi = pop pop pop + (XHeight ) print + (x) getbbox + ceiling cvi = pop pop pop + (Ascender ) print + (d) getbbox + ceiling cvi = pop pop pop + (Descender ) print + (p) getbbox + pop pop floor cvi = pop + } + { + (Comment font doesn't contain H, x, d and p; therefore no CapHeight, XHeight, Ascender and Descender)= + } + ifelse + pop + dup /Encoding get + [ + [ (ISOLatin1Encoding) /ISOLatin1Encoding ] + [ (AdobeStandardEncoding) /StandardEncoding ] + ] + { + aload pop dup where + { + exch get 2 index eq + { + (EncodingScheme ) print + buf cvs = + } + { + pop + } + ifelse + } + { + pop pop + } + ifelse + } + forall + pop + } + bind def + + /printcharmetric + { + % chardictname fontdict charnamedict encoding charindex charname + + 4 index dup length dict dup begin exch + { + 1 index /FID ne + 2 index /UniqueID ne + and + { + 1 index /Encoding eq { 256 array copy } if + def + } + { pop pop } + ifelse + } + forall + end + dup /Encoding get 32 3 index put + /f2 exch definefont + setfont + + (C ) print + 1 index buf cvs print + + ( ; WX ) print +% Metrics entries are: +% 1 number: which is the character width +% an array of 2 numbers: which are the left sidebearing and width +% an array of 4 numbers: x & y left sidebearing, width and height + dup 5 index % /charname fontdict + dup /Metrics known { + /Metrics get exch 2 copy known { + get dup type /arraytype eq { + dup length 2 eq + {1 get} {2 get} ifelse + } if + round cvi buf cvs print + } { + pop pop ( ) stringwidth pop round cvi buf cvs print + } ifelse + } { + pop pop ( ) stringwidth pop round cvi buf cvs print + } ifelse + + ( ; N ) print + dup buf cvs print + + ( ; B) print + gsave + newpath 0 0 moveto + ( ) true charpath flattenpath pathbbox + grestore + 2 { ceiling cvi 4 1 roll } repeat + 2 { floor cvi 4 1 roll } repeat + prbbox + + looksRoman + { + [ + [ /f [ /i /f /l ] ] + [ /ff [ /i /l ] ] + ] + { + aload pop 1 index 3 index eq + { + { + 1 index buf cvs + length + 1 index buf2 cvs dup length + 2 index add + buf + 4 2 roll putinterval + buf 0 + 3 -1 roll getinterval + dup cvn + 7 index + exch known + { + exch + ( ; L ) print + buf2 cvs print + ( ) print + print + } + { + pop pop + } + ifelse + } + forall + pop + } + { + pop pop + } + ifelse + } + forall + } + if + pop + + ( ;)= + } + bind def + + /printcharmetrics + { + (StartCharMetrics ) print + 2 copy exch get length 1 sub buf cvs = + + 256 dict dup begin + 1 index /Encoding get + { null def } + forall + end + % chardictname fontdict charnamedict + 1 index /Encoding get + 0 1 255 + { + % encoding index + 2 copy get + dup /.notdef eq { pop } { printcharmetric } ifelse + pop % index + } for + + -1 + 3 index 5 index get + { + pop + dup /.notdef eq + { pop } + { + % chardictname fontdict charnamedict encoding charindex charname + dup 4 index exch known + { pop } + { printcharmetric } + ifelse + } + ifelse + } + forall + % charnamedict encoding index + pop pop pop + + (EndCharMetrics)= + } + bind def + + /printfontmetrics + { + (StartFontMetrics 3.0)= + (Comment Produced by getafm 3.0 (which is by rj@rainbow.in-berlin.de))= + + printfontname + printfontinfo + printmiscinfo + printcharmetrics + + (EndFontMetrics)= + } + bind def + +end def + +/getafm +{ + getafmdict begin + save exch + findfont 1000 scalefont + + null + [ /CharDefs /CharData /CharProcs /CharStrings ] + { + 2 index 1 index known { exch } if + pop + } + forall + dup null eq + { + (can't find dictionary with character data!)= + quit + } + if + exch % dictname fontdict + + printfontmetrics + + pop pop + restore + end +} +bind def + +/$1 getafm + +EOF diff --git a/contrib/ttf2pfb/t1asm.c b/contrib/ttf2pfb/t1asm.c new file mode 100644 index 0000000..5b63aab --- /dev/null +++ b/contrib/ttf2pfb/t1asm.c @@ -0,0 +1,529 @@ +/* t1asm +** +** This program `assembles' Adobe Type-1 font programs in pseudo-PostScript +** form into either PFB or PFA format. The human readable/editable input is +** charstring- and eexec-encrypted as specified in the `Adobe Type 1 Font +** Format' version 1.1 (the `black book'). There is a companion program, +** t1disasm, which `disassembles' PFB and PFA files into a pseudo-PostScript +** file. +** +** Copyright (c) 1992 by I. Lee Hetherington, all rights reserved. +** +** Permission is hereby granted to use, modify, and distribute this program +** for any purpose provided this copyright notice and the one below remain +** intact. +** +** author: I. Lee Hetherington (ilh@lcs.mit.edu) +*/ + +#ifndef lint +static char sccsid[] = + "@(#) t1asm.c 1.2 10:09:46 5/22/92"; +static char copyright[] = + "@(#) Copyright (c) 1992 by I. Lee Hetherington, all rights reserved."; +#endif + +/* Note: this is ANSI C. */ + +#include +#include +#include +#include + +#ifdef MSDOS +#define WB "wb" +#else +#define WB "w" +#endif + +#define BANNER "This is t1asm 1.2.\n" +#define LINESIZE 256 + +#define MAXBLOCKLEN ((1<<17)-6) +#define MINBLOCKLEN ((1<<8)-6) + +#define MARKER 128 +#define ASCII 1 +#define BINARY 2 +#define DONE 3 + +typedef unsigned char byte; + +static FILE *ifp = stdin; +static FILE *ofp = stdout; + +/* flags */ +static int pfb = 0; +static int active = 0; +static int start_charstring = 0; +static int in_eexec = 0; + +static char line[LINESIZE + 1]; + +/* lenIV and charstring start command */ +static int lenIV = 4; +static char cs_start[10]; + +/* for charstring buffering */ +static byte charstring_buf[65535]; +static byte *charstring_bp; + +/* for PFB block buffering */ +static byte blockbuf[MAXBLOCKLEN]; +static int blocklen = MAXBLOCKLEN; +static int blockpos = -1; +static int blocktyp = ASCII; + +/* decryption stuff */ +static unsigned short er, cr; +static unsigned short c1 = 52845, c2 = 22719; + +/* table of charstring commands */ +static struct command { + char *name; + int one, two; +} command_table[] = { + { "callothersubr", 12, 16 }, + { "callsubr", 10, -1 }, + { "closepath", 9, -1 }, + { "div", 12, 12 }, + { "dotsection", 12, 0 }, + { "endchar", 14, -1 }, + { "escape", 12, -1 }, + { "hlineto", 6, -1 }, + { "hmoveto", 22, -1 }, + { "hsbw", 13, -1 }, + { "hstem", 1, -1 }, + { "hstem3", 12, 2 }, + { "hvcurveto", 31, -1 }, + { "pop", 12, 17 }, + { "return", 11, -1 }, + { "rlineto", 5, -1 }, + { "rmoveto", 21, -1 }, + { "rrcurveto", 8, -1 }, + { "sbw", 12, 7 }, + { "seac", 12, 6 }, + { "setcurrentpoint", 12, 33 }, + { "vhcurveto", 30, -1 }, + { "vlineto", 7, -1 }, + { "vmoveto", 4, -1 }, + { "vstem", 3, -1 }, + { "vstem3", 12, 1 }, +}; /* alphabetical */ + +/* Two separate decryption functions because eexec and charstring decryption + must proceed in parallel. */ + +static byte eencrypt(byte plain) +{ + byte cipher; + + cipher = (plain ^ (er >> 8)); + er = (cipher + er) * c1 + c2; + return cipher; +} + +static byte cencrypt(byte plain) +{ + byte cipher; + + cipher = (plain ^ (cr >> 8)); + cr = (cipher + cr) * c1 + c2; + return cipher; +} + +/* This function flushes a buffered PFB block. */ + +static void output_block() +{ + int i; + + /* output four-byte block length */ + fputc(blockpos & 0xff, ofp); + fputc((blockpos >> 8) & 0xff, ofp); + fputc((blockpos >> 16) & 0xff, ofp); + fputc((blockpos >> 24) & 0xff, ofp); + + /* output block data */ + for (i = 0; i < blockpos; i++) + fputc(blockbuf[i], ofp); + + /* mark block buffer empty and uninitialized */ + blockpos = -1; +} + +/* This function outputs a single byte. If output is in PFB format then output + is buffered through blockbuf[]. If output is in PFA format, then output + will be hexadecimal if in_eexec is set, ASCII otherwise. */ + +static void output_byte(byte b) +{ + static char *hexchar = "0123456789ABCDEF"; + static int hexcol = 0; + + if (pfb) { + /* PFB */ + if (blockpos < 0) { + fputc(MARKER, ofp); + fputc(blocktyp, ofp); + blockpos = 0; + } + blockbuf[blockpos++] = b; + if (blockpos == blocklen) + output_block(); + } else { + /* PFA */ + if (in_eexec) { + /* trim hexadecimal lines to 64 columns */ + if (hexcol >= 64) { + fputc('\n', ofp); + hexcol = 0; + } + fputc(hexchar[(b >> 4) & 0xf], ofp); + fputc(hexchar[b & 0xf], ofp); + hexcol += 2; + } else { + fputc(b, ofp); + } + } +} + +/* This function outputs a byte through possible eexec encryption. */ + +static void eexec_byte(byte b) +{ + if (in_eexec) + output_byte(eencrypt(b)); + else + output_byte(b); +} + +/* This function outputs a null-terminated string through possible eexec + encryption. */ + +static void eexec_string(char *string) +{ + while (*string) + eexec_byte((byte) *string++); +} + +/* This function gets ready for the eexec-encrypted data. If output is in + PFB format then flush current ASCII block and get ready for binary block. + We start encryption with four random (zero) bytes. */ + +static void eexec_start() +{ + eexec_string(line); + if (pfb) { + output_block(); + blocktyp = BINARY; + } + + in_eexec = 1; + er = 55665; + eexec_byte(0); + eexec_byte(0); + eexec_byte(0); + eexec_byte(0); +} + +/* This function wraps-up the eexec-encrypted data and writes ASCII trailer. + If output is in PFB format then this entails flushing binary block and + starting an ASCII block. */ + +static void eexec_end() +{ + int i, j; + + if (pfb) { + output_block(); + blocktyp = ASCII; + } else { + fputc('\n', ofp); + } + in_eexec = 0; + for (i = 0; i < 7; i++) { + for (j = 0; j < 64; j++) + eexec_byte('0'); + eexec_byte('\n'); + } + eexec_string("cleartomark\n"); + if (pfb) { + output_block(); + fputc(MARKER, ofp); + fputc(DONE, ofp); + } +} + +/* This function returns an input line of characters. A line is terminated by + length (including terminating null) greater than LINESIZE, a newline \n, or + when active (looking for charstrings) by '{'. When terminated by a newline + the newline is put into line[]. When terminated by '{', the '{' is not put + into line[], and the flag start_charstring is set to 1. */ + +static void getline() +{ + int c; + char *p = line; + int comment = 0; + + start_charstring = 0; + while (p < line + LINESIZE) { + c = fgetc(ifp); + if (c == EOF) + break; + if (c == '%') + comment = 1; + if (active && !comment && c == '{') { + start_charstring = 1; + break; + } + *p++ = (char) c; + if (c == '\n') + break; + } + *p = '\0'; +} + +/* This function is used by the binary search, bsearch(), for command names in + the command table. */ + +static int command_compare(const void *key, const void *item) +{ + return strcmp((char *) key, ((struct command *) item)->name); +} + +/* This function returns 1 if the string is an integer and 0 otherwise. */ + +static int is_integer(char *string) +{ + if (isdigit(string[0]) || string[0] == '-' || string[0] == '+') { + while (*++string && isdigit(*string)) + ; /* deliberately empty */ + if (!*string) + return 1; + } + return 0; +} + +/* This function initializes charstring encryption. Note that this is called + at the beginning of every charstring. */ + +static void charstring_start() +{ + int i; + + charstring_bp = charstring_buf; + cr = 4330; + for (i = 0; i < lenIV; i++) + *charstring_bp++ = cencrypt((byte) 0); +} + +/* This function encrypts and buffers a single byte of charstring data. */ + +static void charstring_byte(v) + int v; +{ + byte b = ((unsigned int)v) & 0xff; + + if (charstring_bp - charstring_buf > sizeof(charstring_buf)) { + fprintf(stderr, "error: charstring_buf full (%d bytes)\n", + sizeof(charstring_buf)); + exit(1); + } + *charstring_bp++ = cencrypt(b); +} + +/* This function outputs buffered, encrypted charstring data through possible + eexec encryption. */ + +static void charstring_end() +{ + byte *bp; + + sprintf(line, "%d %s ", charstring_bp - charstring_buf, cs_start); + eexec_string(line); + for (bp = charstring_buf; bp < charstring_bp; bp++) + eexec_byte(*bp); +} + +/* This function generates the charstring representation of an integer. */ + +static void charstring_int(int num) +{ + int x; + + if (num >= -107 && num <= 107) { + charstring_byte(num + 139); + } else if (num >= 108 && num <= 1131) { + x = num - 108; + charstring_byte(x / 256 + 247); + charstring_byte(x % 256); + } else if (num >= -1131 && num <= -108) { + x = abs(num) - 108; + charstring_byte(x / 256 + 251); + charstring_byte(x % 256); + } else if (num >= (-2147483647-1) && num <= 2147483647) { + charstring_byte(255); + charstring_byte(num >> 24); + charstring_byte(num >> 16); + charstring_byte(num >> 8); + charstring_byte(num); + } else { + fprintf(stderr, + "error: cannot format the integer %d, too large\n", num); + exit(1); + } +} + +/* This function parses an entire charstring into integers and commands, + outputting bytes through the charstring buffer. */ + +static void parse_charstring() +{ + struct command *cp; + + charstring_start(); + while (fscanf(ifp, "%s", line) == 1) { + if (line[0] == '%') { + /* eat comment to end of line */ + while (fgetc(ifp) != '\n' && !feof(ifp)) + ; /* deliberately empty */ + continue; + } + if (line[0] == '}') + break; + if (is_integer(line)) { + charstring_int(atoi(line)); + } else { + cp = (struct command *) + bsearch((void *) line, (void *) command_table, + sizeof(command_table) / sizeof(struct command), + sizeof(struct command), + command_compare); + if (cp) { + charstring_byte(cp->one); + if (cp->two >= 0) + charstring_byte(cp->two); + } else { + fprintf(stderr, "error: cannot use `%s' in charstring\n", cp->name); + exit(1); + } + } + } + charstring_end(); +} + +static void usage() +{ + fprintf(stderr, + "usage: t1asm [-b] [-l block-length] [input [output]]\n"); + fprintf(stderr, + "\n-b means output in PFB format, otherwise PFA format.\n"); + fprintf(stderr, + "The block length applies to the length of blocks in the\n"); + fprintf(stderr, + "PFB output file; the default is to use the largest possible.\n"); + exit(1); +} + + +int main(int argc, char **argv) +{ + char *p, *q, *r; + int c; + + extern char *optarg; + extern int optind; + extern int getopt(int argc, char **argv, char *optstring); + + fprintf(stderr, "%s", BANNER); + + /* interpret command line arguments using getopt */ + while ((c = getopt(argc, argv, "bl:")) != -1) + switch (c) { + case 'b': + pfb = 1; + break; + case 'l': + blocklen = atoi(optarg); + if (blocklen < MINBLOCKLEN) { + blocklen = MINBLOCKLEN; + fprintf(stderr, + "warning: using minimum block length of %d\n", + blocklen); + } else if (blocklen > MAXBLOCKLEN) { + blocklen = MAXBLOCKLEN; + fprintf(stderr, + "warning: using maximum block length of %d\n", + blocklen); + } + break; + default: + usage(); + break; + } + if (argc - optind > 2) + usage(); + + /* possibly open input & output files */ + if (argc - optind >= 1) { + ifp = fopen(argv[optind], "r"); + if (!ifp) { + fprintf(stderr, "error: cannot open %s for reading\n", argv[1]); + exit(1); + } + } + if (argc - optind >= 2) { + ofp = fopen(argv[optind + 1], WB); + if (!ofp) { + fprintf(stderr, "error: cannot open %s for writing\n", argv[2]); + exit(1); + } + } + + /* Finally, we loop until no more input. Some special things to look for + are the `currentfile eexec' line, the beginning of the `/Subrs' + definition, the definition of `/lenIV', and the definition of the + charstring start command which has `...string currentfile...' in it. */ + + while (!feof(ifp) && !ferror(ifp)) { + getline(); + if (strcmp(line, "currentfile eexec\n") == 0) { + eexec_start(); + continue; + } else if (strstr(line, "/Subrs") && isspace(line[6])) { + active = 1; + } else if ((p = strstr(line, "/lenIV"))) { + sscanf(p, "%*s %d", &lenIV); + } else if ((p = strstr(line, "string currentfile"))) { + /* locate the name of the charstring start command */ + *p = '\0'; /* damage line[] */ + q = strrchr(line, '/'); + if (q) { + r = cs_start; + ++q; + while (!isspace(*q) && *q != '{') + *r++ = *q++; + *r = '\0'; + } + *p = 's'; /* repair line[] */ + } + /* output line data */ + eexec_string(line); + if (start_charstring) { + if (!cs_start[0]) { + fprintf(stderr, "error: couldn't find charstring start command\n"); + exit(1); + } + parse_charstring(); + } + } + eexec_end(); + + fclose(ifp); + fclose(ofp); + + return 0; +} + diff --git a/contrib/ttf2pfb/ttf2pfb.c b/contrib/ttf2pfb/ttf2pfb.c new file mode 100644 index 0000000..8295eee --- /dev/null +++ b/contrib/ttf2pfb/ttf2pfb.c @@ -0,0 +1,1725 @@ +/* + * ttf2pfb.c -- TrueType to PostScript Type 1 Font converter. + * + * Author: Chun-Yu Lee + * Maintainer: Werner Lemberg + * + * The generated output is in a raw Type 1 Font format. An encoder + * (e.g. t1asm or t1binary) is needed to convert it into PFA or PFB format. + * + * This program was adapted from the ntu2cjk package (which was part of the + * LaTeX2e CJK package (by Werner Lemberg )). + * + * + * Modified by Joachim H. Kaiser to include real glyph + * names and other font infos (see PS_Head function). + * The test programs of the FreeType distribution have been heavily used as + * templates. + * + */ + +/* + * Requirements: + * - the FreeType library. + * - t1asm or a similar converter if PFA or PFB format is required. + * - getafm or a similar program if AFM font metrics are required. + * - afm2tfm or a similar program if TFM font metrics are required. + * - for compact fonts: the CJK package for typesetting LaTeX documents. + * - dvips 5.66 or higher if self-contained PostScript document + * outputs with partially downloaded fonts are required. Note that + * the partial download code in dvips is still buggy, causing strange + * error messages during loading of the created PS fonts. + * - Ghostscript 3.33 or newer (this is optional). + */ + +#include +#include +#include +#include +#include +#include +#ifdef TM_IN_SYS_TIME +#include +#endif +#include + +#include "freetype.h" +#include "extend/ftxpost.h" /* we are in the FreeType package tree */ + +char rcsid[] = "$Id: ttf2pfb.c,v 1.13 1999/08/20 13:14:26 werner Exp $"; + + +#define PID_UNICODE 3 +#define EID_UNICODE 1 +#define PID_SJIS 3 +#define EID_SJIS 2 +#define PID_GB 3 +#define EID_GB 3 +#define PID_BIG5 3 +#define EID_BIG5 4 +#define PID_KS 3 /* KS is also called Wansung */ +#define EID_KS 5 +#define PID_JOHAB 3 +#define EID_JOHAB 6 + +/* Set default values */ +#ifndef DEFAULT_PLATFORM_ID +#define DEFAULT_PLATFORM_ID PID_UNICODE /* MS platform */ +#endif + +#ifndef DEFAULT_ENCODING_ID +#define DEFAULT_ENCODING_ID EID_UNICODE +#endif + +/* The possible values for the `force_enc' variable. */ +typedef enum enc_type_ +{ + GB = 1, Big5, JIS, KS, Johab, SJIS, X +} enc_type; + +/* A variable to enforce a certain font encoding (if > 0). */ +enc_type force_enc = 0; + + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef FAILURE +#define FAILURE -1 +#endif + + +#define LINELEN 40 /* max # of columns of code range file */ +#define NAMELEN 80 /* max length of name used from LookUp */ + + +/* + * Flags and globals + */ + +int verbose = FALSE; /* messages should be printed or not. */ +int compact = FALSE; /* generate compact font? */ +int keep = FALSE; /* keep output font in case of error? */ +int mapping = FALSE; /* use encoding file as mapping? */ +float fontShift = 0; + +#ifndef UShort +typedef unsigned short UShort; +#endif +#ifndef UChar +typedef unsigned char UChar; +#endif + +#define TT_Flag_On_Curve 1 + +/* default platform and encoding ID's. */ +int pid = DEFAULT_PLATFORM_ID; +int eid = DEFAULT_ENCODING_ID; + + +char* prog; /* program name */ + + +/* for orthogonality with fprintf */ +#define Fputs(_string_) fprintf(out, "%s\n", _string_) + + +/* Postscript font related defines and functions */ +TT_F26Dot6 lastpsx, lastpsy; + +#define Coord(x) (int)(x) +#define PS_LastPt(x, y) lastpsx = x; lastpsy = y +#define PS_Moveto(x, y) \ + fprintf(out, "%d %d rmoveto\n", \ + Coord(x - lastpsx), Coord(y - lastpsy)); \ + PS_LastPt(x, y) +#define PS_Lineto(x, y) \ + fprintf(out, "%d %d rlineto\n", \ + Coord(x - lastpsx), Coord(y - lastpsy)); \ + PS_LastPt(x, y) + + +/* + * Freetype globals. + */ + +TT_Engine engine; +TT_Face face; +TT_Instance instance; +TT_Glyph glyph; +TT_CharMap cmap; +TT_Error error; +TT_Post post; + +TT_Outline outline; +TT_Glyph_Metrics metrics; +TT_Face_Properties properties; + + +/* + * Data structures defined for encoding vectors + */ + +/* + * A code range file for the encoding vector of a font contains code + * range pairs, each pair a line. The values for the begin and end of the + * ranges are separated by ` - '. Note that the spaces before and after the + * minus sign are significant. The possible syntax is as follows: + * + * (Note that code ranges must appear in ascending order.) + * + * 1. Absolute range, i.e., the code is at least a two-byte number, e.g.: + * + * 0xA140 - 0xA17E + * 41280 - 41342 + * 0xE00000 - 0xE000FF + * + * The first two lines represent the same range. + * + * 2. Relative range, i.e., the code is a one-byte number. If the line ends + * with a colon `:', it designates the high byte(s) range, otherwise the + * low byte range. If there is no high byte(s) range declared before the low + * byte range, the last defined high byte(s) range or `0x00 - 0x00:' will be + * used. e.g.: + * + * 0xA1 - 0xFE: + * 0x40 - 0x7E + * 0xA1 - 0xFE + * + * which is Big-5 Encoding. + * + * 3. Single code. Similar to absolute or relative range but the second + * number of the range is the same as the first number. E.g.: + * + * 0xA141 == 0xA141 - 0xA141 + * 0xA1: == 0xA1 - 0xA1: + * 0xA1 == 0xA1 - 0xA1 + * + * 4. If the high byte range is declared and there is no low byte range + * declared consecutively, the assumed low byte range is `0x00 - 0xFF'. + * + * 5. Comment line. A line starting with a hash mark `#' followed by any + * characters up to the end of the line is ignored. Blank lines are also + * discarded. + */ + +typedef struct _EVHigh +{ + UShort start, end; +} EVHigh; + +typedef struct _EVLow +{ + UChar start, end; +} EVLow; + +typedef struct _EVcRange +{ + EVHigh high; + UShort numLowRanges; + EVLow* low; +} EVcRange; + +typedef struct _EncVec +{ + UShort numCodeRanges; + EVcRange* codeRange; +} EncVec; + +/* Select encoding vector with respect to pid and eid */ +EncVec* eVecMap[5][10]; + +/* Select encoding vector with respect to force_enc */ +EncVec* eVecMap_force[10]; + + +/*************/ +/* Functions */ +/*************/ + + +void +mesg(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + vfprintf(stderr, msg, ap); + va_end(ap); +} + + +/* + * Usage. + */ + +void +Usage(int eval) +{ +#ifdef DEBUG + mesg("Usage: %s [-h][-v][-c][-k][-m][-d charcode][-l][-ng][-nc]\n", prog); +#else + mesg("Usage: %s [-h][-v][-c][-k][-m]\n", prog); +#endif + mesg("\t[-pid id] [-eid id] [-force enc] [-enc file]\n"); + mesg("\t[-plane pl] [-f fname] [-uid id] [-s shift]\n"); + mesg("\t[-o output] [-ttf font.ttf | font.ttf]\n"); + mesg("-h\t\tThis message.\n"); + mesg("-v\t\tPrint messages during conversion.\n"); + mesg("-c\t\tCompact font"); + mesg(" (256 chars per font; useful for the CJK package).\n"); + mesg("-k\t\tKeep output file in case of error.\n"); + mesg("-m\t\tUse encoding file as mapping file.\n"); +#ifdef DEBUG + mesg("-d charcode\tDebug CharString for the given character code.\n"); + mesg("-l\t\tDisplay point labels.\n"); + mesg("-ng\t\tDo not show glyph outline.\n"); + mesg("-nc\t\tDo not show control paths.\n"); +#endif + mesg("-pid id\t\tSet the platform ID [%d].\n", DEFAULT_PLATFORM_ID); + mesg("-eid id\t\tSet the encoding ID [%d].\n", DEFAULT_ENCODING_ID); + mesg("\t\t(Use a strange pid,eid pair to list all possible pid,eid)\n"); + mesg("-force enc\tForce a certain encoding [none].\n"); + mesg("\t\t(Possible values are `GB', `JIS', `KS', `SJIS', and `X').\n"); + mesg("-enc file\tFile contains code ranges [none].\n"); + mesg("-plane pl\tA single font plane [0x0].\n"); + mesg("-f fname\tFont name [UNKNOWN].\n"); + mesg("-uid id\t\tUnique font ID, for private fonts 4000000-4999999 [4999999].\n"); + mesg("-s shift\tY-offset factor [%5.3f].\n", fontShift); + mesg("-o outfile\tSet the output filename [stdout].\n"); + mesg("-ttf ttfpath\tThe TTF font pathname.\n"); + + exit(eval); +} + + +void +fatal(const char *msg, + ...) +{ + va_list ap; + + va_start(ap, msg); + fprintf(stderr, "%s: ", prog); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(FAILURE); +} + + +void +fatal_error(const char *msg, + ...) +{ + va_list ap; + + va_start(ap, msg); + fprintf(stderr, "%s: Error code 0x%04lx: ", prog, error); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(FAILURE); +} + + +/* + * Reallocate a pointer. + */ + +void * +re_alloc(void* ptr, + size_t size, + char* sub) +{ + register void* value = realloc(ptr, size); + + if (value == NULL) + fatal("%s: Virtual memory exhausted", sub); + return value; +} + + +/* + * We have to introduce the `dummy' integer to assure correct handling of + * the stack. Using `UShort' as the first parameter may fail in case + * this type is promoted to a different type (as happens e.g. under + * emx for DOS). + */ + +EncVec* +Alloc_EncVec(int dummy, + ...) +{ + va_list vp; + EncVec* encVec = NULL; + EVcRange* cRange = NULL; + EVLow* evLow = NULL; + UShort numCR, numLows; + int i, j; + + va_start(vp, dummy); + numCR = va_arg(vp, UShort); + + encVec = re_alloc(encVec, 1 * sizeof (EncVec), "Alloc_EncVec"); + encVec->numCodeRanges = numCR; + + cRange = re_alloc(cRange, numCR * sizeof (EVcRange), "Alloc_EncVec"); + for (i = 0; i < numCR; i++) + { + (cRange + i)->high.start = va_arg(vp, UShort); + (cRange + i)->high.end = va_arg(vp, UShort); + (cRange + i)->numLowRanges = numLows = va_arg(vp, UShort); + evLow = NULL; + evLow = re_alloc(evLow, numLows * sizeof (EVLow), "Alloc_EncVec"); + for (j = 0; j < numLows; j++) + { + (evLow + j)->start = va_arg(vp, UChar); + (evLow + j)->end = va_arg(vp, UChar); + } + (cRange + i)->low = evLow; + } + encVec->codeRange = cRange; + + va_end(vp); + return encVec; +} + + +void +Known_Encodings(void) +{ + EncVec* encVec; + + /* Big-5 encoding */ + encVec = Alloc_EncVec(1, + 1, 0xA1, 0xFE, + 2, 0x40, 0x7E, 0xA1, 0xFE); + eVecMap[PID_BIG5][EID_BIG5] = encVec; + eVecMap_force[Big5] = encVec; + + /* GB encoding */ + encVec = Alloc_EncVec(2, + 1, 0xA1, 0xF7, + 1, 0xA1, 0xFE); + eVecMap[PID_GB][EID_GB] = encVec; + eVecMap_force[GB] = encVec; + + /* KS encoding */ + encVec = Alloc_EncVec(3, + 1, 0xA1, 0xFE, + 1, 0xA1, 0xFE); + eVecMap[PID_KS][EID_KS] = encVec; + eVecMap_force[KS] = encVec; + + /* Johab encoding */ + encVec = Alloc_EncVec(4, + 3, 0x84, 0xD3, + 2, 0x41, 0x7E, + 0x81, 0xFE, + 0xD8, 0xDE, + 2, 0x31, 0x7E, + 0x91, 0xFE, + 0xE0, 0xF9, + 2, 0x31, 0x7E, + 0x91, 0xFE); + eVecMap[PID_JOHAB][EID_JOHAB] = encVec; + eVecMap_force[Johab] = encVec; + + /* JIS encoding */ + encVec = Alloc_EncVec(5, + 1, 0xA1, 0xF4, + 1, 0xA1, 0xFE); + eVecMap_force[JIS] = encVec; + eVecMap_force[X] = encVec; /* will be internally translated to SJIS */ + + /* Unicode encoding */ + encVec = Alloc_EncVec(6, + 1, 0x00, 0xFF, + 1, 0x00, 0xFF); + eVecMap[PID_UNICODE][EID_UNICODE] = encVec; + + /* SJIS encoding */ + encVec = Alloc_EncVec(7, + 3, 0x0, 0x0, + 1, 0xA1, 0xDF, + 0x81, 0x9F, + 2, 0x40, 0x7E, + 0x80, 0xFC, + 0xE0, 0xEF, + 2, 0x40, 0x7E, + 0x80, 0xFC); + eVecMap[PID_SJIS][EID_SJIS] = encVec; + eVecMap_force[SJIS] = encVec; +} + + +/* + * Convert JIS to SJIS encoding. + */ + +UShort +JIS_to_SJIS(UShort code) +{ + UShort index; + UShort cc0 = (code >> 8) & 0xFF; + UShort cc1 = code & 0xFF; + + index = (cc0 - 0xa1) * (0xfe - 0xa1 + 1) + (cc1 - 0xa1); + cc0 = index / ((0x7e - 0x40 + 1) + (0xfc - 0x80 + 1)); + cc1 = index % ((0x7e - 0x40 + 1) + (0xfc - 0x80 + 1)); + if (cc0 < (0x9f - 0x81 + 1)) + cc0 += 0x81; + else + cc0 += 0xe0 - (0x9f - 0x81 + 1); + if (cc1 < (0x7e - 0x40 + 1)) + cc1 += 0x40; + else + cc1 += 0x80 - (0x7E - 0x40 + 1); + + return (cc0 << 8) + cc1; +} + + +/* + * Open TTF file and select cmap. + */ + +int +Init_Font_Engine(char* infile) +{ + UShort cmapindex, platformID, encodingID, num_cmap; + + if (verbose) + printf("Initializing TrueType font engine...\n"); + + /* initialization of the FreeType engine */ + error = TT_Init_FreeType(&engine); + if (error) + fatal_error("Couldn't initialize FreeType engine"); + + /* initialization of the post extension */ + error = TT_Init_Post_Extension(engine); + if (error) + fatal_error("Couldn't initialize the post extension"); + + /* open the input file */ + error = TT_Open_Face(engine, infile, &face); + if (error) + fatal_error("Unable to open input file `%s'", infile); + + /* load full post table */ + error = TT_Load_PS_Names(face, &post); + if (error) + fatal_error("Unable to load post table"); + + /* get face properties */ + TT_Get_Face_Properties(face, &properties); + + /* Load the instance. */ + error = TT_New_Instance(face, &instance); + if (error) + fatal_error("Couldn't create instance"); + + error = TT_Set_Instance_Resolutions(instance, 600, 600); + if (error) + fatal_error("Error setting resolutions"); + + error = TT_Set_Instance_CharSize(instance, 120 * 64); + if (error) + fatal_error("Error setting character size"); + + error = TT_New_Glyph(face, &glyph); + if (error) + fatal_error("Couldn't create new glyph"); + + /* Get the requested cmap. */ + num_cmap = TT_Get_CharMap_Count(face); + for (cmapindex = 0; cmapindex < num_cmap; cmapindex++) + { + TT_Get_CharMap_ID(face, cmapindex, &platformID, &encodingID); + if (platformID == pid && encodingID == eid) + break; + } + if (cmapindex == num_cmap) + { + mesg("Possible platform and encoding ID pairs:"); + for (cmapindex = 0; cmapindex < num_cmap; cmapindex++) + { + TT_Get_CharMap_ID(face, cmapindex, &platformID, &encodingID); + mesg(" (%d, %d)", platformID, encodingID); + } + mesg ("\n"); + fatal("No character map for given platform %d, encoding %d", pid, eid); + } + + /* malloc for glyph data */ + error = TT_Get_CharMap(face, cmapindex, &cmap); + if (error) + fatal_error("Cannot load cmap"); + + return TRUE; +} + + +/* + * Get font infos: name, version, copyright. + */ + +char* +LookUp_Name(int index) +{ + UShort platform, encoding, language, id; + char* string; + UShort string_len; + UShort i, n; + + n = properties.num_Names; + + for (i = 0; i < n; i++) + { + TT_Get_Name_ID(face, i, &platform, &encoding, &language, &id); + TT_Get_Name_String(face, i, &string, &string_len); + + if (id == index) + break; + } + i = (string_len > NAMELEN) ? NAMELEN : string_len; + string[i] = '\0'; + return string; +} + + +/* + * Load a glyph's outline and metrics. + */ + +int +LoadTrueTypeChar(int idx) +{ + TT_Matrix scale = {(1 << 16) / 64, 0, 0, (1 << 16) / 64}; + + error = TT_Load_Glyph(instance, glyph, idx, TTLOAD_DEFAULT); + if (error) + fatal_error("Load glyph"); + + error = TT_Get_Glyph_Outline(glyph, &outline); + if (error) + fatal_error("Get glyph outlines"); + + TT_Transform_Outline(&outline, &scale); + + error = TT_Get_Glyph_Metrics(glyph, &metrics); + if (error) + fatal_error("Get glyph_metrics"); + + return TRUE; +} + + +/* + * Get PS name of a glyph. + */ + +char* +PS_GlyphName(UShort idx, + UShort code) +{ + char *glyphname = ".notdef"; + static char CJK_glyphname[8]; + + if (compact) + { + sprintf(CJK_glyphname, "cjk%04X", code); + glyphname = CJK_glyphname; + } + else + { + if (idx) + TT_Get_PS_Name(face, idx, &glyphname); + } + + return glyphname; +} + + +/* + * Header of Type 1 font. + */ + +void +PS_Head(FILE *out, + int plane, + EncVec* planeEV, + char* font, + int UID) +{ + EVcRange* cRange = planeEV->codeRange; + UShort numCR = planeEV->numCodeRanges; + int cjk = 0, nGlyph = 0, irange; + EVLow* pLow = cRange->low; + UShort nLow = cRange->numLowRanges; + int ipl, ilow, ich; + int idx; + UShort code; + time_t curtime; + struct tm *loctime; + char text[NAMELEN]; + char fam_name[NAMELEN]; + char* version; + char fullname[NAMELEN]; + char copyright[NAMELEN]; + + /* Get the current time with local representation */ + curtime = time(NULL); + loctime = localtime(&curtime); + + /* Get font infos: family name, version, notice */ + strcpy(fullname, LookUp_Name(6)); + strcpy(fam_name, LookUp_Name(1)); + strcpy(text, LookUp_Name(5)); + version = &text[strcspn(text, "1234567890.")]; + version[strspn(version, "1234567890.")] = '\0'; + strcpy(copyright, LookUp_Name(0)); + + fprintf(out, "%%!FontType1-1.0: %s %s\n", font, version); + fprintf(out, "%%%%Creator: %s, ", prog); + fprintf(out, "%s\n", rcsid); + fprintf(out, "%%%%CreationDate: %s", asctime(loctime)); + + Fputs("%%VMusage: 030000 030000"); + Fputs("11 dict begin"); + Fputs("/FontInfo 8 dict dup begin"); + fprintf(out, "/version (%s) readonly def\n", version); + fprintf(out, "/Copyright (%s) readonly def\n", copyright); + fprintf(out, "/Notice (Plane %d) readonly def\n", plane); + fprintf(out, "/FullName (%s) readonly def\n", fullname); + fprintf(out, "/FamilyName (%s) readonly def\n", fam_name); + Fputs("/Weight (Regular) readonly def"); + Fputs("/ItalicAngle 0 def"); + Fputs("/isFixedPitch false def"); + /* Fputs("/UnderlineThickness 50 def"); */ + Fputs("end readonly def"); + fprintf(out, "/FontName /%s def\n", font); + Fputs("/PaintType 0 def"); + Fputs("/FontType 1 def"); + + if (fontShift == 0) + Fputs("/FontMatrix [0.001 0 0 0.001 0 0] readonly def"); + else + fprintf(out, "/FontMatrix [0.001 0 0 0.001 0 %5.3f] readonly def\n", + fontShift); + + Fputs("/Encoding 256 array"); + Fputs("0 1 255 {1 index exch /.notdef put} for"); + /* encoding vector */ + for (irange = 0; irange < numCR; irange++, cRange++) + { + pLow = cRange->low; + nLow = cRange->numLowRanges; + for (ipl = cRange->high.start; ipl <= cRange->high.end; ipl++) + { + if (nLow == 0) + { + nGlyph = 0x100; + for (ich = 0; ich <= 0xff; ich++) + { + code = ipl<<8 | ich; + idx = TT_Char_Index(cmap, code); + fprintf(out, "dup %d /%s put\n", ich, PS_GlyphName(idx, code)); + } + } + else + { + for (ilow = 0; ilow < nLow; ilow++, pLow++) + { + if (!compact && !mapping) + cjk = pLow->start; + nGlyph += pLow->end - pLow->start + 1; + for (ich = pLow->start; ich <= pLow->end; ich++, cjk++) + { + code = ipl<<8 | ich; + idx = TT_Char_Index(cmap, code); + fprintf(out, "dup %d /%s put\n", cjk, PS_GlyphName(idx, code)); + if (mapping && cjk == 0xFF) + goto done; + } + } + } + } + } + +done: + + Fputs("readonly def"); + Fputs("/FontBBox [0 -300 1000 1000] readonly def"); + fprintf(out, "/UniqueID %d def\n",UID); + Fputs("currentdict end"); + Fputs("currentfile eexec"); + + Fputs("dup /Private 8 dict dup begin"); + Fputs("/-| { string currentfile exch readstring pop } executeonly def"); + Fputs("/|- { noaccess def } executeonly def"); + Fputs("/| { noaccess put } executeonly def"); + Fputs("/BlueValues [ ] |-"); + Fputs("/ForceBold true def"); + Fputs("/LanguageGroup 1 def"); + Fputs("/RndStemUp false def"); + Fputs("/MinFeature{16 16} |-"); + /* Fputs("/password 5839 def"); */ + fprintf(out, "/UniqueID %d def\n",UID); + + Fputs("/Subrs 4 array"); + Fputs("dup 0 { 3 0 callothersubr pop pop setcurrentpoint return } |"); + Fputs("dup 1 { 0 1 callothersubr return } |"); + Fputs("dup 2 { 0 2 callothersubr return } |"); + Fputs("dup 3 { return } |"); + Fputs("|-"); + + fprintf(out, "2 index /CharStrings %d dict dup begin\n", nGlyph + 1); +} + + +/* + * Tail of Type 1 font. + */ + +void +PS_Tail(FILE *out) +{ + Fputs("/.notdef { 0 250 hsbw endchar } |-"); + Fputs("end end readonly put noaccess put"); + Fputs("dup /FontName get exch definefont pop"); + Fputs("mark currentfile closefile"); +} + + +/* + * Use the `rrcurveto' command on more than one `off' points. + */ + +void +PS_Curveto(FILE *out, + TT_F26Dot6 x, + TT_F26Dot6 y, + int s, + int e) +{ + int N, i; + TT_F26Dot6 sx[3], sy[3], cx[4], cy[4]; + + N = e - s + 1; + cx[0] = lastpsx; cy[0] = lastpsy; + if (s == e) + { + cx[1] = (2 * outline.points[s].x + outline.points[s - 1].x) / 3; + cy[1] = (2 * outline.points[s].y + outline.points[s - 1].y) / 3; + cx[2] = (2 * outline.points[s].x + x) / 3; + cy[2] = (2 * outline.points[s].y + y) / 3; + cx[3] = x; + cy[3] = y; + + fprintf(out, "%d %d %d %d %d %d rrcurveto\n", + Coord(cx[1] - cx[0]), Coord(cy[1] - cy[0]), + Coord(cx[2] - cx[1]), Coord(cy[2] - cy[1]), + Coord(cx[3] - cx[2]), Coord(cy[3] - cy[2])); + } + else + { + for(i = 0; i < N; i++) + { + sx[0] = (i == 0) ? + outline.points[s - 1].x : + (outline.points[i + s].x + outline.points[i + s - 1].x) / 2; + sy[0] = (i == 0) ? + outline.points[s - 1].y : + (outline.points[i + s].y + outline.points[i + s - 1].y) / 2; + sx[1] = outline.points[s + i].x; + sy[1] = outline.points[s + i].y; + sx[2] = (i == N - 1) ? + x : + (outline.points[s + i].x + outline.points[s + i + 1].x) / 2; + sy[2] = (i == N - 1) ? + y : + (outline.points[s + i].y + outline.points[s + i + 1].y) / 2; + + cx[1] = (2 * sx[1] + sx[0]) / 3; + cy[1] = (2 * sy[1] + sy[0]) / 3; + cx[2] = (2 * sx[1] + sx[2]) / 3; + cy[2] = (2 * sy[1] + sy[2]) / 3; + cx[3] = sx[2]; + cy[3] = sy[2]; + + fprintf(out, "%d %d %d %d %d %d rrcurveto\n", + Coord(cx[1] - cx[0]), Coord(cy[1] - cy[0]), + Coord(cx[2] - cx[1]), Coord(cy[2] - cy[1]), + Coord(cx[3] - cx[2]), Coord(cy[3] - cy[2])); + + cx[0] = cx[3]; + cy[0] = cy[3]; + } + } + PS_LastPt(x, y); +} + + +#ifdef DEBUG +int debug_Char_Code = 0xFFFF; +FILE* tmpout; +int showlabel = FALSE; +int no_glyph = FALSE; +int no_control= FALSE; + +#define Fputps(_msg_) fprintf(tmpout, "%s\n", _msg_) + + +void +tmp_out(FILE* tmpout) +{ + int i, j; + + Fputps("%!PS"); + Fputps("%%% CharString debugging program."); + Fputps("%%% Generated by: ttf2pfb $Revision: 1.13 $"); + Fputps("%%% plot char-string (pathes defined in /cjkxxxx)"); + Fputps(""); + Fputps("%%% user-defined parameter"); + Fputps("/scalefactor .6 def"); + Fputps("%% 0 black, 1 white"); + Fputps("/glyph-outline-gray 0 def"); + Fputps("/control-point-gray 0.7 def"); + Fputps(""); + Fputps("%%% calculate shifts and scale factor"); + Fputps("currentpagedevice /PageSize get dup"); + Fputps("0 get /pagewidth exch def"); + Fputps("1 get /pageheight exch def"); + Fputps(""); + fprintf(tmpout, + "/llx %d.0 def /lly %d.0 def /urx %d.0 def /ury %d.0 def\n", + Coord(metrics.bbox.xMin / 64), Coord(metrics.bbox.yMin / 64), + Coord(metrics.bbox.xMax / 64), Coord(metrics.bbox.yMax / 64)); + Fputps("/olwidth urx llx sub def"); + Fputps("/olheight ury lly sub def"); + Fputps(""); + Fputps("/scale scalefactor pagewidth mul olwidth div def"); + Fputps("/xshift pagewidth 1 scalefactor sub mul 2 div def"); + Fputps("/yshift pageheight olheight scale mul sub 2 div def"); + Fputps(""); + Fputps("%% save old gray-scale value"); + Fputps("/oldgray currentgray def"); + Fputps(""); + Fputps("%%% for point sequence label"); + Fputps("/TimesRoman 8 selectfont"); + Fputps("/i++ {i /i i 1 add def} def"); + Fputps("/itos {4 string cvs} def"); + Fputps("/point {2 copy i++ 3 1 roll 5 3 roll} def"); + Fputps("/drawlabel"); + Fputps(" {{moveto dup 0 eq {exit}"); + Fputps(" {itos show} ifelse} loop pop} def"); + Fputps("/nodrawlabel {clear} def"); + Fputps("/i 0 def"); + Fputps(""); + Fputps("%%% for drawing glyph paths, redefine commands used in CharString"); + Fputps("%% scaled to proper size"); + Fputps("/addr {scale mul 3 -1 roll add 3 1 roll"); + Fputps(" scale mul add exch 2 copy} def"); + if (no_glyph) + { + Fputps("/rmoveto {addr pop pop point} def"); + Fputps("/rlineto {addr pop pop point} def"); + Fputps("/rrcurveto {8 4 roll addr 8 -2 roll addr 8 -2 roll addr"); + Fputps(" 8 2 roll 6 {pop} repeat point} def"); + } + else + { + Fputps("/rmoveto {addr moveto point} def"); + Fputps("/rlineto {addr lineto point} def"); + Fputps("/rrcurveto {8 4 roll addr 8 -2 roll addr 8 -2 roll addr"); + Fputps(" 8 2 roll curveto point} def"); + } + Fputps("/hsbw {pop pop"); + Fputps(" xshift llx scale mul sub"); + Fputps(" yshift lly scale mul sub} def"); + Fputps("/endchar {stroke pop pop} def"); + Fputps(""); + Fputps("%%% for drawing control paths"); + Fputps("/T {pop lly sub scale mul yshift add exch"); + Fputps(" llx sub scale mul xshift add exch } def"); + Fputps("/mt {T 2 copy moveto} def"); + if (no_control) + Fputps("/lt {T} def"); + else + Fputps("/lt {T 2 copy lineto} def"); + Fputps(""); + Fputps("1 setlinecap 1 setlinejoin"); + Fputps("%%% draw control points and paths"); + Fputps("control-point-gray setgray"); + + for (i = 0, j = 0; i < outline.n_contours; i++) + { + Fputps(""); + fprintf(tmpout, + "%d %d %d %d mt\n", + j, + Coord(outline.points[j].x), Coord(outline.points[j].y), + outline.flags[j]); + j++; + for (; j <= outline.contours[i]; j++) + fprintf(tmpout, + "%d %d %d %d lt\n", + j, + Coord(outline.points[j].x), Coord(outline.points[j].y), + outline.flags[j]); + Fputps("closepath"); + } + Fputps("stroke"); + if (showlabel && !no_control) + Fputps("drawlabel"); + else + Fputps("nodrawlabel"); + Fputps(""); + Fputps("%%% draw glyph outlines"); + Fputps("glyph-outline-gray setgray"); + Fputps(""); +} +#endif + + +/* + * Construct CharString of a glyph. + */ + +short +PS_CharString(FILE *out, + UShort char_Code) +{ + int idx, i, j; + UShort start_offpt, end_offpt = 0, fst; +#if DEBUG + FILE* oldout = out; + int loop = 1; +#endif + + if (force_enc == X) + char_Code = JIS_to_SJIS(char_Code); + + idx = TT_Char_Index(cmap, char_Code); + if (idx == 0) + return FALSE; + + if (!LoadTrueTypeChar(idx)) + fatal("Couldn't load character with index %d (code %d)", idx, char_Code); + + if (verbose) + printf("0x%04x (%05d): %s\n", + char_Code, idx, PS_GlyphName(idx, char_Code)); + + /* Begin string */ + fprintf(out, "/%s {\n", PS_GlyphName(idx, char_Code)); + +#ifdef DEBUG + if (char_Code == debug_Char_Code) + { + tmp_out(tmpout); + out = tmpout; + loop = 0; + } + for (; loop < 2; loop++) + { +#endif + + /* coordinates are all relative to (0,0) in FreeType */ + fprintf(out, "0 %d hsbw\n", (int)(metrics.advance / 64)); + + /* Initialize ending contour point, relative coordinates */ + lastpsx = lastpsy = 0; + + for (i = 0, j = 0; i < outline.n_contours; i++) + { + fst = j; + PS_Moveto(outline.points[j].x, outline.points[j].y); + j++; + + start_offpt = 0; /* start at least 1 */ + + /* + * data pts for all contours stored in one array. + * each round j init at last j + 1 + */ + + /* + * start_offpt means start of off points. + * 0 means no off points in record. + * N means the position of the off point. + * end_offpt means the ending off point. + * lastx, lasty is the last ON point from which Curve and Line + * shall start. + */ + + /* + * start with j=0. into loop, j=1. + * if pt[1] off, if start_offpt == 0, toggle start_offpt + * next j=2. if on, now start_off != 0, run Curveto. + * if pt[1] on, start_off == 0, will run Lineto. + */ + + for (; j <= outline.contours[i]; j++) + { + if (!(outline.flags[j] & TT_Flag_On_Curve)) + { + if (!start_offpt) + start_offpt = end_offpt = j; + else + end_offpt++; + } + else + { /* On Curve */ + if (start_offpt) + { + /* + * start_offpt stuck at j, end_offpt++. + * end_offpt - start_offpt gives no of off pts. + * start_offpt gives start of sequence. + * why need outline.xCoord[j] outline.yCoord[j]? + */ + + PS_Curveto(out, + outline.points[j].x, outline.points[j].y, + start_offpt, end_offpt); + start_offpt = 0; + + /* + * also use start_offpt as indicator to save one variable!! + * after curveto, reset condition. + */ + } + else + PS_Lineto(outline.points[j].x, outline.points[j].y); + } + } + + /* + * looks like closepath fst = first, i.e. go back to first + */ + + if (start_offpt) + PS_Curveto(out, + outline.points[fst].x, outline.points[fst].y, + start_offpt, end_offpt); + else + Fputs("closepath"); + } + + Fputs("endchar"); + +#if DEBUG + out = oldout; + } + if (char_Code == debug_Char_Code) + { + if (showlabel && !no_glyph) + Fputps("drawlabel"); + else + Fputps("nodrawlabel"); + Fputps(""); + Fputps("%%% end of drawing"); + Fputps("oldgray setgray"); + Fputps("showpage"); + fclose(tmpout); + } +#endif + + Fputs(" } |-"); + return TRUE; +} + + +/* + * Get code ranges of an encoding scheme either from + * the eVecMap or a code range file. + */ + +EncVec* +Get_EncVec(FILE *enc) +{ + EncVec* encVec = NULL; + EVcRange* cRange = NULL; + EVLow* lByte = NULL; + UShort numCR = 0, numLow = 0; + int start, end; + int buflen = LINELEN, numAssigned; + char buf[LINELEN]; + + if (force_enc != 0) + return eVecMap_force[force_enc]; + + if (enc == NULL && eVecMap[pid][eid] != NULL) + return eVecMap[pid][eid]; + + /* parse each code range line */ + while (fgets(buf, buflen, enc) != NULL) + { + if (buf[0] != '#' && buf[0] != '\n') + { + if (strrchr(buf,':') != NULL) + { + /* if there is no high value declared before low value */ + if (lByte != NULL) + { + if (cRange == NULL) + { + /* default code range `0x00-0x00:' */ + cRange = re_alloc(cRange, ++numCR * sizeof (EVcRange), + "Get_EncVec"); + cRange->high.start = cRange->high.end = 0; + } + /* Assign the last low value */ + (cRange + numCR - 1)->low = lByte; + (cRange + numCR - 1)->numLowRanges = numLow; + } + + /* New high byte range */ + cRange = re_alloc(cRange, ++numCR * sizeof (EVcRange), "Get_EncVec"); + (cRange + numCR - 1)->numLowRanges = numLow = 0; + lByte = NULL; + + /* Parse code range */ + numAssigned = sscanf(buf, "%i %*40s %i", &start, &end); + if (numAssigned <= 0 || numAssigned > 2) + { + mesg("%s: Get_EncVec: Invalid high code range.\n", prog); + return NULL; + } + else + { + (cRange + numCR - 1)->high.start = start; + if (numAssigned == 1) + (cRange + numCR - 1)->high.end = start; + else + (cRange + numCR - 1)->high.end = end; + } + } + else + { + lByte = re_alloc(lByte, ++numLow * sizeof (EVLow), "Get_EncVec"); + numAssigned = sscanf(buf, "%i %*40s %i", &start, &end); + if (numAssigned <= 0 || numAssigned > 2) + { + mesg("%s: Get_EncVec: Invalid long code range.\n", prog); + return NULL; + } + else + { + (lByte + numLow - 1)->start = start; + if (numAssigned == 1) + (lByte + numLow - 1)->end = start; + else + (lByte + numLow - 1)->end = end; + } + } + } + } + + if (cRange == NULL) + { + cRange = re_alloc(cRange, ++numCR * sizeof (EVcRange), "Get_EncVec"); + cRange->high.start = cRange->high.end = 0; + cRange->numLowRanges = 0; + } + + if (lByte != NULL) + { + (cRange + numCR - 1)->low = lByte; + (cRange + numCR - 1)->numLowRanges = numLow; + } + + encVec = re_alloc(encVec, 1 * sizeof (EncVec), "Get_EncVec"); + encVec->numCodeRanges = numCR; + encVec->codeRange = cRange; + return encVec; +} + + +/* + * Match code ranges by a font plane. + */ + +EncVec* +Get_PlaneEV(EncVec* encVec, + int plane) +{ + UShort numCR = encVec->numCodeRanges; + EVcRange* cRange = encVec->codeRange; + + EncVec* encV = NULL; + EVcRange* planeCR = NULL; + EVLow* planeLow = NULL; + UShort nCR = 0, nLow = 0; + + int icr; + + if (compact) + { + int iChar = 0; /* summed # of chars */ + int nChar = (plane-1) * 256; /* the first char code ranges recorded */ + int recording = 0; + + /* if compact, plane starts from 1 to be */ + /* compatible with the CJK package */ + if (plane < 1 || plane > 99) + fatal("Get_PlaneEV: Given plane out of range"); + + for (icr = 0; icr < numCR; icr++, cRange++) + { + UShort numLow = cRange->numLowRanges; + int ipl; + + for (ipl = cRange->high.start; ipl <= cRange->high.end; ipl++) + { + EVLow* pLow = cRange->low; + int ilow; + + if (recording) + { /* if we have made a hit */ + if (planeLow != NULL) + { /* if low byte range has not been saved */ + (planeCR + nCR - 1)->low = planeLow; + (planeCR + nCR - 1)->numLowRanges = nLow; + planeLow = NULL; + } + + /* each new plane starts a EVcRange if */ + /* iChar is still less than nChar */ + if (iChar <= nChar) + { + planeCR = re_alloc(planeCR, ++nCR * sizeof (EVcRange), + "Get_PlaneEV"); + (planeCR + nCR - 1)->high.start = + (planeCR + nCR - 1)->high.end = ipl; + (planeCR + nCR - 1)->numLowRanges = nLow = 0; + } + } + + /* scan each low byte range */ + for (ilow = 0; ilow < (numLow == 0 ? 1 : numLow); ilow++, pLow++) + { + int start, end, nLowChar; + + if (numLow == 0) + { /* default range */ + start = 0x0; + end = 0xff; + } + else + { + start = pLow->start; + end = pLow->end; + } + nLowChar = end - start + 1; + if (iChar + nLowChar > nChar) + { /* a hit! */ + int bchar = start + nChar - iChar; + if (planeCR == NULL) + { + /* the first time code range is recorded */ + planeCR = re_alloc(planeCR, ++nCR * sizeof (EVcRange), + "Get_PlaneEV"); + (planeCR + nCR - 1)->high.start = ipl; + (planeCR + nCR - 1)->high.end = ipl; + } + + /* adjust range boundary */ + if (recording == 0) + start = bchar; + else + end = bchar; + nChar += 0xff; + + /* recording starts */ + recording++; + } + + iChar += nLowChar; /* next range */ + + if (recording) + { + /* a new low range */ + if (iChar <= nChar) + { + planeLow = re_alloc(planeLow, ++nLow * sizeof (EVLow), + "Get_PlaneEV"); + (planeLow + nLow - 1)->start = start; + (planeLow + nLow - 1)->end = end; + } + if (recording > 1 || iChar > nChar) + { + /* beyond recording range */ + (planeCR + nCR - 1)->numLowRanges = nLow; + (planeCR + nCR - 1)->low = planeLow; + encV = re_alloc(encV, 1 * sizeof (EncVec), "Get_PlaneEV"); + encV->numCodeRanges = nCR; + encV->codeRange = planeCR; + return encV; + } + } + } + } + } + /* we must finalize the ranges */ + if (recording) + { + (planeCR + nCR - 1)->numLowRanges = nLow; + (planeCR + nCR - 1)->low = planeLow; + encV = re_alloc(encV, 1 * sizeof (EncVec), "Get_PlaneEV"); + encV->numCodeRanges = nCR; + encV->codeRange = planeCR; + return encV; + } + } + else + { + for (icr = 0; icr < numCR; icr++, cRange++) + { + if (plane >= cRange->high.start && plane <= cRange->high.end) + { + encV = re_alloc(encV, 1 * sizeof (EncVec), "Get_PlaneEV"); + planeCR = re_alloc(planeCR, 1 * sizeof (EVcRange), "Get_PlaneEV"); + + planeCR->high.start = planeCR->high.end = plane; + planeCR->numLowRanges = cRange->numLowRanges; + planeCR->low = cRange->low; + encV->numCodeRanges = 1; + encV->codeRange = planeCR; + return encV; + } + } + } + return NULL; +} + + +/* + * The main subroutine for generating Type 1 fonts. + * One subfont per call. + */ + +short +Generate_Font(FILE *out, + int plane, + FILE *enc, + char *fname, + int UID) +{ + EncVec* encVec = Get_EncVec(enc); + EncVec* planeEncVec; + EVcRange* cRange; + UShort numCR; + UShort code; + int ilow, iplan, ichar, irange; + + if (verbose) + printf("Generating fonts...\n\n"); + + if (encVec == NULL) + return FALSE; + if (mapping) + planeEncVec = encVec; + else + if ((planeEncVec = Get_PlaneEV(encVec, plane)) == NULL) + { + mesg("%s: Can't find encoding vector for the font plane 0x%X.\n", + prog, plane); + return FALSE; + } + + /* Header of Type1 font */ + PS_Head(out, plane, planeEncVec, fname, UID); + + numCR = planeEncVec->numCodeRanges; + cRange = planeEncVec->codeRange; + + for (irange = 0; irange < numCR; irange++, cRange++) + { + EVLow* pLow = cRange->low; + UShort nLow = cRange->numLowRanges; + + for (iplan = cRange->high.start; iplan <= cRange->high.end; iplan++) + { + if (nLow == 0) + { + for (ichar = 0; ichar <= 0xff; ichar++) + { + code = iplan << 8 | ichar; + PS_CharString(out, code); + } + } + else + { + for (ilow = 0; ilow < nLow; ilow++, pLow++) + { + for (ichar = pLow->start; ichar <= pLow->end; ichar++) + { + code = iplan << 8 | ichar; + PS_CharString(out, code); + } + } + } + } + } + PS_Tail(out); + + return TRUE; +} + + +/* + * Main: process options, file I/O, etc. + */ + +int +main(int argc, + char *argv[]) +{ + char *infile, *outfile, *encFile, *fname = "UNKNOWN"; + FILE *out, *enc; + int result, plane = 0, UID = 4999999; + + if ((prog = strrchr(argv[0], '/'))) + prog++; + else + prog = argv[0]; + + /* set up known encoding vectors */ + Known_Encodings(); + + out = stdout; + enc = NULL; + infile = outfile = encFile = NULL; + + argc--; + argv++; + + while (argc > 0) + { + if (argv[0][0] == '-') + { + switch (argv[0][1]) + { + case 'v': + case 'V': + verbose = TRUE; + break; + case 'c': + case 'C': + compact = TRUE; + break; + case 'k': + case 'K': + keep = TRUE; + break; + case 'm': + case 'M': + mapping = TRUE; + break; + case 'p': + case 'P': + result = argv[0][2]; + argc--; + argv++; + if (result == 'i' || result == 'I') + { + /* Set the platform ID. Assumed upper bound is 64 */ + if ((pid = atoi(argv[0])) < 0 || pid > 64) + /* Check the platform and encoding IDs. */ + fatal("Invalid platform ID %d", pid); + } + else if (result == 'l' || result == 'L') + { + result = 0; + while (argv[0][result] == '0' && + toupper(argv[0][result + 1]) != 'X') + result++; /* no octal number */ + sscanf(&argv[0][result], "%i", &plane); + } + break; + case 'e': + case 'E': + result = argv[0][2]; + argc--; + argv++; + if (result == 'i' || result == 'I') + { + /* Set the encoding ID. */ + if ((eid = atoi(argv[0])) < 0 || eid > 64) + fatal("Invalid encoding ID %d", eid); + } + else if (result == 'n' || result == 'N') + encFile = argv[0]; + break; + case 'u': + case 'U': + argc--; + argv++; + UID = atoi(argv[0]); + break; + case 'f': + case 'F': + result = argv[0][2]; + argc--; + argv++; + if (result == '\0') + fname = argv[0]; + else if (result == 'o' || result == 'O') + { + switch (argv[0][0]) + { + case 'g': + case 'G': + force_enc = GB; + break; + case 'k': + case 'K': + force_enc = KS; + break; + case 'b': + case 'B': + force_enc = Big5; + break; + case 'j': + case 'J': + result = argv[0][1]; + if (result == 'o' || result == 'O') + force_enc = Johab; + else + force_enc = JIS; + break; + case 's': + case 'S': + force_enc = SJIS; + break; + case 'x': + case 'X': + force_enc = X; + } + } + break; + case 't': /* Get the TTF file name. */ + case 'T': + argc--; + argv++; + infile = argv[0]; + break; + case 'o': /* Set the output file name. */ + case 'O': + argc--; + argv++; + outfile = argv[0]; + break; + case 's': /* shift font bbox up or down */ + case 'S': + argc--; + argv++; + sscanf(argv[0], "%f", &fontShift); + break; +#ifdef DEBUG + case 'd': /* character code for debugging */ + case 'D': + argc--; + argv++; + sscanf(argv[0], "%i", &debug_Char_Code); + tmpout = fopen("ch-debug.ps", "wt"); + mesg("You have specified the character code 0x%04x for debugging.\n", + debug_Char_Code); + mesg("A PostScript program named `ch-debug.ps' will be created.\n"); + break; + case 'l': + case 'L': + showlabel = TRUE; + break; + case 'n': + case 'N': + result = argv[0][2]; + if (result == 'g' || result == 'G') + no_glyph = TRUE; + else if (result == 'c' || result == 'C') + no_control = TRUE; + break; +#endif + default: + Usage(1); + } + } + else + /* Set the input file name. */ + infile = argv[0]; + + argc--; + argv++; + } + + /* Open the output file if specified. */ + if (outfile != NULL) + /* Attempt to open the output file. */ + if ((out = fopen(outfile, "wt")) == 0) + { + fatal("Unable to open the output file `%s'", outfile); + exit(FAILURE); + } + + /* Validate the values passed on the command line. */ + if (infile == NULL) + { + mesg("%s: No input TTF file provided\n", prog); + Usage(1); + } + + if (encFile != NULL) + { + if ((enc = fopen(encFile, "rt")) == 0) + fatal("No input code range file"); + } + + /* Initialize font engine */ + if (!Init_Font_Engine(infile)) + { + if (out != stdout) + { + fclose(out); + if (!keep) + (void)unlink(outfile); + } + exit(FAILURE); + } + + /* Generate the disassembled PFB font from the TrueType font */ + if (Generate_Font(out, plane, enc, fname, UID)) + result = 0; + else + result = 2; + + if (out != stdout) + { + fclose(out); + if (result != 0) + { + mesg("%s: An error occurred while generating the font", prog); + if (!keep) + (void)unlink(outfile); + } + } + + TT_Close_Face(face); + TT_Done_FreeType(engine); + + exit(result); + + return 0; /* never reached */ +} + + +/* end of ttf2pfb.c */ diff --git a/contrib/ttf2pk/.cvsignore b/contrib/ttf2pk/.cvsignore new file mode 100644 index 0000000..1db72e5 --- /dev/null +++ b/contrib/ttf2pk/.cvsignore @@ -0,0 +1,8 @@ +ttf2tfm +ttf2pk +.libs +MakeSub +config.status +config.cache +config.log +Makefile diff --git a/contrib/ttf2pk/BUGS b/contrib/ttf2pk/BUGS new file mode 100644 index 0000000..af531e4 --- /dev/null +++ b/contrib/ttf2pk/BUGS @@ -0,0 +1,3 @@ + +Some characters (Arial A) have a bounding box that extends outside the +character width... such a character will get an italic correction. diff --git a/contrib/ttf2pk/MakeSub.in b/contrib/ttf2pk/MakeSub.in new file mode 100644 index 0000000..948f13b --- /dev/null +++ b/contrib/ttf2pk/MakeSub.in @@ -0,0 +1,6 @@ +# This file is part of the ttf2pk package + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ diff --git a/contrib/ttf2pk/Makefile.dm b/contrib/ttf2pk/Makefile.dm new file mode 100644 index 0000000..9c14745 --- /dev/null +++ b/contrib/ttf2pk/Makefile.dm @@ -0,0 +1,71 @@ +# Makefile for ttf2pk -- loyer@enst.fr, wl@gnu.org +# +# This Makefile assumes that you've already built and installed +# the FreeType library. +# +# It builds the ttf2pk and ttf2tfm for emx-gcc. +# +# You will need dmake. +# +# Use this file while with the following statement: +# +# dmake -r -f Makefile.dm + + +.IMPORT: COMSPEC +SHELL := $(COMSPEC) +SHELLFLAGS := /c +GROUPSHELL := $(SHELL) +GROUPFLAGS := $(SHELLFLAGS) +GROUPSUFFIX := .bat +SHELLMETAS := *"?<>&| + +CC = gcc +LIBDIR = ../../lib +INCDIR = -I$(LIBDIR) -I. + +# CFLAGS = -Wall -O2 -g $(INCDIR) -fbounds-checking -DHAVE_EMTEXDIR -DMSDOS +CFLAGS = -Wall -O2 -s $(INCDIR) -DHAVE_EMTEXDIR -DMSDOS + +SRC = case.c emdir.c emtexdir.c errormsg.c filesrch.c ligkern.c newobj.c \ + parse.c pklib.c subfont.c texenc.c tfmaux.c ttf2pk.c ttf2tfm.c \ + ttfaux.c ttfenc.c ttflib.c vplaux.c + +ttf2pkobjs = emdir.o emtexdir.o errormsg.o filesrch.o ligkern.o newobj.o \ + parse.o pklib.o subfont.o texenc.o ttf2pk.o ttfenc.o ttflib.o +ttf2tfmobjs = case.o emdir.o emtexdir.o errormsg.o filesrch.o ligkern.o \ + newobj.o parse.o subfont.o texenc.o tfmaux.o ttf2tfm.o \ + ttfaux.o ttfenc.o vplaux.o + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ @$(mktmp $(&:t"\n")\n) + + +PROGRAMS = ttf2pk.exe ttf2tfm.exe + +.PHONY: all clean distclean + + +all: $(PROGRAMS) + +ttf2pk.exe: $(ttf2pkobjs) $(LIBDIR)/libttf.a +ttf2tfm.exe: $(ttf2tfmobjs) $(LIBDIR)/libttf.a + + +clean: +-[ + del *.o +] + +distclean: clean +-[ + del dep.end + del *.exe + del core +] + +#end of Makefile.dm diff --git a/contrib/ttf2pk/Makefile.in b/contrib/ttf2pk/Makefile.in new file mode 100644 index 0000000..af7e495 --- /dev/null +++ b/contrib/ttf2pk/Makefile.in @@ -0,0 +1,116 @@ +# Makefile for ttf2pk -- loyer@enst.fr, wl@gnu.org +# +# This Makefile assumes that you've already built and installed +# the FreeType library. + +VPATH = @srcdir@ +srcdir = @srcdir@ + +RM = @RM@ +RMF = @RM@ -f +RMDIR = @RMDIR@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = ../../libtool +MKINSTALLDIRS = $(srcdir)/../../mkinstalldirs + +include MakeSub + +CFLAGS = @CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ @DEFS@ +FT_CFLAGS = $(CFLAGS) $(CPPFLAGS) +LDFLAGS = @LDFLAGS@ @LIBS@ +LIBDIR = ../../lib + +SRC = $(srcdir)/case.c \ + $(srcdir)/errormsg.c \ + $(srcdir)/filesrch.c \ + $(srcdir)/ligkern.c \ + $(srcdir)/newobj.c \ + $(srcdir)/parse.c \ + $(srcdir)/pklib.c \ + $(srcdir)/subfont.c \ + $(srcdir)/texenc.c \ + $(srcdir)/tfmaux.c \ + $(srcdir)/ttf2pk.c \ + $(srcdir)/ttf2tfm.c \ + $(srcdir)/ttfaux.c \ + $(srcdir)/ttfenc.c \ + $(srcdir)/ttflib.c \ + $(srcdir)/vplaux.c + +ttf2pkobjs = errormsg.o filesrch.o ligkern.o newobj.o parse.o pklib.o \ + subfont.o texenc.o ttf2pk.o ttfenc.o ttflib.o +ttf2tfmobjs = case.o errormsg.o filesrch.o ligkern.o newobj.o parse.o \ + subfont.o texenc.o tfmaux.o ttf2tfm.o ttfaux.o ttfenc.o \ + vplaux.o + + +.c.o: + $(CC) -c $(FT_CFLAGS) $< + + +PROGRAMS = ttf2pk ttf2tfm + +default all: $(PROGRAMS) + +ttf2pk: $(ttf2pkobjs) $(LIBDIR)/libttf.la + $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o ttf2pk $(ttf2pkobjs) \ + $(LIBDIR)/libttf.la $(LDFLAGS) + +ttf2tfm: $(ttf2tfmobjs) $(LIBDIR)/libttf.la + $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o ttf2tfm $(ttf2tfmobjs) \ + $(LIBDIR)/libttf.la $(LDFLAGS) + +install: $(PROGRAMS) + $(MKINSTALLDIRS) $(bindir) $(mandir)/man1 + for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$P $(bindir)/$$P ; \ + $(INSTALL_DATA) $(srcdir)/$$P.1 $(mandir)/man1 ; \ + done + +uninstall: + -for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=uninstall $(RM) $(bindir)/$$P ; \ + $(RMF) $(mandir)/man1/$$P.1 ; \ + done + +clean: do_clean + +distclean: do_clean + -$(RMF) dep.end $(PROGRAMS) + -$(RMF) *~ *.orig core *.core + -$(RMF) config.cache config.log config.status Makefile MakeSub + -$(RMF) .libs/* + -$(RMDIR) .libs + +do_clean: + -$(RMF) *.o + + +depend: + (echo '/^#.* PUT NO STUFF BELOW/,$$d' ; echo w ; echo q) | \ + ed - Makefile + echo '# Dependencies generated by make depend: PUT NO STUFF BELOW' \ + >> Makefile + for file in $(SRC) ; do \ + $(CPP) $(CPPFLAGS) $$file | \ + sed -n -e 's|^# [1-9][0-9]* "\([^/].*\.h\)".*|\1|p' \ + -e 's|^# [1-9][0-9]* "\($(srcdir)/.*\.h\)".*|\1|p' | \ + sed -e 's|/\./|.|g' -e "s/^/`basename $$file .c`.o: /" ; \ + done | \ + sort -u | \ + awk '{ if (LINE == 1) \ + { line = last = $$1 } \ + else if ($$1 != last) \ + { print line ; line = last = $$1 } \ + line = line " " $$2 } \ + END { print line }' >> Makefile + +# Dependencies generated by make depend: PUT NO STUFF BELOW diff --git a/contrib/ttf2pk/README b/contrib/ttf2pk/README new file mode 100644 index 0000000..a9439d7 --- /dev/null +++ b/contrib/ttf2pk/README @@ -0,0 +1,104 @@ +This directory contains ttf2tfm and ttf2pk, two utilities based on + + afm2tfm (dvipsk distribution), + gsftopkk (dvipsk distribution), + and the FreeType rasterizer for TrueType fonts. + + +Compile the FreeType library first! It is recommended to use the kpathsea +library if you want to use the programs with web2c resp. teTeX. Source files +for emTeX-like search routines are included; similarly, support for MiKTeX +file searching routines is available if `MIKTEX' is defined during +compilation. Nevertheless, as a last resort, you can compile both programs +without a search library too. + +The kpathsea library is *not* part of the ttf2pk package (see notes below). + + + +Under UNIX-like systems say + + ./configure --prefix=/usr/local/TeX --with-kpathsea-dir= + make + make install + +for a normal compilation and installation. Replace `/usr/local/TeX' with a +path to your TeX distribution. + + +[Note 1: + Try to find `libkpathsea.*' on your system. Use the directory above this + one as the argument for --with-kpathsea-dir. This should work in most + cases. If you can't find the library, you probably have a web2c package + with statically linked binaries. This means that you have to get the web2c + sources from CTAN, configure it with something like + + ./configure --prefix=/usr/local/TeX --datadir=/usr/local/TeX \ + --enable-shared --disable-static + + according to your setup; then change to the kpathsea directory and say + `make' and `make install' (Do the latter with caution not to overwrite + binaries like kpsewhich). + + It even works with the source tree from the TeX Live CD 3! You just have + to add a proper --srcdir option to the configure script. + + Unfortunately, teTeX-0.4 uses a very old kpathsea library version without + automatical shared-library support, thus you have to install the static + libraries: + + .) unpack the sources (basically you need only the contents of kpse-2.6 + and the two subdirs `kpathsea' and `make'. + + .) say + + ./configure --prefix=... + make + + in the kpse-2.6 directory + + .) say + + make install-library + + in the kpathsea subdirectory. See Note 2 also. + + DON'T USE A NEWER KPATHSEA VERSION IF YOU USE teTeX 0.4 BINARIES! Newer + kpathsea versions are not compatible with version 2.6. + + Note 2: + It seems that c-auto.h created during the kpathsea library compiling + process won't be installed for some older web2c versions. You should add + it manually, i.e., copy /kpathsea/c-auto.h to the + location where the other kpathsea header files have been installed. + + Note 3: + If you want to use the --srcdir option of the configure script, you must + compile FreeType with --srcdir too. You have to use the same directory + structure to make it work (i.e., if you have said for FreeType + `./configure --srcdir=foo', and you are in the `bar' directory, FreeType's + configure script will generate all the needed subdirs for compiling + FreeType. You've then manually to add the directory `bar/contrib/ttf2pk'; + there you should start to say ./configure --srcdir=foo/contrib/ttf2pk').] + + + +Use Makefile.dm for emx + dmake and say + + dmake -r -f Makefile.dm + +[Note: It should work with djgpp too, but I haven't tested this.] + + +ttf2pk and ttf2tfm are already part of MiKTeX. + + + +Primary author of afm2tfm: T. Rokicki, +Primary author of gsftopk: P.Vojta +Primary author of the kpathsea library, + afm2tfm/gsftopk adaptation: K. Berry. + +-- +Frederic Loyer +Werner Lemberg diff --git a/contrib/ttf2pk/TODO b/contrib/ttf2pk/TODO new file mode 100644 index 0000000..474f407 --- /dev/null +++ b/contrib/ttf2pk/TODO @@ -0,0 +1,22 @@ +. multiple configuration files similar to newer versions of gsftopk(k). + +. support for different horizontal and vertical resolutions. + +. character composition via the vpl file. + +. using GSUB for accessing small caps (if available). + +. enabling -v and -V at the same time. + +. Omega support + +. afm output + +. possibility to create `real' fonts, i.e., avoiding virtual fonts for small + caps etc. -- some dvi previewers still can't handle virtual fonts. Due to + the huge amount of work to support this it is rather unlikely that I'll do + it. + +. using hash tables to store glyph names for better performance + +. show replacement glyphs too in glyph listings diff --git a/contrib/ttf2pk/c-auto.h b/contrib/ttf2pk/c-auto.h new file mode 100644 index 0000000..efc07e6 --- /dev/null +++ b/contrib/ttf2pk/c-auto.h @@ -0,0 +1,23 @@ +/* + * c-auto.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef C_AUTO_H +#define C_AUTO_H + +/* + * We need to get kpathsea's configuration file. + */ + +#include "kpathsea/c-auto.h" + +#endif /* C_AUTO_H */ + + +/* end */ diff --git a/contrib/ttf2pk/case.c b/contrib/ttf2pk/case.c new file mode 100644 index 0000000..6bb0ce8 --- /dev/null +++ b/contrib/ttf2pk/case.c @@ -0,0 +1,179 @@ +/* + * case.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include /* for definition of NULL */ + +#include "case.h" + + +/* This is a table of uppercase/lowercase pairs which can't be deduced */ +/* by lowercasing the uppercase Adobe glyph name. */ +/* It has been extracted from the ucs2ps.um database compiled by */ +/* Bjorn Brox . */ + +Case casetable[] = +{ + {"afii10017", "afii10065"}, + {"afii10018", "afii10066"}, + {"afii10019", "afii10067"}, + {"afii10020", "afii10068"}, + {"afii10021", "afii10069"}, + {"afii10022", "afii10070"}, + {"afii10023", "afii10071"}, + {"afii10024", "afii10072"}, + {"afii10025", "afii10073"}, + {"afii10026", "afii10074"}, + {"afii10027", "afii10075"}, + {"afii10028", "afii10076"}, + {"afii10029", "afii10077"}, + {"afii10030", "afii10078"}, + {"afii10031", "afii10079"}, + {"afii10032", "afii10080"}, + {"afii10033", "afii10081"}, + {"afii10034", "afii10082"}, + {"afii10035", "afii10083"}, + {"afii10036", "afii10084"}, + {"afii10037", "afii10085"}, + {"afii10038", "afii10086"}, + {"afii10039", "afii10087"}, + {"afii10040", "afii10088"}, + {"afii10041", "afii10089"}, + {"afii10042", "afii10090"}, + {"afii10043", "afii10091"}, + {"afii10044", "afii10092"}, + {"afii10045", "afii10093"}, + {"afii10046", "afii10094"}, + {"afii10047", "afii10095"}, + {"afii10048", "afii10096"}, + {"afii10049", "afii10097"}, + {"afii10050", "afii10098"}, + {"afii10051", "afii10099"}, + {"afii10052", "afii10100"}, + {"afii10053", "afii10101"}, + {"afii10054", "afii10102"}, + {"afii10055", "afii10103"}, + {"afii10056", "afii10104"}, + {"afii10057", "afii10105"}, + {"afii10058", "afii10106"}, + {"afii10059", "afii10107"}, + {"afii10060", "afii10108"}, + {"afii10061", "afii10109"}, + {"afii10062", "afii10110"}, + {"afii10145", "afii10193"}, + {"afii10146", "afii10194"}, + {"afii10147", "afii10195"}, + {"afii10148", "afii10196"}, + {"afii10149", "afii10197"}, + {"afii10152", "afii10200"}, + {"afii10202", "afii10154"}, + {"afii10155", "afii10203"}, + {"afii10156", "afii10204"}, + {"afii10157", "afii10205"}, + {"afii10158", "afii10206"}, + {"afii10160", "afii10208"}, + {"afii10161", "afii10209"}, + {"afii10162", "afii10210"}, + {"afii10163", "afii10211"}, + {"afii10164", "afii10212"}, + {"afii10166", "afii10214"}, + {"afii10167", "afii10215"}, + {"afii10168", "afii10216"}, + {"afii10170", "afii10218"}, + {"afii10171", "afii10219"}, + {"afii10172", "afii10220"}, + {"afii10173", "afii10221"}, + {"afii10174", "afii10222"}, + {"afii10176", "afii10224"}, + {"afii10178", "afii10226"}, + {"afii10179", "afii10227"}, + {"afii10181", "afii10229"}, + {"afii10182", "afii10230"}, + {"afii10184", "afii10232"}, + {"afii10185", "afii10233"}, + {"afii10187", "afii10235"}, + {"afii10188", "afii10236"}, + {"afii10190", "afii10238"}, + {"afii10785", "afii10833"}, + {"afii10786", "afii10834"}, + {"afii10787", "afii10835"}, + {"afii10795", "afii10843"}, + {"afii10798", "afii10846"}, + {"afii10799", "afii10847"}, + {"afii10800", "afii10848"}, + {"afii10801", "afii10849"}, + {"afii64308", "afii64436"}, + {"afii10803", "afii10851"}, + {"afii10808", "afii10856"}, + {"afii10809", "afii10857"}, + {"afii10810", "afii10858"}, + {"afii10811", "afii10859"}, + {"afii10817", "afii10865"}, + {"afii10818", "afii10866"}, + {"afii10819", "afii10867"}, + {"afii10822", "afii10870"}, + {"afii10827", "afii10875"}, + {"afii10914", "afii10962"}, + {"afii10920", "afii10968"}, + {"afii10924", "afii10972"}, + {"afii10927", "afii10975"}, + {"afii10929", "afii10977"}, + {"afii10930", "afii10978"}, + {"afii10931", "afii10979"}, + {"afii10932", "afii10980"}, + {"afii10934", "afii10982"}, + {"afii10943", "afii10991"}, + {"afii10944", "afii10992"}, + {"afii10951", "afii10967"}, +/*{? "ash"} */ + {"Beta", "beta1"}, + {"Bhook", "bhooktop"}, + {"Chook", "chooktop"}, +/*{"Oopen" "cturn" ?} */ + {"Dbar1", "dbar"}, + {"Dhook", "dhooktop"}, + {"Dmacron", "dmacron3"}, + {"Dslash", "dmacron"}, + {"I", "dotlessi"}, + {"J", "dotlessj"}, +/*{"Dbar", "drighttail" ?} */ +/*{"Dbar" "drthook" ?} */ +/*{"Dslash", ?} */ + {"Fhook", "fscript"}, + {"Ghook", "ghooktop"}, + {"Ibar", "ibarred"}, + {"I", "iundotted"}, + {"Kappa", "kappa1"}, + {"Khook", "khooktop"}, + {"S", "longs"}, + {"mcapturn", "mturn"}, + {"mcapturn", "mturned"}, + {"Mu", "mu1"}, + {"Nhook", "nlefthookatleft"}, + {"Nhook", "nlftlfthook"}, + {"Obar", "obarred"}, + {"Pi", "omega1"}, + {"Phi", "phi1"}, + {"Phi", "philatin"}, + {"Pi", "pi1"}, + {"Rho", "rho1"}, + {"Sigma", "sigma1"}, + {"Sigma", "sigmafinal"}, + {"Sigma", "sigmalunate"}, + {"S", "slong"}, + {"Theta", "theta1"}, + {"Thook", "thooktop"}, + {"Trthook", "trighttail"}, + {"Upsilon2", "upsilon"}, + {"Vcursive", "vscript"}, + {NULL, NULL} +}; + + +/* end */ diff --git a/contrib/ttf2pk/case.h b/contrib/ttf2pk/case.h new file mode 100644 index 0000000..ad39ef7 --- /dev/null +++ b/contrib/ttf2pk/case.h @@ -0,0 +1,27 @@ +/* + * case.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef CASE_H +#define CASE_H + +struct _Case +{ + char *upper; + char *lower; +}; +typedef struct _Case Case; + + +extern Case casetable[]; + +#endif /* CASE_H */ + + +/* end */ diff --git a/contrib/ttf2pk/configure b/contrib/ttf2pk/configure new file mode 100644 index 0000000..4f7bff9 --- /dev/null +++ b/contrib/ttf2pk/configure @@ -0,0 +1,1700 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-kpathsea-dir=DIR Location of the kpathsea base dir (/usr/local)" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=../../lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:575: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:596: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:614: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:640: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:670: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:721: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:753: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 764 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:795: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:800: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:828: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:860: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:881: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:915: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + +# Check whether --with-kpathsea-dir or --without-kpathsea-dir was given. +if test "${with_kpathsea_dir+set}" = set; then + withval="$with_kpathsea_dir" + + if test x$withval = xyes; then + echo "configure: warning: Usage is: --with-kpathsea-dir=basedir" 1>&2 + else + if test x$withval = xno; then + echo "configure: warning: Usage is: --with-kpathsea-dir=basedir" 1>&2 + else + kpathsea_dir=$withval + fi + fi + +fi + + +if test -n "$kpathsea_dir"; then + LIBS="$LIBS -L$kpathsea_dir/lib" + CPPFLAGS="$CPPFLAGS -I$kpathsea_dir/include -I$srcdir" + + echo $ac_n "checking for kpse_set_program_name in -lkpathsea""... $ac_c" 1>&6 +echo "configure:962: checking for kpse_set_program_name in -lkpathsea" >&5 +ac_lib_var=`echo kpathsea'_'kpse_set_program_name | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lkpathsea $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + +else + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define OLD_KPATHSEA 1 +EOF + +fi + + + echo $ac_n "checking for kpse_init_prog in -lkpathsea""... $ac_c" 1>&6 +echo "configure:1007: checking for kpse_init_prog in -lkpathsea" >&5 +ac_lib_var=`echo kpathsea'_'kpse_init_prog | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lkpathsea $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo kpathsea | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 + + { echo "configure: error: Can't find kpathsea library! Use --with-kpathsea-dir option." 1>&2; exit 1; } +fi + + + ac_safe=`echo "kpathsea/kpathsea.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for kpathsea/kpathsea.h""... $ac_c" 1>&6 +echo "configure:1058: checking for kpathsea/kpathsea.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1068: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + +else + echo "$ac_t""no" 1>&6 +cat >> confdefs.h <<\EOF +#define VERY_OLD_KPATHSEA 1 +EOF + +fi + + + ac_safe=`echo "kpathsea/c-auto.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for kpathsea/c-auto.h""... $ac_c" 1>&6 +echo "configure:1096: checking for kpathsea/c-auto.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1106: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find kpathsea include files! Use --with-kpathsea-dir option." 1>&2; exit 1; } +fi + +else + CPPFLAGS="$CPPFLAGS -I$srcdir" +fi + +echo $ac_n "checking for floor in -lm""... $ac_c" 1>&6 +echo "configure:1134: checking for floor in -lm" >&5 +ac_lib_var=`echo m'_'floor | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lm $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 +echo "configure:1181: checking for gettext in -lintl" >&5 +ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo intl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 +echo "configure:1232: checking for TT_Init_FreeType in -lttf" >&5 +ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lttf $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lttf" +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find ttf library! Compile FreeType first." 1>&2; exit 1; } +fi + +LIBS=$OLDLIBS + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1293: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Extract the first word of "rmdir", so it can be a program name with args. +set dummy rmdir; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1322: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RMDIR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RMDIR"; then + ac_cv_prog_RMDIR="$RMDIR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RMDIR="rmdir" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RMDIR="$ac_cv_prog_RMDIR" +if test -n "$RMDIR"; then + echo "$ac_t""$RMDIR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1360: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +if test -z "$kpathsea_dir"; then + echo "configure: warning: + + The binaries will be compiled without file search library support! + For kpathsea support use the --with-kpathsea-dir option. + " 1>&2 +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile MakeSub" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@RM@%$RM%g +s%@RMDIR@%$RMDIR%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + diff --git a/contrib/ttf2pk/configure.in b/contrib/ttf2pk/configure.in new file mode 100644 index 0000000..44ae470 --- /dev/null +++ b/contrib/ttf2pk/configure.in @@ -0,0 +1,87 @@ +dnl This file is part of the ttf2pk package + +dnl Process this file with autoconf to produce a configure script. + +dnl Some tests are omitted since we assume that you've built the +dnl FreeType library successfully. + +AC_INIT(../../lib/freetype.h) + +AC_CANONICAL_SYSTEM + +AC_PROG_CC +AC_PROG_CPP + +AC_ARG_WITH(kpathsea-dir, + [ --with-kpathsea-dir=DIR Location of the kpathsea base dir (/usr/local)],[ + if test x$withval = xyes; then + AC_MSG_WARN(Usage is: --with-kpathsea-dir=basedir) + else + if test x$withval = xno; then + AC_MSG_WARN(Usage is: --with-kpathsea-dir=basedir) + else + kpathsea_dir=$withval + fi + fi +]) + +if test -n "$kpathsea_dir"; then + LIBS="$LIBS -L$kpathsea_dir/lib" + CPPFLAGS="$CPPFLAGS -I$kpathsea_dir/include -I$srcdir" + + dnl the function kpse_set_program_name() is available since kpathsea 3.2 + AC_CHECK_LIB(kpathsea, kpse_set_program_name, [[]], AC_DEFINE(OLD_KPATHSEA)) + + AC_CHECK_LIB(kpathsea, kpse_init_prog, ,[ + AC_MSG_ERROR([Can't find kpathsea library! Use --with-kpathsea-dir option.])]) + + dnl the header file kpathsea.h doesn't exist in kpathsea 2.6 and before + AC_CHECK_HEADER(kpathsea/kpathsea.h, [[]], AC_DEFINE(VERY_OLD_KPATHSEA)) + + AC_CHECK_HEADER(kpathsea/c-auto.h, ,[ + AC_MSG_ERROR([Can't find kpathsea include files! Use --with-kpathsea-dir option.])]) +else + CPPFLAGS="$CPPFLAGS -I$srcdir" +fi + +AC_CHECK_LIB(m, floor) +AC_CHECK_LIB(intl, gettext) + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[ + AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])]) +LIBS=$OLDLIBS + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +AC_CHECK_PROG(RM, rm, rm) +AC_CHECK_PROG(RMDIR, rmdir, rmdir) +AC_PROG_INSTALL + +if test -z "$kpathsea_dir"; then + AC_MSG_WARN([ + + The binaries will be compiled without file search library support! + For kpathsea support use the --with-kpathsea-dir option. + ]) +fi + +AC_OUTPUT(Makefile MakeSub) + +dnl end of configure.in diff --git a/contrib/ttf2pk/data/Big5.sfd b/contrib/ttf2pk/data/Big5.sfd new file mode 100644 index 0000000..54a2e60 --- /dev/null +++ b/contrib/ttf2pk/data/Big5.sfd @@ -0,0 +1,65 @@ +# Big5.sfd +# +# subfont numbers for Big 5 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. + +01 0xA140_0xA17E 0xA1A1_0xA1FE 0xA240_0xA27E 0xA2A1_0xA2C4 +02 0xA2C5_0xA2FE 0xA340_0xA37E 0xA3A1_0xA3FE 0xA440_0xA468 +03 0xA469_0xA47E 0xA4A1_0xA4FE 0xA540_0xA57E 0xA5A1_0xA5ED +04 0xA5EE_0xA5FE 0xA640_0xA67E 0xA6A1_0xA6FE 0xA740_0xA77E 0xA7A1_0xA7B3 +05 0xA7B4_0xA7FE 0xA840_0xA87E 0xA8A1_0xA8FE 0xA940_0xA957 +06 0xA958_0xA97E 0xA9A1_0xA9FE 0xAA40_0xAA7E 0xAAA1_0xAADC +07 0xAADD_0xAAFE 0xAB40_0xAB7E 0xABA1_0xABFE 0xAC40_0xAC7E 0xACA1_0xACA2 +08 0xACA3_0xACFE 0xAD40_0xAD7E 0xADA1_0xADFE 0xAE40_0xAE46 +09 0xAE47_0xAE7E 0xAEA1_0xAEFE 0xAF40_0xAF7E 0xAFA1_0xAFCB +10 0xAFCC_0xAFFE 0xB040_0xB07E 0xB0A1_0xB0FE 0xB140_0xB16F +11 0xB170_0xB17E 0xB1A1_0xB1FE 0xB240_0xB27E 0xB2A1_0xB2F4 +12 0xB2F5_0xB2FE 0xB340_0xB37E 0xB3A1_0xB3FE 0xB440_0xB47E 0xB4A1_0xB4BA +13 0xB4BB_0xB4FE 0xB540_0xB57E 0xB5A1_0xB5FE 0xB640_0xB65E +14 0xB65F_0xB67E 0xB6A1_0xB6FE 0xB740_0xB77E 0xB7A1_0xB7E3 +15 0xB7E4_0xB7FE 0xB840_0xB87E 0xB8A1_0xB8FE 0xB940_0xB97E 0xB9A1_0xB9A9 +16 0xB9AA_0xB9FE 0xBA40_0xBA7E 0xBAA1_0xBAFE 0xBB40_0xBB4D +17 0xBB4E_0xBB7E 0xBBA1_0xBBFE 0xBC40_0xBC7E 0xBCA1_0xBCD2 +18 0xBCD3_0xBCFE 0xBD40_0xBD7E 0xBDA1_0xBDFE 0xBE40_0xBE76 +19 0xBE77_0xBE7E 0xBEA1_0xBEFE 0xBF40_0xBF7E 0xBFA1_0xBFFB +20 0xBFFC_0xBFFE 0xC040_0xC07E 0xC0A1_0xC0FE 0xC140_0xC17E 0xC1A1_0xC1C1 +21 0xC1C2_0xC1FE 0xC240_0xC27E 0xC2A1_0xC2FE 0xC340_0xC365 +22 0xC366_0xC37E 0xC3A1_0xC3FE 0xC440_0xC47E 0xC4A1_0xC4EA +23 0xC4EB_0xC4FE 0xC540_0xC57E 0xC5A1_0xC5FE 0xC640_0xC67E 0xC6A1_0xC6B0 +24 0xC6B1_0xC6FE 0xC740_0xC77E 0xC7A1_0xC7FE 0xC840_0xC854 +25 0xC855_0xC87E 0xC8A1_0xC8FE 0xC940_0xC97E 0xC9A1_0xC9D9 +26 0xC9DA_0xC9FE 0xCA40_0xCA7E 0xCAA1_0xCAFE 0xCB40_0xCB7D +27 0xCB7E 0xCBA1_0xCBFE 0xCC40_0xCC7E 0xCCA1_0xCCFE 0xCD40_0xCD43 +28 0xCD44_0xCD7E 0xCDA1_0xCDFE 0xCE40_0xCE7E 0xCEA1_0xCEC8 +29 0xCEC9_0xCEFE 0xCF40_0xCF7E 0xCFA1_0xCFFE 0xD040_0xD06C +30 0xD06D_0xD07E 0xD0A1_0xD0FE 0xD140_0xD17E 0xD1A1_0xD1F1 +31 0xD1F2_0xD1FE 0xD240_0xD27E 0xD2A1_0xD2FE 0xD340_0xD37E 0xD3A1_0xD3B7 +32 0xD3B8_0xD3FE 0xD440_0xD47E 0xD4A1_0xD4FE 0xD540_0xD55B +33 0xD55C_0xD57E 0xD5A1_0xD5FE 0xD640_0xD67E 0xD6A1_0xD6E0 +34 0xD6E1_0xD6FE 0xD740_0xD77E 0xD7A1_0xD7FE 0xD840_0xD87E 0xD8A1_0xD8A6 +35 0xD8A7_0xD8FE 0xD940_0xD97E 0xD9A1_0xD9FE 0xDA40_0xDA4A +36 0xDA4B_0xDA7E 0xDAA1_0xDAFE 0xDB40_0xDB7E 0xDBA1_0xDBCF +37 0xDBD0_0xDBFE 0xDC40_0xDC7E 0xDCA1_0xDCFE 0xDD40_0xDD73 +38 0xDD74_0xDD7E 0xDDA1_0xDDFE 0xDE40_0xDE7E 0xDEA1_0xDEF8 +39 0xDEF9_0xDEFE 0xDF40_0xDF7E 0xDFA1_0xDFFE 0xE040_0xE07E 0xE0A1_0xE0BE +40 0xE0BF_0xE0FE 0xE140_0xE17E 0xE1A1_0xE1FE 0xE240_0xE262 +41 0xE263_0xE27E 0xE2A1_0xE2FE 0xE340_0xE37E 0xE3A1_0xE3E7 +42 0xE3E8_0xE3FE 0xE440_0xE47E 0xE4A1_0xE4FE 0xE540_0xE57E 0xE5A1_0xE5AD +43 0xE5AE_0xE5FE 0xE640_0xE67E 0xE6A1_0xE6FE 0xE740_0xE751 +44 0xE752_0xE77E 0xE7A1_0xE7FE 0xE840_0xE87E 0xE8A1_0xE8D6 +45 0xE8D7_0xE8FE 0xE940_0xE97E 0xE9A1_0xE9FE 0xEA40_0xEA7A +46 0xEA7B_0xEA7E 0xEAA1_0xEAFE 0xEB40_0xEB7E 0xEBA1_0xEBFE 0xEC40 +47 0xEC41_0xEC7E 0xECA1_0xECFE 0xED40_0xED7E 0xEDA1_0xEDC5 +48 0xEDC6_0xEDFE 0xEE40_0xEE7E 0xEEA1_0xEEFE 0xEF40_0xEF69 +49 0xEF6A_0xEF7E 0xEFA1_0xEFFE 0xF040_0xF07E 0xF0A1_0xF0EE +50 0xF0EF_0xF0FE 0xF140_0xF17E 0xF1A1_0xF1FE 0xF240_0xF27E 0xF2A1_0xF2B4 +51 0xF2B5_0xF2FE 0xF340_0xF37E 0xF3A1_0xF3FE 0xF440_0xF458 +52 0xF459_0xF47E 0xF4A1_0xF4FE 0xF540_0xF57E 0xF5A1_0xF5DD +53 0xF5DE_0xF5FE 0xF640_0xF67E 0xF6A1_0xF6FE 0xF740_0xF77E 0xF7A1_0xF7A3 +54 0xF7A4_0xF7FE 0xF840_0xF87E 0xF8A1_0xF8FE 0xF940_0xF947 +55 0xF948_0xF97E 0xF9A1_0xF9FE 0xFA40_0xFA7E 0xFAA1_0xFACC +56 0xFACD_0xFAFE 0xFB40_0xFB7E 0xFBA1_0xFBFE 0xFC40_0xFC70 +57 0xFC71_0xFC7E 0xFCA1_0xFCFE 0xFD40_0xFD7E 0xFDA1_0xFDF5 +58 0xFDF6_0xFDFE 0xFE40_0xFE7E 0xFEA1_0xFEFE + +# eof diff --git a/contrib/ttf2pk/data/ET5.enc b/contrib/ttf2pk/data/ET5.enc new file mode 100644 index 0000000..dc47f88 --- /dev/null +++ b/contrib/ttf2pk/data/ET5.enc @@ -0,0 +1,119 @@ +% ET5.enc +% +% +% This is LaTeX ET5 encoding for Vietnamese. +% +% +% LIGKERN question quoteleft =: questiondown ; +% LIGKERN exclam quoteleft =: exclamdown ; +% LIGKERN hyphen hyphen =: endash ; +% LIGKERN endash hyphen =: emdash ; +% LIGKERN quoteleft quoteleft =: quotedblleft ; +% LIGKERN quoteright quoteright =: quotedblright ; +% LIGKERN comma comma =: quotedblbase ; +% +% LIGKERN f i =: fi ; +% LIGKERN f l =: fl ; +% LIGKERN f f =: ff ; +% LIGKERN ff i =: ffi ; +% LIGKERN ff l =: ffl ; +% +% We blow away kerns to and from spaces (TeX doesn't have a +% space) and also remove any kerns from the numbers. +% +% LIGKERN space {} * ; * {} space ; +% LIGKERN zero {} * ; * {} zero ; +% LIGKERN one {} * ; * {} one ; +% LIGKERN two {} * ; * {} two ; +% LIGKERN three {} * ; * {} three ; +% LIGKERN four {} * ; * {} four ; +% LIGKERN five {} * ; * {} five ; +% LIGKERN six {} * ; * {} six ; +% LIGKERN seven {} * ; * {} seven ; +% LIGKERN eight {} * ; * {} eight ; +% LIGKERN nine {} * ; * {} nine ; + +/ET5encoding [ +% 0x00 + /Abrevehookabove /Abrevetilde /Acircumflextilde /Yhookabove + /Ytilde /Ydotbelow /Sigma /Upsilon + /Phi /Psi /Omega /ff + /fi /fl /ffi /ffl +% 0x10 + /dotlessi /dotlessj /grave /acute + /caron /breve /macron /ring + /cedilla /germandbls /ae /oe + /oslash /AE /OE /Oslash +% 0x20 + /.notdef /exclam /quotedblright /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus + /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three + /four /five /six /seven + /eight /nine /colon /semicolon + /exclamdown /equal /questiondown /question +% 0x40 + /at /A /B /C + /D /E /F /G + /H /I /J /K + /L /M /N /O +% 0x50 + /P /Q /R /S + /T /U /V /W + /X /Y /Z /bracketleft + /quotedblleft /bracketright /circumflex /dotaccent +% 0x60 + /quoteleft /a /b /c + /d /e /f /g + /h /i /j /k + /l /m /n /o +% 0x70 + /p /q /r /s + /t /u /v /w + /x /y /z /endash + /emdash /hungarumlaut /tilde /dieresis +% 0x80 + /Adotbelow /Abreveacute /Abrevegrave /Abrevedotbelow + /Acircumflexacute /Acircumflexgrave /Acircumflexhookabove /Acircumflexdotbelow + /Etilde /Edotbelow /Ecircumflexacute /Ecircumflexgrave + /Ecircumflexhookabove /Ecircumflextilde /Ecircumflexdotbelow /Ocircumflexacute +% 0x90 + /Ocircumflexgrave /Ocircumflexhookabove /Ocircumflextilde /Ocircumflexdotbelow + /Ohorndotbelow /Ohornacute /Ohorngrave /Ohornhookabove + /Idotbelow /Ohookabove /Odotbelow /Ihookabove + /Uhookabove /Utilde /Udotbelow /Ygrave +% 0xA0 + /Otilde /abreveacute /abrevegrave /abrevedotbelow + /acircumflexacute /acircumflexgrave /acircumflexhookabove /acircumflexdotbelow + /etilde /edotbelow /ecircumflexacute /ecircumflexgrave + /ecircumflexhookabove /ecircumflextilde /ecircumflexdotbelow /ocircumflexacute +% 0xB0 + /ocircumflexgrave /ocircumflexhookabove /ocircumflextilde /Ohorntilde + /Ohorn /ocircumflexdotbelow /ohorngrave /ohornhookabove + /idotbelow /Uhorndotbelow /Uhornacute /Uhorngrave + /Uhornhookabove /ohorn /ohornacute /Uhorn +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde + /Ahookabove /Abreve /abrevehookabove /abrevetilde + /Egrave /Eacute /Ecircumflex /Ehookabove + /Igrave /Iacute /Itilde /ygrave +% 0xD0 + /Dbar /uhornacute /Ograve /Oacute + /Ocircumflex /adotbelow /yhookabove /uhorngrave + /uhornhookabove /Ugrave /Uacute /ytilde + /ydotbelow /Yacute /ohorntilde /uhorn +% 0xE0 + /agrave /aacute /acircumflex /atilde + /ahookabove /abreve /uhorntilde /acircumflextilde + /egrave /eacute /ecircumflex /ehookabove + /igrave /iacute /itilde /ihookabove +% 0xF0 + /dbar /uhorndotbelow /ograve /oacute + /ocircumflex /otilde /ohookabove /odotbelow + /udotbelow /ugrave /uacute /utilde + /uhookabove /yacute /ohorndotbelow /Uhorntilde +] def + +% eof diff --git a/contrib/ttf2pk/data/EUC.sfd b/contrib/ttf2pk/data/EUC.sfd new file mode 100644 index 0000000..5a148da --- /dev/null +++ b/contrib/ttf2pk/data/EUC.sfd @@ -0,0 +1,49 @@ +# EUC.sfd +# +# subfont numbers for character sets in EUC encoding and its corresponding +# code ranges to be used with the CJK package for LaTeX. +# +# Examples for such character sets: +# +# GB 2312-1980, +# KS X 1001:1992 (=KS C 5601-1992), +# JIS X 0208:1997, +# CNS 11643-1992 planes 1-7. + +01 0xA1A1_0xA1FE 0xA2A1_0xA2FE 0xA3A1_0xA3E4 +02 0xA3E5_0xA3FE 0xA4A1_0xA4FE 0xA5A1_0xA5FE 0xA6A1_0xA6CA +03 0xA6CB_0xA6FE 0xA7A1_0xA7FE 0xA8A1_0xA8FE 0xA9A1_0xA9B0 +04 0xA9B1_0xA9FE 0xAAA1_0xAAFE 0xABA1_0xABF4 +05 0xABF5_0xABFE 0xACA1_0xACFE 0xADA1_0xADFE 0xAEA1_0xAEDA +06 0xAEDB_0xAEFE 0xAFA1_0xAFFE 0xB0A1_0xB0FE 0xB1A1_0xB1C0 +07 0xB1C1_0xB1FE 0xB2A1_0xB2FE 0xB3A1_0xB3FE 0xB4A1_0xB4A6 +08 0xB4A7_0xB4FE 0xB5A1_0xB5FE 0xB6A1_0xB6EA +09 0xB6EB_0xB6FE 0xB7A1_0xB7FE 0xB8A1_0xB8FE 0xB9A1_0xB9D0 +10 0xB9D1_0xB9FE 0xBAA1_0xBAFE 0xBBA1_0xBBFE 0xBCA1_0xBCB6 +11 0xBCB7_0xBCFE 0xBDA1_0xBDFE 0xBEA1_0xBEFA +12 0xBEFB_0xBEFE 0xBFA1_0xBFFE 0xC0A1_0xC0FE 0xC1A1_0xC1E0 +13 0xC1E1_0xC1FE 0xC2A1_0xC2FE 0xC3A1_0xC3FE 0xC4A1_0xC4C6 +14 0xC4C7_0xC4FE 0xC5A1_0xC5FE 0xC6A1_0xC6FE 0xC7A1_0xC7AC +15 0xC7AD_0xC7FE 0xC8A1_0xC8FE 0xC9A1_0xC9F0 +16 0xC9F1_0xC9FE 0xCAA1_0xCAFE 0xCBA1_0xCBFE 0xCCA1_0xCCD6 +17 0xCCD7_0xCCFE 0xCDA1_0xCDFE 0xCEA1_0xCEFE 0xCFA1_0xCFBC +18 0xCFBD_0xCFFE 0xD0A1_0xD0FE 0xD1A1_0xD1FE 0xD2A1_0xD2A2 +19 0xD2A3_0xD2FE 0xD3A1_0xD3FE 0xD4A1_0xD4E6 +20 0xD4E7_0xD4FE 0xD5A1_0xD5FE 0xD6A1_0xD6FE 0xD7A1_0xD7CC +21 0xD7CD_0xD7FE 0xD8A1_0xD8FE 0xD9A1_0xD9FE 0xDAA1_0xDAB2 +22 0xDAB3_0xDAFE 0xDBA1_0xDBFE 0xDCA1_0xDCF6 +23 0xDCF7_0xDCFE 0xDDA1_0xDDFE 0xDEA1_0xDEFE 0xDFA1_0xDFDC +24 0xDFDD_0xDFFE 0xE0A1_0xE0FE 0xE1A1_0xE1FE 0xE2A1_0xE2C2 +25 0xE2C3_0xE2FE 0xE3A1_0xE3FE 0xE4A1_0xE4FE 0xE5A1_0xE5A8 +26 0xE5A9_0xE5FE 0xE6A1_0xE6FE 0xE7A1_0xE7EC +27 0xE7ED_0xE7FE 0xE8A1_0xE8FE 0xE9A1_0xE9FE 0xEAA1_0xEAD2 +28 0xEAD3_0xEAFE 0xEBA1_0xEBFE 0xECA1_0xECFE 0xEDA1_0xEDB8 +29 0xEDB9_0xEDFE 0xEEA1_0xEEFE 0xEFA1_0xEFFC +30 0xEFFD_0xEFFE 0xF0A1_0xF0FE 0xF1A1_0xF1FE 0xF2A1_0xF2E2 +31 0xF2E3_0xF2FE 0xF3A1_0xF3FE 0xF4A1_0xF4FE 0xF5A1_0xF5C8 +32 0xF5C9_0xF5FE 0xF6A1_0xF6FE 0xF7A1_0xF7FE 0xF8A1_0xF8AE +33 0xF8AF_0xF8FE 0xF9A1_0xF9FE 0xFAA1_0xFAF2 +34 0xFAF3_0xFAFE 0xFBA1_0xFBFE 0xFCA1_0xFCFE 0xFDA1_0xFDD8 +35 0xFDD9_0xFDFE 0xFEA1_0xFEFE + +# eof diff --git a/contrib/ttf2pk/data/SJIS.sfd b/contrib/ttf2pk/data/SJIS.sfd new file mode 100644 index 0000000..cf7387b --- /dev/null +++ b/contrib/ttf2pk/data/SJIS.sfd @@ -0,0 +1,52 @@ +# SJIS.sfd +# +# subfont numbers for SJIS encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. + +01 0x8140_0x817E 0x8180_0x81FC 0x8240_0x827E 0x8280_0x8284 +02 0x8285_0x82FC 0x8340_0x837E 0x8380_0x83C8 +03 0x83C9_0x83FC 0x8440_0x847E 0x8480_0x84FC 0x8540_0x854F +04 0x8550_0x857E 0x8580_0x85FC 0x8640_0x867E 0x8680_0x8694 +05 0x8695_0x86FC 0x8740_0x877E 0x8780_0x87D8 +06 0x87D9_0x87FC 0x8840_0x887E 0x8880_0x88FC 0x8940_0x895F +07 0x8960_0x897E 0x8980_0x89FC 0x8A40_0x8A7E 0x8A80_0x8AA4 +08 0x8AA5_0x8AFC 0x8B40_0x8B7E 0x8B80_0x8BE8 +09 0x8BE9_0x8BFC 0x8C40_0x8C7E 0x8C80_0x8CFC 0x8D40_0x8D6F +10 0x8D70_0x8D7E 0x8D80_0x8DFC 0x8E40_0x8E7E 0x8E80_0x8EB4 +11 0x8EB5_0x8EFC 0x8F40_0x8F7E 0x8F80_0x8FF8 +12 0x8FF9_0x8FFC 0x9040_0x907E 0x9080_0x90FC 0x9140_0x917E 0x9180 +13 0x9181_0x91FC 0x9240_0x927E 0x9280_0x92C4 +14 0x92C5_0x92FC 0x9340_0x937E 0x9380_0x93FC 0x9440_0x944B +15 0x944C_0x947E 0x9480_0x94FC 0x9540_0x957E 0x9580_0x9590 +16 0x9591_0x95FC 0x9640_0x967E 0x9680_0x96D4 +17 0x96D5_0x96FC 0x9740_0x977E 0x9780_0x97FC 0x9840_0x985B +18 0x985C_0x987E 0x9880_0x98FC 0x9940_0x997E 0x9980_0x99A0 +19 0x99A1_0x99FC 0x9A40_0x9A7E 0x9A80_0x9AE4 +20 0x9AE5_0x9AFC 0x9B40_0x9B7E 0x9B80_0x9BFC 0x9C40_0x9C6B +21 0x9C6C_0x9C7E 0x9C80_0x9CFC 0x9D40_0x9D7E 0x9D80_0x9DB0 +22 0x9DB1_0x9DFC 0x9E40_0x9E7E 0x9E80_0x9EF4 +23 0x9EF5_0x9EFC 0x9F40_0x9F7E 0x9F80_0x9FFC 0xE040_0xE07B +24 0xE07C_0xE07E 0xE080_0xE0FC 0xE140_0xE17E 0xE180_0xE1C0 +25 0xE1C1_0xE1FC 0xE240_0xE27E 0xE280_0xE2FC 0xE340_0xE347 +26 0xE348_0xE37E 0xE380_0xE3FC 0xE440_0xE47E 0xE480_0xE48C +27 0xE48D_0xE4FC 0xE540_0xE57E 0xE580_0xE5D0 +28 0xE5D1_0xE5FC 0xE640_0xE67E 0xE680_0xE6FC 0xE740_0xE757 +29 0xE758_0xE77E 0xE780_0xE7FC 0xE840_0xE87E 0xE880_0xE89C +30 0xE89D_0xE8FC 0xE940_0xE97E 0xE980_0xE9E0 +31 0xE9E1_0xE9FC 0xEA40_0xEA7E 0xEA80_0xEAFC 0xEB40_0xEB67 +32 0xEB68_0xEB7E 0xEB80_0xEBFC 0xEC40_0xEC7E 0xEC80_0xECAC +33 0xECAD_0xECFC 0xED40_0xED7E 0xED80_0xEDF0 +34 0xEDF1_0xEDFC 0xEE40_0xEE7E 0xEE80_0xEEFC 0xEF40_0xEF77 +35 0xEF78_0xEF7E 0xEF80_0xEFFC 0xF040_0xF07E 0xF080_0xF0BC +36 0xF0BD_0xF0FC 0xF140_0xF17E 0xF180_0xF1FC 0xF240_0xF243 +37 0xF244_0xF27E 0xF280_0xF2FC 0xF340_0xF37E 0xF380_0xF388 +38 0xF389_0xF3FC 0xF440_0xF47E 0xF480_0xF4CC +39 0xF4CD_0xF4FC 0xF540_0xF57E 0xF580_0xF5FC 0xF640_0xF653 +40 0xF654_0xF67E 0xF680_0xF6FC 0xF740_0xF77E 0xF780_0xF798 +41 0xF799_0xF7FC 0xF840_0xF87E 0xF880_0xF8DC +42 0xF8DD_0xF8FC 0xF940_0xF97E 0xF980_0xF9FC 0xFA40_0xFA63 +43 0xFA64_0xFA7E 0xFA80_0xFAFC 0xFB40_0xFB7E 0xFB80_0xFBA8 +44 0xFBA9_0xFBFC 0xFC40_0xFC7E 0xFC80_0xFCEC +45 0xFCED_0xFCFC + +# eof diff --git a/contrib/ttf2pk/data/T1-WGL4.enc b/contrib/ttf2pk/data/T1-WGL4.enc new file mode 100644 index 0000000..064c723 --- /dev/null +++ b/contrib/ttf2pk/data/T1-WGL4.enc @@ -0,0 +1,128 @@ +% T1-WGL4.enc +% +% +% This is LaTeX T1 encoding for WGL4 encoded TrueType fonts +% (e.g. from Windows 95) +% +% +% Note that /hyphen appears twice (for the T1 code points `hyphen' 0x2d +% and `hyphenchar' 0x7f). +% +% +% LIGKERN space l =: lslash ; +% LIGKERN space L =: Lslash ; +% LIGKERN question quoteleft =: questiondown ; +% LIGKERN exclam quoteleft =: exclamdown ; +% LIGKERN hyphen hyphen =: endash ; +% LIGKERN endash hyphen =: emdash ; +% LIGKERN quoteleft quoteleft =: quotedblleft ; +% LIGKERN quoteright quoteright =: quotedblright ; +% LIGKERN comma comma =: quotedblbase ; +% LIGKERN less less =: guillemotleft ; +% LIGKERN greater greater =: guillemotright ; +% +% LIGKERN f i =: fi ; +% LIGKERN f l =: fl ; +% LIGKERN f f =: ff ; +% LIGKERN ff i =: ffi ; +% LIGKERN ff l =: ffl ; +% +% We blow away kerns to and from spaces (TeX doesn't have a +% space) and also remove any kerns from the numbers. +% +% LIGKERN space {} * ; * {} space ; +% LIGKERN zero {} * ; * {} zero ; +% LIGKERN one {} * ; * {} one ; +% LIGKERN two {} * ; * {} two ; +% LIGKERN three {} * ; * {} three ; +% LIGKERN four {} * ; * {} four ; +% LIGKERN five {} * ; * {} five ; +% LIGKERN six {} * ; * {} six ; +% LIGKERN seven {} * ; * {} seven ; +% LIGKERN eight {} * ; * {} eight ; +% LIGKERN nine {} * ; * {} nine ; + +/T1Encoding [ % now 256 chars follow +% 0x00 + /grave /acute /circumflex /tilde + /dieresis /hungarumlaut /ring /caron + /breve /macron /dotaccent /cedilla + /ogonek /quotesinglbase /guilsinglleft /guilsinglright +% 0x10 + /quotedblleft /quotedblright /quotedblbase /guillemotleft + /guillemotright /endash /emdash /compwordmark + /perthousandzero /dotlessi /dotlessj /ff + /fi /fl /ffi /ffl +% 0x20 + /visualspace /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus + /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three + /four /five /six /seven + /eight /nine /colon /semicolon + /less /equal /greater /question +% 0x40 + /at /A /B /C + /D /E /F /G + /H /I /J /K + /L /M /N /O +% 0x50 + /P /Q /R /S + /T /U /V /W + /X /Y /Z /bracketleft + /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c + /d /e /f /g + /h /i /j /k + /l /m /n /o +% 0x70 + /p /q /r /s + /t /u /v /w + /x /y /z /braceleft + /bar /braceright /asciitilde /hyphen +% 0x80 + /Abreve /Aogonek /Cacute /Ccaron + /Dcaron /Ecaron /Eogonek /Gbreve + /Lacute /Lcaron /Lslash /Nacute + /Ncaron /Eng /Odblacute /Racute +% 0x90 + /Rcaron /Sacute /Scaron /Scedilla + /Tcaron /Tcedilla /Udblacute /Uring + /Ydieresis /Zacute /Zcaron /Zdot + /IJ /Idot /dmacron /section +% 0xA0 + /abreve /aogonek /cacute /ccaron + /dcaron /ecaron /eogonek /gbreve + /lacute /lcaron /lslash /nacute + /ncaron /eng /odblacute /racute +% 0xB0 + /rcaron /sacute /scaron /scedilla + /tcaron /tcedilla /udblacute /uring + /ydieresis /zacute /zcaron /zdot + /ij /exclamdown /questiondown /sterling +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde + /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /OE + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /Germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /oe + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /germandbls +] def + +% eof diff --git a/contrib/ttf2pk/data/UBg5plus.sfd b/contrib/ttf2pk/data/UBg5plus.sfd new file mode 100644 index 0000000..a8f1972 --- /dev/null +++ b/contrib/ttf2pk/data/UBg5plus.sfd @@ -0,0 +1,3002 @@ +# UBg5plus.sfd +# +# subfont numbers for Big 5+ encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x8488 0x8710 0x871F 0x870F 0x88D3 0x8C87 0x8CC6 0x90CC \ + 0x916D 0x9258 0x9242 0x9268 0x9269 0x9243 0x9247 0x959D \ + 0x96CF 0x97F4 0x9809 0x98AB 0x98FB 0x9AAC 0x9AAE 0x9AAA \ + 0x9B5C 0x50DF 0x5619 0x560A 0x589A 0x5D85 0x5E56 0x5E51 \ + 0x5FB1 0x645A 0x6463 0x669B 0x66A3 0x669E 0x69B8 0x69BA \ + 0x69C7 0x69D7 0x6B70 0x6B9D 0x6F16 0x6F24 0x6F45 0x7179 \ + 0x717A 0x7254 0x757C 0x757B 0x7612 0x76B6 0x76E0 0x7773 \ + 0x7772 0x7770 0x789D 0x7A27 0x7A35 0x7BA2 0x7B89 0x4E28 \ + 0x4E05 0x4E04 0x4E2A 0x4E87 0x4E49 0x51E2 0x4E46 0x4E8F \ + 0x4EBC 0x4EBE 0x5166 0x51E3 0x5204 0x529C 0x5344 0x5F51 \ + 0x961D 0x4E63 0x4E62 0x4EA3 0x5185 0x4EC5 0x4ECF 0x4ECE \ + 0x4ECC 0x5184 0x5186 0x51E4 0x5205 0x529E 0x529D 0x52FD \ + 0x7BA5 0x7CB6 0x7DA5 0x7DC3 0x7FAB 0x8025 0x8059 0x8185 \ + 0x818E 0x84BE 0x84A6 0x872F 0x89A0 0x8A97 0x8C8B 0x8F0F \ + 0x9275 0x929F 0x95A6 0x969A 0x9757 0x97F7 0x98B0 0x99C6 \ + 0x50FA 0x5285 0x5643 0x563C 0x5BED 0x5C35 0x5F47 0x616D \ + 0x69F5 0x6A03 0x6A65 0x6B75 0x6F56 0x6F98 0x6F68 0x7234 \ + 0x7245 0x735C 0x7356 0x78BF 0x78BD 0x78E4 0x7A34 0x7A36 \ + 0x7BBA 0x7BBC 0x7BC8 0x7BC3 0x7BB6 0x7BC2 0x7BC5 0x7BBD \ + 0x7BB0 0x7BBB 0x7E04 0x81F1 0x8522 0x8538 0x8532 0x8510 \ + 0x854F 0x877C 0x890D 0x8908 0x8D9E 0x8F28 0x8F21 0x9066 \ + 0x906C 0x90F6 0x92EC 0x92BA 0x92E3 0x92BD 0x95B4 0x97D1 \ + 0x9823 0x990B 0x9AB2 0x9ADB 0x9B73 0x9B6E 0x9B65 0x9B6A \ + 0x9B6D 0x9D0B 0x9E76 0x9F11 0x5119 0x5675 0x596F 0x61A5 \ + 0x61A0 0x65B4 0x65D8 0x66C2 0x6BA8 0x6F83 0x6FC5 0x71CD \ + 0x729C 0x7499 0x7639 0x762E 0x769F 0x76A0 0x7794 0x77AE \ + 0x78E6 0x7ABC 0x7BD6 0x7CCF 0x7E18 0x806D 0x8190 0x8552 \ + 0x8550 0x87A0 0x8786 0x8795 0x8860 0x8928 0x8920 0x89A8 \ + 0x8E3A 0x9194 0x9311 0x9337 0x9343 0x96A6 0x9795 0x9796 \ + 0x9825 0x9926 0x9934 0x9B8A 0x9B7F 0x9D11 0x9ED9 0x9F3C \ + 0x5123 0x512C 0x5295 0x5688 0x568B 0x61E1 0x61D7 0x65A3 \ + 0x66D3 0x6A8B 0x6BAC 0x7374 0x7640 0x5300 0x533A 0x5346 +02 0x535D 0x5386 0x53B7 0x53CC 0x53CE 0x5721 0x5E00 0x5F0C \ + 0x6237 0x6238 0x6535 0x738D 0x4E97 0x4EE0 0x4EE7 0x4EE6 \ + 0x56D8 0x518B 0x518C 0x5199 0x51E5 0x520B 0x5304 0x5303 \ + 0x5307 0x531E 0x535F 0x536D 0x5389 0x53BA 0x7641 0x76E8 \ + 0x78F6 0x7900 0x7A59 0x7A55 0x7AF4 0x7C04 0x7C15 0x7BF5 \ + 0x81C1 0x857D 0x85A5 0x893A 0x8E51 0x9198 0x9381 0x936F \ + 0x9842 0x9937 0x9BA9 0x9BA7 0x9BAC 0x9B9C 0x9D3C 0x9D1C \ + 0x9D3A 0x9D32 0x9D34 0x9F3F 0x5EEB 0x61D5 0x6502 0x7012 \ + 0x7585 0x7654 0x7655 0x76A7 0x76A8 0x790F 0x7CE4 0x7CE5 \ + 0x7E65 0x7E4E 0x7F82 0x802D 0x85CA 0x85BC 0x8CFF 0x91A6 \ + 0x93B6 0x93AB 0x97A7 0x983E 0x9BBC 0x9BB7 0x9BBE 0x9D62 \ + 0x9E8F 0x9ECB 0x56A9 0x5913 0x5BF4 0x61EC 0x61EF 0x6AD6 \ + 0x7209 0x7379 0x74C6 0x77C3 0x791F 0x7A65 0x7AC6 0x7C3A \ + 0x7CEB 0x7F84 0x85E0 0x85F3 0x881E 0x89B4 0x89F9 0x8B44 \ + 0x8E71 0x8E6E 0x8E79 0x8EC4 0x908C 0x93C9 0x97B0 0x985A \ + 0x9946 0x9AC3 0x9B0F 0x9BF4 0x9BFA 0x9BDD 0x9BED 0x9BEF \ + 0x9E96 0x9EB3 0x9EE2 0x9F8F 0x56B1 0x5B41 0x6AF6 0x6AF2 \ + 0x7588 0x8267 0x860E 0x8D0E 0x91B6 0x942F 0x97E0 0x97DB \ + 0x9861 0x9A33 0x9C0F 0x9C11 0x9C03 0x9C01 0x9C16 0x9D93 \ + 0x535B 0x56BF 0x5DCE 0x76AC 0x77D2 0x7C52 0x8B76 0x8EC7 \ + 0x9434 0x943E 0x97BC 0x9B39 0x9C2A 0x9C26 0x9C27 0x9DC0 \ + 0x9DC9 0x9EEC 0x9F68 0x8032 0x8031 0x89FD 0x908E 0x97C2 \ + 0x9A4B 0x9B1C 0x9B1B 0x9C42 0x56D0 0x56CF 0x5DDA 0x66EA \ + 0x8B89 0x9458 0x9DE7 0x53D0 0x53F6 0x53F7 0x53F9 0x53F4 \ + 0x5724 0x5904 0x5918 0x5932 0x5930 0x5934 0x5975 0x5B82 \ + 0x5BF9 0x5C14 0x5E81 0x5E83 0x5F0D 0x5F52 0x5FCA 0x5FC7 \ + 0x6239 0x624F 0x65E7 0x672F 0x6B7A 0x6C39 0x6C37 0x6C44 \ + 0x6C45 0x738C 0x9093 0x9092 0x9DEA 0x9DF1 0x9F44 0x9F6D \ + 0x5DD9 0x883A 0x8975 0x9A5D 0x9C64 0x9E0A 0x9F73 0x77E1 \ + 0x9B2D 0x9E0C 0x9F1F 0x7C70 0x9479 0x974A 0x7E9D 0x9960 \ + 0x9F9E 0x9EF8 0x9F3A 0x9F7D 0x9F96 0x6729 0x5E07 0x5FCB \ + 0x52B7 0x52B8 0x52B6 0x52BA 0x6306 0x6B85 0x8C38 0x7309 +03 0x8A2F 0x52DC 0x5921 0x5E3F 0x7B3F 0x83D0 0x86E7 0x6117 \ + 0x8714 0x88D1 0x8CCB 0x8EED 0x52EC 0x52E8 0x7527 0x798C \ + 0x7991 0x8660 0x9904 0x999B 0x729F 0x8770 0x8E37 0x9703 \ + 0x52F6 0x64CC 0x764A 0x7AB9 0x7BD7 0x999F 0x9B8D 0x9E77 \ + 0x764B 0x76A2 0x87F1 0x9BBA 0x8804 0x9BD8 0x9D7C 0x7C46 \ + 0x9D8D 0x957E 0x9C20 0x9C22 0x9C1E 0x8970 0x9C43 0x9DE0 \ + 0x9459 0x9C72 0x6530 0x72DD 0x6804 0x82FF 0x8FEC 0x53DE \ + 0x5A30 0x5BB2 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x4E21 0x4E20 0x4E22 0x4E68 0x4E89 0x4E98 0x4EF9 \ + 0x4EEF 0x4EF8 0x4F06 0x4F03 0x4EFC 0x4EEE 0x4F16 0x4F28 \ + 0x4F1C 0x4F07 0x4F1A 0x4EFA 0x4F17 0x514A 0x5172 0x51B4 \ + 0x51B3 0x51B2 0x51E8 0x5214 0x520F 0x5215 0x5218 0x52A8 \ + 0x534B 0x534F 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +04 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x5350 \ + 0x538B 0x53BE 0x53D2 0x5416 0x53FF 0x5400 0x5405 0x5413 \ + 0x5415 0x56E3 0x5735 0x5736 0x5731 0x5732 0x58EE 0x5905 \ + 0x4E54 0x5936 0x597A 0x5986 0x5B86 0x5F53 0x5C18 0x5C3D \ + 0x5C78 0x5C80 0x5E08 0x5EF5 0x5F0E 0x5FD3 0x5FDA 0x5FDB \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x620F 0x625D 0x625F \ + 0x6267 0x6257 0x9F50 0x65EB 0x65EA 0x6737 0x6732 0x6736 +05 0x6B22 0x6BCE 0x6C58 0x6C51 0x6C77 0x6C3C 0x6C5A 0x6C53 \ + 0x706F 0x7072 0x706E 0x7073 0x72B1 0x72B2 0x738F 0x793C \ + 0x808D 0x808E 0x827B 0x8D71 0x8FB9 0x9096 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x909A 0x4E24 0x4E71 0x4E9C 0x4F45 \ + 0x4F4A 0x4F39 0x4F37 0x4F32 0x4F42 0x4F44 0x4F4B 0x4F40 \ + 0x4F35 0x4F31 0x5151 0x5150 0x514E 0x519D 0x51B5 0x51B8 \ + 0x51EC 0x5223 0x5227 0x5226 0x521F 0x522B 0x5220 0x52B4 \ + 0x52B3 0x5325 0x533B 0x5374 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +06 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x544D 0x543A 0x5444 0x544C 0x5423 0x541A 0x5432 \ + 0x544B 0x5421 0x5434 0x5449 0x5450 0x5422 0x543F 0x5451 \ + 0x545A 0x542F 0x56E9 0x56F2 0x56F3 0x56EF 0x56ED 0x56EC \ + 0x56E6 0x5748 0x5744 0x573F 0x573C 0x5753 0x5756 0x575F \ + 0x5743 0x5758 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +07 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x5757 \ + 0x5746 0x573D 0x5742 0x5754 0x5755 0x58F1 0x58F2 0x58F0 \ + 0x590B 0x9EA6 0x56F1 0x593D 0x5994 0x598C 0x599C 0x599F \ + 0x599B 0x5989 0x599A 0x6588 0x5B8D 0x5BFE 0x5BFF 0x5BFD \ + 0x5C2B 0x5C84 0x5C8E 0x5C9C 0x5C85 0x5DF5 0x5E09 0x5E0B \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x5E92 0x5E90 0x5F03 \ + 0x5F1E 0x5F63 0x5FE7 0x5FFE 0x5FE6 0x5FDC 0x5FCE 0x5FFC \ + 0x5FDF 0x5FEC 0x5FF6 0x5FF2 0x5FF0 0x5FF9 0x6213 0x623B +08 0x623C 0x6282 0x6278 0x628B 0x629E 0x62A5 0x629B 0x629C \ + 0x6299 0x628D 0x6285 0x629D 0x6275 0x65F6 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x66F5 0x675B 0x6754 0x6752 0x6758 \ + 0x6744 0x674A 0x6761 0x6C7F 0x6C91 0x6C9E 0x6C6E 0x6C7C \ + 0x6C9F 0x6C75 0x6C56 0x6CA2 0x6C79 0x6CA1 0x6CAA 0x6CA0 \ + 0x7079 0x7077 0x707E 0x7075 0x707B 0x7264 0x72BB 0x72BC \ + 0x72C7 0x72B9 0x72BE 0x72B6 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +09 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x7398 0x7593 0x7680 0x7683 0x76C0 0x76C1 0x77F4 \ + 0x77F5 0x7ACC 0x7ACD 0x7CFA 0x809F 0x8091 0x8097 0x8094 \ + 0x8286 0x828C 0x8295 0x866C 0x8FBE 0x8FC7 0x8FC1 0x90A9 \ + 0x90A4 0x90A8 0x9627 0x9626 0x962B 0x9633 0x9634 0x9629 \ + 0x4E3D 0x4E9D 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +10 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x4F93 \ + 0x4F8A 0x4F6D 0x4F8E 0x4FA0 0x4FA2 0x4FA1 0x4F9F 0x4FA3 \ + 0x4F72 0x4F8C 0x5156 0x5190 0x51ED 0x51FE 0x522F 0x523C \ + 0x5234 0x5239 0x52B9 0x52B5 0x52BF 0x5355 0x5376 0x537A \ + 0x5393 0x53C1 0x53C2 0x53D5 0x5485 0x545F 0x5493 0x5489 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x8038 0x8081 \ + 0x8158 0x8A24 0x8DC3 0x51F2 0x55B6 0x5EC3 0x7861 0x7A01 \ + 0x8849 0x8999 0x921F 0x5313 0x55E0 0x6139 0x6ED7 0x733D \ + 0x9775 0x7FE4 0x8088 0x5655 0x617F 0x71D7 0x8666 0x8F3A \ + 0x933D 0x64F5 0x7F80 0x8D01 0x58E1 0x7CE9 0x81CB 0x95D9 \ + 0x6707 0x9A47 0x7674 0x5301 0x53FA 0x9F99 0x6C49 0x8FB7 \ + 0x4F29 0x534E 0x5C81 0x5F10 0x6268 0x6742 0x6740 0x51EA \ + 0x6C62 0x7391 0x8FBB 0x8FBC 0x56E8 0x575B 0x5C97 0x6762 \ + 0x62A4 0x6766 0x6CA3 0x707F 0x77F6 0x5479 0x9EFE 0x548F \ + 0x5469 0x546D 0x5494 0x546A 0x548A 0x56FD 0x56FB 0x56F8 \ + 0x56FC 0x56F6 0x5765 0x5781 0x5763 0x5767 0x576E 0x5778 \ + 0x577F 0x58F3 0x594B 0x594C 0x59AD 0x59C4 0x59C2 0x59B0 +11 0x59BF 0x59C9 0x59B8 0x59AC 0x59B7 0x59D7 0x8FC8 0x4FAB \ + 0x5C2D 0x549C 0x5788 0x62C3 0x6619 0x67A1 0x67A6 0x77FE \ + 0x7F57 0x82C5 0x8FDF 0x8FDC 0x4FE4 0x551B 0x57AA 0x57AB \ + 0x5BA9 0x6811 0x7551 0x7553 0x7818 0x7AD7 0x7C7E 0x867E \ + 0x5266 0x5520 0x5521 0x57D7 0x5BBE 0x6857 0x7F3C 0x8273 \ + 0x96BE 0x66FA 0x5A72 0x68BD 0x6E15 0x7413 0x74F8 0x7B3D \ + 0x76D8 0x79FC 0x7B39 0x7D4B 0x83B9 0x86CF 0x8EAE 0x96EB \ + 0x55B0 0x5840 0x5842 0x692B 0x6916 0x691B 0x6927 0x6BF5 \ + 0x6E82 0x6E7A 0x7129 0x7CAB 0x7CAC 0x83F7 0x9596 0x55F1 \ + 0x5F41 0x698A 0x698C 0x6980 0x697F 0x789C 0x7B7B 0x90D2 \ + 0x95A0 0x51A9 0x7195 0x7198 0x7478 0x78B9 0x7A33 0x7CC0 \ + 0x7CC1 0x8744 0x9064 0x9277 0x92AF 0x5E64 0x6A2B 0x6F46 \ + 0x6F9A 0x92F2 0x9B79 0x567A 0x5F5C 0x65D9 0x6A72 0x6A78 \ + 0x6B5A 0x8EBE 0x933B 0x9340 0x933A 0x9B96 0x71F5 0x7A50 \ + 0x9387 0x9385 0x9BB1 0x9D47 0x93B9 0x93BF 0x9BCF 0x9D64 \ + 0x9EBF 0x89B8 0x9BF3 0x7C4F 0x9425 0x95E6 0x9C2F 0x6B0C \ + 0x9C47 0x7936 0x6B15 0x53B5 0x4F66 0x4F68 0x4FE7 0x503F \ + 0x50A6 0x510F 0x523E 0x5324 0x5365 0x539B 0x517F 0x54CB \ + 0x5573 0x5571 0x556B 0x55F4 0x5622 0x5620 0x5692 0x56BA \ + 0x5691 0x56B0 0x5759 0x578A 0x580F 0x5812 0x5813 0x5847 \ + 0x589B 0x5900 0x594D 0x5B60 0x5B96 0x5B9E 0x5B94 0x5B9F \ + 0x5B9D 0x5C00 0x5C19 0x5C49 0x5C4A 0x5CBB 0x5CC1 0x5CB9 \ + 0x5C9E 0x5CB4 0x5CBA 0x5DF6 0x5E13 0x5E12 0x5E77 0x5E98 \ + 0x5E99 0x5E9D 0x5EF8 0x5EF9 0x5F06 0x5F21 0x5F25 0x5F55 \ + 0x5F84 0x5F83 0x6030 0x6007 0x5AD1 0x5AD3 0x5B67 0x5C57 \ + 0x5C77 0x5CD5 0x5D75 0x5D8E 0x5DA5 0x5DB6 0x5DBF 0x5E65 \ + 0x5ECD 0x5EED 0x5F94 0x5F9A 0x5FBA 0x6125 0x6150 0x62A3 \ + 0x6360 0x6364 0x63B6 0x6403 0x64B6 0x651A 0x7A25 0x5C21 \ + 0x66E2 0x6702 0x67A4 0x67AC 0x6810 0x6806 0x685E 0x685A \ + 0x692C 0x6929 0x6A2D 0x6A77 0x6A7A 0x6ACA 0x6AE6 0x6AF5 \ + 0x6B0D 0x6B0E 0x6BDC 0x6BDD 0x6BF6 0x6C1E 0x6C63 0x6DA5 \ + 0x6E0F 0x6E8A 0x6E84 0x6E8B 0x6E7C 0x6F4C 0x6F48 0x6F49 +12 0x6F9D 0x6F99 0x6FF8 0x702E 0x702D 0x705C 0x79CC 0x70BF \ + 0x70EA 0x70E5 0x7111 0x7112 0x713F 0x7139 0x713B 0x713D \ + 0x7177 0x7175 0x7176 0x7171 0x7196 0x7193 0x71B4 0x71DD \ + 0x71DE 0x720E 0x5911 0x7218 0x7347 0x7348 0x73EF 0x7412 \ + 0x743B 0x74A4 0x748D 0x74B4 0x7673 0x7677 0x76BC 0x7819 \ + 0x781B 0x783D 0x7853 0x7854 0x7858 0x78B7 0x78D8 0x78EE \ + 0x7922 0x794D 0x7986 0x7999 0x79A3 0x79BC 0x7AA7 0x7B37 \ + 0x7B59 0x7BD0 0x7C2F 0x7C32 0x7C42 0x7C4E 0x7C68 0x7CA9 \ + 0x7CED 0x7DD0 0x7E07 0x7DD3 0x7E64 0x7F40 0x8041 0x8063 \ + 0x80BB 0x6711 0x6725 0x8248 0x8310 0x8362 0x8312 0x8421 \ + 0x841E 0x84E2 0x84DE 0x84E1 0x8573 0x85D4 0x85F5 0x8637 \ + 0x8645 0x8672 0x874A 0x87A9 0x87A5 0x87F5 0x8834 0x8850 \ + 0x8887 0x6036 0x5FE9 0x603D 0x6008 0x62BA 0x62B2 0x62B7 \ + 0x62E4 0x62A7 0x62D5 0x62E1 0x62DD 0x62A6 0x62C1 0x62C5 \ + 0x62C0 0x62DF 0x62E0 0x62DE 0x6589 0x65A6 0x65BA 0x65FF \ + 0x6617 0x6618 0x6601 0x65FE 0x670C 0x676B 0x6796 0x6782 \ + 0x678A 0x67A3 0x8954 0x8984 0x8B03 0x8C52 0x8CD8 0x8D0C \ + 0x8D18 0x8DB0 0x8EBC 0x8ED5 0x8FAA 0x909C 0x915C 0x922B \ + 0x9221 0x9273 0x92F4 0x92F5 0x933F 0x9342 0x9386 0x93BE \ + 0x93BC 0x93BD 0x93F1 0x93F2 0x93EF 0x9422 0x9423 0x9424 \ + 0x9467 0x9466 0x9597 0x95CE 0x95E7 0x973B 0x974D 0x98E4 \ + 0x9942 0x9B1D 0x9B98 0x9D49 0x6449 0x5E71 0x5E85 0x61D3 \ + 0x990E 0x8002 0x781E 0x5528 0x5572 0x55BA 0x55F0 0x55EE \ + 0x56B8 0x56B9 0x56C4 0x8053 0x92B0 0x4E13 0x4E1A 0x4E1B \ + 0x4E1C 0x4E1D 0x4E25 0x4E27 0x4E2C 0x4E34 0x4E3A 0x4E3E \ + 0x4E4C 0x4E50 0x4E60 0x4E61 0x4E66 0x4E70 0x4E78 0x4E9A \ + 0x4EA7 0x4EA9 0x4EAA 0x4EB5 0x4EB8 0x4EBB 0x4EBF 0x4ED1 \ + 0x4ED3 0x4EEA 0x4EEB 0x4EEC 0x4F1E 0x4F1F 0x4F20 0x4F21 \ + 0x4F23 0x4F24 0x4F25 0x4F26 0x4F27 0x4F2A 0x4F2B 0x4F65 \ + 0x4FA5 0x4FA6 0x4FA7 0x4FA8 0x4FA9 0x4FAA 0x4FAC 0x4FE6 \ + 0x4FE8 0x4FEA 0x4FEB 0x4FED 0x503A 0x503D 0x503E 0x507E \ + 0x507F 0x50A4 0x50A5 0x50A7 0x50A8 0x50A9 0x5170 0x5174 +13 0x517B 0x517D 0x5181 0x519A 0x519B 0x519C 0x51A7 0x51AE \ + 0x51AF 0x51BB 0x51EB 0x51EF 0x51FB 0x51FC 0x51FF 0x520D \ + 0x5219 0x521A 0x521B 0x522C 0x522D 0x523F 0x5240 0x5242 \ + 0x5250 0x5251 0x528F 0x52A1 0x52A2 0x52B2 0x52CB 0x67A2 \ + 0x678F 0x67F9 0x6780 0x6B26 0x6B27 0x6B68 0x6B69 0x6B81 \ + 0x6BB4 0x6BD1 0x6C1C 0x6C97 0x6C6C 0x6CDF 0x6CEA 0x6CE4 \ + 0x6CD8 0x6CB2 0x6CCE 0x6CC8 0x708B 0x7088 0x7090 0x708F \ + 0x7087 0x7089 0x708D 0x7081 0x708C 0x7240 0x7265 0x7266 \ + 0x52DA 0x5326 0x532E 0x5356 0x5362 0x536B 0x5385 0x538C \ + 0x538D 0x5390 0x5395 0x53A2 0x53A3 0x53BF 0x53C6 0x53C7 \ + 0x53D1 0x53D8 0x53FE 0x5417 0x5452 0x5453 0x5456 0x5457 \ + 0x5458 0x5459 0x545B 0x545C 0x5497 0x5499 0x549B 0x549D \ + 0x54D1 0x54D2 0x54D3 0x54D4 0x54D5 0x54D7 0x54D9 0x54DC \ + 0x54DD 0x54DF 0x551D 0x551E 0x5522 0x5523 0x5524 0x5525 \ + 0x5567 0x556C 0x556D 0x556E 0x556F 0x5570 0x5574 0x5578 \ + 0x5579 0x55B7 0x55B9 0x55BC 0x55BE 0x55EB 0x55EC 0x55F3 \ + 0x55F5 0x5621 0x5623 0x5624 0x5625 0x565C 0x565D 0x567C \ + 0x56A1 0x56A3 0x56A4 0x56D6 0x56E2 0x56F4 0x56F5 0x56FE \ + 0x5706 0x5719 0x5739 0x573A 0x575A 0x575C 0x575D 0x575E \ + 0x5760 0x5784 0x5785 0x57AD 0x57AF 0x57B1 0x57B2 0x57D8 \ + 0x57D9 0x57DA 0x5811 0x5816 0x5846 0x5899 0x58B6 0x58CB \ + 0x58EA 0x58F6 0x58F8 0x5907 0x5939 0x593A 0x5941 0x5942 \ + 0x5956 0x5987 0x5988 0x59A9 0x59AA 0x59AB 0x5A05 0x5A06 \ + 0x5A07 0x5A08 0x5A32 0x5A34 0x5A74 0x5A76 0x5AAD 0x5AD2 \ + 0x5AD4 0x5AF1 0x5AF2 0x5B59 0x5B6D 0x5BA0 0x5BA1 0x5BAA \ + 0x5BBD 0x5BFB 0x5BFC 0x5C1C 0x5C1D 0x5C27 0x5C34 0x5C42 \ + 0x5C43 0x5C66 0x5C72 0x5C7F 0x5C82 0x5C83 0x5C96 0x5C98 \ + 0x5C99 0x5C9A 0x5C9B 0x5CBD 0x5CBF 0x7268 0x72CD 0x72D3 \ + 0x72DB 0x72CF 0x73A7 0x73A3 0x739E 0x73AF 0x73AA 0x739C \ + 0x7542 0x7544 0x753B 0x7541 0x759B 0x759E 0x79C4 0x79C3 \ + 0x79C6 0x79C7 0x79CA 0x7ACF 0x7C76 0x7C74 0x7CFF 0x7CFC \ + 0x7F59 0x80A8 0x80B0 0x80B3 0x80A4 0x80B6 0x5CC2 0x5CC3 +14 0x5CC4 0x5CE3 0x5CE4 0x5CE7 0x5D02 0x5D03 0x5D04 0x5D05 \ + 0x5D2D 0x5D58 0x5D5A 0x5D5D 0x5DC5 0x5DEF 0x5E05 0x5E0F \ + 0x5E10 0x5E1C 0x5E26 0x5E27 0x5E31 0x5E3B 0x5E3C 0x5E86 \ + 0x5E91 0x5E93 0x5E94 0x5E9E 0x5E9F 0x5EBC 0x5F20 0x5F2A \ + 0x5F5F 0x5F68 0x5F7B 0x5F95 0x6001 0x6002 0x6003 0x6004 \ + 0x6005 0x6006 0x603B 0x603C 0x603F 0x6076 0x6078 0x6079 \ + 0x607A 0x607B 0x607D 0x60AB 0x60AC 0x60AD 0x60AF 0x60EB \ + 0x60EC 0x60ED 0x60EF 0x6124 0x6126 0x6151 0x61D1 0x61D2 \ + 0x61D4 0x6206 0x620B 0x6217 0x6269 0x626A 0x626B 0x626C \ + 0x629F 0x62A0 0x62A1 0x62A2 0x62E2 0x62E3 0x62E6 0x62E7 \ + 0x62E8 0x62E9 0x631A 0x631C 0x631D 0x631E 0x6320 0x6322 \ + 0x6324 0x6325 0x6326 0x635E 0x635F 0x6361 0x6362 0x6363 \ + 0x63B3 0x63B7 0x63B8 0x63B9 0x63BC 0x63FB 0x63FC 0x63FD \ + 0x63FF 0x6400 0x6401 0x6402 0x6404 0x6405 0x6444 0x6445 \ + 0x6448 0x644A 0x6484 0x64B5 0x64B7 0x64B8 0x64BA 0x64DD \ + 0x64DE 0x6512 0x6569 0x6586 0x658F 0x6593 0x65A9 0x65F7 \ + 0x65F8 0x663D 0x663E 0x6653 0x6654 0x6655 0x6656 0x6682 \ + 0x66A7 0x6743 0x6767 0x6768 0x6769 0x67A5 0x67A7 0x67A8 \ + 0x67AA 0x67AB 0x67AD 0x67FD 0x6807 0x6808 0x6809 0x680A \ + 0x680B 0x680C 0x680E 0x80A7 0x80AC 0x80A6 0x5367 0x820E \ + 0x82C4 0x833E 0x829C 0x82AA 0x82C9 0x82A6 0x82B2 0x8FCC \ + 0x8FD9 0x8FCA 0x8FD8 0x8FCF 0x90B7 0x90AD 0x90B9 0x9637 \ + 0x9641 0x963E 0x9751 0x9763 0x4E57 0x4E79 0x4EB2 0x4EB0 \ + 0x4EAF 0x4EB1 0x4FD2 0x4FD5 0x680F 0x6860 0x6861 0x6862 \ + 0x6864 0x6865 0x6866 0x6868 0x6869 0x686A 0x68BE 0x68BF \ + 0x68C0 0x691D 0x691F 0x6920 0x6924 0x692D 0x6984 0x6987 \ + 0x6988 0x6989 0x69DA 0x69DB 0x69DC 0x69DF 0x69E0 0x6A2F \ + 0x6A31 0x6A79 0x6A7C 0x6AA9 0x6B7C 0x6B87 0x6B92 0x6B93 \ + 0x6B9A 0x6BC2 0x6BD5 0x6BD9 0x6C07 0x6C22 0x6C29 0x6C47 \ + 0x6C48 0x6C64 0x6CA4 0x6CA5 0x6CA6 0x6CA7 0x6CA8 0x6CA9 \ + 0x6CF6 0x6CF7 0x6CF8 0x6CFA 0x6CFB 0x6CFC 0x6CFD 0x6CFE \ + 0x6D46 0x6D47 0x6D48 0x6D49 0x6D4A 0x6D4B 0x6D4D 0x6D4E +15 0x6D4F 0x6D50 0x6D51 0x6D52 0x6D53 0x6D54 0x6D55 0x6D9D \ + 0x6D9F 0x6DA0 0x6DA1 0x6DA2 0x6DA3 0x6DA4 0x6DA6 0x6DA7 \ + 0x6DA8 0x6DA9 0x6E0D 0x6E0E 0x6E10 0x6E11 0x6E14 0x6E16 \ + 0x6E81 0x6E83 0x6E85 0x6E87 0x6EDF 0x6EE0 0x6EE1 0x6EE2 \ + 0x6EE4 0x6EE5 0x6EE7 0x6EEA 0x6F47 0x6F4B 0x6F4D 0x6F9B \ + 0x6F9C 0x6FD1 0x6FD2 0x704F 0x706D 0x7080 0x709C 0x709D \ + 0x709E 0x70BC 0x70BD 0x70C1 0x70C2 0x70C3 0x70E6 0x70E7 \ + 0x70E8 0x70E9 0x70EB 0x70EC 0x70ED 0x7115 0x7116 0x7118 \ + 0x7140 0x71F7 0x7231 0x7237 0x724D 0x7275 0x728A 0x72B7 \ + 0x72B8 0x72C8 0x72DE 0x72EE 0x72EF 0x72F0 0x72F1 0x72F2 \ + 0x7303 0x7321 0x736D 0x7399 0x739A 0x739B 0x73AE 0x73B0 \ + 0x73B1 0x4FBE 0x4FB8 0x4FB0 0x4FB1 0x4FC8 0x4FC6 0x4FCC \ + 0x4FE5 0x4FE3 0x4FB4 0x516A 0x519F 0x51C1 0x51C2 0x51C3 \ + 0x5245 0x5248 0x524F 0x52C5 0x52CA 0x52C4 0x5327 0x5358 \ + 0x537D 0x53DD 0x53DC 0x53DA 0x53D9 0x54B9 0x54D0 0x54B4 \ + 0x54CA 0x54A3 0x73D1 0x73F0 0x73F2 0x740E 0x740F 0x7410 \ + 0x7437 0x7477 0x748E 0x74D2 0x7519 0x7534 0x7535 0x7545 \ + 0x758D 0x7596 0x759F 0x75A0 0x75A1 0x75AC 0x75AD 0x75AE \ + 0x75AF 0x75C8 0x75C9 0x75D6 0x75E8 0x75EA 0x75EB 0x7605 \ + 0x7617 0x7618 0x762A 0x762B 0x763E 0x763F 0x765D 0x765E \ + 0x7663 0x7666 0x766B 0x7691 0x76B1 0x76B2 0x76CF 0x76D0 \ + 0x76D1 0x770D 0x772C 0x7750 0x7751 0x7786 0x7792 0x7793 \ + 0x77CB 0x77EB 0x77FF 0x7800 0x7801 0x7816 0x7817 0x781A \ + 0x781C 0x7839 0x783B 0x783E 0x7840 0x7841 0x7855 0x7856 \ + 0x7857 0x7859 0x785A 0x785B 0x7875 0x7877 0x789B 0x78D7 \ + 0x78D9 0x7903 0x7933 0x7943 0x794E 0x796F 0x7978 0x79EF \ + 0x79FE 0x7A06 0x7A23 0x7A51 0x7A52 0x7A5E 0x7A77 0x7A8D \ + 0x7A8E 0x7A9C 0x7A9D 0x7AA5 0x7AA6 0x7AAD 0x7AD6 0x7ADE \ + 0x7B03 0x7B15 0x7B3A 0x7B3C 0x7B3E 0x7B5A 0x7B5B 0x7B5C \ + 0x7B7C 0x7B7E 0x7B7F 0x7B80 0x7BA6 0x7BA7 0x7BA8 0x7BA9 \ + 0x7BAB 0x7BD1 0x7BD3 0x7BEE 0x7BEF 0x7C16 0x7C41 0x7CAA \ + 0x7CF9 0x7D27 0x7D77 0x7DD4 0x7E06 0x7E9F 0x7EA0 0x7EA1 +16 0x7EA2 0x7EA3 0x7EA4 0x7EA5 0x7EA6 0x7EA7 0x7EA8 0x7EA9 \ + 0x7EAA 0x7EAB 0x7EAC 0x7EAD 0x7EAE 0x7EAF 0x7EB0 0x7EB1 \ + 0x7EB2 0x7EB3 0x7EB4 0x7EB5 0x7EB6 0x7EB7 0x7EB8 0x54DA \ + 0x54A4 0x54B2 0x549E 0x549F 0x54B5 0x54CD 0x54CC 0x5700 \ + 0x57AC 0x5791 0x578E 0x578D 0x5792 0x57A1 0x5790 0x57A6 \ + 0x57A8 0x579C 0x5796 0x57A7 0x58F5 0x5909 0x5908 0x5952 \ + 0x59DF 0x59EB 0x59EF 0x59F0 0x59D5 0x5A0D 0x5A04 0x59F9 \ + 0x7EB9 0x7EBA 0x7EBB 0x7EBC 0x7EBD 0x7EBE 0x7EBF 0x7EC0 \ + 0x7EC1 0x7EC2 0x7EC3 0x7EC4 0x7EC5 0x7EC6 0x7EC7 0x7EC8 \ + 0x7EC9 0x7ECA 0x7ECB 0x7ECC 0x7ECD 0x7ECE 0x7ECF 0x7ED0 \ + 0x7ED1 0x7ED2 0x7ED3 0x7ED4 0x7ED5 0x7ED6 0x7ED7 0x7ED8 \ + 0x7ED9 0x7EDA 0x7EDB 0x7EDC 0x7EDD 0x7EDE 0x7EDF 0x7EE0 \ + 0x7EE1 0x7EE2 0x7EE3 0x7EE4 0x7EE5 0x7EE6 0x7EE7 0x7EE8 \ + 0x7EE9 0x7EEA 0x7EEB 0x7EEC 0x7EED 0x7EEE 0x7EEF 0x7EF0 \ + 0x7EF1 0x7EF2 0x7EF3 0x7EF4 0x7EF5 0x7EF6 0x7EF7 0x7EF8 \ + 0x7EF9 0x7EFA 0x7EFB 0x7EFC 0x7EFD 0x7EFE 0x7EFF 0x7F00 \ + 0x7F01 0x7F02 0x7F03 0x7F04 0x7F05 0x7F06 0x7F07 0x7F08 \ + 0x7F09 0x7F0A 0x7F0B 0x7F0C 0x7F0D 0x7F0E 0x7F0F 0x7F10 \ + 0x7F11 0x7F12 0x7F13 0x7F14 0x7F15 0x7F16 0x7F17 0x7F18 \ + 0x7F19 0x7F1A 0x7F1B 0x7F1C 0x7F1D 0x7F1E 0x7F1F 0x7F20 \ + 0x7F21 0x7F22 0x7F23 0x7F24 0x7F25 0x7F26 0x7F27 0x7F28 \ + 0x7F29 0x7F2A 0x7F2B 0x7F2C 0x7F2D 0x7F2E 0x7F2F 0x7F30 \ + 0x7F31 0x7F32 0x7F33 0x7F34 0x7F35 0x7F42 0x7F49 0x7F56 \ + 0x7F5A 0x7F74 0x7F81 0x7F9F 0x7FD8 0x7FD9 0x7FDA 0x8022 \ + 0x8027 0x8042 0x804B 0x804C 0x804D 0x8054 0x8069 0x8080 \ + 0x8083 0x80A0 0x80BC 0x80BD 0x80BE 0x80BF 0x80C0 0x80C1 \ + 0x80E7 0x80E8 0x80E9 0x80EA 0x80EB 0x5A02 0x59F8 0x59E2 \ + 0x59D9 0x59E7 0x5B6A 0x5BAB 0x5C1B 0x5C2F 0x663C 0x5CD1 \ + 0x5CDC 0x5CE6 0x5CE1 0x5CCD 0x5CE2 0x5CDD 0x5CE5 0x5DFB \ + 0x5DFA 0x5E1E 0x5EA1 0x5EFC 0x5EFB 0x5F2F 0x5F66 0x605C \ + 0x604E 0x6051 0x6023 0x6031 0x607C 0x6060 0x80EC 0x810C \ + 0x810D 0x810E 0x810F 0x8110 0x8111 0x8112 0x8113 0x8132 +17 0x8136 0x8137 0x8138 0x8156 0x8159 0x815A 0x817B 0x817C \ + 0x817E 0x8191 0x81A5 0x81B6 0x81DC 0x8206 0x8223 0x8230 \ + 0x8231 0x823B 0x823E 0x8254 0x8270 0x8282 0x8288 0x8297 \ + 0x82C7 0x82C8 0x82CB 0x82CC 0x82CD 0x82CE 0x82CF 0x830F \ + 0x8311 0x8313 0x8314 0x8315 0x8359 0x835A 0x835B 0x835C \ + 0x835D 0x835E 0x835F 0x8360 0x8361 0x8364 0x8365 0x8366 \ + 0x8367 0x8368 0x8369 0x836A 0x836B 0x836C 0x836D 0x836E \ + 0x836F 0x83B2 0x83B3 0x83B4 0x83B6 0x83B8 0x83BA 0x83BC \ + 0x841A 0x841C 0x841D 0x8424 0x8425 0x8426 0x8427 0x8428 \ + 0x8487 0x8489 0x848C 0x84DD 0x84DF 0x84E0 0x84E3 0x84E5 \ + 0x84E6 0x8537 0x8539 0x853A 0x853C 0x8572 0x8574 0x85D3 \ + 0x8614 0x864F 0x867F 0x8680 0x8681 0x8682 0x8683 0x86AC \ + 0x86F0 0x86F1 0x86F2 0x86F3 0x86F4 0x8717 0x8748 0x877E \ + 0x8780 0x87A8 0x87CF 0x8854 0x8865 0x886C 0x8885 0x8886 \ + 0x88AD 0x88AF 0x88C6 0x88C7 0x88C8 0x88E2 0x88E3 0x88E4 \ + 0x88E5 0x8934 0x8947 0x8955 0x8980 0x89C1 0x89C2 0x89C3 \ + 0x89C4 0x89C5 0x89C6 0x89C7 0x89C8 0x89C9 0x89CA 0x89CB \ + 0x89CC 0x89CD 0x89CE 0x89CF 0x89D0 0x89D1 0x89DE 0x89EF \ + 0x8A01 0x8A1A 0x8A5F 0x604A 0x6061 0x6218 0x631F 0x6317 \ + 0x62EA 0x6321 0x6304 0x6305 0x6531 0x6544 0x6540 0x6542 \ + 0x65BE 0x6629 0x661B 0x6623 0x662C 0x661A 0x6630 0x663B \ + 0x661E 0x6637 0x6638 0x670E 0x67E8 0x67D6 0x67C7 0x67BC \ + 0x6852 0x67BF 0x67D5 0x67FE 0x8A8A 0x8BA0 0x8BA1 0x8BA2 \ + 0x8BA3 0x8BA4 0x8BA5 0x8BA6 0x8BA7 0x8BA8 0x8BA9 0x8BAA \ + 0x8BAB 0x8BAC 0x8BAD 0x8BAE 0x8BAF 0x8BB0 0x8BB1 0x8BB2 \ + 0x8BB3 0x8BB4 0x8BB5 0x8BB6 0x8BB7 0x8BB8 0x8BB9 0x8BBA \ + 0x8BBB 0x8BBC 0x8BBD 0x8BBE 0x8BBF 0x8BC0 0x8BC1 0x8BC2 \ + 0x8BC3 0x8BC4 0x8BC5 0x8BC6 0x8BC7 0x8BC8 0x8BC9 0x8BCA \ + 0x8BCB 0x8BCC 0x8BCD 0x8BCE 0x8BCF 0x8BD0 0x8BD1 0x8BD2 \ + 0x8BD3 0x8BD4 0x8BD5 0x8BD6 0x8BD7 0x8BD8 0x8BD9 0x8BDA \ + 0x8BDB 0x8BDC 0x8BDD 0x8BDE 0x8BDF 0x8BE0 0x8BE1 0x8BE2 \ + 0x8BE3 0x8BE4 0x8BE5 0x8BE6 0x8BE7 0x8BE8 0x8BE9 0x8BEA +18 0x8BEB 0x8BEC 0x8BED 0x8BEE 0x8BEF 0x8BF0 0x8BF1 0x8BF2 \ + 0x8BF3 0x8BF4 0x8BF5 0x8BF6 0x8BF7 0x8BF8 0x8BF9 0x8BFA \ + 0x8BFB 0x8BFC 0x8BFD 0x8BFE 0x8BFF 0x8C00 0x8C01 0x8C02 \ + 0x8C03 0x8C04 0x8C05 0x8C06 0x8C07 0x8C08 0x8C09 0x8C0A \ + 0x8C0B 0x8C0C 0x8C0D 0x8C0E 0x8C0F 0x8C10 0x8C11 0x8C12 \ + 0x8C13 0x8C14 0x8C15 0x8C16 0x8C17 0x8C18 0x8C19 0x8C1A \ + 0x8C1B 0x8C1C 0x8C1D 0x8C1E 0x8C1F 0x8C20 0x8C21 0x8C22 \ + 0x8C23 0x8C24 0x8C25 0x8C26 0x8C27 0x8C28 0x8C29 0x8C2A \ + 0x8C2B 0x8C2C 0x8C2D 0x8C2E 0x8C2F 0x8C30 0x8C31 0x8C32 \ + 0x8C33 0x8C34 0x8C35 0x8C36 0x8C6E 0x8D1D 0x8D1E 0x8D1F \ + 0x8D20 0x8363 0x67FB 0x67B1 0x6801 0x6805 0x6800 0x67D7 \ + 0x6B2A 0x6B6B 0x6BE1 0x6D23 0x6CFF 0x6D14 0x6D05 0x6D13 \ + 0x6D06 0x6D21 0x6D15 0x6CAF 0x6CF4 0x6D02 0x6D45 0x6D26 \ + 0x6D44 0x6D24 0x70A5 0x70A3 0x70A2 0x70BB 0x70A0 0x70AA \ + 0x70A8 0x70B6 0x8D21 0x8D22 0x8D23 0x8D24 0x8D25 0x8D26 \ + 0x8D27 0x8D28 0x8D29 0x8D2A 0x8D2B 0x8D2C 0x8D2D 0x8D2E \ + 0x8D2F 0x8D30 0x8D31 0x8D32 0x8D33 0x8D34 0x8D35 0x8D36 \ + 0x8D37 0x8D38 0x8D39 0x8D3A 0x8D3B 0x8D3C 0x8D3D 0x8D3E \ + 0x8D3F 0x8D40 0x8D41 0x8D42 0x8D43 0x8D44 0x8D45 0x8D46 \ + 0x8D47 0x8D48 0x8D49 0x8D4A 0x8D4B 0x8D4C 0x8D4D 0x8D4E \ + 0x8D4F 0x8D50 0x8D51 0x8D52 0x8D53 0x8D54 0x8D55 0x8D56 \ + 0x8D57 0x8D58 0x8D59 0x8D5A 0x8D5B 0x8D5C 0x8D5D 0x8D5E \ + 0x8D5F 0x8D60 0x8D61 0x8D62 0x8D63 0x8D6A 0x8D75 0x8DB1 \ + 0x8DB8 0x8DC4 0x8DDE 0x8DF6 0x8DF7 0x8DF8 0x8DF9 0x8DFB \ + 0x8E0C 0x8E0E 0x8E2C 0x8E2D 0x8E2F 0x8E52 0x8E7E 0x8E7F \ + 0x8E80 0x8E8F 0x8E9C 0x8ECE 0x8F66 0x8F67 0x8F68 0x8F69 \ + 0x8F6A 0x8F6B 0x8F6C 0x8F6D 0x8F6E 0x8F6F 0x8F70 0x8F71 \ + 0x8F72 0x8F73 0x8F74 0x8F75 0x8F76 0x8F77 0x8F78 0x8F79 \ + 0x8F7A 0x8F7B 0x8F7C 0x8F7D 0x8F7E 0x8F7F 0x8F80 0x8F81 \ + 0x8F82 0x8F83 0x8F84 0x8F85 0x8F86 0x8F87 0x8F88 0x8F89 \ + 0x8F8A 0x8F8B 0x8F8C 0x8F8D 0x8F8E 0x8F8F 0x8F90 0x8F91 \ + 0x8F92 0x8F93 0x8F94 0x8F95 0x8F96 0x8F97 0x8F98 0x8F99 +19 0x8F9A 0x8FA9 0x8FAB 0x8FBD 0x8FDB 0x8FDD 0x8FDE 0x8FF3 \ + 0x900A 0x9026 0x9057 0x909D 0x90AC 0x90BA 0x90BB 0x70B2 \ + 0x70A7 0x70B9 0x722E 0x723C 0x726D 0x72E7 0x72ED 0x72EC \ + 0x72E5 0x72E2 0x73C4 0x73BD 0x73CF 0x73C9 0x73C1 0x73D0 \ + 0x73CE 0x74ED 0x74EB 0x74EF 0x7549 0x7550 0x7546 0x754A \ + 0x754D 0x75A6 0x75A8 0x76C7 0x76FF 0x76FD 0x77E6 0x780A \ + 0x90CF 0x90D0 0x90D1 0x90D3 0x90E6 0x90E7 0x90F8 0x9142 \ + 0x915D 0x915E 0x9166 0x9171 0x917D 0x917E 0x917F 0x91CA \ + 0x91D2 0x91FA 0x922A 0x9274 0x933E 0x9341 0x93F0 0x9426 \ + 0x9485 0x9486 0x9487 0x9488 0x9489 0x948A 0x948B 0x948C \ + 0x948D 0x948E 0x948F 0x9490 0x9491 0x9492 0x9493 0x9494 \ + 0x9495 0x9496 0x9497 0x9498 0x9499 0x949A 0x949B 0x949C \ + 0x949D 0x949E 0x949F 0x94A0 0x94A1 0x94A2 0x94A3 0x94A4 \ + 0x94A5 0x94A6 0x94A7 0x94A8 0x94A9 0x94AA 0x94AB 0x94AC \ + 0x94AD 0x94AE 0x94AF 0x94B0 0x94B1 0x94B2 0x94B3 0x94B4 \ + 0x94B5 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BB 0x94BC \ + 0x94BD 0x94BE 0x94BF 0x94C0 0x94C1 0x94C2 0x94C3 0x94C4 \ + 0x94C5 0x94C6 0x94C7 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC \ + 0x94CD 0x94CE 0x94CF 0x94D0 0x94D1 0x94D2 0x94D3 0x94D4 \ + 0x94D5 0x94D6 0x94D7 0x94D8 0x94D9 0x94DA 0x94DB 0x94DC \ + 0x94DD 0x94DE 0x94DF 0x94E0 0x94E1 0x94E2 0x94E3 0x94E4 \ + 0x94E5 0x94E6 0x94E7 0x94E8 0x94E9 0x94EA 0x94EB 0x94EC \ + 0x94ED 0x94EE 0x94EF 0x94F0 0x94F1 0x94F2 0x94F3 0x94F4 \ + 0x94F5 0x94F6 0x94F7 0x94F8 0x94F9 0x94FA 0x94FB 0x94FC \ + 0x94FD 0x94FE 0x94FF 0x9500 0x9501 0x9502 0x9503 0x9504 \ + 0x9505 0x9506 0x9507 0x9508 0x9509 0x7804 0x780B 0x7807 \ + 0x7815 0x7808 0x79D3 0x79D4 0x79D0 0x79D7 0x7A7C 0x7A7D \ + 0x7A83 0x7A82 0x7AD4 0x7AD5 0x7AD3 0x7AD0 0x7AD2 0x7AFE \ + 0x7AFC 0x7C77 0x7C7C 0x7C7B 0x7F8F 0x80D3 0x80CB 0x80D2 \ + 0x8109 0x80E2 0x80DF 0x80C6 0x8224 0x82F7 0x950A 0x950B \ + 0x950C 0x950D 0x950E 0x950F 0x9510 0x9511 0x9512 0x9513 \ + 0x9514 0x9515 0x9516 0x9517 0x9518 0x9519 0x951A 0x951B +20 0x951C 0x951D 0x951E 0x951F 0x9520 0x9521 0x9522 0x9523 \ + 0x9524 0x9525 0x9526 0x9527 0x9528 0x9529 0x952A 0x952B \ + 0x952C 0x952D 0x952E 0x952F 0x9530 0x9531 0x9532 0x9533 \ + 0x9534 0x9535 0x9536 0x9537 0x9538 0x9539 0x953A 0x953B \ + 0x953C 0x953D 0x953E 0x953F 0x9540 0x9541 0x9542 0x9543 \ + 0x9544 0x9545 0x9546 0x9547 0x9548 0x9549 0x954A 0x954B \ + 0x954C 0x954D 0x954E 0x954F 0x9550 0x9551 0x9552 0x9553 \ + 0x9554 0x9555 0x9556 0x9557 0x9558 0x9559 0x955A 0x955B \ + 0x955C 0x955D 0x955E 0x955F 0x9560 0x9561 0x9562 0x9563 \ + 0x9564 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B \ + 0x956C 0x956D 0x956E 0x956F 0x9570 0x9571 0x9572 0x9573 \ + 0x9574 0x9575 0x9576 0x957F 0x95E8 0x95E9 0x95EA 0x95EB \ + 0x95EC 0x95ED 0x95EE 0x95EF 0x95F0 0x95F1 0x95F2 0x95F3 \ + 0x95F4 0x95F5 0x95F6 0x95F7 0x95F8 0x95F9 0x95FA 0x95FB \ + 0x95FC 0x95FD 0x95FE 0x95FF 0x9600 0x9601 0x9602 0x9603 \ + 0x9604 0x9605 0x9606 0x9607 0x9608 0x9609 0x960A 0x960B \ + 0x960C 0x960D 0x960E 0x960F 0x9610 0x9611 0x9612 0x9613 \ + 0x9614 0x9615 0x9616 0x82D8 0x82DD 0x82F8 0x82FC 0x82E9 \ + 0x82EE 0x82D0 0x830E 0x82E2 0x830B 0x82FD 0x5179 0x8676 \ + 0x8678 0x8675 0x867D 0x8842 0x8866 0x898C 0x8A05 0x8A06 \ + 0x8C9F 0x8FF1 0x8FE7 0x8FE9 0x8FEF 0x90C2 0x90BC 0x90C6 \ + 0x90C0 0x90CD 0x90C9 0x90C4 0x9617 0x9618 0x9619 0x961A \ + 0x961B 0x961F 0x9635 0x9636 0x9645 0x9646 0x9647 0x9648 \ + 0x9649 0x9667 0x9668 0x9669 0x9690 0x96E0 0x96F3 0x96FE \ + 0x9701 0x972D 0x9753 0x9754 0x9765 0x9791 0x9792 0x97AF \ + 0x97E6 0x97E7 0x97E8 0x97E9 0x97EA 0x97EB 0x97EC 0x9875 \ + 0x9876 0x9877 0x9878 0x9879 0x987A 0x987B 0x987C 0x987D \ + 0x987E 0x987F 0x9880 0x9881 0x9882 0x9883 0x9884 0x9885 \ + 0x9886 0x9887 0x9888 0x9889 0x988A 0x988B 0x988C 0x988D \ + 0x988E 0x988F 0x9890 0x9891 0x9892 0x9893 0x9894 0x9895 \ + 0x9896 0x9897 0x9898 0x9899 0x989A 0x989B 0x989C 0x989D \ + 0x989E 0x989F 0x98A0 0x98A1 0x98A2 0x98A3 0x98A4 0x98A5 +21 0x98A6 0x98A7 0x98CE 0x98CF 0x98D0 0x98D1 0x98D2 0x98D3 \ + 0x98D4 0x98D5 0x98D6 0x98D7 0x98D8 0x98D9 0x98DA 0x98DE \ + 0x98E0 0x98E8 0x990D 0x990F 0x9962 0x9963 0x9964 0x9965 \ + 0x9966 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x996D \ + 0x996E 0x996F 0x9970 0x9971 0x9972 0x9973 0x9974 0x9975 \ + 0x9976 0x9977 0x9978 0x9979 0x997A 0x997B 0x997C 0x997D \ + 0x997E 0x997F 0x9980 0x9981 0x9982 0x9983 0x9984 0x9985 \ + 0x9986 0x9987 0x9988 0x9989 0x998A 0x998B 0x998C 0x998D \ + 0x998E 0x998F 0x9990 0x9991 0x9992 0x9993 0x9994 0x9995 \ + 0x9A6C 0x9581 0x9CEC 0x5032 0x4FF9 0x501D 0x4FFF 0x5004 \ + 0x4FF0 0x5003 0x5002 0x4FFC 0x4FF2 0x5024 0x5008 0x5036 \ + 0x502E 0x5010 0x5038 0x5039 0x4FFD 0x5056 0x4FFB 0x51A3 \ + 0x51A6 0x51A1 0x51C7 0x51C9 0x5260 0x5264 0x5259 0x5265 \ + 0x5267 0x5257 0x9A6D 0x9A6E 0x9A6F 0x9A70 0x9A71 0x9A72 \ + 0x9A73 0x9A74 0x9A75 0x9A76 0x9A77 0x9A78 0x9A79 0x9A7A \ + 0x9A7B 0x9A7C 0x9A7D 0x9A7E 0x9A7F 0x9A80 0x9A81 0x9A82 \ + 0x9A83 0x9A84 0x9A85 0x9A86 0x9A87 0x9A88 0x9A89 0x9A8A \ + 0x9A8B 0x9A8C 0x9A8D 0x9A8E 0x9A8F 0x9A90 0x9A91 0x9A92 \ + 0x9A93 0x9A94 0x9A95 0x9A96 0x9A97 0x9A98 0x9A99 0x9A9A \ + 0x9A9B 0x9A9C 0x9A9D 0x9A9E 0x9A9F 0x9AA0 0x9AA1 0x9AA2 \ + 0x9AA3 0x9AA4 0x9AA5 0x9AA6 0x9AA7 0x9ACB 0x9ACC 0x9B13 \ + 0x9B47 0x9C7C 0x9C7D 0x9C7E 0x9C7F 0x9C80 0x9C81 0x9C82 \ + 0x9C83 0x9C84 0x9C85 0x9C86 0x9C87 0x9C88 0x9C89 0x9C8A \ + 0x9C8B 0x9C8C 0x9C8D 0x9C8E 0x9C8F 0x9C90 0x9C91 0x9C92 \ + 0x9C93 0x9C94 0x9C95 0x9C96 0x9C97 0x9C98 0x9C99 0x9C9A \ + 0x9C9B 0x9C9C 0x9C9D 0x9C9E 0x9C9F 0x9CA0 0x9CA1 0x9CA2 \ + 0x9CA3 0x9CA4 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAA \ + 0x9CAB 0x9CAC 0x9CAD 0x9CAE 0x9CAF 0x9CB0 0x9CB1 0x9CB2 \ + 0x9CB3 0x9CB4 0x9CB5 0x9CB6 0x9CB7 0x9CB8 0x9CB9 0x9CBA \ + 0x9CBB 0x9CBC 0x9CBD 0x9CBE 0x9CBF 0x9CC0 0x9CC1 0x9CC2 \ + 0x9CC3 0x9CC4 0x9CC5 0x9CC6 0x9CC7 0x9CC8 0x9CC9 0x9CCA \ + 0x9CCB 0x9CCC 0x9CCD 0x9CCE 0x9CCF 0x9CD0 0x9CD1 0x9CD2 +22 0x9CD3 0x9CD4 0x9CD5 0x9CD6 0x9CD7 0x9CD8 0x9CD9 0x5263 \ + 0x5253 0x52CF 0x52CE 0x52D0 0x52D1 0x52CC 0x550D 0x54F4 \ + 0x5513 0x54EF 0x54F5 0x54F9 0x5502 0x5500 0x5518 0x54F0 \ + 0x54F6 0x5519 0x5705 0x57C9 0x57B7 0x57CD 0x57BE 0x57BB \ + 0x57DB 0x57C8 0x57C4 0x57C5 0x57D1 0x57CA 0x57C0 0x5A21 \ + 0x9CDA 0x9CDB 0x9CDC 0x9CDD 0x9CDE 0x9CDF 0x9CE0 0x9CE1 \ + 0x9CE2 0x9CE3 0x9CE4 0x9E1F 0x9E20 0x9E21 0x9E22 0x9E23 \ + 0x9E24 0x9E25 0x9E26 0x9E27 0x9E28 0x9E29 0x9E2A 0x9E2B \ + 0x9E2C 0x9E2D 0x9E2E 0x9E2F 0x9E30 0x9E31 0x9E32 0x9E33 \ + 0x9E34 0x9E35 0x9E36 0x9E37 0x9E38 0x9E39 0x9E3A 0x9E3B \ + 0x9E3C 0x9E3D 0x9E3E 0x9E3F 0x9E40 0x9E41 0x9E42 0x9E43 \ + 0x9E44 0x9E45 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4A 0x9E4B \ + 0x9E4C 0x9E4D 0x9E4E 0x9E4F 0x9E50 0x9E51 0x9E52 0x9E53 \ + 0x9E54 0x9E55 0x9E56 0x9E57 0x9E58 0x9E59 0x9E5A 0x9E5B \ + 0x9E5C 0x9E5D 0x9E5E 0x9E5F 0x9E60 0x9E61 0x9E62 0x9E63 \ + 0x9E64 0x9E65 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B \ + 0x9E6C 0x9E6D 0x9E6E 0x9E6F 0x9E70 0x9E71 0x9E72 0x9E73 \ + 0x9E74 0x9E7E 0x9EC9 0x9EE1 0x9EE9 0x9EEA 0x9F0B 0x9F0C \ + 0x9F0D 0x9F51 0x9F7F 0x9F80 0x9F81 0x9F82 0x9F83 0x9F84 \ + 0x9F85 0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A 0x9F8B 0x9F8C \ + 0x9F9A 0x9F9B 0x9F9F 0x4E06 0x4E37 0x4E44 0x4E4A 0x4E55 \ + 0x4E5B 0x4E64 0x4E65 0x4E67 0x4E6B 0x4E6C 0x4E6D 0x4E6E \ + 0x4E6F 0x4E72 0x4E76 0x4E77 0x4E7A 0x4E7B 0x4E7C 0x4E7D \ + 0x4E8A 0x4E90 0x4EBD 0x4ED2 0x4EED 0x4FA4 0x4FAD 0x503B \ + 0x50F2 0x516F 0x517A 0x51E6 0x51E7 0x5A2A 0x5A1D 0x5A0B \ + 0x5A22 0x5A24 0x5A14 0x5A31 0x5A2F 0x5A1A 0x5A12 0x5A26 \ + 0x5BBC 0x5BBB 0x5BB7 0x5C05 0x5C06 0x5C52 0x5C53 0x5CFA \ + 0x5CEB 0x5CF3 0x5CF5 0x5CE9 0x5CEF 0x5E2A 0x5E30 0x5E2E \ + 0x5E2C 0x5E2F 0x5EAF 0x5EA9 0x5EFD 0x5F32 0x51E9 0x5271 \ + 0x5302 0x5381 0x5391 0x53BC 0x5414 0x5455 0x54D8 0x54DB \ + 0x551C 0x551F 0x5569 0x55B8 0x55BD 0x55ED 0x561A 0x565B \ + 0x56A2 0x56CE 0x56D5 0x5726 0x5737 0x5738 0x5786 0x5789 +23 0x57B0 0x57B3 0x57D6 0x5815 0x5841 0x586E 0x5870 0x58B8 \ + 0x58B9 0x58CC 0x58D7 0x58E5 0x58ED 0x591E 0x593B 0x5B36 \ + 0x5B5E 0x5B91 0x5BC9 0x5C02 0x5C26 0x5C2E 0x5C32 0x5C76 \ + 0x5CBC 0x5CBE 0x5CC5 0x5CE0 0x5D2B 0x5D5C 0x5D76 0x5DEA \ + 0x5DEC 0x5DED 0x5DFC 0x5E49 0x5EE4 0x5F09 0x5F16 0x5F45 \ + 0x5FC6 0x603A 0x603E 0x6077 0x6184 0x61F4 0x6244 0x6255 \ + 0x6256 0x62E5 0x6318 0x6327 0x63B4 0x63B5 0x63BB 0x6442 \ + 0x655B 0x657D 0x657E 0x65C0 0x65D5 0x663F 0x6683 0x66FB \ + 0x66FD 0x6730 0x6741 0x6763 0x6764 0x67A0 0x67A9 0x6802 \ + 0x6803 0x680D 0x685B 0x685C 0x685D 0x685F 0x6863 0x6867 \ + 0x688D 0x68BA 0x68BB 0x68BC 0x68C2 0x6919 0x691A 0x6921 \ + 0x6922 0x6923 0x6926 0x6928 0x697E 0x6981 0x698B 0x69DD \ + 0x69DE 0x6A2E 0x6A30 0x6A73 0x6A74 0x6A75 0x6A7B 0x6AC9 \ + 0x6AE4 0x6AF7 0x6B05 0x6B1F 0x6BA9 0x6BB1 0x6BDF 0x6BEE \ + 0x6C0E 0x6C17 0x6C35 0x6C3A 0x6C3D 0x6D4C 0x6D9C 0x6D9E \ + 0x6E13 0x6E7F 0x6E8C 0x6EDE 0x6FF9 0x704E 0x7050 0x7114 \ + 0x713C 0x713E 0x7155 0x5F8E 0x5F93 0x5F8F 0x604F 0x6099 \ + 0x607E 0x6074 0x604B 0x6073 0x6075 0x6056 0x60A9 0x608B \ + 0x60A6 0x6093 0x60AE 0x609E 0x60A7 0x6245 0x632E 0x6352 \ + 0x6330 0x635B 0x6319 0x631B 0x6331 0x635D 0x6337 0x6335 \ + 0x6353 0x635C 0x633F 0x654B 0x7173 0x71F6 0x7233 0x725C \ + 0x72A0 0x731F 0x7320 0x7339 0x7363 0x7364 0x73F1 0x7411 \ + 0x748F 0x7491 0x74E7 0x74F0 0x74F1 0x74F2 0x74FC 0x7505 \ + 0x753C 0x7552 0x7560 0x7569 0x7573 0x7574 0x7582 0x7597 \ + 0x75E9 0x7604 0x7606 0x764D 0x767A 0x770C 0x77C8 0x783A \ + 0x783C 0x783F 0x7872 0x7873 0x7874 0x78B5 0x78B6 0x78F5 \ + 0x7916 0x7934 0x793B 0x7985 0x79F4 0x79FD 0x7A24 0x7A43 \ + 0x7A5D 0x7A63 0x7AC3 0x7B02 0x7B07 0x7B5D 0x7B7A 0x7B7D \ + 0x7B9A 0x7BAA 0x7BCF 0x7BD2 0x7C13 0x7C14 0x7C17 0x7C31 \ + 0x7C61 0x7C82 0x7C8F 0x7C90 0x7CAD 0x7CD8 0x7D26 0x7D9A \ + 0x7D9B 0x7DD5 0x7E05 0x7E28 0x7E4A 0x7E4B 0x7E67 0x7E83 \ + 0x7E90 0x7F53 0x7FAA 0x8062 0x810B 0x8133 0x8135 0x8157 +24 0x81A4 0x81D3 0x8217 0x822E 0x824D 0x825D 0x8260 0x827A \ + 0x82C6 0x83B1 0x83B5 0x83BB 0x8419 0x8420 0x8422 0x8485 \ + 0x848A 0x848B 0x84D9 0x84DC 0x8536 0x85AD 0x85AE 0x8612 \ + 0x8630 0x8644 0x86AB 0x86CD 0x86CE 0x86EF 0x8749 0x874B \ + 0x877F 0x87A6 0x87A7 0x87D0 0x8864 0x88AE 0x88B0 0x88C3 \ + 0x88C4 0x88C5 0x8904 0x891C 0x891D 0x8945 0x8968 0x8977 \ + 0x8A33 0x8A89 0x8AAD 0x8AAE 0x8ADA 0x8B21 0x8B5B 0x8B72 \ + 0x8B8F 0x8CCE 0x8DE5 0x8DF5 0x8E7D 0x8E9B 0x8EB5 0x8EBB \ + 0x8EC5 0x658B 0x659A 0x6650 0x6646 0x664E 0x6640 0x664B \ + 0x6648 0x6660 0x6644 0x664D 0x6837 0x6824 0x681B 0x6836 \ + 0x682C 0x6819 0x6856 0x6847 0x683E 0x681E 0x6815 0x6822 \ + 0x6827 0x6859 0x6858 0x6855 0x6830 0x6823 0x6B2E 0x6B2B \ + 0x6B30 0x6B6C 0x8EC8 0x8EE2 0x8EE3 0x8F0C 0x8F4C 0x8FBA \ + 0x8FDA 0x8FF2 0x9027 0x9039 0x9056 0x9065 0x915B 0x9197 \ + 0x91A4 0x91B8 0x91C8 0x91E1 0x91FB 0x91FC 0x9228 0x9229 \ + 0x922C 0x9271 0x9344 0x93BA 0x9421 0x9441 0x9453 0x958A \ + 0x95AA 0x95CF 0x9665 0x9666 0x967A 0x974C 0x974E 0x974F \ + 0x9771 0x9786 0x9790 0x982C 0x98AA 0x98B4 0x98C5 0x98EE \ + 0x99C5 0x99F2 0x9A12 0x9A13 0x9A28 0x9AC5 0x9B36 0x9B5E \ + 0x9B78 0x9B97 0x9BB2 0x9BB4 0x9BCE 0x9BD0 0x9BD1 0x9BF1 \ + 0x9BF2 0x9BF5 0x9C18 0x9C19 0x9C1A 0x9C30 0x9C5A 0x9C5B \ + 0x9C5C 0x9C69 0x9C6A 0x9C6B 0x9C70 0x9CF0 0x9D0E 0x9D2B \ + 0x9D2C 0x9D46 0x9D48 0x9D65 0x9D8E 0x9D8F 0x9DAB 0x9DC6 \ + 0x9E78 0x9EB8 0x9EB9 0x9EBA 0x9F21 0x9F62 0xFFFE 0xFFFE \ + 0x3000 0xFF0C 0x3001 0x3002 0xFF0E 0x2027 0xFF1B 0xFF1A \ + 0xFF1F 0xFF01 0xFE30 0x2026 0x2025 0xFE50 0xFE51 0xFE52 \ + 0x00B7 0xFE54 0xFE55 0xFE56 0xFE57 0xFF5C 0x2015 0xFE31 \ + 0x2014 0xFE33 0x2574 0xFE34 0xFE4F 0xFF08 0xFF09 0xFE35 \ + 0xFE36 0xFF5B 0xFF5D 0xFE37 0xFE38 0x3014 0x3015 0xFE39 \ + 0xFE3A 0x3010 0x3011 0xFE3B 0xFE3C 0x300A 0x300B 0xFE3D \ + 0xFE3E 0x3008 0x3009 0xFE3F 0xFE40 0x300C 0x300D 0xFE41 \ + 0xFE42 0x300E 0x300F 0xFE43 0xFE44 0xFE59 0xFE5A 0x6B8B +25 0x6BE9 0x6BEA 0x6BE5 0x6D6B 0x6D73 0x6D57 0x6D5D 0x6D56 \ + 0x6D8F 0x6D5B 0x6D1C 0x6D9A 0x6D9B 0x6D99 0x6D81 0x6D71 \ + 0x6D72 0x6D5C 0x6D96 0x70C4 0x70DB 0x70CC 0x70D0 0x70E3 \ + 0x70DF 0x70D6 0x70EE 0x70D5 0x727A 0x72F5 0x7302 0x73E2 \ + 0xFE5B 0xFE5C 0xFE5D 0xFE5E 0x2018 0x2019 0x201C 0x201D \ + 0x301D 0x301E 0x2035 0x2032 0xFF03 0xFF06 0xFF0A 0x203B \ + 0x00A7 0x3003 0x25CB 0x25CF 0x25B3 0x25B2 0x25CE 0x2606 \ + 0x2605 0x25C7 0x25C6 0x25A1 0x25A0 0x25BD 0x25BC 0x32A3 \ + 0x2105 0x203E 0xFFE3 0xFF3F 0x02CD 0xFE49 0xFE4A 0xFE4D \ + 0xFE4E 0xFE4B 0xFE4C 0xFE5F 0xFE60 0xFE61 0xFF0B 0xFF0D \ + 0x00D7 0x00F7 0x00B1 0x221A 0xFF1C 0xFF1E 0xFF1D 0x2266 \ + 0x2267 0x2260 0x221E 0x2252 0x2261 0xFE62 0xFE63 0xFE64 \ + 0xFE65 0xFE66 0xFF5E 0x2229 0x222A 0x22A5 0x2220 0x221F \ + 0x22BF 0x33D2 0x33D1 0x222B 0x222E 0x2235 0x2234 0x2640 \ + 0x2642 0x2295 0x2299 0x2191 0x2193 0x2190 0x2192 0x2196 \ + 0x2197 0x2199 0x2198 0x2225 0x2223 0xFF0F 0xFF3C 0x2215 \ + 0xFE68 0xFF04 0xFFE5 0x3012 0xFFE0 0xFFE1 0xFF05 0xFF20 \ + 0x2103 0x2109 0xFE69 0xFE6A 0xFE6B 0x33D5 0x339C 0x339D \ + 0x339E 0x33CE 0x33A1 0x338E 0x338F 0x33C4 0x00B0 0x5159 \ + 0x515B 0x515E 0x515D 0x5161 0x5163 0x55E7 0x74E9 0x7CCE \ + 0x2581 0x2582 0x2583 0x2584 0x2585 0x2586 0x2587 0x2588 \ + 0x258F 0x258E 0x258D 0x258C 0x258B 0x258A 0x2589 0x253C \ + 0x2534 0x252C 0x2524 0x251C 0x2594 0x2500 0x2502 0x2595 \ + 0x250C 0x2510 0x2514 0x2518 0x256D 0x73EC 0x73D5 0x73F9 \ + 0x73DF 0x73E6 0x73E4 0x73E1 0x74F3 0x7556 0x7555 0x7558 \ + 0x7557 0x755E 0x75C3 0x75B4 0x75B1 0x76CB 0x76CC 0x772A \ + 0x7716 0x770F 0x773F 0x772B 0x770E 0x7724 0x7721 0x7718 \ + 0x77DD 0x7824 0x7836 0x7958 0x7959 0x7962 0x256E 0x2570 \ + 0x256F 0x2501 0x251D 0x253F 0x2525 0x25E2 0x25E3 0x25E5 \ + 0x25E4 0x2571 0x2572 0x2573 0xFF10 0xFF11 0xFF12 0xFF13 \ + 0xFF14 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0x2160 0x2161 \ + 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 +26 0x3021 0x3022 0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 \ + 0x3029 0x5341 0x5344 0x5345 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF41 0xFF42 \ + 0xFF43 0xFF44 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A \ + 0xFF4B 0xFF4C 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 \ + 0xFF53 0xFF54 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A \ + 0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 \ + 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 \ + 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 \ + 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 \ + 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 \ + 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 \ + 0x3105 0x3106 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C \ + 0x310D 0x310E 0x310F 0x79DA 0x79D9 0x79E1 0x79E5 0x79E8 \ + 0x79DB 0x79E2 0x79F0 0x7ADA 0x7ADD 0x7ADB 0x7ADC 0x7B0D \ + 0x7B0B 0x7B14 0x7C8E 0x7C86 0x7C87 0x7C83 0x7C8B 0x7D24 \ + 0x7D25 0x7F62 0x7F93 0x7F99 0x7F97 0x7FC4 0x7FC6 0x800A \ + 0x8040 0x803C 0x803B 0x80F6 0x3110 0x3111 0x3112 0x3113 \ + 0x3114 0x3115 0x3116 0x3117 0x3118 0x3119 0x311A 0x311B \ + 0x311C 0x311D 0x311E 0x311F 0x3120 0x3121 0x3122 0x3123 \ + 0x3124 0x3125 0x3126 0x3127 0x3128 0x3129 0x02D9 0x02C9 \ + 0x02CA 0x02C7 0x02CB 0x2400 0x2401 0x2402 0x2403 0x2404 \ + 0x2405 0x2406 0x2407 0x2408 0x2409 0x240A 0x240B 0x240C \ + 0x240D 0x240E 0x240F 0x2410 0x2411 0x2412 0x2413 0x2414 \ + 0x2415 0x2416 0x2417 0x2418 0x2419 0x241A 0x241B 0x241C \ + 0x241D 0x241E 0x241F 0x2421 0x532C 0x5359 0x5368 0x537E \ + 0x53A1 0x555B 0x5542 0x5547 0x553D 0x5560 0x57EB 0x595F \ + 0x5B6F 0x5C5A 0x5FA2 0x5F9D 0x5FA3 0x60C2 0x60A5 0x621C \ + 0x621D 0x6395 0x639A 0x63A6 0x6550 0x6552 0x65C8 0x6658 \ + 0x6888 0x6BB8 0x4E00 0x4E59 0x4E01 0x4E03 0x4E43 0x4E5D +27 0x4E86 0x4E8C 0x4EBA 0x513F 0x5165 0x516B 0x51E0 0x5200 \ + 0x5201 0x529B 0x5315 0x5341 0x535C 0x53C8 0x4E09 0x4E0B \ + 0x4E08 0x4E0A 0x4E2B 0x4E38 0x51E1 0x4E45 0x4E48 0x4E5F \ + 0x4E5E 0x4E8E 0x4EA1 0x5140 0x5203 0x52FA 0x5343 0x53C9 \ + 0x53E3 0x571F 0x58EB 0x5915 0x5927 0x5973 0x5B50 0x5B51 \ + 0x5B53 0x5BF8 0x5C0F 0x5C22 0x5C38 0x5C71 0x5DDD 0x5DE5 \ + 0x5DF1 0x5DF2 0x5DF3 0x5DFE 0x5E72 0x5EFE 0x5F0B 0x5F13 \ + 0x624D 0x80FF 0x80EE 0x8104 0x8103 0x8107 0x80F7 0x822D \ + 0x8227 0x8229 0x831F 0x8357 0x8321 0x8318 0x8358 0x8684 \ + 0x869F 0x869B 0x8689 0x86A6 0x8692 0x868F 0x86A0 0x884F \ + 0x8878 0x887A 0x886E 0x887B 0x8884 0x8873 0x8A0D 0x8A0B \ + 0x8A19 0x8ED0 0x4E11 0x4E10 0x4E0D 0x4E2D 0x4E30 0x4E39 \ + 0x4E4B 0x5C39 0x4E88 0x4E91 0x4E95 0x4E92 0x4E94 0x4EA2 \ + 0x4EC1 0x4EC0 0x4EC3 0x4EC6 0x4EC7 0x4ECD 0x4ECA 0x4ECB \ + 0x4EC4 0x5143 0x5141 0x5167 0x516D 0x516E 0x516C 0x5197 \ + 0x51F6 0x5206 0x5207 0x5208 0x52FB 0x52FE 0x52FF 0x5316 \ + 0x5339 0x5348 0x5347 0x5345 0x535E 0x5384 0x53CB 0x53CA \ + 0x53CD 0x58EC 0x5929 0x592B 0x592A 0x592D 0x5B54 0x5C11 \ + 0x5C24 0x5C3A 0x5C6F 0x5DF4 0x5E7B 0x5EFF 0x5F14 0x5F15 \ + 0x5FC3 0x6208 0x6236 0x624B 0x624E 0x652F 0x6587 0x6597 \ + 0x65A4 0x65B9 0x65E5 0x66F0 0x6708 0x6728 0x6B20 0x6B62 \ + 0x6B79 0x6BCB 0x6BD4 0x6BDB 0x6C0F 0x6C34 0x706B 0x722A \ + 0x7236 0x723B 0x7247 0x7259 0x725B 0x72AC 0x738B 0x4E19 \ + 0x4E16 0x4E15 0x4E14 0x4E18 0x4E3B 0x4E4D 0x4E4F 0x4E4E \ + 0x4EE5 0x4ED8 0x4ED4 0x4ED5 0x4ED6 0x4ED7 0x4EE3 0x4EE4 \ + 0x4ED9 0x4EDE 0x5145 0x5144 0x5189 0x518A 0x51AC 0x51F9 \ + 0x51FA 0x51F8 0x520A 0x52A0 0x529F 0x5305 0x5306 0x5317 \ + 0x531D 0x4EDF 0x534A 0x5349 0x5361 0x5360 0x536F 0x536E \ + 0x53BB 0x53EF 0x53E4 0x53F3 0x53EC 0x53EE 0x53E9 0x53E8 \ + 0x53FC 0x53F8 0x53F5 0x53EB 0x53E6 0x53EA 0x53F2 0x53F1 \ + 0x53F0 0x53E5 0x53ED 0x53FB 0x56DB 0x56DA 0x5916 0x8FF9 \ + 0x9009 0x9008 0x90DE 0x9151 0x91DB 0x91DF 0x91DE 0x91D6 +28 0x91E0 0x9585 0x9660 0x9659 0x9656 0x96BD 0x5042 0x5059 \ + 0x5044 0x5066 0x5052 0x5054 0x5071 0x5050 0x507B 0x507C \ + 0x5058 0x5079 0x506C 0x5078 0x51A8 0x51D1 0x51CF 0x5268 \ + 0x592E 0x5931 0x5974 0x5976 0x5B55 0x5B83 0x5C3C 0x5DE8 \ + 0x5DE7 0x5DE6 0x5E02 0x5E03 0x5E73 0x5E7C 0x5F01 0x5F18 \ + 0x5F17 0x5FC5 0x620A 0x6253 0x6254 0x6252 0x6251 0x65A5 \ + 0x65E6 0x672E 0x672C 0x672A 0x672B 0x672D 0x6B63 0x6BCD \ + 0x6C11 0x6C10 0x6C38 0x6C41 0x6C40 0x6C3E 0x72AF 0x7384 \ + 0x7389 0x74DC 0x74E6 0x7518 0x751F 0x7528 0x7529 0x7530 \ + 0x7531 0x7532 0x7533 0x758B 0x767D 0x76AE 0x76BF 0x76EE \ + 0x77DB 0x77E2 0x77F3 0x793A 0x79BE 0x7A74 0x7ACB 0x4E1E \ + 0x4E1F 0x4E52 0x4E53 0x4E69 0x4E99 0x4EA4 0x4EA6 0x4EA5 \ + 0x4EFF 0x4F09 0x4F19 0x4F0A 0x4F15 0x4F0D 0x4F10 0x4F11 \ + 0x4F0F 0x4EF2 0x4EF6 0x4EFB 0x4EF0 0x4EF3 0x4EFD 0x4F01 \ + 0x4F0B 0x5149 0x5147 0x5146 0x5148 0x5168 0x5171 0x518D \ + 0x51B0 0x5217 0x5211 0x5212 0x520E 0x5216 0x52A3 0x5308 \ + 0x5321 0x5320 0x5370 0x5371 0x5409 0x540F 0x540C 0x540A \ + 0x5410 0x5401 0x540B 0x5404 0x5411 0x540D 0x5408 0x5403 \ + 0x540E 0x5406 0x5412 0x56E0 0x56DE 0x56DD 0x5733 0x5730 \ + 0x5728 0x572D 0x572C 0x572F 0x5729 0x5919 0x591A 0x5937 \ + 0x5938 0x5984 0x5978 0x5983 0x597D 0x5979 0x5982 0x5981 \ + 0x5B57 0x5B58 0x5B87 0x5B88 0x5B85 0x5B89 0x5BFA 0x5C16 \ + 0x5C79 0x5DDE 0x5E06 0x5E76 0x5E74 0x5276 0x52D4 0x53A0 \ + 0x53C4 0x5558 0x554C 0x5568 0x5549 0x555D 0x5529 0x5554 \ + 0x5553 0x555A 0x553A 0x553F 0x552B 0x57EA 0x57EF 0x57DD \ + 0x57FE 0x57DE 0x57E6 0x57E8 0x57FF 0x5803 0x58F7 0x68A6 \ + 0x591F 0x595B 0x595D 0x595E 0x5A2B 0x5A3B 0x5F0F 0x5F1B \ + 0x5FD9 0x5FD6 0x620E 0x620C 0x620D 0x6210 0x6263 0x625B \ + 0x6258 0x6536 0x65E9 0x65E8 0x65EC 0x65ED 0x66F2 0x66F3 \ + 0x6709 0x673D 0x6734 0x6731 0x6735 0x6B21 0x6B64 0x6B7B \ + 0x6C16 0x6C5D 0x6C57 0x6C59 0x6C5F 0x6C60 0x6C50 0x6C55 \ + 0x6C61 0x6C5B 0x6C4D 0x6C4E 0x7070 0x725F 0x725D 0x767E +29 0x7AF9 0x7C73 0x7CF8 0x7F36 0x7F8A 0x7FBD 0x8001 0x8003 \ + 0x800C 0x8012 0x8033 0x807F 0x8089 0x808B 0x808C 0x81E3 \ + 0x81EA 0x81F3 0x81FC 0x820C 0x821B 0x821F 0x826E 0x8272 \ + 0x827E 0x866B 0x8840 0x884C 0x8863 0x897F 0x9621 0x4E32 \ + 0x4EA8 0x4F4D 0x4F4F 0x4F47 0x4F57 0x4F5E 0x4F34 0x4F5B \ + 0x4F55 0x4F30 0x4F50 0x4F51 0x4F3D 0x4F3A 0x4F38 0x4F43 \ + 0x4F54 0x4F3C 0x4F46 0x4F63 0x4F5C 0x4F60 0x4F2F 0x4F4E \ + 0x4F36 0x4F59 0x4F5D 0x4F48 0x4F5A 0x514C 0x514B 0x514D \ + 0x5175 0x51B6 0x51B7 0x5225 0x5224 0x5229 0x522A 0x5228 \ + 0x52AB 0x52A9 0x52AA 0x52AC 0x5323 0x5373 0x5375 0x541D \ + 0x542D 0x541E 0x543E 0x5426 0x544E 0x5427 0x5446 0x5443 \ + 0x5433 0x5448 0x5442 0x541B 0x5429 0x544A 0x5439 0x543B \ + 0x5438 0x542E 0x5435 0x5436 0x5420 0x543C 0x5440 0x5431 \ + 0x542B 0x541F 0x542C 0x56EA 0x56F0 0x56E4 0x56EB 0x574A \ + 0x5751 0x5740 0x574D 0x5A61 0x5A3A 0x5A6E 0x5A4B 0x5A6B \ + 0x5A45 0x5A4E 0x5A68 0x5A3D 0x5A71 0x5A3F 0x5A6F 0x5A75 \ + 0x5A73 0x5A2C 0x5A59 0x5A54 0x5A4F 0x5A63 0x5BC8 0x5BC3 \ + 0x5C5B 0x5C61 0x5D21 0x5D0A 0x5D09 0x5D2C 0x5D08 0x5D2A \ + 0x5D15 0x5D10 0x5D13 0x5D2F 0x5747 0x574E 0x573E 0x5750 \ + 0x574F 0x573B 0x58EF 0x593E 0x599D 0x5992 0x59A8 0x599E \ + 0x59A3 0x5999 0x5996 0x598D 0x59A4 0x5993 0x598A 0x59A5 \ + 0x5B5D 0x5B5C 0x5B5A 0x5B5B 0x5B8C 0x5B8B 0x5B8F 0x5C2C \ + 0x5C40 0x5C41 0x5C3F 0x5C3E 0x5C90 0x5C91 0x5C94 0x5C8C \ + 0x5DEB 0x5E0C 0x5E8F 0x5E87 0x5E8A 0x5EF7 0x5F04 0x5F1F \ + 0x5F64 0x5F62 0x5F77 0x5F79 0x5FD8 0x5FCC 0x5FD7 0x5FCD \ + 0x5FF1 0x5FEB 0x5FF8 0x5FEA 0x6212 0x6211 0x6284 0x6297 \ + 0x6296 0x6280 0x6276 0x6289 0x626D 0x628A 0x627C 0x627E \ + 0x6279 0x6273 0x6292 0x626F 0x6298 0x626E 0x6295 0x6293 \ + 0x6291 0x6286 0x6539 0x653B 0x6538 0x65F1 0x66F4 0x675F \ + 0x674E 0x674F 0x6750 0x6751 0x675C 0x6756 0x675E 0x6749 \ + 0x6746 0x6760 0x6753 0x6757 0x6B65 0x6BCF 0x6C42 0x6C5E \ + 0x6C99 0x6C81 0x6C88 0x6C89 0x6C85 0x6C9B 0x6C6A 0x6C7A +30 0x6C90 0x6C70 0x6C8C 0x6C68 0x6C96 0x6C92 0x6C7D 0x6C83 \ + 0x6C72 0x6C7E 0x6C74 0x6C86 0x6C76 0x6C8D 0x6C94 0x6C98 \ + 0x6C82 0x7076 0x707C 0x707D 0x7078 0x7262 0x7261 0x7260 \ + 0x72C4 0x72C2 0x7396 0x752C 0x752B 0x7537 0x7538 0x7682 \ + 0x76EF 0x77E3 0x79C1 0x79C0 0x79BF 0x7A76 0x7CFB 0x7F55 \ + 0x8096 0x8093 0x809D 0x8098 0x809B 0x809A 0x80B2 0x826F \ + 0x8292 0x5D18 0x5DE3 0x5E39 0x5E35 0x5E3A 0x5E32 0x5EBB \ + 0x5EBA 0x5F34 0x5F39 0x6098 0x60D0 0x60D7 0x60AA 0x60A1 \ + 0x60A4 0x60EE 0x60E7 0x60E8 0x60DE 0x637E 0x638B 0x6379 \ + 0x6386 0x6393 0x6373 0x636A 0x636C 0x637F 0x63B2 0x63BA \ + 0x6366 0x6374 0x828B 0x828D 0x898B 0x89D2 0x8A00 0x8C37 \ + 0x8C46 0x8C55 0x8C9D 0x8D64 0x8D70 0x8DB3 0x8EAB 0x8ECA \ + 0x8F9B 0x8FB0 0x8FC2 0x8FC6 0x8FC5 0x8FC4 0x5DE1 0x9091 \ + 0x90A2 0x90AA 0x90A6 0x90A3 0x9149 0x91C6 0x91CC 0x9632 \ + 0x962E 0x9631 0x962A 0x962C 0x4E26 0x4E56 0x4E73 0x4E8B \ + 0x4E9B 0x4E9E 0x4EAB 0x4EAC 0x4F6F 0x4F9D 0x4F8D 0x4F73 \ + 0x4F7F 0x4F6C 0x4F9B 0x4F8B 0x4F86 0x4F83 0x4F70 0x4F75 \ + 0x4F88 0x4F69 0x4F7B 0x4F96 0x4F7E 0x4F8F 0x4F91 0x4F7A \ + 0x5154 0x5152 0x5155 0x5169 0x5177 0x5176 0x5178 0x51BD \ + 0x51FD 0x523B 0x5238 0x5237 0x523A 0x5230 0x522E 0x5236 \ + 0x5241 0x52BE 0x52BB 0x5352 0x5354 0x5353 0x5351 0x5366 \ + 0x5377 0x5378 0x5379 0x53D6 0x53D4 0x53D7 0x5473 0x5475 \ + 0x5496 0x5478 0x5495 0x5480 0x547B 0x5477 0x5484 0x5492 \ + 0x5486 0x547C 0x5490 0x5471 0x5476 0x548C 0x549A 0x5462 \ + 0x5468 0x548B 0x547D 0x548E 0x56FA 0x5783 0x5777 0x576A \ + 0x5769 0x5761 0x5766 0x5764 0x577C 0x591C 0x5949 0x5947 \ + 0x5948 0x5944 0x5954 0x59BE 0x59BB 0x59D4 0x59B9 0x59AE \ + 0x59D1 0x59C6 0x59D0 0x59CD 0x59CB 0x59D3 0x59CA 0x59AF \ + 0x59B3 0x59D2 0x59C5 0x5B5F 0x5B64 0x5B63 0x5B97 0x5B9A \ + 0x5B98 0x5B9C 0x5B99 0x5B9B 0x5C1A 0x5C48 0x5C45 0x655A \ + 0x654E 0x654D 0x658D 0x658E 0x65AD 0x65C7 0x65CA 0x65C9 \ + 0x65E3 0x6657 0x6663 0x6667 0x671A 0x6719 0x6716 0x689E +31 0x68B6 0x6898 0x6873 0x689A 0x688E 0x68B7 0x68DB 0x68A5 \ + 0x686C 0x68C1 0x6884 0x6895 0x687A 0x6899 0x68B8 0x68B9 \ + 0x5C46 0x5CB7 0x5CA1 0x5CB8 0x5CA9 0x5CAB 0x5CB1 0x5CB3 \ + 0x5E18 0x5E1A 0x5E16 0x5E15 0x5E1B 0x5E11 0x5E78 0x5E9A \ + 0x5E97 0x5E9C 0x5E95 0x5E96 0x5EF6 0x5F26 0x5F27 0x5F29 \ + 0x5F80 0x5F81 0x5F7F 0x5F7C 0x5FDD 0x5FE0 0x5FFD 0x5FF5 \ + 0x5FFF 0x600F 0x6014 0x602F 0x6035 0x6016 0x602A 0x6015 \ + 0x6021 0x6027 0x6029 0x602B 0x601B 0x6216 0x6215 0x623F \ + 0x623E 0x6240 0x627F 0x62C9 0x62CC 0x62C4 0x62BF 0x62C2 \ + 0x62B9 0x62D2 0x62DB 0x62AB 0x62D3 0x62D4 0x62CB 0x62C8 \ + 0x62A8 0x62BD 0x62BC 0x62D0 0x62D9 0x62C7 0x62CD 0x62B5 \ + 0x62DA 0x62B1 0x62D8 0x62D6 0x62D7 0x62C6 0x62AC 0x62CE \ + 0x653E 0x65A7 0x65BC 0x65FA 0x6614 0x6613 0x660C 0x6606 \ + 0x6602 0x660E 0x6600 0x660F 0x6615 0x660A 0x6607 0x670D \ + 0x670B 0x676D 0x678B 0x6795 0x6771 0x679C 0x6773 0x6777 \ + 0x6787 0x679D 0x6797 0x676F 0x6770 0x677F 0x6789 0x677E \ + 0x6790 0x6775 0x679A 0x6793 0x677C 0x676A 0x6772 0x6B23 \ + 0x6B66 0x6B67 0x6B7F 0x6C13 0x6C1B 0x6CE3 0x6CE8 0x6CF3 \ + 0x6CB1 0x6CCC 0x6CE5 0x6CB3 0x6CBD 0x6CBE 0x6CBC 0x6CE2 \ + 0x6CAB 0x6CD5 0x6CD3 0x6CB8 0x6CC4 0x6CB9 0x6CC1 0x6CAE \ + 0x6CD7 0x6CC5 0x6CF1 0x6CBF 0x6CBB 0x6CE1 0x6CDB 0x6CCA \ + 0x6CAC 0x6CEF 0x6CDC 0x6CD6 0x6CE0 0x6870 0x6B35 0x6B90 \ + 0x6BBB 0x6BED 0x6DC1 0x6DC3 0x6DCE 0x6DAD 0x6E04 0x6DB9 \ + 0x6DE7 0x6E08 0x6E06 0x6E0A 0x6DB0 0x6DF8 0x6E0C 0x6DB1 \ + 0x6E02 0x6E07 0x6E09 0x6E01 0x6E17 0x6DFF 0x6E12 0x7103 \ + 0x7107 0x7101 0x70F5 0x70F1 0x7108 0x70F2 0x7095 0x708E \ + 0x7092 0x708A 0x7099 0x722C 0x722D 0x7238 0x7248 0x7267 \ + 0x7269 0x72C0 0x72CE 0x72D9 0x72D7 0x72D0 0x73A9 0x73A8 \ + 0x739F 0x73AB 0x73A5 0x753D 0x759D 0x7599 0x759A 0x7684 \ + 0x76C2 0x76F2 0x76F4 0x77E5 0x77FD 0x793E 0x7940 0x7941 \ + 0x79C9 0x79C8 0x7A7A 0x7A79 0x7AFA 0x7CFE 0x7F54 0x7F8C \ + 0x7F8B 0x8005 0x80BA 0x80A5 0x80A2 0x80B1 0x80A1 0x80AB +32 0x80A9 0x80B4 0x80AA 0x80AF 0x81E5 0x81FE 0x820D 0x82B3 \ + 0x829D 0x8299 0x82AD 0x82BD 0x829F 0x82B9 0x82B1 0x82AC \ + 0x82A5 0x82AF 0x82B8 0x82A3 0x82B0 0x82BE 0x82B7 0x864E \ + 0x8671 0x521D 0x8868 0x8ECB 0x8FCE 0x8FD4 0x8FD1 0x90B5 \ + 0x90B8 0x90B1 0x90B6 0x91C7 0x91D1 0x9577 0x9580 0x961C \ + 0x9640 0x963F 0x963B 0x9644 0x9642 0x96B9 0x96E8 0x9752 \ + 0x975E 0x4E9F 0x4EAD 0x4EAE 0x4FE1 0x4FB5 0x4FAF 0x4FBF \ + 0x4FE0 0x4FD1 0x4FCF 0x4FDD 0x4FC3 0x4FB6 0x4FD8 0x4FDF \ + 0x4FCA 0x4FD7 0x4FAE 0x4FD0 0x4FC4 0x4FC2 0x4FDA 0x4FCE \ + 0x4FDE 0x4FB7 0x5157 0x5192 0x5191 0x51A0 0x524E 0x5243 \ + 0x524A 0x524D 0x524C 0x524B 0x5247 0x52C7 0x52C9 0x52C3 \ + 0x52C1 0x530D 0x5357 0x537B 0x539A 0x53DB 0x54AC 0x54C0 \ + 0x54A8 0x54CE 0x54C9 0x54B8 0x54A6 0x54B3 0x54C7 0x54C2 \ + 0x54BD 0x54AA 0x54C1 0x710F 0x70FE 0x731A 0x7310 0x730E \ + 0x7402 0x73F3 0x73FB 0x751B 0x7523 0x7561 0x7568 0x7567 \ + 0x75D3 0x7690 0x76D5 0x76D7 0x76D6 0x7730 0x7726 0x7740 \ + 0x771E 0x7847 0x784B 0x7851 0x784F 0x7842 0x7846 0x796E \ + 0x796C 0x79F2 0x79F1 0x79F5 0x54C4 0x54C8 0x54AF 0x54AB \ + 0x54B1 0x54BB 0x54A9 0x54A7 0x54BF 0x56FF 0x5782 0x578B \ + 0x57A0 0x57A3 0x57A2 0x57CE 0x57AE 0x5793 0x5955 0x5951 \ + 0x594F 0x594E 0x5950 0x59DC 0x59D8 0x59FF 0x59E3 0x59E8 \ + 0x5A03 0x59E5 0x59EA 0x59DA 0x59E6 0x5A01 0x59FB 0x5B69 \ + 0x5BA3 0x5BA6 0x5BA4 0x5BA2 0x5BA5 0x5C01 0x5C4E 0x5C4F \ + 0x5C4D 0x5C4B 0x5CD9 0x5CD2 0x5DF7 0x5E1D 0x5E25 0x5E1F \ + 0x5E7D 0x5EA0 0x5EA6 0x5EFA 0x5F08 0x5F2D 0x5F65 0x5F88 \ + 0x5F85 0x5F8A 0x5F8B 0x5F87 0x5F8C 0x5F89 0x6012 0x601D \ + 0x6020 0x6025 0x600E 0x6028 0x604D 0x6070 0x6068 0x6062 \ + 0x6046 0x6043 0x606C 0x606B 0x606A 0x6064 0x6241 0x62DC \ + 0x6316 0x6309 0x62FC 0x62ED 0x6301 0x62EE 0x62FD 0x6307 \ + 0x62F1 0x62F7 0x62EF 0x62EC 0x62FE 0x62F4 0x6311 0x6302 \ + 0x653F 0x6545 0x65AB 0x65BD 0x65E2 0x6625 0x662D 0x6620 \ + 0x6627 0x662F 0x661F 0x6628 0x6631 0x6624 0x66F7 0x67FF +33 0x67D3 0x67F1 0x67D4 0x67D0 0x67EC 0x67B6 0x67AF 0x67F5 \ + 0x67E9 0x67EF 0x67C4 0x67D1 0x67B4 0x67DA 0x67E5 0x67B8 \ + 0x67CF 0x67DE 0x67F3 0x67B0 0x67D9 0x67E2 0x67DD 0x67D2 \ + 0x6B6A 0x6B83 0x6B86 0x6BB5 0x6BD2 0x6BD7 0x6C1F 0x6CC9 \ + 0x6D0B 0x6D32 0x6D2A 0x6D41 0x6D25 0x6D0C 0x6D31 0x6D1E \ + 0x6D17 0x79F3 0x79F9 0x7A9A 0x7A93 0x7A91 0x7AE1 0x7B21 \ + 0x7B1C 0x7B16 0x7B17 0x7B36 0x7B1F 0x7C93 0x7C99 0x7C9A \ + 0x7C9C 0x7D49 0x7D34 0x7D37 0x7D2D 0x7D4C 0x7D48 0x7F3B \ + 0x8008 0x801A 0x801D 0x8049 0x8045 0x8044 0x7C9B 0x812A \ + 0x812E 0x8131 0x6D3B 0x6D3D 0x6D3E 0x6D36 0x6D1B 0x6CF5 \ + 0x6D39 0x6D27 0x6D38 0x6D29 0x6D2E 0x6D35 0x6D0E 0x6D2B \ + 0x70AB 0x70BA 0x70B3 0x70AC 0x70AF 0x70AD 0x70B8 0x70AE \ + 0x70A4 0x7230 0x7272 0x726F 0x7274 0x72E9 0x72E0 0x72E1 \ + 0x73B7 0x73CA 0x73BB 0x73B2 0x73CD 0x73C0 0x73B3 0x751A \ + 0x752D 0x754F 0x754C 0x754E 0x754B 0x75AB 0x75A4 0x75A5 \ + 0x75A2 0x75A3 0x7678 0x7686 0x7687 0x7688 0x76C8 0x76C6 \ + 0x76C3 0x76C5 0x7701 0x76F9 0x76F8 0x7709 0x770B 0x76FE \ + 0x76FC 0x7707 0x77DC 0x7802 0x7814 0x780C 0x780D 0x7946 \ + 0x7949 0x7948 0x7947 0x79B9 0x79BA 0x79D1 0x79D2 0x79CB \ + 0x7A7F 0x7A81 0x7AFF 0x7AFD 0x7C7D 0x7D02 0x7D05 0x7D00 \ + 0x7D09 0x7D07 0x7D04 0x7D06 0x7F38 0x7F8E 0x7FBF 0x8004 \ + 0x8010 0x800D 0x8011 0x8036 0x80D6 0x80E5 0x80DA 0x80C3 \ + 0x80C4 0x80CC 0x80E1 0x80DB 0x80CE 0x80DE 0x80E4 0x80DD \ + 0x81F4 0x8222 0x82E7 0x8303 0x8305 0x82E3 0x82DB 0x82E6 \ + 0x8304 0x82E5 0x8302 0x8309 0x82D2 0x82D7 0x82F1 0x8301 \ + 0x82DC 0x82D4 0x82D1 0x82DE 0x82D3 0x82DF 0x82EF 0x8306 \ + 0x8650 0x8679 0x867B 0x867A 0x884D 0x886B 0x8981 0x89D4 \ + 0x8A08 0x8A02 0x8A03 0x8C9E 0x8CA0 0x8D74 0x8D73 0x8DB4 \ + 0x8ECD 0x8ECC 0x8FF0 0x8FE6 0x8FE2 0x8FEA 0x8FE5 0x811A \ + 0x8134 0x8117 0x831D 0x8371 0x8384 0x8380 0x8372 0x83A1 \ + 0x8379 0x8391 0x839F 0x83AD 0x8323 0x8385 0x839C 0x83B7 \ + 0x8658 0x865A 0x8657 0x86B2 0x86AE 0x8845 0x889C 0x8894 +34 0x88A3 0x888F 0x88A5 0x88A9 0x88A6 0x888A 0x88A0 0x8890 \ + 0x8FED 0x8FEB 0x8FE4 0x8FE8 0x90CA 0x90CE 0x90C1 0x90C3 \ + 0x914B 0x914A 0x91CD 0x9582 0x9650 0x964B 0x964C 0x964D \ + 0x9762 0x9769 0x97CB 0x97ED 0x97F3 0x9801 0x98A8 0x98DB \ + 0x98DF 0x9996 0x9999 0x4E58 0x4EB3 0x500C 0x500D 0x5023 \ + 0x4FEF 0x5026 0x5025 0x4FF8 0x5029 0x5016 0x5006 0x503C \ + 0x501F 0x501A 0x5012 0x5011 0x4FFA 0x5000 0x5014 0x5028 \ + 0x4FF1 0x5021 0x500B 0x5019 0x5018 0x4FF3 0x4FEE 0x502D \ + 0x502A 0x4FFE 0x502B 0x5009 0x517C 0x51A4 0x51A5 0x51A2 \ + 0x51CD 0x51CC 0x51C6 0x51CB 0x5256 0x525C 0x5254 0x525B \ + 0x525D 0x532A 0x537F 0x539F 0x539D 0x53DF 0x54E8 0x5510 \ + 0x5501 0x5537 0x54FC 0x54E5 0x54F2 0x5506 0x54FA 0x5514 \ + 0x54E9 0x54ED 0x54E1 0x5509 0x54EE 0x54EA 0x54E6 0x5527 \ + 0x5507 0x54FD 0x550F 0x5703 0x5704 0x57C2 0x57D4 0x57CB \ + 0x57C3 0x5809 0x590F 0x5957 0x5958 0x595A 0x5A11 0x5A18 \ + 0x5A1C 0x5A1F 0x5A1B 0x5A13 0x59EC 0x5A20 0x5A23 0x5A29 \ + 0x5A25 0x5A0C 0x5A09 0x5B6B 0x5C58 0x5BB0 0x5BB3 0x5BB6 \ + 0x5BB4 0x5BAE 0x5BB5 0x5BB9 0x5BB8 0x5C04 0x5C51 0x5C55 \ + 0x5C50 0x5CED 0x5CFD 0x5CFB 0x5CEA 0x5CE8 0x5CF0 0x5CF6 \ + 0x5D01 0x5CF4 0x5DEE 0x5E2D 0x5E2B 0x5EAB 0x5EAD 0x5EA7 \ + 0x5F31 0x5F92 0x5F91 0x5F90 0x6059 0x8992 0x8991 0x8994 \ + 0x8A26 0x8A32 0x8A28 0x8A1C 0x8A2B 0x8A20 0x8A29 0x8A21 \ + 0x8C3A 0x8C5B 0x8C58 0x8C7C 0x8CA6 0x8CAE 0x8CAD 0x8D65 \ + 0x8D7E 0x8D7C 0x8D7F 0x8D7A 0x8DBD 0x8DC0 0x8DBB 0x8EAD \ + 0x8EAF 0x8ED6 0x8ED9 0x9012 0x900E 0x9025 0x6063 0x6065 \ + 0x6050 0x6055 0x606D 0x6069 0x606F 0x6084 0x609F 0x609A \ + 0x608D 0x6094 0x608C 0x6085 0x6096 0x6247 0x62F3 0x6308 \ + 0x62FF 0x634E 0x633E 0x632F 0x6355 0x6342 0x6346 0x634F \ + 0x6349 0x633A 0x6350 0x633D 0x632A 0x632B 0x6328 0x634D \ + 0x634C 0x6548 0x6549 0x6599 0x65C1 0x65C5 0x6642 0x6649 \ + 0x664F 0x6643 0x6652 0x664C 0x6645 0x6641 0x66F8 0x6714 \ + 0x6715 0x6717 0x6821 0x6838 0x6848 0x6846 0x6853 0x6839 +35 0x6842 0x6854 0x6829 0x68B3 0x6817 0x684C 0x6851 0x683D \ + 0x67F4 0x6850 0x6840 0x683C 0x6843 0x682A 0x6845 0x6813 \ + 0x6818 0x6841 0x6B8A 0x6B89 0x6BB7 0x6C23 0x6C27 0x6C28 \ + 0x6C26 0x6C24 0x6CF0 0x6D6A 0x6D95 0x6D88 0x6D87 0x6D66 \ + 0x6D78 0x6D77 0x6D59 0x6D93 0x6D6C 0x6D89 0x6D6E 0x6D5A \ + 0x6D74 0x6D69 0x6D8C 0x6D8A 0x6D79 0x6D85 0x6D65 0x6D94 \ + 0x70CA 0x70D8 0x70E4 0x70D9 0x70C8 0x70CF 0x7239 0x7279 \ + 0x72FC 0x72F9 0x72FD 0x72F8 0x72F7 0x7386 0x73ED 0x7409 \ + 0x73EE 0x73E0 0x73EA 0x73DE 0x7554 0x755D 0x755C 0x755A \ + 0x7559 0x75BE 0x75C5 0x75C7 0x75B2 0x75B3 0x75BD 0x75BC \ + 0x75B9 0x75C2 0x75B8 0x768B 0x76B0 0x76CA 0x76CD 0x76CE \ + 0x7729 0x771F 0x7720 0x7728 0x77E9 0x7830 0x7827 0x7838 \ + 0x781D 0x7834 0x7837 0x9013 0x90EE 0x90AB 0x90F7 0x9159 \ + 0x9154 0x91F2 0x91F0 0x91E5 0x91F6 0x9587 0x965A 0x966E \ + 0x9679 0x98E1 0x98E6 0x9EC4 0x9ED2 0x4E80 0x4E81 0x508F \ + 0x5097 0x5088 0x5089 0x5081 0x5160 0x5E42 0x51D3 0x51D2 \ + 0x51D6 0x5273 0x5270 0x53A8 0x7825 0x782D 0x7820 0x781F \ + 0x7832 0x7955 0x7950 0x7960 0x795F 0x7956 0x795E 0x795D \ + 0x7957 0x795A 0x79E4 0x79E3 0x79E7 0x79DF 0x79E6 0x79E9 \ + 0x79D8 0x7A84 0x7A88 0x7AD9 0x7B06 0x7B11 0x7C89 0x7D21 \ + 0x7D17 0x7D0B 0x7D0A 0x7D20 0x7D22 0x7D14 0x7D10 0x7D15 \ + 0x7D1A 0x7D1C 0x7D0D 0x7D19 0x7D1B 0x7F3A 0x7F5F 0x7F94 \ + 0x7FC5 0x7FC1 0x8006 0x8018 0x8015 0x8019 0x8017 0x803D \ + 0x803F 0x80F1 0x8102 0x80F0 0x8105 0x80ED 0x80F4 0x8106 \ + 0x80F8 0x80F3 0x8108 0x80FD 0x810A 0x80FC 0x80EF 0x81ED \ + 0x81EC 0x8200 0x8210 0x822A 0x822B 0x8228 0x822C 0x82BB \ + 0x832B 0x8352 0x8354 0x834A 0x8338 0x8350 0x8349 0x8335 \ + 0x8334 0x834F 0x8332 0x8339 0x8336 0x8317 0x8340 0x8331 \ + 0x8328 0x8343 0x8654 0x868A 0x86AA 0x8693 0x86A4 0x86A9 \ + 0x868C 0x86A3 0x869C 0x8870 0x8877 0x8881 0x8882 0x887D \ + 0x8879 0x8A18 0x8A10 0x8A0E 0x8A0C 0x8A15 0x8A0A 0x8A17 \ + 0x8A13 0x8A16 0x8A0F 0x8A11 0x8C48 0x8C7A 0x8C79 0x8CA1 +36 0x8CA2 0x8D77 0x8EAC 0x8ED2 0x8ED4 0x8ECF 0x8FB1 0x9001 \ + 0x9006 0x8FF7 0x9000 0x8FFA 0x8FF4 0x9003 0x8FFD 0x9005 \ + 0x8FF8 0x9095 0x90E1 0x90DD 0x90E2 0x9152 0x914D 0x914C \ + 0x91D8 0x91DD 0x91D7 0x91DC 0x91D9 0x9583 0x9662 0x9663 \ + 0x9661 0x53A6 0x53C5 0x5597 0x55DE 0x5596 0x55B4 0x5585 \ + 0x559B 0x55A0 0x5559 0x5586 0x55AF 0x557A 0x559E 0x55A9 \ + 0x570F 0x570E 0x581A 0x581F 0x583C 0x5818 0x583E 0x5826 \ + 0x583A 0x5822 0x58FB 0x5963 0x5964 0x5AA8 0x5AA3 0x5A82 \ + 0x5A88 0x5AA1 0x965B 0x965D 0x9664 0x9658 0x965E 0x96BB \ + 0x98E2 0x99AC 0x9AA8 0x9AD8 0x9B25 0x9B32 0x9B3C 0x4E7E \ + 0x507A 0x507D 0x505C 0x5047 0x5043 0x504C 0x505A 0x5049 \ + 0x5065 0x5076 0x504E 0x5055 0x5075 0x5074 0x5077 0x504F \ + 0x500F 0x506F 0x506D 0x515C 0x5195 0x51F0 0x526A 0x526F \ + 0x52D2 0x52D9 0x52D8 0x52D5 0x5310 0x530F 0x5319 0x533F \ + 0x5340 0x533E 0x53C3 0x66FC 0x5546 0x556A 0x5566 0x5544 \ + 0x555E 0x5561 0x5543 0x554A 0x5531 0x5556 0x554F 0x5555 \ + 0x552F 0x5564 0x5538 0x552E 0x555C 0x552C 0x5563 0x5533 \ + 0x5541 0x5557 0x5708 0x570B 0x5709 0x57DF 0x5805 0x580A \ + 0x5806 0x57E0 0x57E4 0x57FA 0x5802 0x5835 0x57F7 0x57F9 \ + 0x5920 0x5962 0x5A36 0x5A41 0x5A49 0x5A66 0x5A6A 0x5A40 \ + 0x5A3C 0x5A62 0x5A5A 0x5A46 0x5A4A 0x5B70 0x5BC7 0x5BC5 \ + 0x5BC4 0x5BC2 0x5BBF 0x5BC6 0x5C09 0x5C08 0x5C07 0x5C60 \ + 0x5C5C 0x5C5D 0x5D07 0x5D06 0x5D0E 0x5D1B 0x5D16 0x5D22 \ + 0x5D11 0x5D29 0x5D14 0x5D19 0x5D24 0x5D27 0x5D17 0x5DE2 \ + 0x5E38 0x5E36 0x5E33 0x5E37 0x5EB7 0x5EB8 0x5EB6 0x5EB5 \ + 0x5EBE 0x5F35 0x5F37 0x5F57 0x5F6C 0x5F69 0x5F6B 0x5F97 \ + 0x5F99 0x5F9E 0x5F98 0x5FA1 0x5FA0 0x5F9C 0x607F 0x60A3 \ + 0x6089 0x60A0 0x60A8 0x60CB 0x60B4 0x60E6 0x60BD 0x5A85 \ + 0x5A98 0x5A99 0x5A89 0x5A81 0x5A96 0x5A80 0x5A91 0x5ACF \ + 0x5A87 0x5AA0 0x5A79 0x5A86 0x5AAB 0x5AAA 0x5AA4 0x5A8D \ + 0x5A7E 0x5BD5 0x5C1E 0x5C5F 0x5C5E 0x5D44 0x5D3E 0x5D48 \ + 0x5D1C 0x5D5B 0x5D4D 0x5D57 0x5D53 0x5D4F 0x5D3B 0x5D46 +37 0x60C5 0x60BB 0x60B5 0x60DC 0x60BC 0x60D8 0x60D5 0x60C6 \ + 0x60DF 0x60B8 0x60DA 0x60C7 0x621A 0x621B 0x6248 0x63A0 \ + 0x63A7 0x6372 0x6396 0x63A2 0x63A5 0x6377 0x6367 0x6398 \ + 0x63AA 0x6371 0x63A9 0x6389 0x6383 0x639B 0x636B 0x63A8 \ + 0x6384 0x6388 0x6399 0x63A1 0x63AC 0x6392 0x638F 0x6380 \ + 0x637B 0x6369 0x6368 0x637A 0x655D 0x6556 0x6551 0x6559 \ + 0x6557 0x555F 0x654F 0x6558 0x6555 0x6554 0x659C 0x659B \ + 0x65AC 0x65CF 0x65CB 0x65CC 0x65CE 0x665D 0x665A 0x6664 \ + 0x6668 0x6666 0x665E 0x66F9 0x52D7 0x671B 0x6881 0x68AF \ + 0x68A2 0x6893 0x68B5 0x687F 0x6876 0x68B1 0x68A7 0x6897 \ + 0x68B0 0x6883 0x68C4 0x68AD 0x6886 0x6885 0x6894 0x689D \ + 0x68A8 0x689F 0x68A1 0x6882 0x6B32 0x6BBA 0x6BEB 0x6BEC \ + 0x6C2B 0x6D8E 0x6DBC 0x6DF3 0x6DD9 0x6DB2 0x6DE1 0x6DCC \ + 0x6DE4 0x6DFB 0x6DFA 0x6E05 0x6DC7 0x6DCB 0x6DAF 0x6DD1 \ + 0x6DAE 0x6DDE 0x6DF9 0x6DB8 0x6DF7 0x6DF5 0x6DC5 0x6DD2 \ + 0x6E1A 0x6DB5 0x6DDA 0x6DEB 0x6DD8 0x6DEA 0x6DF1 0x6DEE \ + 0x6DE8 0x6DC6 0x6DC4 0x6DAA 0x6DEC 0x6DBF 0x6DE6 0x70F9 \ + 0x7109 0x710A 0x70FD 0x70EF 0x723D 0x727D 0x7281 0x731C \ + 0x731B 0x7316 0x7313 0x7319 0x7387 0x7405 0x740A 0x7403 \ + 0x7406 0x73FE 0x740D 0x74E0 0x74F6 0x5E46 0x5E47 0x5E48 \ + 0x5EC0 0x5EBD 0x5EBF 0x5F11 0x5F3E 0x5F3B 0x5F3A 0x5FA7 \ + 0x60EA 0x6107 0x6122 0x610C 0x60B3 0x60D6 0x60D2 0x60E3 \ + 0x60E5 0x60E9 0x6111 0x60FD 0x611E 0x6120 0x6121 0x621E \ + 0x63E2 0x63DE 0x63E6 0x63F8 0x63FE 0x63C1 0x74F7 0x751C \ + 0x7522 0x7565 0x7566 0x7562 0x7570 0x758F 0x75D4 0x75D5 \ + 0x75B5 0x75CA 0x75CD 0x768E 0x76D4 0x76D2 0x76DB 0x7737 \ + 0x773E 0x773C 0x7736 0x7738 0x773A 0x786B 0x7843 0x784E \ + 0x7965 0x7968 0x796D 0x79FB 0x7A92 0x7A95 0x7B20 0x7B28 \ + 0x7B1B 0x7B2C 0x7B26 0x7B19 0x7B1E 0x7B2E 0x7C92 0x7C97 \ + 0x7C95 0x7D46 0x7D43 0x7D71 0x7D2E 0x7D39 0x7D3C 0x7D40 \ + 0x7D30 0x7D33 0x7D44 0x7D2F 0x7D42 0x7D32 0x7D31 0x7F3D \ + 0x7F9E 0x7F9A 0x7FCC 0x7FCE 0x7FD2 0x801C 0x804A 0x8046 +38 0x812F 0x8116 0x8123 0x812B 0x8129 0x8130 0x8124 0x8202 \ + 0x8235 0x8237 0x8236 0x8239 0x838E 0x839E 0x8398 0x8378 \ + 0x83A2 0x8396 0x83BD 0x83AB 0x8392 0x838A 0x8393 0x8389 \ + 0x83A0 0x8377 0x837B 0x837C 0x8386 0x83A7 0x8655 0x5F6A \ + 0x86C7 0x86C0 0x86B6 0x86C4 0x86B5 0x86C6 0x86CB 0x86B1 \ + 0x86AF 0x86C9 0x8853 0x889E 0x8888 0x88AB 0x8892 0x8896 \ + 0x888D 0x888B 0x8993 0x898F 0x8A2A 0x8A1D 0x8A23 0x8A25 \ + 0x8A31 0x8A2D 0x8A1F 0x8A1B 0x8A22 0x8C49 0x8C5A 0x8CA9 \ + 0x8CAC 0x8CAB 0x8CA8 0x8CAA 0x8CA7 0x8D67 0x8D66 0x8DBE \ + 0x8DBA 0x8EDB 0x8EDF 0x9019 0x900D 0x901A 0x9017 0x9023 \ + 0x901F 0x901D 0x9010 0x9015 0x901E 0x9020 0x900F 0x9022 \ + 0x9016 0x901B 0x9014 0x63BF 0x63F7 0x63D1 0x655F 0x6560 \ + 0x6561 0x65D1 0x667D 0x666B 0x667F 0x6673 0x6681 0x666D \ + 0x6669 0x671E 0x68ED 0x6903 0x68FE 0x68E5 0x691E 0x6902 \ + 0x6909 0x68CA 0x6900 0x6901 0x6918 0x68E2 0x68CF 0x692E \ + 0x68C5 0x68FF 0x691C 0x68C3 0x90E8 0x90ED 0x90FD 0x9157 \ + 0x91CE 0x91F5 0x91E6 0x91E3 0x91E7 0x91ED 0x91E9 0x9589 \ + 0x966A 0x9675 0x9673 0x9678 0x9670 0x9674 0x9676 0x9677 \ + 0x966C 0x96C0 0x96EA 0x96E9 0x7AE0 0x7ADF 0x9802 0x9803 \ + 0x9B5A 0x9CE5 0x9E75 0x9E7F 0x9EA5 0x9EBB 0x50A2 0x508D \ + 0x5085 0x5099 0x5091 0x5080 0x5096 0x5098 0x509A 0x6700 \ + 0x51F1 0x5272 0x5274 0x5275 0x5269 0x52DE 0x52DD 0x52DB \ + 0x535A 0x53A5 0x557B 0x5580 0x55A7 0x557C 0x558A 0x559D \ + 0x5598 0x5582 0x559C 0x55AA 0x5594 0x5587 0x558B 0x5583 \ + 0x55B3 0x55AE 0x559F 0x553E 0x55B2 0x559A 0x55BB 0x55AC \ + 0x55B1 0x557E 0x5589 0x55AB 0x5599 0x570D 0x582F 0x582A \ + 0x5834 0x5824 0x5830 0x5831 0x5821 0x581D 0x5820 0x58F9 \ + 0x58FA 0x5960 0x5A77 0x5A9A 0x5A7F 0x5A92 0x5A9B 0x5AA7 \ + 0x5B73 0x5B71 0x5BD2 0x5BCC 0x5BD3 0x5BD0 0x5C0A 0x5C0B \ + 0x5C31 0x5D4C 0x5D50 0x5D34 0x5D47 0x5DFD 0x5E45 0x5E3D \ + 0x5E40 0x5E43 0x5E7E 0x5ECA 0x5EC1 0x5EC2 0x5EC4 0x5F3C \ + 0x5F6D 0x5FA9 0x5FAA 0x5FA8 0x60D1 0x60E1 0x60B2 0x60B6 +39 0x60E0 0x611C 0x6123 0x60FA 0x6115 0x60F0 0x60FB 0x60F4 \ + 0x6168 0x60F1 0x610E 0x60F6 0x6109 0x6100 0x6112 0x621F \ + 0x6249 0x63A3 0x638C 0x63CF 0x63C0 0x63E9 0x63C9 0x63C6 \ + 0x63CD 0x6B6F 0x6B6E 0x6BBE 0x6BF4 0x6C2D 0x6DB6 0x6E75 \ + 0x6E1E 0x6E18 0x6E48 0x6E4F 0x6E42 0x6E6A 0x6E70 0x6DFE \ + 0x6E6D 0x6E7B 0x6E7E 0x6E59 0x6E57 0x6E80 0x6E50 0x6E29 \ + 0x6E76 0x6E2A 0x6E4C 0x712A 0x7135 0x712C 0x7137 0x711D \ + 0x7138 0x7134 0x63D2 0x63E3 0x63D0 0x63E1 0x63D6 0x63ED \ + 0x63EE 0x6376 0x63F4 0x63EA 0x63DB 0x6452 0x63DA 0x63F9 \ + 0x655E 0x6566 0x6562 0x6563 0x6591 0x6590 0x65AF 0x666E \ + 0x6670 0x6674 0x6676 0x666F 0x6691 0x667A 0x667E 0x6677 \ + 0x66FE 0x66FF 0x671F 0x671D 0x68FA 0x68D5 0x68E0 0x68D8 \ + 0x68D7 0x6905 0x68DF 0x68F5 0x68EE 0x68E7 0x68F9 0x68D2 \ + 0x68F2 0x68E3 0x68CB 0x68CD 0x690D 0x6912 0x690E 0x68C9 \ + 0x68DA 0x696E 0x68FB 0x6B3E 0x6B3A 0x6B3D 0x6B98 0x6B96 \ + 0x6BBC 0x6BEF 0x6C2E 0x6C2F 0x6C2C 0x6E2F 0x6E38 0x6E54 \ + 0x6E21 0x6E32 0x6E67 0x6E4A 0x6E20 0x6E25 0x6E23 0x6E1B \ + 0x6E5B 0x6E58 0x6E24 0x6E56 0x6E6E 0x6E2D 0x6E26 0x6E6F \ + 0x6E34 0x6E4D 0x6E3A 0x6E2C 0x6E43 0x6E1D 0x6E3E 0x6ECB \ + 0x6E89 0x6E19 0x6E4E 0x6E63 0x6E44 0x6E72 0x6E69 0x6E5F \ + 0x7119 0x711A 0x7126 0x7130 0x7121 0x7136 0x716E 0x711C \ + 0x724C 0x7284 0x7280 0x7336 0x7325 0x7334 0x7329 0x743A \ + 0x742A 0x7433 0x7422 0x7425 0x7435 0x7436 0x7434 0x742F \ + 0x741B 0x7426 0x7428 0x7525 0x7526 0x756B 0x756A 0x75E2 \ + 0x75DB 0x75E3 0x75D9 0x75D8 0x75DE 0x75E0 0x767B 0x767C \ + 0x7696 0x7693 0x76B4 0x76DC 0x774F 0x77ED 0x785D 0x786C \ + 0x786F 0x7A0D 0x7A08 0x7A0B 0x7A05 0x7A00 0x7A98 0x712B \ + 0x7133 0x7127 0x7124 0x712D 0x7232 0x7283 0x7282 0x7287 \ + 0x7306 0x7324 0x7338 0x732A 0x732C 0x732B 0x732F 0x7328 \ + 0x7417 0x7419 0x7438 0x741F 0x7414 0x743C 0x73F7 0x741C \ + 0x7415 0x7418 0x7439 0x74F9 0x7524 0x756E 0x756D 0x7571 \ + 0x7A97 0x7A96 0x7AE5 0x7AE3 0x7B49 0x7B56 0x7B46 0x7B50 +40 0x7B52 0x7B54 0x7B4D 0x7B4B 0x7B4F 0x7B51 0x7C9F 0x7CA5 \ + 0x7D5E 0x7D50 0x7D68 0x7D55 0x7D2B 0x7D6E 0x7D72 0x7D61 \ + 0x7D66 0x7D62 0x7D70 0x7D73 0x5584 0x7FD4 0x7FD5 0x800B \ + 0x8052 0x8085 0x8155 0x8154 0x814B 0x8151 0x814E 0x8139 \ + 0x8146 0x813E 0x814C 0x8153 0x8174 0x8212 0x821C 0x83E9 \ + 0x8403 0x83F8 0x840D 0x83E0 0x83C5 0x840B 0x83C1 0x83EF \ + 0x83F1 0x83F4 0x8457 0x840A 0x83F0 0x840C 0x83CC 0x83FD \ + 0x83F2 0x83CA 0x8438 0x840E 0x8404 0x83DC 0x8407 0x83D4 \ + 0x83DF 0x865B 0x86DF 0x86D9 0x86ED 0x86D4 0x86DB 0x86E4 \ + 0x86D0 0x86DE 0x8857 0x88C1 0x88C2 0x88B1 0x8983 0x8996 \ + 0x8A3B 0x8A60 0x8A55 0x8A5E 0x8A3C 0x8A41 0x8A54 0x8A5B \ + 0x8A50 0x8A46 0x8A34 0x8A3A 0x8A36 0x8A56 0x8C61 0x8C82 \ + 0x8CAF 0x8CBC 0x8CB3 0x8CBD 0x8CC1 0x8CBB 0x8CC0 0x8CB4 \ + 0x8CB7 0x8CB6 0x8CBF 0x8CB8 0x8D8A 0x8D85 0x8D81 0x8DCE \ + 0x8DDD 0x8DCB 0x8DDA 0x8DD1 0x8DCC 0x8DDB 0x8DC6 0x8EFB \ + 0x8EF8 0x8EFC 0x8F9C 0x902E 0x9035 0x9031 0x9038 0x9032 \ + 0x9036 0x9102 0x90F5 0x9109 0x90FE 0x9163 0x9165 0x91CF \ + 0x9214 0x9215 0x9223 0x9209 0x921E 0x920D 0x9210 0x9207 \ + 0x9211 0x9594 0x958F 0x958B 0x9591 0x758E 0x75E5 0x7694 \ + 0x76B3 0x76D9 0x7748 0x7749 0x7743 0x7742 0x77DF 0x7863 \ + 0x7876 0x785F 0x7866 0x7966 0x7971 0x7976 0x7984 0x7975 \ + 0x79FF 0x7A07 0x7A0E 0x7A09 0x7AE7 0x7AE2 0x7B55 0x7B43 \ + 0x7B57 0x7B6C 0x7B42 0x7B53 0x7B41 0x7CA0 0x9593 0x9592 \ + 0x958E 0x968A 0x968E 0x968B 0x967D 0x9685 0x9686 0x968D \ + 0x9672 0x9684 0x96C1 0x96C5 0x96C4 0x96C6 0x96C7 0x96EF \ + 0x96F2 0x97CC 0x9805 0x9806 0x9808 0x98E7 0x98EA 0x98EF \ + 0x98E9 0x98F2 0x98ED 0x99AE 0x99AD 0x9EC3 0x9ECD 0x9ED1 \ + 0x4E82 0x50AD 0x50B5 0x50B2 0x50B3 0x50C5 0x50BE 0x50AC \ + 0x50B7 0x50BB 0x50AF 0x50C7 0x527F 0x5277 0x527D 0x52DF \ + 0x52E6 0x52E4 0x52E2 0x52E3 0x532F 0x55DF 0x55E8 0x55D3 \ + 0x55E6 0x55CE 0x55DC 0x55C7 0x55D1 0x55E3 0x55E4 0x55EF \ + 0x55DA 0x55E1 0x55C5 0x55C6 0x55E5 0x55C9 0x5712 0x5713 +41 0x585E 0x5851 0x5858 0x5857 0x585A 0x5854 0x586B 0x584C \ + 0x586D 0x584A 0x5862 0x5852 0x584B 0x5967 0x5AC1 0x5AC9 \ + 0x5ACC 0x5ABE 0x5ABD 0x5ABC 0x5AB3 0x5AC2 0x5AB2 0x5D69 \ + 0x5D6F 0x5E4C 0x5E79 0x5EC9 0x5EC8 0x5F12 0x5F59 0x5FAC \ + 0x5FAE 0x611A 0x610F 0x6148 0x611F 0x60F3 0x611B 0x60F9 \ + 0x6101 0x6108 0x614E 0x614C 0x6144 0x614D 0x613E 0x6134 \ + 0x6127 0x610D 0x6106 0x6137 0x6221 0x6222 0x6413 0x643E \ + 0x641E 0x642A 0x642D 0x643D 0x642C 0x640F 0x641C 0x6414 \ + 0x640D 0x6436 0x6416 0x6417 0x6406 0x656C 0x659F 0x65B0 \ + 0x6697 0x6689 0x6687 0x6688 0x6696 0x6684 0x6698 0x668D \ + 0x6703 0x6994 0x696D 0x7CA6 0x7CA4 0x7D74 0x7D59 0x7D60 \ + 0x7D57 0x7D6C 0x7D7E 0x7D64 0x7D5A 0x7D5D 0x7D76 0x7D4D \ + 0x7D75 0x7FD3 0x7FD6 0x8060 0x804E 0x8145 0x813B 0x8148 \ + 0x8142 0x8149 0x8140 0x8114 0x8141 0x81EF 0x81F6 0x8203 \ + 0x83ED 0x83DA 0x8418 0x83D2 0x695A 0x6977 0x6960 0x6954 \ + 0x6975 0x6930 0x6982 0x694A 0x6968 0x696B 0x695E 0x6953 \ + 0x6979 0x6986 0x695D 0x6963 0x695B 0x6B47 0x6B72 0x6BC0 \ + 0x6BBF 0x6BD3 0x6BFD 0x6EA2 0x6EAF 0x6ED3 0x6EB6 0x6EC2 \ + 0x6E90 0x6E9D 0x6EC7 0x6EC5 0x6EA5 0x6E98 0x6EBC 0x6EBA \ + 0x6EAB 0x6ED1 0x6E96 0x6E9C 0x6EC4 0x6ED4 0x6EAA 0x6EA7 \ + 0x6EB4 0x714E 0x7159 0x7169 0x7164 0x7149 0x7167 0x715C \ + 0x716C 0x7166 0x714C 0x7165 0x715E 0x7146 0x7168 0x7156 \ + 0x723A 0x7252 0x7337 0x7345 0x733F 0x733E 0x746F 0x745A \ + 0x7455 0x745F 0x745E 0x7441 0x743F 0x7459 0x745B 0x745C \ + 0x7576 0x7578 0x7600 0x75F0 0x7601 0x75F2 0x75F1 0x75FA \ + 0x75FF 0x75F4 0x75F3 0x76DE 0x76DF 0x775B 0x776B 0x7766 \ + 0x775E 0x7763 0x7779 0x776A 0x776C 0x775C 0x7765 0x7768 \ + 0x7762 0x77EE 0x788E 0x78B0 0x7897 0x7898 0x788C 0x7889 \ + 0x787C 0x7891 0x7893 0x787F 0x797A 0x797F 0x7981 0x842C \ + 0x79BD 0x7A1C 0x7A1A 0x7A20 0x7A14 0x7A1F 0x7A1E 0x7A9F \ + 0x7AA0 0x7B77 0x7BC0 0x7B60 0x7B6E 0x7B67 0x7CB1 0x7CB3 \ + 0x7CB5 0x7D93 0x7D79 0x7D91 0x7D81 0x7D8F 0x7D5B 0x7F6E +42 0x7F69 0x7F6A 0x7F72 0x7FA9 0x7FA8 0x7FA4 0x8056 0x8058 \ + 0x8086 0x8084 0x8171 0x8170 0x8178 0x8165 0x816E 0x8173 \ + 0x816B 0x8408 0x8400 0x8417 0x8346 0x8414 0x83D3 0x8405 \ + 0x841F 0x8402 0x8416 0x83CD 0x83E6 0x865D 0x86D5 0x86E1 \ + 0x86EE 0x8847 0x8846 0x88BB 0x88BF 0x88B4 0x88B5 0x899A \ + 0x8A43 0x8A5A 0x8A35 0x8A38 0x8A42 0x8A49 0x8A5D 0x8A4B \ + 0x8A3D 0x8C60 0x8179 0x817A 0x8166 0x8205 0x8247 0x8482 \ + 0x8477 0x843D 0x8431 0x8475 0x8466 0x846B 0x8449 0x846C \ + 0x845B 0x843C 0x8435 0x8461 0x8463 0x8469 0x846D 0x8446 \ + 0x865E 0x865C 0x865F 0x86F9 0x8713 0x8708 0x8707 0x8700 \ + 0x86FE 0x86FB 0x8702 0x8703 0x8706 0x870A 0x8859 0x88DF \ + 0x88D4 0x88D9 0x88DC 0x88D8 0x88DD 0x88E1 0x88CA 0x88D5 \ + 0x88D2 0x899C 0x89E3 0x8A6B 0x8A72 0x8A73 0x8A66 0x8A69 \ + 0x8A70 0x8A87 0x8A7C 0x8A63 0x8AA0 0x8A71 0x8A85 0x8A6D \ + 0x8A62 0x8A6E 0x8A6C 0x8A79 0x8A7B 0x8A3E 0x8A68 0x8C62 \ + 0x8C8A 0x8C89 0x8CCA 0x8CC7 0x8CC8 0x8CC4 0x8CB2 0x8CC3 \ + 0x8CC2 0x8CC5 0x8DE1 0x8DDF 0x8DE8 0x8DEF 0x8DF3 0x8DFA \ + 0x8DEA 0x8DE4 0x8DE6 0x8EB2 0x8F03 0x8F09 0x8EFE 0x8F0A \ + 0x8F9F 0x8FB2 0x904B 0x904A 0x9053 0x9042 0x9054 0x903C \ + 0x9055 0x9050 0x9047 0x904F 0x904E 0x904D 0x9051 0x903E \ + 0x9041 0x9112 0x9117 0x916C 0x916A 0x9169 0x91C9 0x9237 \ + 0x9257 0x9238 0x923D 0x9240 0x923E 0x925B 0x924B 0x9264 \ + 0x9251 0x9234 0x9249 0x924D 0x9245 0x9239 0x923F 0x925A \ + 0x9598 0x9698 0x9694 0x9695 0x96CD 0x96CB 0x96C9 0x96CA \ + 0x96F7 0x96FB 0x96F9 0x96F6 0x9756 0x9774 0x9776 0x9810 \ + 0x9811 0x9813 0x980A 0x9812 0x980C 0x98FC 0x98F4 0x8C5E \ + 0x8C7F 0x8C7E 0x8C83 0x8CB1 0x8D87 0x8D88 0x8D83 0x8D86 \ + 0x8D8B 0x8D82 0x8DCA 0x8DD2 0x8DD4 0x8DC9 0x8EB0 0x8EF2 \ + 0x8EE4 0x8EF3 0x8EEA 0x8EFD 0x8F9D 0x902B 0x902A 0x9028 \ + 0x9029 0x902C 0x903A 0x9030 0x9037 0x903B 0x910A 0x91FE \ + 0x98FD 0x98FE 0x99B3 0x99B1 0x99B4 0x9AE1 0x9CE9 0x9E82 \ + 0x9F0E 0x9F13 0x9F20 0x50E7 0x50EE 0x50E5 0x50D6 0x50ED +43 0x50DA 0x50D5 0x50CF 0x50D1 0x50F1 0x50CE 0x50E9 0x5162 \ + 0x51F3 0x5283 0x5282 0x5331 0x53AD 0x55FE 0x5600 0x561B \ + 0x5617 0x55FD 0x5614 0x5606 0x5609 0x560D 0x560E 0x55F7 \ + 0x5616 0x561F 0x5608 0x5610 0x55F6 0x5718 0x5716 0x5875 \ + 0x587E 0x5883 0x5893 0x588A 0x5879 0x5885 0x587D 0x58FD \ + 0x5925 0x5922 0x5924 0x596A 0x5969 0x5AE1 0x5AE6 0x5AE9 \ + 0x5AD7 0x5AD6 0x5AD8 0x5AE3 0x5B75 0x5BDE 0x5BE7 0x5BE1 \ + 0x5BE5 0x5BE6 0x5BE8 0x5BE2 0x5BE4 0x5BDF 0x5C0D 0x5C62 \ + 0x5D84 0x5D87 0x5E5B 0x5E63 0x5E55 0x5E57 0x5E54 0x5ED3 \ + 0x5ED6 0x5F0A 0x5F46 0x5F70 0x5FB9 0x6147 0x613F 0x614B \ + 0x6177 0x6162 0x6163 0x615F 0x615A 0x6158 0x6175 0x622A \ + 0x6487 0x6458 0x6454 0x64A4 0x6478 0x645F 0x647A 0x6451 \ + 0x6467 0x6434 0x646D 0x647B 0x6572 0x65A1 0x65D7 0x65D6 \ + 0x66A2 0x66A8 0x669D 0x699C 0x69A8 0x6995 0x69C1 0x69AE \ + 0x69D3 0x69CB 0x699B 0x69B7 0x69BB 0x69AB 0x69B4 0x69D0 \ + 0x69CD 0x69AD 0x69CC 0x69A6 0x69C3 0x69A3 0x6B49 0x6B4C \ + 0x6C33 0x6F33 0x6F14 0x6EFE 0x6F13 0x6EF4 0x6F29 0x6F3E \ + 0x6F20 0x6F2C 0x6F0F 0x6F02 0x6F22 0x9220 0x920B 0x9218 \ + 0x9222 0x921B 0x9208 0x920E 0x9213 0x9595 0x968C 0x967B \ + 0x967F 0x9681 0x9682 0x96EE 0x96ED 0x96EC 0x975F 0x976F \ + 0x976D 0x98F0 0x9AA9 0x9AE0 0x4EB7 0x50CC 0x50BC 0x50AA \ + 0x50B9 0x50AB 0x50C3 0x50CD 0x517E 0x527E 0x6EFF 0x6EEF \ + 0x6F06 0x6F31 0x6F38 0x6F32 0x6F23 0x6F15 0x6F2B 0x6F2F \ + 0x6F88 0x6F2A 0x6EEC 0x6F01 0x6EF2 0x6ECC 0x6EF7 0x7194 \ + 0x7199 0x717D 0x718A 0x7184 0x7192 0x723E 0x7292 0x7296 \ + 0x7344 0x7350 0x7464 0x7463 0x746A 0x7470 0x746D 0x7504 \ + 0x7591 0x7627 0x760D 0x760B 0x7609 0x7613 0x76E1 0x76E3 \ + 0x7784 0x777D 0x777F 0x7761 0x78C1 0x789F 0x78A7 0x78B3 \ + 0x78A9 0x78A3 0x798E 0x798F 0x798D 0x7A2E 0x7A31 0x7AAA \ + 0x7AA9 0x7AED 0x7AEF 0x7BA1 0x7B95 0x7B8B 0x7B75 0x7B97 \ + 0x7B9D 0x7B94 0x7B8F 0x7BB8 0x7B87 0x7B84 0x7CB9 0x7CBD \ + 0x7CBE 0x7DBB 0x7DB0 0x7D9C 0x7DBD 0x7DBE 0x7DA0 0x7DCA +44 0x7DB4 0x7DB2 0x7DB1 0x7DBA 0x7DA2 0x7DBF 0x7DB5 0x7DB8 \ + 0x7DAD 0x7DD2 0x7DC7 0x7DAC 0x7F70 0x7FE0 0x7FE1 0x7FDF \ + 0x805E 0x805A 0x8087 0x8150 0x8180 0x818F 0x8188 0x818A \ + 0x817F 0x8182 0x81E7 0x81FA 0x8207 0x8214 0x821E 0x824B \ + 0x84C9 0x84BF 0x84C6 0x84C4 0x8499 0x849E 0x84B2 0x849C \ + 0x84CB 0x84B8 0x84C0 0x84D3 0x8490 0x84BC 0x84D1 0x84CA \ + 0x873F 0x871C 0x873B 0x8722 0x8725 0x8734 0x8718 0x8755 \ + 0x8737 0x8729 0x88F3 0x8902 0x88F4 0x88F9 0x88F8 0x88FD \ + 0x88E8 0x891A 0x88EF 0x8AA6 0x8A8C 0x8A9E 0x8AA3 0x8A8D \ + 0x8AA1 0x8A93 0x8AA4 0x5279 0x52E1 0x52E0 0x52E7 0x5380 \ + 0x53AB 0x53AA 0x53A9 0x53E0 0x55EA 0x55D7 0x55C1 0x5715 \ + 0x586C 0x585C 0x5850 0x5861 0x586A 0x5869 0x5856 0x5860 \ + 0x5866 0x585F 0x5923 0x5966 0x5968 0x5ACE 0x5AC5 0x5AC3 \ + 0x5AD0 0x5B74 0x5B76 0x5BDC 0x8AAA 0x8AA5 0x8AA8 0x8A98 \ + 0x8A91 0x8A9A 0x8AA7 0x8C6A 0x8C8D 0x8C8C 0x8CD3 0x8CD1 \ + 0x8CD2 0x8D6B 0x8D99 0x8D95 0x8DFC 0x8F14 0x8F12 0x8F15 \ + 0x8F13 0x8FA3 0x9060 0x9058 0x905C 0x9063 0x9059 0x905E \ + 0x9062 0x905D 0x905B 0x9119 0x9118 0x911E 0x9175 0x9178 \ + 0x9177 0x9174 0x9278 0x9280 0x9285 0x9298 0x9296 0x927B \ + 0x9293 0x929C 0x92A8 0x927C 0x9291 0x95A1 0x95A8 0x95A9 \ + 0x95A3 0x95A5 0x95A4 0x9699 0x969C 0x969B 0x96CC 0x96D2 \ + 0x9700 0x977C 0x9785 0x97F6 0x9817 0x9818 0x98AF 0x98B1 \ + 0x9903 0x9905 0x990C 0x9909 0x99C1 0x9AAF 0x9AB0 0x9AE6 \ + 0x9B41 0x9B42 0x9CF4 0x9CF6 0x9CF3 0x9EBC 0x9F3B 0x9F4A \ + 0x5104 0x5100 0x50FB 0x50F5 0x50F9 0x5102 0x5108 0x5109 \ + 0x5105 0x51DC 0x5287 0x5288 0x5289 0x528D 0x528A 0x52F0 \ + 0x53B2 0x562E 0x563B 0x5639 0x5632 0x563F 0x5634 0x5629 \ + 0x5653 0x564E 0x5657 0x5674 0x5636 0x562F 0x5630 0x5880 \ + 0x589F 0x589E 0x58B3 0x589C 0x58AE 0x58A9 0x58A6 0x596D \ + 0x5B09 0x5AFB 0x5B0B 0x5AF5 0x5B0C 0x5B08 0x5BEE 0x5BEC \ + 0x5BE9 0x5BEB 0x5C64 0x5C65 0x5D9D 0x5D94 0x5E62 0x5E5F \ + 0x5E61 0x5EE2 0x5EDA 0x5EDF 0x5EDD 0x5EE3 0x5EE0 0x5F48 +45 0x5F71 0x5FB7 0x5FB5 0x6176 0x6167 0x616E 0x615D 0x6155 \ + 0x6182 0x5BD7 0x5BDA 0x5BDB 0x5C20 0x5D6D 0x5D66 0x5D64 \ + 0x5D6E 0x5D60 0x5F42 0x5F5A 0x5F6E 0x6130 0x613A 0x612A \ + 0x6143 0x6119 0x6131 0x613D 0x6408 0x6432 0x6438 0x6431 \ + 0x6419 0x6411 0x6429 0x641D 0x643C 0x6446 0x6447 0x643A \ + 0x6407 0x656B 0x617C 0x6170 0x616B 0x617E 0x61A7 0x6190 \ + 0x61AB 0x618E 0x61AC 0x619A 0x61A4 0x6194 0x61AE 0x622E \ + 0x6469 0x646F 0x6479 0x649E 0x64B2 0x6488 0x6490 0x64B0 \ + 0x64A5 0x6493 0x6495 0x64A9 0x6492 0x64AE 0x64AD 0x64AB \ + 0x649A 0x64AC 0x6499 0x64A2 0x64B3 0x6575 0x6577 0x6578 \ + 0x66AE 0x66AB 0x66B4 0x66B1 0x6A23 0x6A1F 0x69E8 0x6A01 \ + 0x6A1E 0x6A19 0x69FD 0x6A21 0x6A13 0x6A0A 0x69F3 0x6A02 \ + 0x6A05 0x69ED 0x6A11 0x6B50 0x6B4E 0x6BA4 0x6BC5 0x6BC6 \ + 0x6F3F 0x6F7C 0x6F84 0x6F51 0x6F66 0x6F54 0x6F86 0x6F6D \ + 0x6F5B 0x6F78 0x6F6E 0x6F8E 0x6F7A 0x6F70 0x6F64 0x6F97 \ + 0x6F58 0x6ED5 0x6F6F 0x6F60 0x6F5F 0x719F 0x71AC 0x71B1 \ + 0x71A8 0x7256 0x729B 0x734E 0x7357 0x7469 0x748B 0x7483 \ + 0x747E 0x7480 0x757F 0x7620 0x7629 0x761F 0x7624 0x7626 \ + 0x7621 0x7622 0x769A 0x76BA 0x76E4 0x778E 0x7787 0x778C \ + 0x7791 0x778B 0x78CB 0x78C5 0x78BA 0x78CA 0x78BE 0x78D5 \ + 0x78BC 0x78D0 0x7A3F 0x7A3C 0x7A40 0x7A3D 0x7A37 0x7A3B \ + 0x7AAF 0x7AAE 0x7BAD 0x7BB1 0x7BC4 0x7BB4 0x7BC6 0x7BC7 \ + 0x7BC1 0x7BA0 0x7BCC 0x7CCA 0x7DE0 0x7DF4 0x7DEF 0x7DFB \ + 0x7DD8 0x7DEC 0x7DDD 0x7DE8 0x7DE3 0x7DDA 0x7DDE 0x7DE9 \ + 0x7D9E 0x7DD9 0x7DF2 0x7DF9 0x7F75 0x7F77 0x7FAF 0x6570 \ + 0x656D 0x65E4 0x6693 0x668F 0x6692 0x668E 0x6946 0x6931 \ + 0x693E 0x697C 0x6943 0x6973 0x6955 0x6985 0x694D 0x6950 \ + 0x6947 0x6967 0x6936 0x6964 0x6961 0x697D 0x6B44 0x6B40 \ + 0x6B71 0x6B73 0x6B9C 0x6BC1 0x6BFA 0x6C31 0x6C32 0x6EB8 \ + 0x7FE9 0x8026 0x819B 0x819C 0x819D 0x81A0 0x819A 0x8198 \ + 0x8517 0x853D 0x851A 0x84EE 0x852C 0x852D 0x8513 0x8511 \ + 0x8523 0x8521 0x8514 0x84EC 0x8525 0x84FF 0x8506 0x8782 +46 0x8774 0x8776 0x8760 0x8766 0x8778 0x8768 0x8759 0x8757 \ + 0x874C 0x8753 0x885B 0x885D 0x8910 0x8907 0x8912 0x8913 \ + 0x8915 0x890A 0x8ABC 0x8AD2 0x8AC7 0x8AC4 0x8A95 0x8ACB \ + 0x8AF8 0x8AB2 0x8AC9 0x8AC2 0x8ABF 0x8AB0 0x8AD6 0x8ACD \ + 0x8AB6 0x8AB9 0x8ADB 0x8C4C 0x8C4E 0x8C6C 0x8CE0 0x8CDE \ + 0x8CE6 0x8CE4 0x8CEC 0x8CED 0x8CE2 0x8CE3 0x8CDC 0x8CEA \ + 0x8CE1 0x8D6D 0x8D9F 0x8DA3 0x8E2B 0x8E10 0x8E1D 0x8E22 \ + 0x8E0F 0x8E29 0x8E1F 0x8E21 0x8E1E 0x8EBA 0x8F1D 0x8F1B \ + 0x8F1F 0x8F29 0x8F26 0x8F2A 0x8F1C 0x8F1E 0x8F25 0x9069 \ + 0x906E 0x9068 0x906D 0x9077 0x9130 0x912D 0x9127 0x9131 \ + 0x9187 0x9189 0x918B 0x9183 0x92C5 0x92BB 0x92B7 0x92EA \ + 0x92AC 0x92E4 0x92C1 0x92B3 0x92BC 0x92D2 0x92C7 0x92F0 \ + 0x92B2 0x95AD 0x95B1 0x9704 0x9706 0x9707 0x9709 0x9760 \ + 0x978D 0x978B 0x978F 0x9821 0x982B 0x981C 0x98B3 0x990A \ + 0x9913 0x9912 0x9918 0x99DD 0x99D0 0x99DF 0x99DB 0x99D1 \ + 0x99D5 0x99D2 0x99D9 0x9AB7 0x9AEE 0x9AEF 0x9B27 0x9B45 \ + 0x9B44 0x9B77 0x9B6F 0x9D06 0x9D09 0x6EA8 0x6E91 0x6EBB \ + 0x6E9A 0x6EA9 0x6EB5 0x6E6C 0x6EE8 0x6EDD 0x6EDA 0x6EE6 \ + 0x6EAC 0x6ED9 0x6EE3 0x6EE9 0x6EDB 0x716F 0x7148 0x714A \ + 0x716B 0x714F 0x7157 0x7174 0x7145 0x7151 0x716D 0x7251 \ + 0x7250 0x724E 0x7341 0x732E 0x7346 0x7427 0x9D03 0x9EA9 \ + 0x9EBE 0x9ECE 0x58A8 0x9F52 0x5112 0x5118 0x5114 0x5110 \ + 0x5115 0x5180 0x51AA 0x51DD 0x5291 0x5293 0x52F3 0x5659 \ + 0x566B 0x5679 0x5669 0x5664 0x5678 0x566A 0x5668 0x5665 \ + 0x5671 0x566F 0x566C 0x5662 0x5676 0x58C1 0x58BE 0x58C7 \ + 0x58C5 0x596E 0x5B1D 0x5B34 0x5B78 0x5BF0 0x5C0E 0x5F4A \ + 0x61B2 0x6191 0x61A9 0x618A 0x61CD 0x61B6 0x61BE 0x61CA \ + 0x61C8 0x6230 0x64C5 0x64C1 0x64CB 0x64BB 0x64BC 0x64DA \ + 0x64C4 0x64C7 0x64C2 0x64CD 0x64BF 0x64D2 0x64D4 0x64BE \ + 0x6574 0x66C6 0x66C9 0x66B9 0x66C4 0x66C7 0x66B8 0x6A3D \ + 0x6A38 0x6A3A 0x6A59 0x6A6B 0x6A58 0x6A39 0x6A44 0x6A62 \ + 0x6A61 0x6A4B 0x6A47 0x6A35 0x6A5F 0x6A48 0x6B59 0x6B77 +47 0x6C05 0x6FC2 0x6FB1 0x6FA1 0x6FC3 0x6FA4 0x6FC1 0x6FA7 \ + 0x6FB3 0x6FC0 0x6FB9 0x6FB6 0x6FA6 0x6FA0 0x6FB4 0x71BE \ + 0x71C9 0x71D0 0x71D2 0x71C8 0x71D5 0x71B9 0x71CE 0x71D9 \ + 0x71DC 0x71C3 0x71C4 0x7368 0x749C 0x74A3 0x7498 0x749F \ + 0x749E 0x74E2 0x750C 0x750D 0x7634 0x7638 0x763A 0x76E7 \ + 0x76E5 0x77A0 0x779E 0x779F 0x77A5 0x78E8 0x78DA 0x78EC \ + 0x78E7 0x79A6 0x7A4D 0x7A4E 0x7A46 0x7A4C 0x7A4B 0x7ABA \ + 0x7BD9 0x7C11 0x7BC9 0x7BE4 0x7BDB 0x7BE1 0x7BE9 0x7BE6 \ + 0x7CD5 0x7CD6 0x7E0A 0x7448 0x7453 0x743D 0x745D 0x7456 \ + 0x741E 0x7447 0x7443 0x7458 0x7449 0x744C 0x7445 0x743E \ + 0x7501 0x751E 0x757A 0x75EE 0x7602 0x7697 0x7698 0x775D \ + 0x7764 0x7753 0x7758 0x7882 0x7890 0x788A 0x787A 0x787D \ + 0x788B 0x7878 0x788D 0x7888 0x7E11 0x7E08 0x7E1B 0x7E23 \ + 0x7E1E 0x7E1D 0x7E09 0x7E10 0x7F79 0x7FB2 0x7FF0 0x7FF1 \ + 0x7FEE 0x8028 0x81B3 0x81A9 0x81A8 0x81FB 0x8208 0x8258 \ + 0x8259 0x854A 0x8559 0x8548 0x8568 0x8569 0x8543 0x8549 \ + 0x856D 0x856A 0x855E 0x8783 0x879F 0x879E 0x87A2 0x878D \ + 0x8861 0x892A 0x8932 0x8925 0x892B 0x8921 0x89AA 0x89A6 \ + 0x8AE6 0x8AFA 0x8AEB 0x8AF1 0x8B00 0x8ADC 0x8AE7 0x8AEE \ + 0x8AFE 0x8B01 0x8B02 0x8AF7 0x8AED 0x8AF3 0x8AF6 0x8AFC \ + 0x8C6B 0x8C6D 0x8C93 0x8CF4 0x8E44 0x8E31 0x8E34 0x8E42 \ + 0x8E39 0x8E35 0x8F3B 0x8F2F 0x8F38 0x8F33 0x8FA8 0x8FA6 \ + 0x9075 0x9074 0x9078 0x9072 0x907C 0x907A 0x9134 0x9192 \ + 0x9320 0x9336 0x92F8 0x9333 0x932F 0x9322 0x92FC 0x932B \ + 0x9304 0x931A 0x9310 0x9326 0x9321 0x9315 0x932E 0x9319 \ + 0x95BB 0x96A7 0x96A8 0x96AA 0x96D5 0x970E 0x9711 0x9716 \ + 0x970D 0x9713 0x970F 0x975B 0x975C 0x9766 0x9798 0x9830 \ + 0x9838 0x983B 0x9837 0x982D 0x9839 0x9824 0x9910 0x9928 \ + 0x991E 0x991B 0x9921 0x991A 0x99ED 0x99E2 0x99F1 0x9AB8 \ + 0x9ABC 0x9AFB 0x9AED 0x9B28 0x9B91 0x9D15 0x9D23 0x9D26 \ + 0x9D28 0x9D12 0x9D1B 0x9ED8 0x9ED4 0x9F8D 0x9F9C 0x512A \ + 0x511F 0x5121 0x5132 0x52F5 0x568E 0x5680 0x5690 0x5685 +48 0x5687 0x7892 0x797E 0x7983 0x7980 0x7A0F 0x7A1D 0x7AA1 \ + 0x7AA4 0x7AE9 0x7AEA 0x7B62 0x7B6B 0x7B5E 0x7B79 0x7B6F \ + 0x7B68 0x7CAE 0x7CB0 0x7D90 0x7D8A 0x7D8B 0x7D99 0x7D95 \ + 0x7D87 0x7D78 0x7D97 0x7D89 0x7D98 0x7FA3 0x7FDD 0x8057 \ + 0x8163 0x816A 0x568F 0x58D5 0x58D3 0x58D1 0x58CE 0x5B30 \ + 0x5B2A 0x5B24 0x5B7A 0x5C37 0x5C68 0x5DBC 0x5DBA 0x5DBD \ + 0x5DB8 0x5E6B 0x5F4C 0x5FBD 0x61C9 0x61C2 0x61C7 0x61E6 \ + 0x61CB 0x6232 0x6234 0x64CE 0x64CA 0x64D8 0x64E0 0x64F0 \ + 0x64E6 0x64EC 0x64F1 0x64E2 0x64ED 0x6582 0x6583 0x66D9 \ + 0x66D6 0x6A80 0x6A94 0x6A84 0x6AA2 0x6A9C 0x6ADB 0x6AA3 \ + 0x6A7E 0x6A97 0x6A90 0x6AA0 0x6B5C 0x6BAE 0x6BDA 0x6C08 \ + 0x6FD8 0x6FF1 0x6FDF 0x6FE0 0x6FDB 0x6FE4 0x6FEB 0x6FEF \ + 0x6F80 0x6FEC 0x6FE1 0x6FE9 0x6FD5 0x6FEE 0x6FF0 0x71E7 \ + 0x71DF 0x71EE 0x71E6 0x71E5 0x71ED 0x71EC 0x71F4 0x71E0 \ + 0x7235 0x7246 0x7370 0x7372 0x74A9 0x74B0 0x74A6 0x74A8 \ + 0x7646 0x7642 0x764C 0x76EA 0x77B3 0x77AA 0x77B0 0x77AC \ + 0x77A7 0x77AD 0x77EF 0x78F7 0x78FA 0x78F4 0x78EF 0x7901 \ + 0x79A7 0x79AA 0x7A57 0x7ABF 0x7C07 0x7C0D 0x7BFE 0x7BF7 \ + 0x7C0C 0x7BE0 0x7CE0 0x7CDC 0x7CDE 0x7CE2 0x7CDF 0x7CD9 \ + 0x7CDD 0x7E2E 0x7E3E 0x7E46 0x7E37 0x7E32 0x7E43 0x7E2B \ + 0x7E3D 0x7E31 0x7E45 0x7E41 0x7E34 0x7E39 0x7E48 0x7E35 \ + 0x7E3F 0x7E2F 0x7F44 0x7FF3 0x7FFC 0x8071 0x8072 0x8070 \ + 0x806F 0x8073 0x81C6 0x81C3 0x81BA 0x81C2 0x81C0 0x81BF \ + 0x81BD 0x81C9 0x81BE 0x81E8 0x8209 0x8271 0x85AA 0x816C \ + 0x815D 0x8175 0x815F 0x817D 0x816D 0x8241 0x844F 0x8484 \ + 0x847F 0x8448 0x842A 0x847B 0x8472 0x8464 0x842E 0x845C \ + 0x8453 0x8441 0x84C8 0x8462 0x8480 0x843E 0x8483 0x8471 \ + 0x844A 0x8455 0x8458 0x86FC 0x86FD 0x8715 0x8716 0x86FF \ + 0x8584 0x857E 0x859C 0x8591 0x8594 0x85AF 0x859B 0x8587 \ + 0x85A8 0x858A 0x8667 0x87C0 0x87D1 0x87B3 0x87D2 0x87C6 \ + 0x87AB 0x87BB 0x87BA 0x87C8 0x87CB 0x893B 0x8936 0x8944 \ + 0x8938 0x893D 0x89AC 0x8B0E 0x8B17 0x8B19 0x8B1B 0x8B0A +49 0x8B20 0x8B1D 0x8B04 0x8B10 0x8C41 0x8C3F 0x8C73 0x8CFA \ + 0x8CFD 0x8CFC 0x8CF8 0x8CFB 0x8DA8 0x8E49 0x8E4B 0x8E48 \ + 0x8E4A 0x8F44 0x8F3E 0x8F42 0x8F45 0x8F3F 0x907F 0x907D \ + 0x9084 0x9081 0x9082 0x9080 0x9139 0x91A3 0x919E 0x919C \ + 0x934D 0x9382 0x9328 0x9375 0x934A 0x9365 0x934B 0x9318 \ + 0x937E 0x936C 0x935B 0x9370 0x935A 0x9354 0x95CA 0x95CB \ + 0x95CC 0x95C8 0x95C6 0x96B1 0x96B8 0x96D6 0x971C 0x971E \ + 0x97A0 0x97D3 0x9846 0x98B6 0x9935 0x9A01 0x99FF 0x9BAE \ + 0x9BAB 0x9BAA 0x9BAD 0x9D3B 0x9D3F 0x9E8B 0x9ECF 0x9EDE \ + 0x9EDC 0x9EDD 0x9EDB 0x9F3E 0x9F4B 0x53E2 0x5695 0x56AE \ + 0x58D9 0x58D8 0x5B38 0x5F5E 0x61E3 0x6233 0x64F4 0x64F2 \ + 0x64FE 0x6506 0x64FA 0x64FB 0x64F7 0x65B7 0x66DC 0x6726 \ + 0x6AB3 0x6AAC 0x6AC3 0x6ABB 0x6AB8 0x6AC2 0x6AAE 0x6AAF \ + 0x6B5F 0x6B78 0x6BAF 0x7009 0x700B 0x6FFE 0x7006 0x6FFA \ + 0x7011 0x700F 0x71FB 0x71FC 0x71FE 0x71F8 0x7377 0x7375 \ + 0x74A7 0x74BF 0x7515 0x7656 0x7658 0x8858 0x88E0 0x89E7 \ + 0x8A6A 0x8A80 0x8A6F 0x8A65 0x8A78 0x8A7D 0x8A88 0x8A64 \ + 0x8A7E 0x8A67 0x8C63 0x8C88 0x8CCD 0x8CC9 0x8DED 0x8EB1 \ + 0x8F04 0x8F9E 0x8FA0 0x9043 0x9046 0x9048 0x9045 0x9040 \ + 0x904C 0x910C 0x9113 0x9115 0x916B 0x9167 0x7652 0x77BD \ + 0x77BF 0x77BB 0x77BC 0x790E 0x79AE 0x7A61 0x7A62 0x7A60 \ + 0x7AC4 0x7AC5 0x7C2B 0x7C27 0x7C2A 0x7C1E 0x7C23 0x7C21 \ + 0x7CE7 0x7E54 0x7E55 0x7E5E 0x7E5A 0x7E61 0x7E52 0x7E59 \ + 0x7F48 0x7FF9 0x7FFB 0x8077 0x8076 0x81CD 0x81CF 0x820A \ + 0x85CF 0x85A9 0x85CD 0x85D0 0x85C9 0x85B0 0x85BA 0x85B9 \ + 0x85A6 0x87EF 0x87EC 0x87F2 0x87E0 0x8986 0x89B2 0x89F4 \ + 0x8B28 0x8B39 0x8B2C 0x8B2B 0x8C50 0x8D05 0x8E59 0x8E63 \ + 0x8E66 0x8E64 0x8E5F 0x8E55 0x8EC0 0x8F49 0x8F4D 0x9087 \ + 0x9083 0x9088 0x91AB 0x91AC 0x91D0 0x9394 0x938A 0x9396 \ + 0x93A2 0x93B3 0x93AE 0x93AC 0x93B0 0x9398 0x939A 0x9397 \ + 0x95D4 0x95D6 0x95D0 0x95D5 0x96E2 0x96DC 0x96D9 0x96DB \ + 0x96DE 0x9724 0x97A3 0x97A6 0x97AD 0x97F9 0x984D 0x984F +50 0x984C 0x984E 0x9853 0x98BA 0x993E 0x993F 0x993D 0x992E \ + 0x99A5 0x9A0E 0x9AC1 0x9B03 0x9B06 0x9B4F 0x9B4E 0x9B4D \ + 0x9BCA 0x9BC9 0x9BFD 0x9BC8 0x9BC0 0x9D51 0x9D5D 0x9D60 \ + 0x9EE0 0x9F15 0x9F2C 0x5133 0x56A5 0x58DE 0x58DF 0x58E2 \ + 0x5BF5 0x9F90 0x5EEC 0x61F2 0x61F7 0x61F6 0x61F5 0x6500 \ + 0x650F 0x66E0 0x66DD 0x6AE5 0x6ADD 0x6ADA 0x6AD3 0x701B \ + 0x701F 0x7028 0x701A 0x701D 0x7015 0x7018 0x7206 0x720D \ + 0x7258 0x72A2 0x7378 0x925D 0x9255 0x9235 0x9259 0x922F \ + 0x923C 0x928F 0x925C 0x926A 0x9262 0x925F 0x926B 0x926E \ + 0x923B 0x9244 0x9241 0x959A 0x9599 0x968F 0x9696 0x96F4 \ + 0x96FC 0x9755 0x9779 0x97EE 0x97F5 0x980B 0x98F3 0x98F7 \ + 0x98FF 0x98F5 0x98EC 0x98F1 0x737A 0x74BD 0x74CA 0x74E3 \ + 0x7587 0x7586 0x765F 0x7661 0x77C7 0x7919 0x79B1 0x7A6B \ + 0x7A69 0x7C3E 0x7C3F 0x7C38 0x7C3D 0x7C37 0x7C40 0x7E6B \ + 0x7E6D 0x7E79 0x7E69 0x7E6A 0x7F85 0x7E73 0x7FB6 0x7FB9 \ + 0x7FB8 0x81D8 0x85E9 0x85DD 0x85EA 0x85D5 0x85E4 0x85E5 \ + 0x85F7 0x87FB 0x8805 0x880D 0x87F9 0x87FE 0x8960 0x895F \ + 0x8956 0x895E 0x8B41 0x8B5C 0x8B58 0x8B49 0x8B5A 0x8B4E \ + 0x8B4F 0x8B46 0x8B59 0x8D08 0x8D0A 0x8E7C 0x8E72 0x8E87 \ + 0x8E76 0x8E6C 0x8E7A 0x8E74 0x8F54 0x8F4E 0x8FAD 0x908A \ + 0x908B 0x91B1 0x91AE 0x93E1 0x93D1 0x93DF 0x93C3 0x93C8 \ + 0x93DC 0x93DD 0x93D6 0x93E2 0x93CD 0x93D8 0x93E4 0x93D7 \ + 0x93E8 0x95DC 0x96B4 0x96E3 0x972A 0x9727 0x9761 0x97DC \ + 0x97FB 0x985E 0x9858 0x985B 0x98BC 0x9945 0x9949 0x9A16 \ + 0x9A19 0x9B0D 0x9BE8 0x9BE7 0x9BD6 0x9BDB 0x9D89 0x9D61 \ + 0x9D72 0x9D6A 0x9D6C 0x9E92 0x9E97 0x9E93 0x9EB4 0x52F8 \ + 0x56A8 0x56B7 0x56B6 0x56B4 0x56BC 0x58E4 0x5B40 0x5B43 \ + 0x5B7D 0x5BF6 0x5DC9 0x61F8 0x61FA 0x6518 0x6514 0x6519 \ + 0x66E6 0x6727 0x6AEC 0x703E 0x7030 0x7032 0x7210 0x737B \ + 0x74CF 0x7662 0x7665 0x7926 0x792A 0x792C 0x792B 0x7AC7 \ + 0x7AF6 0x7C4C 0x7C43 0x7C4D 0x7CEF 0x7CF0 0x8FAE 0x7E7D \ + 0x7E7C 0x999A 0x9AE2 0x9B3D 0x9B5D 0x9CE8 0x9CEB 0x9CEF +51 0x9CEE 0x9E81 0x9F14 0x50D0 0x50D9 0x50DC 0x50D8 0x50E1 \ + 0x50EB 0x50F4 0x50E2 0x50DE 0x51F4 0x52ED 0x52EA 0x5332 \ + 0x53AE 0x53B0 0x55FB 0x5603 0x560B 0x5607 0x55F8 0x5628 \ + 0x561E 0x5618 0x7E82 0x7F4C 0x8000 0x81DA 0x8266 0x85FB \ + 0x85F9 0x8611 0x85FA 0x8606 0x860B 0x8607 0x860A 0x8814 \ + 0x8815 0x8964 0x89BA 0x89F8 0x8B70 0x8B6C 0x8B66 0x8B6F \ + 0x8B5F 0x8B6B 0x8D0F 0x8D0D 0x8E89 0x8E81 0x8E85 0x8E82 \ + 0x91B4 0x91CB 0x9418 0x9403 0x93FD 0x95E1 0x9730 0x98C4 \ + 0x9952 0x9951 0x99A8 0x9A2B 0x9A30 0x9A37 0x9A35 0x9C13 \ + 0x9C0D 0x9E79 0x9EB5 0x9EE8 0x9F2F 0x9F5F 0x9F63 0x9F61 \ + 0x5137 0x5138 0x56C1 0x56C0 0x56C2 0x5914 0x5C6C 0x5DCD \ + 0x61FC 0x61FE 0x651D 0x651C 0x6595 0x66E9 0x6AFB 0x6B04 \ + 0x6AFA 0x6BB2 0x704C 0x721B 0x72A7 0x74D6 0x74D4 0x7669 \ + 0x77D3 0x7C50 0x7E8F 0x7E8C 0x7FBC 0x8617 0x862D 0x861A \ + 0x8823 0x8822 0x8821 0x881F 0x896A 0x896C 0x89BD 0x8B74 \ + 0x8B77 0x8B7D 0x8D13 0x8E8A 0x8E8D 0x8E8B 0x8F5F 0x8FAF \ + 0x91BA 0x942E 0x9433 0x9435 0x943A 0x9438 0x9432 0x942B \ + 0x95E2 0x9738 0x9739 0x9732 0x97FF 0x9867 0x9865 0x9957 \ + 0x9A45 0x9A43 0x9A40 0x9A3E 0x9ACF 0x9B54 0x9B51 0x9C2D \ + 0x9C25 0x9DAF 0x9DB4 0x9DC2 0x9DB8 0x9E9D 0x9EEF 0x9F19 \ + 0x9F5C 0x9F66 0x9F67 0x513C 0x513B 0x56C8 0x56CA 0x56C9 \ + 0x5B7F 0x5DD4 0x5DD2 0x5F4E 0x61FF 0x6524 0x6B0A 0x6B61 \ + 0x7051 0x7058 0x7380 0x74E4 0x758A 0x766E 0x766C 0x5611 \ + 0x5651 0x5605 0x5717 0x5892 0x588C 0x5878 0x5884 0x5873 \ + 0x58AD 0x5897 0x5895 0x5877 0x5872 0x5896 0x588D 0x5910 \ + 0x596C 0x5AE7 0x5AE4 0x5AEF 0x5626 0x5AF0 0x5D7B 0x5D83 \ + 0x5D8B 0x5D8C 0x5D78 0x5E52 0x5ED0 0x5ECF 0x5FB3 0x5FB4 \ + 0x79B3 0x7C60 0x7C5F 0x807E 0x807D 0x81DF 0x8972 0x896F \ + 0x89FC 0x8B80 0x8D16 0x8D17 0x8E91 0x8E93 0x8F61 0x9148 \ + 0x9444 0x9451 0x9452 0x973D 0x973E 0x97C3 0x97C1 0x986B \ + 0x9955 0x9A55 0x9A4D 0x9AD2 0x9B1A 0x9C49 0x9C31 0x9C3E \ + 0x9C3B 0x9DD3 0x9DD7 0x9F34 0x9F6C 0x9F6A 0x9F94 0x56CC +52 0x5DD6 0x6200 0x6523 0x652B 0x652A 0x66EC 0x6B10 0x74DA \ + 0x7ACA 0x7C64 0x7C63 0x7C65 0x7E93 0x7E96 0x7E94 0x81E2 \ + 0x8638 0x863F 0x8831 0x8B8A 0x9090 0x908F 0x9463 0x9460 \ + 0x9464 0x9768 0x986F 0x995C 0x9A5A 0x9A5B 0x9A57 0x9AD3 \ + 0x9AD4 0x9AD1 0x9C54 0x9C57 0x9C56 0x9DE5 0x9E9F 0x9EF4 \ + 0x56D1 0x58E9 0x652C 0x705E 0x7671 0x7672 0x77D7 0x7F50 \ + 0x7F88 0x8836 0x8839 0x8862 0x8B93 0x8B92 0x8B96 0x8277 \ + 0x8D1B 0x91C0 0x946A 0x9742 0x9748 0x9744 0x97C6 0x9870 \ + 0x9A5F 0x9B22 0x9B58 0x9C5F 0x9DF9 0x9DFA 0x9E7C 0x9E7D \ + 0x9F07 0x9F77 0x9F72 0x5EF3 0x6B16 0x7063 0x7C6C 0x7C6E \ + 0x883B 0x89C0 0x8EA1 0x91C1 0x9472 0x9470 0x9871 0x995E \ + 0x9AD6 0x9B23 0x9ECC 0x7064 0x77DA 0x8B9A 0x9477 0x97C9 \ + 0x9A62 0x9A65 0x7E9C 0x8B9C 0x8EAA 0x91C5 0x947D 0x947E \ + 0x947C 0x9C77 0x9C78 0x9EF7 0x8C54 0x947F 0x9E1A 0x7228 \ + 0x9A6A 0x9B31 0x9E1B 0x9E1E 0x7C72 0x617B 0x616F 0x6181 \ + 0x613C 0x6142 0x6138 0x6133 0x6160 0x6169 0x617D 0x6186 \ + 0x622C 0x6228 0x644C 0x6457 0x647C 0x6455 0x6462 0x6471 \ + 0x646A 0x6456 0x643B 0x6481 0x644F 0x647E 0x6464 0x6571 \ + 0x66A5 0x669A 0x669C 0x66A6 0x66A4 0x698F 0x2460 0x2461 \ + 0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 \ + 0x2474 0x2475 0x2476 0x2477 0x2478 0x2479 0x247A 0x247B \ + 0x247C 0x247D 0x2170 0x2171 0x2172 0x2173 0x2174 0x2175 \ + 0x2176 0x2177 0x2178 0x2179 0x4E36 0x4E3F 0x4E85 0x4EA0 \ + 0x5182 0x5196 0x51AB 0x52F9 0x5338 0x5369 0x53B6 0x590A \ + 0x5B80 0x5DDB 0x5E7A 0x5E7F 0x5EF4 0x5F50 0x5F61 0x6534 \ + 0x65E0 0x7592 0x7676 0x8FB5 0x96B6 0x5902 0xFF3E 0x30FD \ + 0x30FE 0x309D 0x309E 0xFF02 0x309B 0x309C 0x30FB 0x3007 \ + 0x30FC 0xFF3B 0xFF3D 0x273D 0x3041 0x3042 0x3043 0x3044 \ + 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C \ + 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 \ + 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C \ + 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 +53 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C \ + 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 \ + 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C \ + 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 \ + 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C \ + 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x30A1 \ + 0x30A2 0x30A3 0x30A4 0x69C5 0x69C8 0x6992 0x69B2 0x69E3 \ + 0x69C0 0x69D6 0x69D1 0x699F 0x69A2 0x69D2 0x69E1 0x69D5 \ + 0x699D 0x6998 0x6B74 0x6BA1 0x6EF0 0x6EF3 0x6F1B 0x6F0C \ + 0x6F1D 0x6F34 0x6F28 0x6F17 0x6F44 0x6F42 0x6F04 0x6F11 \ + 0x6EFA 0x6F4A 0x7191 0x718E 0x30A5 0x30A6 0x30A7 0x30A8 \ + 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 \ + 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 \ + 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 \ + 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 \ + 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 \ + 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 \ + 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 \ + 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 \ + 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 \ + 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x6BB9 0x6E0B \ + 0x7105 0x7314 0x7304 0x7305 0x7315 0x730D 0x772E 0x7741 \ + 0x77EA 0x7844 0x7B29 0x7B27 0x7C9D 0x7FC8 0x8126 0x811C \ + 0x8128 0x8370 0x8382 0x83AC 0x86AD 0x86CA 0x8851 0x889D \ + 0x8990 0x89D8 0x89D7 0x8A2E 0x8C59 0x8EDA 0x9033 0x9018 \ + 0x91EF 0x9AD9 0x4EB4 0x50A0 0x5090 0x5086 0x5084 0x508A \ + 0x509F 0x50A1 0x5093 0x51D5 0x5590 0x5710 0x5817 0x5844 \ + 0x582B 0x5845 0x5965 0x5BCF 0x5D56 0x5D54 0x5F3D 0x5FA4 \ + 0x63EC 0x63FA 0x63D4 0x6675 0x671C 0x68D9 0x6BF1 0x6E37 \ + 0x6E7D 0x6E86 0x74FA 0x7572 0x75DC 0x7867 0x7977 0x7A9B \ + 0x7D2A 0x718B 0x718D 0x717F 0x718C 0x717E 0x717C 0x7183 \ + 0x7188 0x7294 0x7355 0x7353 0x734F 0x7354 0x746C 0x7465 +54 0x7466 0x7461 0x746B 0x7468 0x7476 0x7460 0x7474 0x7506 \ + 0x760E 0x7607 0x76B9 0x76B7 0x76E2 0x7774 0x7777 0x7776 \ + 0x7775 0x7778 0x7D65 0x7F64 0x8020 0x8120 0x813C 0x813F \ + 0x81F0 0x81F5 0x8415 0x83BE 0x86E5 0x86D2 0x86E0 0x88B3 \ + 0x8A53 0x8A37 0x8A47 0x8A5C 0x8EF0 0x921D 0x976B 0x50C0 \ + 0x52E5 0x53AF 0x55D8 0x5711 0x5867 0x5843 0x5BDD 0x5D70 \ + 0x5D6A 0x5D74 0x5D5F 0x5D61 0x5D73 0x5E50 0x5F3F 0x5FB0 \ + 0x6135 0x612D 0x6102 0x6226 0x656E 0x65B1 0x65D4 0x6685 \ + 0x6972 0x693A 0x6EAD 0x6E95 0x7243 0x728F 0x7575 0x75EC \ + 0x7757 0x797B 0x7A21 0x7A16 0x7AE8 0x7B6A 0x7B5F 0x7D82 \ + 0x8055 0x8168 0x8246 0x8243 0x8481 0x847C 0x846A 0x9170 \ + 0x50D2 0x9B62 0x6F8A 0x8772 0x9AF0 0x9EA8 0x5292 0x878C \ + 0x9ABA 0x9B81 0x9384 0x9AFF 0x9BB3 0x9BB0 0x9EC7 0x9721 \ + 0x7C36 0x8B5E 0x9401 0x941D 0x994A 0x8B73 0x9DD4 0x77D6 \ + 0x4E42 0x4E5C 0x51F5 0x531A 0x5382 0x4E07 0x4E0C 0x4E47 \ + 0x4E8D 0x56D7 0x5140 0x5C6E 0x5F73 0x4E0F 0x5187 0x4E0E \ + 0x4E2E 0x4E93 0x4EC2 0x4EC9 0x4EC8 0x5198 0x52FC 0x536C \ + 0x53B9 0x5720 0x5903 0x592C 0x5C10 0x5DFF 0x65E1 0x6BB3 \ + 0x6BCC 0x6C14 0x723F 0x4E31 0x4E3C 0x4EE8 0x4EDC 0x4EE9 \ + 0x4EE1 0x4EDD 0x4EDA 0x520C 0x531C 0x534C 0x5722 0x5723 \ + 0x5917 0x592F 0x5B81 0x5B84 0x5C12 0x5C3B 0x5C74 0x5C73 \ + 0x5E04 0x5E80 0x5E82 0x5FC9 0x6209 0x6250 0x6C15 0x7771 \ + 0x777A 0x715B 0x777B 0x78A6 0x78AE 0x78B8 0x78B1 0x78AF \ + 0x7989 0x7987 0x7A29 0x7A2A 0x7A2D 0x7A2C 0x7A32 0x7AEC \ + 0x7AF0 0x7B81 0x7B9E 0x7B83 0x7B92 0x7BA3 0x7B9F 0x7B93 \ + 0x7B86 0x7CB8 0x7CB7 0x7DC8 0x7DB6 0x7DD1 0x7DA8 0x7DAB \ + 0x6C36 0x6C43 0x6C3F 0x6C3B 0x72AE 0x72B0 0x738A 0x79B8 \ + 0x808A 0x961E 0x4F0E 0x4F18 0x4F2C 0x4EF5 0x4F14 0x4EF1 \ + 0x4F00 0x4EF7 0x4F08 0x4F1D 0x4F02 0x4F05 0x4F22 0x4F13 \ + 0x4F04 0x4EF4 0x4F12 0x51B1 0x5213 0x5209 0x5210 0x52A6 \ + 0x5322 0x531F 0x534D 0x538A 0x5407 0x56E1 0x56DF 0x572E \ + 0x572A 0x5734 0x593C 0x5980 0x597C 0x5985 0x597B 0x597E +55 0x5977 0x597F 0x5B56 0x5C15 0x5C25 0x5C7C 0x5C7A 0x5C7B \ + 0x5C7E 0x5DDF 0x5E75 0x5E84 0x5F02 0x5F1A 0x5F74 0x5FD5 \ + 0x5FD4 0x5FCF 0x625C 0x625E 0x6264 0x6261 0x6266 0x6262 \ + 0x6259 0x6260 0x625A 0x6265 0x65EF 0x65EE 0x673E 0x6739 \ + 0x6738 0x673B 0x673A 0x673F 0x673C 0x6733 0x6C18 0x6C46 \ + 0x6C52 0x6C5C 0x6C4F 0x6C4A 0x6C54 0x6C4B 0x6C4C 0x7071 \ + 0x725E 0x72B4 0x72B5 0x738E 0x752A 0x767F 0x7A75 0x7F51 \ + 0x8278 0x827C 0x8280 0x827D 0x827F 0x864D 0x897E 0x9099 \ + 0x9097 0x9098 0x909B 0x9094 0x9622 0x9624 0x9620 0x9623 \ + 0x4F56 0x4F3B 0x4F62 0x4F49 0x4F53 0x4F64 0x4F3E 0x4F67 \ + 0x4F52 0x4F5F 0x4F41 0x4F58 0x4F2D 0x4F33 0x4F3F 0x4F61 \ + 0x518F 0x51B9 0x521C 0x521E 0x5221 0x52AD 0x52AE 0x5309 \ + 0x5363 0x5372 0x538E 0x538F 0x5430 0x5437 0x542A 0x5454 \ + 0x5445 0x5419 0x541C 0x5425 0x5418 0x7DB3 0x7DCD 0x7DCF \ + 0x7DA4 0x7F41 0x7F6F 0x7F71 0x8023 0x805B 0x8061 0x805F \ + 0x8181 0x8184 0x8213 0x824A 0x824C 0x84BD 0x8495 0x8492 \ + 0x84C3 0x8496 0x84A5 0x84B5 0x84B3 0x84A3 0x84E4 0x84D8 \ + 0x84D5 0x84B7 0x84AD 0x84DA 0x8493 0x8736 0x543D 0x544F \ + 0x5441 0x5428 0x5424 0x5447 0x56EE 0x56E7 0x56E5 0x5741 \ + 0x5745 0x574C 0x5749 0x574B 0x5752 0x5906 0x5940 0x59A6 \ + 0x5998 0x59A0 0x5997 0x598E 0x59A2 0x5990 0x598F 0x59A7 \ + 0x59A1 0x5B8E 0x5B92 0x5C28 0x5C2A 0x5C8D 0x5C8F 0x5C88 \ + 0x5C8B 0x5C89 0x5C92 0x5C8A 0x5C86 0x5C93 0x5C95 0x5DE0 \ + 0x5E0A 0x5E0E 0x5E8B 0x5E89 0x5E8C 0x5E88 0x5E8D 0x5F05 \ + 0x5F1D 0x5F78 0x5F76 0x5FD2 0x5FD1 0x5FD0 0x5FED 0x5FE8 \ + 0x5FEE 0x5FF3 0x5FE1 0x5FE4 0x5FE3 0x5FFA 0x5FEF 0x5FF7 \ + 0x5FFB 0x6000 0x5FF4 0x623A 0x6283 0x628C 0x628E 0x628F \ + 0x6294 0x6287 0x6271 0x627B 0x627A 0x6270 0x6281 0x6288 \ + 0x6277 0x627D 0x6272 0x6274 0x6537 0x65F0 0x65F4 0x65F3 \ + 0x65F2 0x65F5 0x6745 0x6747 0x6759 0x6755 0x674C 0x6748 \ + 0x675D 0x674D 0x675A 0x674B 0x6BD0 0x6C19 0x6C1A 0x6C78 \ + 0x6C67 0x6C6B 0x6C84 0x6C8B 0x6C8F 0x6C71 0x6C6F 0x6C69 +56 0x6C9A 0x6C6D 0x6C87 0x6C95 0x6C9C 0x6C66 0x6C73 0x6C65 \ + 0x6C7B 0x6C8E 0x7074 0x707A 0x7263 0x72BF 0x72BD 0x72C3 \ + 0x72C6 0x72C1 0x72BA 0x72C5 0x7395 0x7397 0x7393 0x7394 \ + 0x7392 0x753A 0x7539 0x7594 0x7595 0x7681 0x793D 0x8034 \ + 0x8095 0x8099 0x8090 0x8092 0x809C 0x8290 0x828F 0x8285 \ + 0x828E 0x8291 0x8293 0x873D 0x872B 0x8747 0x8739 0x8745 \ + 0x871D 0x88FF 0x88EA 0x88F5 0x8900 0x88ED 0x8903 0x88E9 \ + 0x89EA 0x8A9B 0x8A8E 0x8AA2 0x8A9C 0x8A94 0x8A90 0x8AA9 \ + 0x8AAC 0x8A9F 0x8A9D 0x8C67 0x8CD0 0x8CD6 0x8CD4 0x8D98 \ + 0x8D9A 0x8D97 0x8E0B 0x8E08 0x828A 0x8283 0x8284 0x8C78 \ + 0x8FC9 0x8FBF 0x909F 0x90A1 0x90A5 0x909E 0x90A7 0x90A0 \ + 0x9630 0x9628 0x962F 0x962D 0x4E33 0x4F98 0x4F7C 0x4F85 \ + 0x4F7D 0x4F80 0x4F87 0x4F76 0x4F74 0x4F89 0x4F84 0x4F77 \ + 0x4F4C 0x4F97 0x4F6A 0x4F9A 0x4F79 0x4F81 0x4F78 0x4F90 \ + 0x4F9C 0x4F94 0x4F9E 0x4F92 0x4F82 0x4F95 0x4F6B 0x4F6E \ + 0x519E 0x51BC 0x51BE 0x5235 0x5232 0x5233 0x5246 0x5231 \ + 0x52BC 0x530A 0x530B 0x533C 0x5392 0x5394 0x5487 0x547F \ + 0x5481 0x5491 0x5482 0x5488 0x546B 0x547A 0x547E 0x5465 \ + 0x546C 0x5474 0x5466 0x548D 0x546F 0x5461 0x5460 0x5498 \ + 0x5463 0x5467 0x5464 0x56F7 0x56F9 0x576F 0x5772 0x576D \ + 0x576B 0x5771 0x5770 0x5776 0x5780 0x5775 0x577B 0x5773 \ + 0x5774 0x5762 0x5768 0x577D 0x590C 0x5945 0x59B5 0x59BA \ + 0x59CF 0x59CE 0x59B2 0x59CC 0x59C1 0x59B6 0x59BC 0x59C3 \ + 0x59D6 0x59B1 0x59BD 0x59C0 0x59C8 0x59B4 0x59C7 0x5B62 \ + 0x5B65 0x5B93 0x5B95 0x5C44 0x5C47 0x5CAE 0x5CA4 0x5CA0 \ + 0x5CB5 0x5CAF 0x5CA8 0x5CAC 0x5C9F 0x5CA3 0x5CAD 0x5CA2 \ + 0x5CAA 0x5CA7 0x5C9D 0x5CA5 0x5CB6 0x5CB0 0x5CA6 0x5E17 \ + 0x5E14 0x5E19 0x5F28 0x5F22 0x5F23 0x5F24 0x5F54 0x5F82 \ + 0x5F7E 0x5F7D 0x5FDE 0x5FE5 0x602D 0x6026 0x6019 0x6032 \ + 0x600B 0x8E01 0x8EB4 0x8EB3 0x8FA1 0x8FA2 0x905A 0x9061 \ + 0x905F 0x9125 0x917B 0x9176 0x917C 0x9289 0x92F6 0x92B1 \ + 0x92AD 0x9292 0x9281 0x9284 0x92AE 0x9290 0x929E 0x95A2 +57 0x95A7 0x96A0 0x969D 0x969F 0x96D0 0x96D1 0x9759 0x9764 \ + 0x9819 0x9814 0x6034 0x600A 0x6017 0x6033 0x601A 0x601E \ + 0x602C 0x6022 0x600D 0x6010 0x602E 0x6013 0x6011 0x600C \ + 0x6009 0x601C 0x6214 0x623D 0x62AD 0x62B4 0x62D1 0x62BE \ + 0x62AA 0x62B6 0x62CA 0x62AE 0x62B3 0x62AF 0x62BB 0x62A9 \ + 0x62B0 0x62B8 0x653D 0x65A8 0x65BB 0x6609 0x65FC 0x6604 \ + 0x6612 0x6608 0x65FB 0x6603 0x660B 0x660D 0x6605 0x65FD \ + 0x6611 0x6610 0x66F6 0x670A 0x6785 0x676C 0x678E 0x6792 \ + 0x6776 0x677B 0x6798 0x6786 0x6784 0x6774 0x678D 0x678C \ + 0x677A 0x679F 0x6791 0x6799 0x6783 0x677D 0x6781 0x6778 \ + 0x6779 0x6794 0x6B25 0x6B80 0x6B7E 0x6BDE 0x6C1D 0x6C93 \ + 0x6CEC 0x6CEB 0x6CEE 0x6CD9 0x6CB6 0x6CD4 0x6CAD 0x6CE7 \ + 0x6CB7 0x6CD0 0x6CC2 0x6CBA 0x6CC3 0x6CC6 0x6CED 0x6CF2 \ + 0x6CD2 0x6CDD 0x6CB4 0x6C8A 0x6C9D 0x6C80 0x6CDE 0x6CC0 \ + 0x6D30 0x6CCD 0x6CC7 0x6CB0 0x6CF9 0x6CCF 0x6CE9 0x6CD1 \ + 0x7094 0x7098 0x7085 0x7093 0x7086 0x7084 0x7091 0x7096 \ + 0x7082 0x709A 0x7083 0x726A 0x72D6 0x72CB 0x72D8 0x72C9 \ + 0x72DC 0x72D2 0x72D4 0x72DA 0x72CC 0x72D1 0x73A4 0x73A1 \ + 0x73AD 0x73A6 0x73A2 0x73A0 0x73AC 0x739D 0x74DD 0x74E8 \ + 0x753F 0x7540 0x753E 0x758C 0x7598 0x76AF 0x76F3 0x76F1 \ + 0x76F0 0x76F5 0x77F8 0x77FC 0x77F9 0x77FB 0x77FA 0x9815 \ + 0x981A 0x9906 0x98F8 0x9901 0x99BE 0x99BC 0x99B7 0x99B6 \ + 0x99C0 0x99B8 0x99C4 0x99BF 0x9ADA 0x9AE4 0x9AE9 0x9AE8 \ + 0x9AEA 0x9AE5 0x9B26 0x9B40 0x9EBD 0x510E 0x50F7 0x50FC \ + 0x510D 0x5101 0x51DA 0x51D9 0x51DB 0x5286 0x528E 0x52EE \ + 0x77F7 0x7942 0x793F 0x79C5 0x7A78 0x7A7B 0x7AFB 0x7C75 \ + 0x7CFD 0x8035 0x808F 0x80AE 0x80A3 0x80B8 0x80B5 0x80AD \ + 0x8220 0x82A0 0x82C0 0x82AB 0x829A 0x8298 0x829B 0x82B5 \ + 0x82A7 0x82AE 0x82BC 0x829E 0x82BA 0x82B4 0x82A8 0x82A1 \ + 0x82A9 0x82C2 0x82A4 0x82C3 0x82B6 0x82A2 0x8670 0x866F \ + 0x866D 0x866E 0x8C56 0x8FD2 0x8FCB 0x8FD3 0x8FCD 0x8FD6 \ + 0x8FD5 0x8FD7 0x90B2 0x90B4 0x90AF 0x90B3 0x90B0 0x9639 +58 0x963D 0x963C 0x963A 0x9643 0x4FCD 0x4FC5 0x4FD3 0x4FB2 \ + 0x4FC9 0x4FCB 0x4FC1 0x4FD4 0x4FDC 0x4FD9 0x4FBB 0x4FB3 \ + 0x4FDB 0x4FC7 0x4FD6 0x4FBA 0x4FC0 0x4FB9 0x4FEC 0x5244 \ + 0x5249 0x52C0 0x52C2 0x533D 0x537C 0x5397 0x5396 0x5399 \ + 0x5398 0x54BA 0x54A1 0x54AD 0x54A5 0x54CF 0x54C3 0x830D \ + 0x54B7 0x54AE 0x54D6 0x54B6 0x54C5 0x54C6 0x54A0 0x5470 \ + 0x54BC 0x54A2 0x54BE 0x5472 0x54DE 0x54B0 0x57B5 0x579E \ + 0x579F 0x57A4 0x578C 0x5797 0x579D 0x579B 0x5794 0x5798 \ + 0x578F 0x5799 0x57A5 0x579A 0x5795 0x58F4 0x590D 0x5953 \ + 0x59E1 0x59DE 0x59EE 0x5A00 0x59F1 0x59DD 0x59FA 0x59FD \ + 0x59FC 0x59F6 0x59E4 0x59F2 0x59F7 0x59DB 0x59E9 0x59F3 \ + 0x59F5 0x59E0 0x59FE 0x59F4 0x59ED 0x5BA8 0x5C4C 0x5CD0 \ + 0x5CD8 0x5CCC 0x5CD7 0x5CCB 0x5CDB 0x5333 0x53B1 0x5647 \ + 0x562D 0x5654 0x564B 0x5652 0x5631 0x5644 0x5656 0x5650 \ + 0x562B 0x564D 0x5637 0x564F 0x58A2 0x58B7 0x58B2 0x58AA \ + 0x58B5 0x58B0 0x58B4 0x58A4 0x58A7 0x5926 0x5AFE 0x5B04 \ + 0x5AFC 0x5B06 0x5B0A 0x5B0D 0x5B00 0x5B0E 0x5CDE 0x5CDA \ + 0x5CC9 0x5CC7 0x5CCA 0x5CD6 0x5CD3 0x5CD4 0x5CCF 0x5CC8 \ + 0x5CC6 0x5CCE 0x5CDF 0x5CF8 0x5DF9 0x5E21 0x5E22 0x5E23 \ + 0x5E20 0x5E24 0x5EB0 0x5EA4 0x5EA2 0x5E9B 0x5EA3 0x5EA5 \ + 0x5F07 0x5F2E 0x5F56 0x5F86 0x6037 0x6039 0x6054 0x6072 \ + 0x605E 0x6045 0x6053 0x6047 0x6049 0x605B 0x604C 0x6040 \ + 0x6042 0x605F 0x6024 0x6044 0x6058 0x6066 0x606E 0x6242 \ + 0x6243 0x62CF 0x630D 0x630B 0x62F5 0x630E 0x6303 0x62EB \ + 0x62F9 0x630F 0x630C 0x62F8 0x62F6 0x6300 0x6313 0x6314 \ + 0x62FA 0x6315 0x62FB 0x62F0 0x6541 0x6543 0x65AA 0x65BF \ + 0x6636 0x6621 0x6632 0x6635 0x661C 0x6626 0x6622 0x6633 \ + 0x662B 0x663A 0x661D 0x6634 0x6639 0x662E 0x670F 0x6710 \ + 0x67C1 0x67F2 0x67C8 0x67BA 0x67DC 0x67BB 0x67F8 0x67D8 \ + 0x67C0 0x67B7 0x67C5 0x67EB 0x67E4 0x67DF 0x67B5 0x67CD \ + 0x67B3 0x67F7 0x67F6 0x67EE 0x67E3 0x67C2 0x67B9 0x67CE \ + 0x67E7 0x67F0 0x67B2 0x67FC 0x67C6 0x67ED 0x67CC 0x67AE +59 0x67E6 0x67DB 0x67FA 0x67C9 0x67CA 0x67C3 0x67EA 0x67CB \ + 0x6B28 0x6B82 0x6B84 0x6BB6 0x6BD6 0x6BD8 0x6BE0 0x6C20 \ + 0x6C21 0x6D28 0x6D34 0x6D2D 0x6D1F 0x6D3C 0x6D3F 0x6D12 \ + 0x6D0A 0x6CDA 0x6D33 0x6D04 0x6D19 0x6D3A 0x6D1A 0x6D11 \ + 0x6D00 0x6D1D 0x6D42 0x5D91 0x5D8F 0x5D90 0x5D98 0x5DA4 \ + 0x5D9B 0x5DA3 0x5D96 0x5DE4 0x5E5A 0x5E5E 0x5FB8 0x6157 \ + 0x615C 0x61A6 0x6195 0x6188 0x61A3 0x618F 0x6164 0x6159 \ + 0x6178 0x6185 0x6187 0x619E 0x6198 0x619C 0x622F 0x6480 \ + 0x649B 0x648E 0x648D 0x6494 0x6D01 0x6D18 0x6D37 0x6D03 \ + 0x6D0F 0x6D40 0x6D07 0x6D20 0x6D2C 0x6D08 0x6D22 0x6D09 \ + 0x6D10 0x70B7 0x709F 0x70BE 0x70B1 0x70B0 0x70A1 0x70B4 \ + 0x70B5 0x70A9 0x7241 0x7249 0x724A 0x726C 0x7270 0x7273 \ + 0x726E 0x72CA 0x72E4 0x72E8 0x72EB 0x72DF 0x72EA 0x72E6 \ + 0x72E3 0x7385 0x73CC 0x73C2 0x73C8 0x73C5 0x73B9 0x73B6 \ + 0x73B5 0x73B4 0x73EB 0x73BF 0x73C7 0x73BE 0x73C3 0x73C6 \ + 0x73B8 0x73CB 0x74EC 0x74EE 0x752E 0x7547 0x7548 0x75A7 \ + 0x75AA 0x7679 0x76C4 0x7708 0x7703 0x7704 0x7705 0x770A \ + 0x76F7 0x76FB 0x76FA 0x77E7 0x77E8 0x7806 0x7811 0x7812 \ + 0x7805 0x7810 0x780F 0x780E 0x7809 0x7803 0x7813 0x794A \ + 0x794C 0x794B 0x7945 0x7944 0x79D5 0x79CD 0x79CF 0x79D6 \ + 0x79CE 0x7A80 0x7A7E 0x7AD1 0x7B00 0x7B01 0x7C7A 0x7C78 \ + 0x7C79 0x7C7F 0x7C80 0x7C81 0x7D03 0x7D08 0x7D01 0x7F58 \ + 0x7F91 0x7F8D 0x7FBE 0x8007 0x800E 0x800F 0x8014 0x8037 \ + 0x80D8 0x80C7 0x80E0 0x80D1 0x80C8 0x80C2 0x80D0 0x80C5 \ + 0x80E3 0x80D9 0x80DC 0x80CA 0x80D5 0x80C9 0x80CF 0x80D7 \ + 0x80E6 0x80CD 0x81FF 0x8221 0x8294 0x82D9 0x82FE 0x82F9 \ + 0x8307 0x82E8 0x8300 0x82D5 0x833A 0x82EB 0x82D6 0x82F4 \ + 0x82EC 0x82E1 0x82F2 0x82F5 0x830C 0x82FB 0x82F6 0x82F0 \ + 0x82EA 0x64C6 0x64A8 0x6483 0x64B9 0x6486 0x64B4 0x64AF \ + 0x6491 0x64AA 0x64A1 0x64A7 0x66B6 0x66B3 0x66BC 0x66AC \ + 0x66AD 0x6A0E 0x6A1C 0x6A1A 0x6A0B 0x69EF 0x6A0C 0x69F0 \ + 0x6A22 0x69D8 0x6A12 0x69FA 0x6A2A 0x6A10 0x6A29 0x69F9 +60 0x69EA 0x6A2C 0x82E4 0x82E0 0x82FA 0x82F3 0x82ED 0x8677 \ + 0x8674 0x867C 0x8673 0x8841 0x884E 0x8867 0x886A 0x8869 \ + 0x89D3 0x8A04 0x8A07 0x8D72 0x8FE3 0x8FE1 0x8FEE 0x8FE0 \ + 0x90F1 0x90BD 0x90BF 0x90D5 0x90C5 0x90BE 0x90C7 0x90CB \ + 0x90C8 0x91D4 0x91D3 0x9654 0x964F 0x9651 0x9653 0x964A \ + 0x964E 0x501E 0x5005 0x5007 0x5013 0x5022 0x5030 0x501B \ + 0x4FF5 0x4FF4 0x5033 0x5037 0x502C 0x4FF6 0x4FF7 0x5017 \ + 0x501C 0x5020 0x5027 0x5035 0x502F 0x5031 0x500E 0x515A \ + 0x5194 0x5193 0x51CA 0x51C4 0x51C5 0x51C8 0x51CE 0x5261 \ + 0x525A 0x5252 0x525E 0x525F 0x5255 0x5262 0x52CD 0x530E \ + 0x539E 0x5526 0x54E2 0x5517 0x5512 0x54E7 0x54F3 0x54E4 \ + 0x551A 0x54FF 0x5504 0x5508 0x54EB 0x5511 0x5505 0x54F1 \ + 0x550A 0x54FB 0x54F7 0x54F8 0x54E0 0x550E 0x5503 0x550B \ + 0x5701 0x5702 0x57CC 0x5832 0x57D5 0x57D2 0x57BA 0x57C6 \ + 0x57BD 0x57BC 0x57B8 0x57B6 0x57BF 0x57C7 0x57D0 0x57B9 \ + 0x57C1 0x590E 0x594A 0x5A19 0x5A16 0x5A2D 0x5A2E 0x5A15 \ + 0x5A0F 0x5A17 0x5A0A 0x5A1E 0x5A33 0x5B6C 0x5BA7 0x5BAD \ + 0x5BAC 0x5C03 0x5C56 0x5C54 0x5CEC 0x5CFF 0x5CEE 0x5CF1 \ + 0x5CF7 0x5D00 0x5CF9 0x5E29 0x5E28 0x5EA8 0x5EAE 0x5EAA \ + 0x5EAC 0x5F33 0x5F30 0x5F67 0x605D 0x605A 0x6067 0x6A24 \ + 0x69E9 0x6B52 0x6B4F 0x6B53 0x6F10 0x6F65 0x6F75 0x6FD0 \ + 0x6F5C 0x6F3D 0x6F71 0x6F91 0x6F0B 0x6F79 0x6F81 0x6F8F \ + 0x6F59 0x6F74 0x71AE 0x71A3 0x71AD 0x71AB 0x71A6 0x71A2 \ + 0x52F2 0x7257 0x7255 0x7299 0x734B 0x747A 0x748C 0x7484 \ + 0x6041 0x60A2 0x6088 0x6080 0x6092 0x6081 0x609D 0x6083 \ + 0x6095 0x609B 0x6097 0x6087 0x609C 0x608E 0x6219 0x6246 \ + 0x62F2 0x6310 0x6356 0x632C 0x6344 0x6345 0x6336 0x6343 \ + 0x63E4 0x6339 0x634B 0x634A 0x633C 0x6329 0x6341 0x6334 \ + 0x6358 0x6354 0x6359 0x632D 0x6347 0x6333 0x635A 0x6351 \ + 0x6338 0x6357 0x6340 0x6348 0x654A 0x6546 0x65C6 0x65C3 \ + 0x65C4 0x65C2 0x664A 0x665F 0x6647 0x6651 0x6712 0x6713 \ + 0x681F 0x681A 0x6849 0x6832 0x6833 0x683B 0x684B 0x684F +61 0x6816 0x6831 0x681C 0x6835 0x682B 0x682D 0x682F 0x684E \ + 0x6844 0x6834 0x681D 0x6812 0x6814 0x6826 0x6828 0x682E \ + 0x684D 0x683A 0x6825 0x6820 0x6B2C 0x6B2F 0x6B2D 0x6B31 \ + 0x6B34 0x6B6D 0x8082 0x6B88 0x6BE6 0x6BE4 0x6BE8 0x6BE3 \ + 0x6BE2 0x6BE7 0x6C25 0x6D7A 0x6D63 0x6D64 0x6D76 0x6D0D \ + 0x6D61 0x6D92 0x6D58 0x6D62 0x6D6D 0x6D6F 0x6D91 0x6D8D \ + 0x6DEF 0x6D7F 0x6D86 0x6D5E 0x6D67 0x6D60 0x6D97 0x6D70 \ + 0x6D7C 0x6D5F 0x6D82 0x6D98 0x6D2F 0x6D68 0x6D8B 0x6D7E \ + 0x6D80 0x6D84 0x6D16 0x6D83 0x6D7B 0x6D7D 0x6D75 0x6D90 \ + 0x70DC 0x70D3 0x70D1 0x70DD 0x70CB 0x7F39 0x70E2 0x70D7 \ + 0x70D2 0x70DE 0x70E0 0x70D4 0x70CD 0x70C5 0x70C6 0x70C7 \ + 0x70DA 0x70CE 0x70E1 0x7242 0x7278 0x7482 0x7493 0x747B \ + 0x7509 0x778A 0x7790 0x78C6 0x78D3 0x78C0 0x78D2 0x78C7 \ + 0x78C2 0x799F 0x799D 0x799E 0x7A41 0x7A38 0x7A3A 0x7A42 \ + 0x7A3E 0x7AB0 0x7BAE 0x7BB3 0x7BBF 0x7BCD 0x7BB2 0x7CC4 \ + 0x7CCD 0x7CC2 0x7CC6 0x7CC3 0x7CC9 0x7CC7 0x7277 0x7276 \ + 0x7300 0x72FA 0x72F4 0x72FE 0x72F6 0x72F3 0x72FB 0x7301 \ + 0x73D3 0x73D9 0x73E5 0x73D6 0x73BC 0x73E7 0x73E3 0x73E9 \ + 0x73DC 0x73D2 0x73DB 0x73D4 0x73DD 0x73DA 0x73D7 0x73D8 \ + 0x73E8 0x74DE 0x74DF 0x74F4 0x74F5 0x7521 0x755B 0x755F \ + 0x75B0 0x75C1 0x75BB 0x75C4 0x75C0 0x75BF 0x75B6 0x75BA \ + 0x768A 0x76C9 0x771D 0x771B 0x7710 0x7713 0x7712 0x7723 \ + 0x7711 0x7715 0x7719 0x771A 0x7722 0x7727 0x7823 0x782C \ + 0x7822 0x7835 0x782F 0x7828 0x782E 0x782B 0x7821 0x7829 \ + 0x7833 0x782A 0x7831 0x7954 0x795B 0x794F 0x795C 0x7953 \ + 0x7952 0x7951 0x79EB 0x79EC 0x79E0 0x79EE 0x79ED 0x79EA \ + 0x79DC 0x79DE 0x79DD 0x7A86 0x7A89 0x7A85 0x7A8B 0x7A8C \ + 0x7A8A 0x7A87 0x7AD8 0x7B10 0x7B04 0x7B13 0x7B05 0x7B0F \ + 0x7B08 0x7B0A 0x7B0E 0x7B09 0x7B12 0x7C84 0x7C91 0x7C8A \ + 0x7C8C 0x7C88 0x7C8D 0x7C85 0x7D1E 0x7D1D 0x7D11 0x7D0E \ + 0x7D18 0x7D16 0x7D13 0x7D1F 0x7D12 0x7D0F 0x7D0C 0x7F5C \ + 0x7F61 0x7F5E 0x7F60 0x7F5D 0x7F5B 0x7F96 0x7F92 0x7FC3 +62 0x7FC2 0x7FC0 0x8016 0x803E 0x8039 0x80FA 0x80F2 0x80F9 \ + 0x80F5 0x8101 0x80FB 0x8100 0x8201 0x822F 0x8225 0x8333 \ + 0x832D 0x8344 0x8319 0x8351 0x8325 0x8356 0x833F 0x8341 \ + 0x8326 0x831C 0x8322 0x7DF8 0x7DED 0x7DE2 0x7DDC 0x7E02 \ + 0x7E01 0x7DD6 0x7DE4 0x7DFE 0x7E00 0x7DFC 0x7DFD 0x7DF5 \ + 0x7DFF 0x7DEB 0x7DE5 0x7F78 0x7FAE 0x7FE7 0x8065 0x806A \ + 0x8066 0x8068 0x806B 0x8194 0x81A1 0x8192 0x8196 0x8193 \ + 0x8501 0x84F8 0x84F5 0x8504 0x8342 0x834E 0x831B 0x832A \ + 0x8308 0x833C 0x834D 0x8316 0x8324 0x8320 0x8337 0x832F \ + 0x8329 0x8347 0x8345 0x834C 0x8353 0x831E 0x832C 0x834B \ + 0x8327 0x8348 0x8653 0x8652 0x86A2 0x86A8 0x8696 0x868D \ + 0x8691 0x869E 0x8687 0x8697 0x8686 0x868B 0x869A 0x8685 \ + 0x86A5 0x8699 0x86A1 0x86A7 0x8695 0x8698 0x868E 0x869D \ + 0x8690 0x8694 0x8843 0x8844 0x886D 0x8875 0x8876 0x8872 \ + 0x8880 0x8871 0x887F 0x886F 0x8883 0x887E 0x8874 0x887C \ + 0x8A12 0x8C47 0x8C57 0x8C7B 0x8CA4 0x8CA3 0x8D76 0x8D78 \ + 0x8DB5 0x8DB7 0x8DB6 0x8ED1 0x8ED3 0x8FFE 0x8FF5 0x9002 \ + 0x8FFF 0x8FFB 0x9004 0x8FFC 0x8FF6 0x90D6 0x90E0 0x90D9 \ + 0x90DA 0x90E3 0x90DF 0x90E5 0x90D8 0x90DB 0x90D7 0x90DC \ + 0x90E4 0x9150 0x914E 0x914F 0x91D5 0x91E2 0x91DA 0x965C \ + 0x965F 0x96BC 0x98E3 0x9ADF 0x9B2F 0x4E7F 0x5070 0x506A \ + 0x5061 0x505E 0x5060 0x5053 0x504B 0x505D 0x5072 0x5048 \ + 0x504D 0x5041 0x505B 0x504A 0x5062 0x5015 0x5045 0x505F \ + 0x5069 0x506B 0x5063 0x5064 0x5046 0x5040 0x506E 0x5073 \ + 0x5057 0x5051 0x51D0 0x526B 0x526D 0x526C 0x526E 0x52D6 \ + 0x52D3 0x532D 0x539C 0x5575 0x5576 0x553C 0x554D 0x5550 \ + 0x5534 0x552A 0x5551 0x5562 0x5536 0x5535 0x5530 0x5552 \ + 0x5545 0x851B 0x8503 0x8533 0x8534 0x84ED 0x8535 0x8505 \ + 0x877D 0x8771 0x885C 0x88E6 0x890F 0x891B 0x89A9 0x89A5 \ + 0x89EE 0x8AB1 0x8ACC 0x8ACE 0x8AB7 0x8AB5 0x8AE9 0x8AB4 \ + 0x8AB3 0x8AC1 0x8AAF 0x8ACA 0x8AD0 0x8C8E 0x8CE9 0x8CDB \ + 0x8CEB 0x8DA4 0x550C 0x5532 0x5565 0x554E 0x5539 0x5548 +63 0x552D 0x553B 0x5540 0x554B 0x570A 0x5707 0x57FB 0x5814 \ + 0x57E2 0x57F6 0x57DC 0x57F4 0x5800 0x57ED 0x57FD 0x5808 \ + 0x57F8 0x580B 0x57F3 0x57CF 0x5807 0x57EE 0x57E3 0x57F2 \ + 0x57E5 0x57EC 0x57E1 0x580E 0x57FC 0x5810 0x57E7 0x5801 \ + 0x580C 0x57F1 0x57E9 0x57F0 0x580D 0x5804 0x595C 0x5A60 \ + 0x5A58 0x5A55 0x5A67 0x5A5E 0x5A38 0x5A35 0x5A6D 0x5A50 \ + 0x5A5F 0x5A65 0x5A6C 0x5A53 0x5A64 0x5A57 0x5A43 0x5A5D \ + 0x5A52 0x5A44 0x5A5B 0x5A48 0x5A8E 0x5A3E 0x5A4D 0x5A39 \ + 0x5A4C 0x5A70 0x5A69 0x5A47 0x5A51 0x5A56 0x5A42 0x5A5C \ + 0x5B72 0x5B6E 0x5BC1 0x5BC0 0x5C59 0x5D1E 0x5D0B 0x5D1D \ + 0x5D1A 0x5D20 0x5D0C 0x5D28 0x5D0D 0x5D26 0x5D25 0x5D0F \ + 0x5D30 0x5D12 0x5D23 0x5D1F 0x5D2E 0x5E3E 0x5E34 0x5EB1 \ + 0x5EB4 0x5EB9 0x5EB2 0x5EB3 0x5F36 0x5F38 0x5F9B 0x5F96 \ + 0x5F9F 0x608A 0x6090 0x6086 0x60BE 0x60B0 0x60BA 0x60D3 \ + 0x60D4 0x60CF 0x60E4 0x60D9 0x60DD 0x60C8 0x60B1 0x60DB \ + 0x60B7 0x60CA 0x60BF 0x60C3 0x60CD 0x60C0 0x6332 0x6365 \ + 0x638A 0x6382 0x637D 0x63BD 0x639E 0x63AD 0x639D 0x6397 \ + 0x63AB 0x638E 0x636F 0x6387 0x6390 0x636E 0x63AF 0x6375 \ + 0x639C 0x636D 0x63AE 0x637C 0x63A4 0x633B 0x639F 0x8DA2 \ + 0x8D9D 0x8E2A 0x8E28 0x8EB8 0x8EB6 0x8EB9 0x8EB7 0x8F22 \ + 0x8F2B 0x8F27 0x8F19 0x8FA4 0x8FB3 0x9071 0x906A 0x9188 \ + 0x918C 0x92BF 0x92B8 0x92BE 0x92DC 0x92E5 0x92D4 0x92D6 \ + 0x92DA 0x92ED 0x92F3 0x92DB 0x92E2 0x92EB 0x95AF 0x95B2 \ + 0x6378 0x6385 0x6381 0x6391 0x638D 0x6370 0x6553 0x65CD \ + 0x6665 0x6661 0x665B 0x6659 0x665C 0x6662 0x6718 0x6879 \ + 0x6887 0x6890 0x689C 0x686D 0x686E 0x68AE 0x68AB 0x6956 \ + 0x686F 0x68A3 0x68AC 0x68A9 0x6875 0x6874 0x68B2 0x688F \ + 0x6877 0x6892 0x687C 0x686B 0x6872 0x68AA 0x6880 0x6871 \ + 0x687E 0x689B 0x6896 0x688B 0x68A0 0x6889 0x68A4 0x6878 \ + 0x687B 0x6891 0x688C 0x688A 0x687D 0x6B36 0x6B33 0x6B37 \ + 0x6B38 0x6B91 0x6B8F 0x6B8D 0x6B8E 0x6B8C 0x6C2A 0x6DC0 \ + 0x6DAB 0x6DB4 0x6DB3 0x6E74 0x6DAC 0x6DE9 0x6DE2 0x6DB7 +64 0x6DF6 0x6DD4 0x6E00 0x6DC8 0x6DE0 0x6DDF 0x6DD6 0x6DBE \ + 0x6DE5 0x6DDC 0x6DDD 0x6DDB 0x6DF4 0x6DCA 0x6DBD 0x6DED \ + 0x6DF0 0x6DBA 0x6DD5 0x6DC2 0x6DCF 0x6DC9 0x6DD0 0x6DF2 \ + 0x6DD3 0x6DFD 0x6DD7 0x6DCD 0x6DE3 0x6DBB 0x70FA 0x710D \ + 0x70F7 0x7117 0x70F4 0x710C 0x70F0 0x7104 0x70F3 0x7110 \ + 0x70FC 0x70FF 0x7106 0x7113 0x7100 0x70F8 0x70F6 0x710B \ + 0x7102 0x710E 0x727E 0x727B 0x727C 0x727F 0x731D 0x7317 \ + 0x7307 0x7311 0x7318 0x730A 0x7308 0x72FF 0x730F 0x731E \ + 0x7388 0x73F6 0x73F8 0x73F5 0x7404 0x7401 0x73FD 0x7407 \ + 0x7400 0x73FA 0x73FC 0x73FF 0x740C 0x740B 0x73F4 0x7408 \ + 0x7564 0x7563 0x75CE 0x75D2 0x75CF 0x95B3 0x96A3 0x96A5 \ + 0x970A 0x9787 0x9789 0x978C 0x97EF 0x982A 0x9822 0x981F \ + 0x9919 0x99CA 0x99DA 0x99DE 0x99C8 0x99E0 0x9AB6 0x9AB5 \ + 0x9AF4 0x9B6B 0x9B69 0x9B72 0x9B63 0x9D0D 0x9D01 0x9D0C \ + 0x9CF8 0x9CFE 0x9D02 0x9E84 0x9EAB 0x9EAA 0x75CB 0x75CC \ + 0x75D1 0x75D0 0x768F 0x7689 0x76D3 0x7739 0x772F 0x772D \ + 0x7731 0x7732 0x7734 0x7733 0x773D 0x7725 0x773B 0x7735 \ + 0x7848 0x7852 0x7849 0x784D 0x784A 0x784C 0x7826 0x7845 \ + 0x7850 0x7964 0x7967 0x7969 0x796A 0x7963 0x796B 0x7961 \ + 0x79BB 0x79FA 0x79F8 0x79F6 0x79F7 0x7A8F 0x7A94 0x7A90 \ + 0x7B35 0x7B47 0x7B34 0x7B25 0x7B30 0x7B22 0x7B24 0x7B33 \ + 0x7B18 0x7B2A 0x7B1D 0x7B31 0x7B2B 0x7B2D 0x7B2F 0x7B32 \ + 0x7B38 0x7B1A 0x7B23 0x7C94 0x7C98 0x7C96 0x7CA3 0x7D35 \ + 0x7D3D 0x7D38 0x7D36 0x7D3A 0x7D45 0x7D2C 0x7D29 0x7D41 \ + 0x7D47 0x7D3E 0x7D3F 0x7D4A 0x7D3B 0x7D28 0x7F63 0x7F95 \ + 0x7F9C 0x7F9D 0x7F9B 0x7FCA 0x7FCB 0x7FCD 0x7FD0 0x7FD1 \ + 0x7FC7 0x7FCF 0x7FC9 0x801F 0x801E 0x801B 0x8047 0x8043 \ + 0x8048 0x8118 0x8125 0x8119 0x811B 0x812D 0x811F 0x812C \ + 0x811E 0x8121 0x8115 0x8127 0x811D 0x8122 0x8211 0x8238 \ + 0x8233 0x823A 0x8234 0x8232 0x8274 0x8390 0x83A3 0x83A8 \ + 0x838D 0x837A 0x8373 0x83A4 0x8374 0x838F 0x8381 0x8395 \ + 0x8399 0x8375 0x8394 0x83A9 0x837D 0x8383 0x838C 0x839D +65 0x839B 0x83AA 0x838B 0x837E 0x83A5 0x83AF 0x8388 0x8397 \ + 0x83B0 0x837F 0x83A6 0x8387 0x83AE 0x8376 0x839A 0x8659 \ + 0x8656 0x86BF 0x86B7 0x511D 0x5116 0x512B 0x511E 0x511B \ + 0x5290 0x5294 0x5314 0x5667 0x567B 0x565F 0x5661 0x58C3 \ + 0x58CA 0x58C0 0x58C4 0x5901 0x5B1F 0x5B18 0x5B11 0x5B15 \ + 0x5B12 0x5B1C 0x5B22 0x5B79 0x5DA6 0x5DB3 0x5DAB 0x5EEA \ + 0x5F5B 0x61B7 0x61CE 0x61B9 0x86C2 0x86C1 0x86C5 0x86BA \ + 0x86B0 0x86C8 0x86B9 0x86B3 0x86B8 0x86CC 0x86B4 0x86BB \ + 0x86BC 0x86C3 0x86BD 0x86BE 0x8852 0x8889 0x8895 0x88A8 \ + 0x88A2 0x88AA 0x889A 0x8891 0x88A1 0x889F 0x8898 0x88A7 \ + 0x8899 0x889B 0x8897 0x88A4 0x88AC 0x888C 0x8893 0x888E \ + 0x8982 0x89D6 0x89D9 0x89D5 0x8A30 0x8A27 0x8A2C 0x8A1E \ + 0x8C39 0x8C3B 0x8C5C 0x8C5D 0x8C7D 0x8CA5 0x8D7D 0x8D7B \ + 0x8D79 0x8DBC 0x8DC2 0x8DB9 0x8DBF 0x8DC1 0x8ED8 0x8EDE \ + 0x8EDD 0x8EDC 0x8ED7 0x8EE0 0x8EE1 0x9024 0x900B 0x9011 \ + 0x901C 0x900C 0x9021 0x90EF 0x90EA 0x90F0 0x90F4 0x90F2 \ + 0x90F3 0x90D4 0x90EB 0x90EC 0x90E9 0x9156 0x9158 0x915A \ + 0x9153 0x9155 0x91EC 0x91F4 0x91F1 0x91F3 0x91F8 0x91E4 \ + 0x91F9 0x91EA 0x91EB 0x91F7 0x91E8 0x91EE 0x957A 0x9586 \ + 0x9588 0x967C 0x966D 0x966B 0x9671 0x966F 0x96BF 0x976A \ + 0x9804 0x98E5 0x9997 0x509B 0x5095 0x5094 0x509E 0x508B \ + 0x50A3 0x5083 0x508C 0x508E 0x509D 0x5068 0x509C 0x5092 \ + 0x5082 0x5087 0x515F 0x51D4 0x5312 0x5311 0x53A4 0x53A7 \ + 0x5591 0x55A8 0x55A5 0x55AD 0x5577 0x5645 0x55A2 0x5593 \ + 0x5588 0x558F 0x55B5 0x5581 0x55A3 0x5592 0x55A4 0x557D \ + 0x558C 0x55A6 0x557F 0x5595 0x55A1 0x558E 0x570C 0x5829 \ + 0x5837 0x61BD 0x61CF 0x61C0 0x6199 0x6197 0x61BB 0x61D0 \ + 0x61C4 0x6231 0x64D3 0x64C0 0x64DC 0x64D1 0x64C8 0x64D5 \ + 0x66C3 0x66BF 0x66C5 0x66CD 0x66C1 0x6706 0x6724 0x6A63 \ + 0x6A42 0x6A52 0x6A43 0x6A33 0x6A6C 0x6A57 0x6A4C 0x6A6E \ + 0x6A37 0x6A71 0x5819 0x581E 0x5827 0x5823 0x5828 0x57F5 \ + 0x5848 0x5825 0x581C 0x581B 0x5833 0x583F 0x5836 0x582E +66 0x5839 0x5838 0x582D 0x582C 0x583B 0x5961 0x5AAF 0x5A94 \ + 0x5A9F 0x5A7A 0x5AA2 0x5A9E 0x5A78 0x5AA6 0x5A7C 0x5AA5 \ + 0x5AAC 0x5A95 0x5AAE 0x5A37 0x5A84 0x5A8A 0x5A97 0x5A83 \ + 0x5A8B 0x5AA9 0x5A7B 0x5A7D 0x5A8C 0x5A9C 0x5A8F 0x5A93 \ + 0x5A9D 0x5BEA 0x5BCD 0x5BCB 0x5BD4 0x5BD1 0x5BCA 0x5BCE \ + 0x5C0C 0x5C30 0x5D37 0x5D43 0x5D6B 0x5D41 0x5D4B 0x5D3F \ + 0x5D35 0x5D51 0x5D4E 0x5D55 0x5D33 0x5D3A 0x5D52 0x5D3D \ + 0x5D31 0x5D59 0x5D42 0x5D39 0x5D49 0x5D38 0x5D3C 0x5D32 \ + 0x5D36 0x5D40 0x5D45 0x5E44 0x5E41 0x5F58 0x5FA6 0x5FA5 \ + 0x5FAB 0x60C9 0x60B9 0x60CC 0x60E2 0x60CE 0x60C4 0x6114 \ + 0x60F2 0x610A 0x6116 0x6105 0x60F5 0x6113 0x60F8 0x60FC \ + 0x60FE 0x60C1 0x6103 0x6118 0x611D 0x6110 0x60FF 0x6104 \ + 0x610B 0x624A 0x6394 0x63B1 0x63B0 0x63CE 0x63E5 0x63E8 \ + 0x63EF 0x63C3 0x649D 0x63F3 0x63CA 0x63E0 0x63F6 0x63D5 \ + 0x63F2 0x63F5 0x6461 0x63DF 0x63BE 0x63DD 0x63DC 0x63C4 \ + 0x63D8 0x63D3 0x63C2 0x63C7 0x63CC 0x63CB 0x63C8 0x63F0 \ + 0x63D7 0x63D9 0x6532 0x6567 0x656A 0x6564 0x655C 0x6568 \ + 0x6565 0x658C 0x659D 0x659E 0x65AE 0x65D0 0x65D2 0x6A4A \ + 0x6A36 0x6A53 0x6A45 0x6A70 0x6A5C 0x6B58 0x6B57 0x6FBB \ + 0x6FBE 0x6FB5 0x6FD3 0x6F9F 0x6FB7 0x6FF5 0x71B7 0x71BB \ + 0x71D1 0x71BA 0x71B6 0x71CC 0x71D3 0x749B 0x7496 0x74A2 \ + 0x749D 0x750A 0x750E 0x7581 0x762C 0x7637 0x7636 0x763B \ + 0x667C 0x666C 0x667B 0x6680 0x6671 0x6679 0x666A 0x6672 \ + 0x6701 0x690C 0x68D3 0x6904 0x68DC 0x692A 0x68EC 0x68EA \ + 0x68F1 0x690F 0x68D6 0x68F7 0x68EB 0x68E4 0x68F6 0x6913 \ + 0x6910 0x68F3 0x68E1 0x6907 0x68CC 0x6908 0x6970 0x68B4 \ + 0x6911 0x68EF 0x68C6 0x6914 0x68F8 0x68D0 0x68FD 0x68FC \ + 0x68E8 0x690B 0x690A 0x6917 0x68CE 0x68C8 0x68DD 0x68DE \ + 0x68E6 0x68F4 0x68D1 0x6906 0x68D4 0x68E9 0x6915 0x6925 \ + 0x68C7 0x6B39 0x6B3B 0x6B3F 0x6B3C 0x6B94 0x6B97 0x6B99 \ + 0x6B95 0x6BBD 0x6BF0 0x6BF2 0x6BF3 0x6C30 0x6DFC 0x6E46 \ + 0x6E47 0x6E1F 0x6E49 0x6E88 0x6E3C 0x6E3D 0x6E45 0x6E62 +67 0x6E2B 0x6E3F 0x6E41 0x6E5D 0x6E73 0x6E1C 0x6E33 0x6E4B \ + 0x6E40 0x6E51 0x6E3B 0x6E03 0x6E2E 0x6E5E 0x6E68 0x6E5C \ + 0x6E61 0x6E31 0x6E28 0x6E60 0x6E71 0x6E6B 0x6E39 0x6E22 \ + 0x6E30 0x6E53 0x6E65 0x6E27 0x6E78 0x6E64 0x6E77 0x6E55 \ + 0x6E79 0x6E52 0x6E66 0x6E35 0x6E36 0x6E5A 0x7120 0x711E \ + 0x712F 0x70FB 0x712E 0x7131 0x7123 0x7125 0x7122 0x7132 \ + 0x711F 0x7128 0x713A 0x711B 0x724B 0x725A 0x7288 0x7289 \ + 0x7286 0x7285 0x728B 0x7312 0x730B 0x7330 0x7322 0x7331 \ + 0x7333 0x7327 0x7332 0x732D 0x7326 0x7323 0x7335 0x730C \ + 0x742E 0x742C 0x7430 0x742B 0x7416 0x76A1 0x7798 0x7796 \ + 0x78D6 0x78EB 0x78DC 0x79A5 0x79A9 0x9834 0x7A53 0x7A45 \ + 0x7A4F 0x7ABD 0x7ABB 0x7AF1 0x7BEC 0x7BED 0x7CD3 0x7CE1 \ + 0x7E19 0x7E27 0x7E26 0x806E 0x81AF 0x81AD 0x81AA 0x8218 \ + 0x856F 0x854C 0x8542 0x855C 0x8570 0x855F 0x741A 0x7421 \ + 0x742D 0x7431 0x7424 0x7423 0x741D 0x7429 0x7420 0x7432 \ + 0x74FB 0x752F 0x756F 0x756C 0x75E7 0x75DA 0x75E1 0x75E6 \ + 0x75DD 0x75DF 0x75E4 0x75D7 0x7695 0x7692 0x76DA 0x7746 \ + 0x7747 0x7744 0x774D 0x7745 0x774A 0x774E 0x774B 0x774C \ + 0x77DE 0x77EC 0x7860 0x7864 0x7865 0x785C 0x786D 0x7871 \ + 0x786A 0x786E 0x7870 0x7869 0x7868 0x785E 0x7862 0x7974 \ + 0x7973 0x7972 0x7970 0x7A02 0x7A0A 0x7A03 0x7A0C 0x7A04 \ + 0x7A99 0x7AE6 0x7AE4 0x7B4A 0x7B3B 0x7B44 0x7B48 0x7B4C \ + 0x7B4E 0x7B40 0x7B58 0x7B45 0x7CA2 0x7C9E 0x7CA8 0x7CA1 \ + 0x7D58 0x7D6F 0x7D63 0x7D53 0x7D56 0x7D67 0x7D6A 0x7D4F \ + 0x7D6D 0x7D5C 0x7D6B 0x7D52 0x7D54 0x7D69 0x7D51 0x7D5F \ + 0x7D4E 0x7F3E 0x7F3F 0x7F65 0x7F66 0x7FA2 0x7FA0 0x7FA1 \ + 0x7FD7 0x8051 0x804F 0x8050 0x80FE 0x80D4 0x8143 0x814A \ + 0x8152 0x814F 0x8147 0x813D 0x814D 0x813A 0x81E6 0x81EE \ + 0x81F7 0x81F8 0x81F9 0x8204 0x823C 0x823D 0x823F 0x8275 \ + 0x833B 0x83CF 0x83F9 0x8423 0x83C0 0x83E8 0x8412 0x83E7 \ + 0x83E4 0x83FC 0x83F6 0x8410 0x83C6 0x83C8 0x83EB 0x83E3 \ + 0x83BF 0x8401 0x83DD 0x83E5 0x83D8 0x83FF 0x83E1 0x83CB +68 0x83CE 0x83D6 0x83F5 0x83C9 0x8409 0x840F 0x83DE 0x8411 \ + 0x8406 0x83C2 0x83F3 0x855A 0x854B 0x853F 0x878A 0x878B \ + 0x87A1 0x878E 0x8799 0x885E 0x885F 0x8924 0x89A7 0x8AEA \ + 0x8AFD 0x8AF9 0x8AE3 0x8AE5 0x8AEC 0x8CF2 0x8CEF 0x8DA6 \ + 0x8E3B 0x8E43 0x8E32 0x8F31 0x8F30 0x8F2D 0x8F3C 0x8FA7 \ + 0x8FA5 0x9137 0x9195 0x918E 0x83D5 0x83FA 0x83C7 0x83D1 \ + 0x83EA 0x8413 0x83C3 0x83EC 0x83EE 0x83C4 0x83FB 0x83D7 \ + 0x83E2 0x841B 0x83DB 0x83FE 0x86D8 0x86E2 0x86E6 0x86D3 \ + 0x86E3 0x86DA 0x86EA 0x86DD 0x86EB 0x86DC 0x86EC 0x86E9 \ + 0x86D7 0x86E8 0x86D1 0x8848 0x8856 0x8855 0x88BA 0x88D7 \ + 0x88B9 0x88B8 0x88C0 0x88BE 0x88B6 0x88BC 0x88B7 0x88BD \ + 0x88B2 0x8901 0x88C9 0x8995 0x8998 0x8997 0x89DD 0x89DA \ + 0x89DB 0x8A4E 0x8A4D 0x8A39 0x8A59 0x8A40 0x8A57 0x8A58 \ + 0x8A44 0x8A45 0x8A52 0x8A48 0x8A51 0x8A4A 0x8A4C 0x8A4F \ + 0x8C5F 0x8C81 0x8C80 0x8CBA 0x8CBE 0x8CB0 0x8CB9 0x8CB5 \ + 0x8D84 0x8D80 0x8D89 0x8DD8 0x8DD3 0x8DCD 0x8DC7 0x8DD6 \ + 0x8DDC 0x8DCF 0x8DD5 0x8DD9 0x8DC8 0x8DD7 0x8DC5 0x8EEF \ + 0x8EF7 0x8EFA 0x8EF9 0x8EE6 0x8EEE 0x8EE5 0x8EF5 0x8EE7 \ + 0x8EE8 0x8EF6 0x8EEB 0x8EF1 0x8EEC 0x8EF4 0x8EE9 0x902D \ + 0x9034 0x902F 0x9106 0x912C 0x9104 0x90FF 0x90FC 0x9108 \ + 0x90F9 0x90FB 0x9101 0x9100 0x9107 0x9105 0x9103 0x9161 \ + 0x9164 0x915F 0x9162 0x9160 0x9201 0x920A 0x9225 0x9203 \ + 0x921A 0x9226 0x920F 0x920C 0x9200 0x9212 0x91FF 0x91FD \ + 0x9206 0x9204 0x9227 0x9202 0x921C 0x9224 0x9219 0x9217 \ + 0x9205 0x9216 0x957B 0x958D 0x958C 0x9590 0x9687 0x967E \ + 0x9688 0x9196 0x9345 0x930A 0x92FD 0x9317 0x931C 0x9307 \ + 0x9331 0x9332 0x932C 0x9330 0x9303 0x9305 0x95C2 0x95B8 \ + 0x95C1 0x96AB 0x96B7 0x9715 0x9714 0x970C 0x9717 0x9793 \ + 0x97D2 0x9836 0x9831 0x9833 0x983C 0x982E 0x983A 0x983D \ + 0x98B5 0x9922 0x9689 0x9683 0x9680 0x96C2 0x96C8 0x96C3 \ + 0x96F1 0x96F0 0x976C 0x9770 0x976E 0x9807 0x98A9 0x98EB \ + 0x9CE6 0x9EF9 0x4E83 0x4E84 0x4EB6 0x50BD 0x50BF 0x50C6 +69 0x50AE 0x50C4 0x50CA 0x50B4 0x50C8 0x50C2 0x50B0 0x50C1 \ + 0x50BA 0x50B1 0x50CB 0x50C9 0x50B6 0x50B8 0x51D7 0x527A \ + 0x5278 0x527B 0x527C 0x55C3 0x55DB 0x55CC 0x55D0 0x55CB \ + 0x55CA 0x55DD 0x55C0 0x55D4 0x55C4 0x55E9 0x55BF 0x55D2 \ + 0x558D 0x55CF 0x55D5 0x55E2 0x55D6 0x55C8 0x55F2 0x55CD \ + 0x55D9 0x55C2 0x5714 0x5853 0x5868 0x5864 0x584F 0x584D \ + 0x5849 0x586F 0x5855 0x584E 0x585D 0x5859 0x5865 0x585B \ + 0x583D 0x5863 0x5871 0x58FC 0x5AC7 0x5AC4 0x5ACB 0x5ABA \ + 0x5AB8 0x5AB1 0x5AB5 0x5AB0 0x5ABF 0x5AC8 0x5ABB 0x5AC6 \ + 0x5AB7 0x5AC0 0x5ACA 0x5AB4 0x5AB6 0x5ACD 0x5AB9 0x5A90 \ + 0x5BD6 0x5BD8 0x5BD9 0x5C1F 0x5C33 0x5D71 0x5D63 0x5D4A \ + 0x5D65 0x5D72 0x5D6C 0x5D5E 0x5D68 0x5D67 0x5D62 0x5DF0 \ + 0x5E4F 0x5E4E 0x5E4A 0x5E4D 0x5E4B 0x5EC5 0x5ECC 0x5EC6 \ + 0x5ECB 0x5EC7 0x5F40 0x5FAF 0x5FAD 0x60F7 0x6149 0x614A \ + 0x612B 0x6145 0x6136 0x6132 0x612E 0x6146 0x612F 0x614F \ + 0x6129 0x6140 0x6220 0x9168 0x6223 0x6225 0x6224 0x63C5 \ + 0x63F1 0x63EB 0x6410 0x6412 0x6409 0x6420 0x6424 0x9923 \ + 0x9920 0x991C 0x991D 0x99A0 0x99EF 0x99E8 0x99EB 0x99E1 \ + 0x99E6 0x9AF8 0x9AF5 0x9B83 0x9B94 0x9B84 0x9B8B 0x9B8F \ + 0x9B8C 0x9B89 0x9B8E 0x9D24 0x9D0F 0x9D13 0x9D0A 0x9D2A \ + 0x9D1A 0x9D27 0x9D16 0x9D21 0x9E85 0x9EAC 0x9EC6 0x9EC5 \ + 0x6433 0x6443 0x641F 0x6415 0x6418 0x6439 0x6437 0x6422 \ + 0x6423 0x640C 0x6426 0x6430 0x6428 0x6441 0x6435 0x642F \ + 0x640A 0x641A 0x6440 0x6425 0x6427 0x640B 0x63E7 0x641B \ + 0x642E 0x6421 0x640E 0x656F 0x6592 0x65D3 0x6686 0x668C \ + 0x6695 0x6690 0x668B 0x668A 0x6699 0x6694 0x6678 0x6720 \ + 0x6966 0x695F 0x6938 0x694E 0x6962 0x6971 0x693F 0x6945 \ + 0x696A 0x6939 0x6942 0x6957 0x6959 0x697A 0x6948 0x6949 \ + 0x6935 0x696C 0x6933 0x693D 0x6965 0x68F0 0x6978 0x6934 \ + 0x6969 0x6940 0x696F 0x6944 0x6976 0x6958 0x6941 0x6974 \ + 0x694C 0x693B 0x694B 0x6937 0x695C 0x694F 0x6951 0x6932 \ + 0x6952 0x692F 0x697B 0x693C 0x6B46 0x6B45 0x6B43 0x6B42 +70 0x6B48 0x6B41 0x6B9B 0x55C0 0x6BFB 0x6BFC 0x6BF9 0x6BF7 \ + 0x6BF8 0x6E9B 0x6ED6 0x6EC8 0x6E8F 0x6EC0 0x6E9F 0x6E93 \ + 0x6E94 0x6EA0 0x6EB1 0x6EB9 0x6EC6 0x6ED2 0x6EBD 0x6EC1 \ + 0x6E9E 0x6EC9 0x6EB7 0x6EB0 0x6ECD 0x6EA6 0x6ECF 0x6EB2 \ + 0x6EBE 0x6EC3 0x6EDC 0x6ED8 0x6E99 0x6E92 0x6E8E 0x6E8D \ + 0x6EA4 0x6EA1 0x6EBF 0x6EB3 0x6ED0 0x6ECA 0x6E97 0x6EAE \ + 0x6EA3 0x7147 0x7154 0x7152 0x7163 0x7160 0x7141 0x715D \ + 0x7162 0x7172 0x7178 0x716A 0x7161 0x7142 0x7158 0x7143 \ + 0x714B 0x7170 0x715F 0x7150 0x7153 0x9ED7 0x9F53 0x5128 \ + 0x5127 0x51DF 0x5335 0x53B3 0x568A 0x567D 0x5689 0x58CD \ + 0x58D0 0x5B2B 0x5B33 0x5B29 0x5B35 0x5B31 0x5B37 0x5C36 \ + 0x5DBE 0x5DB9 0x5DBB 0x61E2 0x61DB 0x61DD 0x61DC 0x61DA \ + 0x61D9 0x64DF 0x64E1 0x64EE 0x65B5 0x66D4 0x7144 0x714D \ + 0x715A 0x724F 0x728D 0x728C 0x7291 0x7290 0x728E 0x733C \ + 0x7342 0x733B 0x733A 0x7340 0x734A 0x7349 0x7444 0x744A \ + 0x744B 0x7452 0x7451 0x7457 0x7440 0x744F 0x7450 0x744E \ + 0x7442 0x7446 0x744D 0x7454 0x74E1 0x74FF 0x74FE 0x74FD \ + 0x751D 0x7579 0x7577 0x6983 0x75EF 0x760F 0x7603 0x75F7 \ + 0x75FE 0x75FC 0x75F9 0x75F8 0x7610 0x75FB 0x75F6 0x75ED \ + 0x75F5 0x75FD 0x7699 0x76B5 0x76DD 0x7755 0x775F 0x7760 \ + 0x7752 0x7756 0x775A 0x7769 0x7767 0x7754 0x7759 0x776D \ + 0x77E0 0x7887 0x789A 0x7894 0x788F 0x7884 0x7895 0x7885 \ + 0x7886 0x78A1 0x7883 0x7879 0x7899 0x7880 0x7896 0x787B \ + 0x797C 0x7982 0x797D 0x7979 0x7A11 0x7A18 0x7A19 0x7A12 \ + 0x7A17 0x7A15 0x7A22 0x7A13 0x7A1B 0x7A10 0x7AA3 0x7AA2 \ + 0x7A9E 0x7AEB 0x7B66 0x7B64 0x7B6D 0x7B74 0x7B69 0x7B72 \ + 0x7B65 0x7B73 0x7B71 0x7B70 0x7B61 0x7B78 0x7B76 0x7B63 \ + 0x7CB2 0x7CB4 0x7CAF 0x7D88 0x7D86 0x7D80 0x7D8D 0x7D7F \ + 0x7D85 0x7D7A 0x7D8E 0x7D7B 0x7D83 0x7D7C 0x7D8C 0x7D94 \ + 0x7D84 0x7D7D 0x7D92 0x7F6D 0x7F6B 0x7F67 0x7F68 0x7F6C \ + 0x7FA6 0x7FA5 0x7FA7 0x7FDB 0x7FDC 0x8021 0x8164 0x8160 \ + 0x8177 0x815C 0x8169 0x815B 0x8162 0x8172 0x6721 0x815E +71 0x8176 0x8167 0x816F 0x66D5 0x66D0 0x66D1 0x66CE 0x66D7 \ + 0x6A7D 0x6A8A 0x6AA7 0x6A99 0x6A82 0x6A88 0x6A86 0x6A98 \ + 0x6A9D 0x6A8F 0x6AAA 0x6B5D 0x6C0A 0x6FD7 0x6FD6 0x6FE5 \ + 0x6FD9 0x6FDA 0x6FEA 0x6FF6 0x71E3 0x71E9 0x71EB 0x71EF \ + 0x71F3 0x71EA 0x7371 0x74AE 0x8144 0x8161 0x821D 0x8249 \ + 0x8244 0x8240 0x8242 0x8245 0x84F1 0x843F 0x8456 0x8476 \ + 0x8479 0x848F 0x848D 0x8465 0x8451 0x8440 0x8486 0x8467 \ + 0x8430 0x844D 0x847D 0x845A 0x8459 0x8474 0x8473 0x845D \ + 0x8507 0x845E 0x8437 0x843A 0x8434 0x847A 0x8443 0x8478 \ + 0x8432 0x8445 0x8429 0x83D9 0x844B 0x842F 0x8442 0x842D \ + 0x845F 0x8470 0x8439 0x844E 0x844C 0x8452 0x846F 0x84C5 \ + 0x848E 0x843B 0x8447 0x8436 0x8433 0x8468 0x847E 0x8444 \ + 0x842B 0x8460 0x8454 0x846E 0x8450 0x870B 0x8704 0x86F7 \ + 0x870C 0x86FA 0x86D6 0x86F5 0x874D 0x86F8 0x870E 0x8709 \ + 0x8701 0x86F6 0x870D 0x8705 0x88D6 0x88CB 0x88CD 0x88CE \ + 0x88DE 0x88DB 0x88DA 0x88CC 0x88D0 0x8985 0x899B 0x89DF \ + 0x89E5 0x89E4 0x89E1 0x89E0 0x89E2 0x89DC 0x89E6 0x8A76 \ + 0x8A86 0x8A7F 0x8A61 0x8A3F 0x8A77 0x8A82 0x8A84 0x8A75 \ + 0x8A83 0x8A81 0x8A74 0x8A7A 0x8C3C 0x8C4B 0x8C4A 0x8C65 \ + 0x8C64 0x8C66 0x8C86 0x8C84 0x8C85 0x8CCC 0x8D68 0x8D69 \ + 0x8D91 0x8D8C 0x8D8E 0x8D8F 0x8D8D 0x8D93 0x8D94 0x8D90 \ + 0x8D92 0x8DF0 0x8DE0 0x8DEC 0x8DF1 0x8DEE 0x8DD0 0x8DE9 \ + 0x8DE3 0x8DE2 0x8DE7 0x8DF2 0x8DEB 0x8DF4 0x8F06 0x8EFF \ + 0x8F01 0x8F00 0x8F05 0x8F07 0x8F08 0x8F02 0x8F0B 0x9052 \ + 0x903F 0x74B3 0x74AC 0x7583 0x7645 0x764E 0x7644 0x76A3 \ + 0x76A5 0x77A6 0x77A4 0x77A9 0x77AF 0x78F0 0x78F8 0x78F1 \ + 0x7A49 0x7AC2 0x7AF2 0x7AF3 0x7BFA 0x7BF6 0x7BFC 0x7C18 \ + 0x7C08 0x7C12 0x7CDB 0x7CDA 0x7E2C 0x7E4D 0x7F46 0x7FF6 \ + 0x802B 0x8074 0x9044 0x9049 0x903D 0x9110 0x910D 0x910F \ + 0x9111 0x9116 0x9114 0x910B 0x910E 0x916E 0x916F 0x9248 \ + 0x9252 0x9230 0x923A 0x9266 0x9233 0x9265 0x925E 0x9283 \ + 0x922E 0x924A 0x9246 0x926D 0x926C 0x924F 0x9260 0x9267 +72 0x926F 0x9236 0x9261 0x9270 0x9231 0x9254 0x9263 0x9250 \ + 0x9272 0x924E 0x9253 0x924C 0x9256 0x9232 0x959F 0x959C \ + 0x959E 0x959B 0x9692 0x9693 0x9691 0x9697 0x96CE 0x96FA \ + 0x96FD 0x96F8 0x96F5 0x9773 0x9777 0x9778 0x9772 0x980F \ + 0x980D 0x980E 0x98AC 0x98F6 0x98F9 0x99AF 0x99B2 0x99B0 \ + 0x99B5 0x9AAD 0x9AAB 0x9B5B 0x9CEA 0x9CED 0x9CE7 0x9E80 \ + 0x9EFD 0x50E6 0x50D4 0x50D7 0x50E8 0x50F3 0x50DB 0x50EA \ + 0x50DD 0x50E4 0x50D3 0x50EC 0x50F0 0x50EF 0x50E3 0x50E0 \ + 0x51D8 0x5280 0x5281 0x52E9 0x52EB 0x5330 0x53AC 0x5627 \ + 0x5615 0x560C 0x5612 0x55FC 0x560F 0x561C 0x5601 0x5613 \ + 0x5602 0x55FA 0x561D 0x5604 0x55FF 0x55F9 0x5889 0x587C \ + 0x5890 0x5898 0x5886 0x5881 0x587F 0x5874 0x588B 0x587A \ + 0x5887 0x5891 0x588E 0x5876 0x5882 0x5888 0x587B 0x5894 \ + 0x588F 0x58FE 0x596B 0x5ADC 0x5AEE 0x5AE5 0x5AD5 0x5AEA \ + 0x5ADA 0x5AED 0x5AEB 0x5AF3 0x5AE2 0x5AE0 0x5ADB 0x5AEC \ + 0x5ADE 0x5ADD 0x5AD9 0x5AE8 0x5ADF 0x5B77 0x5BE0 0x81B8 \ + 0x81C8 0x8592 0x8593 0x857F 0x85AB 0x8597 0x85AC 0x87CE \ + 0x87CD 0x87C1 0x87B1 0x87C7 0x8940 0x893F 0x8939 0x8943 \ + 0x89AB 0x8B1F 0x8B09 0x8B0C 0x8C40 0x8C96 0x8CF6 0x8CF7 \ + 0x8E46 0x8E4F 0x8F3D 0x8F41 0x9366 0x9378 0x935D 0x9369 \ + 0x5BE3 0x5C63 0x5D82 0x5D80 0x5D7D 0x5D86 0x5D7A 0x5D81 \ + 0x5D77 0x5D8A 0x5D89 0x5D88 0x5D7E 0x5D7C 0x5D8D 0x5D79 \ + 0x5D7F 0x5E58 0x5E59 0x5E53 0x5ED8 0x5ED1 0x5ED7 0x5ECE \ + 0x5EDC 0x5ED5 0x5ED9 0x5ED2 0x5ED4 0x5F44 0x5F43 0x5F6F \ + 0x5FB6 0x612C 0x6128 0x6141 0x615E 0x6171 0x6173 0x6152 \ + 0x6153 0x6172 0x616C 0x6180 0x6174 0x6154 0x617A 0x615B \ + 0x6165 0x613B 0x616A 0x6161 0x6156 0x6229 0x6227 0x622B \ + 0x642B 0x644D 0x645B 0x645D 0x6474 0x6476 0x6472 0x6473 \ + 0x647D 0x6475 0x6466 0x64A6 0x644E 0x6482 0x645E 0x645C \ + 0x644B 0x6453 0x6460 0x6450 0x647F 0x643F 0x646C 0x646B \ + 0x6459 0x6465 0x6477 0x6573 0x65A0 0x66A1 0x66A0 0x669F \ + 0x6705 0x6704 0x6722 0x69B1 0x69B6 0x69C9 0x69A0 0x69CE +73 0x6996 0x69B0 0x69AC 0x69BC 0x6991 0x6999 0x698E 0x69A7 \ + 0x698D 0x69A9 0x69BE 0x69AF 0x69BF 0x69C4 0x69BD 0x69A4 \ + 0x69D4 0x69B9 0x69CA 0x699A 0x69CF 0x69B3 0x6993 0x69AA \ + 0x69A1 0x699E 0x69D9 0x6997 0x6990 0x69C2 0x69B5 0x69A5 \ + 0x69C6 0x6B4A 0x6B4D 0x6B4B 0x6B9E 0x6B9F 0x6BA0 0x6BC3 \ + 0x6BC4 0x6BFE 0x6ECE 0x6EF5 0x6EF1 0x6F03 0x6F25 0x6EF8 \ + 0x6F37 0x6EFB 0x6F2E 0x6F09 0x6F4E 0x6F19 0x6F1A 0x6F27 \ + 0x6F18 0x6F3B 0x6F12 0x6EED 0x6F0A 0x9374 0x937D 0x936E \ + 0x9372 0x9373 0x9362 0x9348 0x9353 0x935F 0x9368 0x937F \ + 0x936B 0x95C4 0x96AF 0x96AD 0x96B2 0x971A 0x971B 0x979B \ + 0x979F 0x9840 0x9847 0x98B7 0x99A2 0x9A00 0x99F3 0x99F5 \ + 0x9ABD 0x9B00 0x9B02 0x9B34 0x9B49 0x9B9F 0x6F36 0x6F73 \ + 0x6EF9 0x6EEE 0x6F2D 0x6F40 0x6F30 0x6F3C 0x6F35 0x6EEB \ + 0x6F07 0x6F0E 0x6F43 0x6F05 0x6EFD 0x6EF6 0x6F39 0x6F1C \ + 0x6EFC 0x6F3A 0x6F1F 0x6F0D 0x6F1E 0x6F08 0x6F21 0x7187 \ + 0x7190 0x7189 0x7180 0x7185 0x7182 0x718F 0x717B 0x7186 \ + 0x7181 0x7197 0x7244 0x7253 0x7297 0x7295 0x7293 0x7343 \ + 0x734D 0x7351 0x734C 0x7462 0x7473 0x7471 0x7475 0x7472 \ + 0x7467 0x746E 0x7500 0x7502 0x7503 0x757D 0x7590 0x7616 \ + 0x7608 0x760C 0x7615 0x7611 0x760A 0x7614 0x76B8 0x7781 \ + 0x777C 0x7785 0x7782 0x776E 0x7780 0x776F 0x777E 0x7783 \ + 0x78B2 0x78AA 0x78B4 0x78AD 0x78A8 0x787E 0x78AB 0x789E \ + 0x78A5 0x78A0 0x78AC 0x78A2 0x78A4 0x7998 0x798A 0x798B \ + 0x7996 0x7995 0x7994 0x7993 0x7997 0x7988 0x7992 0x7990 \ + 0x7A2B 0x7A4A 0x7A30 0x7A2F 0x7A28 0x7A26 0x7AA8 0x7AAB \ + 0x7AAC 0x7AEE 0x7B88 0x7B9C 0x7B8A 0x7B91 0x7B90 0x7B96 \ + 0x7B8D 0x7B8C 0x7B9B 0x7B8E 0x7B85 0x7B98 0x5284 0x7B99 \ + 0x7BA4 0x7B82 0x7CBB 0x7CBF 0x7CBC 0x7CBA 0x7DA7 0x7DB7 \ + 0x7DC2 0x7DA3 0x7DAA 0x7DC1 0x7DC0 0x7DC5 0x7D9D 0x7DCE \ + 0x7DC4 0x7DC6 0x7DCB 0x7DCC 0x7DAF 0x7DB9 0x7D96 0x7DBC \ + 0x7D9F 0x7DA6 0x7DAE 0x7DA9 0x7DA1 0x7DC9 0x7F73 0x7FE2 \ + 0x7FE3 0x7FE5 0x7FDE 0x9BA3 0x9BCD 0x9B99 0x9B9D 0x9D39 +74 0x9D44 0x9D35 0x9EAF 0x512F 0x9F8E 0x569F 0x569B 0x569E \ + 0x5696 0x5694 0x56A0 0x5B3B 0x5B3A 0x5DC1 0x5F4D 0x5F5D \ + 0x61F3 0x64F6 0x64E5 0x64EA 0x64E7 0x6505 0x64F9 0x6AAB \ + 0x6AED 0x6AB2 0x6AB0 0x6AB5 0x8024 0x805D 0x805C 0x8189 \ + 0x8186 0x8183 0x8187 0x818D 0x818C 0x818B 0x8215 0x8497 \ + 0x84A4 0x84A1 0x849F 0x84BA 0x84CE 0x84C2 0x84AC 0x84AE \ + 0x84AB 0x84B9 0x84B4 0x84C1 0x84CD 0x84AA 0x849A 0x84B1 \ + 0x84D0 0x849D 0x84A7 0x84BB 0x84A2 0x8494 0x84C7 0x84CC \ + 0x849B 0x84A9 0x84AF 0x84A8 0x84D6 0x8498 0x84B6 0x84CF \ + 0x84A0 0x84D7 0x84D4 0x84D2 0x84DB 0x84B0 0x8491 0x8661 \ + 0x8733 0x8723 0x8728 0x876B 0x8740 0x872E 0x871E 0x8721 \ + 0x8719 0x871B 0x8743 0x872C 0x8741 0x873E 0x8746 0x8720 \ + 0x8732 0x872A 0x872D 0x873C 0x8712 0x873A 0x8731 0x8735 \ + 0x8742 0x8726 0x8727 0x8738 0x8724 0x871A 0x8730 0x8711 \ + 0x88F7 0x88E7 0x88F1 0x88F2 0x88FA 0x88FE 0x88EE 0x88FC \ + 0x88F6 0x88FB 0x88F0 0x88EC 0x88EB 0x899D 0x89A1 0x899F \ + 0x899E 0x89E9 0x89EB 0x89E8 0x8AAB 0x8A99 0x8A8B 0x8A92 \ + 0x8A8F 0x8A96 0x8C3D 0x8C68 0x8C69 0x8CD5 0x8CCF 0x8CD7 \ + 0x8D96 0x8E09 0x8E02 0x8DFF 0x8E0D 0x8DFD 0x8E0A 0x8E03 \ + 0x8E07 0x8E06 0x8E05 0x8DFE 0x8E00 0x8E04 0x8F10 0x8F11 \ + 0x8F0E 0x8F0D 0x9123 0x911C 0x9120 0x9122 0x911F 0x911D \ + 0x911A 0x9124 0x9121 0x911B 0x917A 0x9172 0x9179 0x9173 \ + 0x92A5 0x92A4 0x9276 0x929B 0x927A 0x92A0 0x9294 0x92AA \ + 0x928D 0x6ABE 0x6AC1 0x6AC8 0x6AC0 0x6ABC 0x6AB1 0x6AC4 \ + 0x6ABF 0x7008 0x7003 0x6FFD 0x7010 0x7002 0x7013 0x71FA \ + 0x7200 0x74B9 0x74BC 0x765B 0x7651 0x764F 0x76EB 0x77B8 \ + 0x77B9 0x77C1 0x77C0 0x77BE 0x790B 0x7907 0x790A 0x7908 \ + 0x790D 0x7906 0x92A6 0x929A 0x92AB 0x9279 0x9297 0x927F \ + 0x92A3 0x92EE 0x928E 0x9282 0x9295 0x92A2 0x927D 0x9288 \ + 0x92A1 0x928A 0x9286 0x928C 0x9299 0x92A7 0x927E 0x9287 \ + 0x92A9 0x929D 0x928B 0x922D 0x969E 0x96A1 0x96FF 0x9758 \ + 0x977D 0x977A 0x977E 0x9783 0x9780 0x9782 0x977B 0x9784 +75 0x9781 0x977F 0x97CE 0x97CD 0x9816 0x98AD 0x98AE 0x9902 \ + 0x9900 0x9907 0x999D 0x999C 0x99C3 0x99B9 0x99BB 0x99BA \ + 0x99C2 0x99BD 0x99C7 0x9AB1 0x9AE3 0x9AE7 0x9B3E 0x9B3F \ + 0x9B60 0x9B61 0x9B5F 0x9CF1 0x9CF2 0x9CF5 0x9EA7 0x50FF \ + 0x5103 0x5130 0x50F8 0x5106 0x5107 0x50F6 0x50FE 0x510B \ + 0x510C 0x50FD 0x510A 0x528B 0x528C 0x52F1 0x52EF 0x5648 \ + 0x5642 0x564C 0x5635 0x5641 0x564A 0x5649 0x5646 0x5658 \ + 0x565A 0x5640 0x5633 0x563D 0x562C 0x563E 0x5638 0x562A \ + 0x563A 0x571A 0x58AB 0x589D 0x58B1 0x58A0 0x58A3 0x58AF \ + 0x58AC 0x58A5 0x58A1 0x58FF 0x5AFF 0x5AF4 0x5AFD 0x5AF7 \ + 0x5AF6 0x5B03 0x5AF8 0x5B02 0x5AF9 0x5B01 0x5B07 0x5B05 \ + 0x5B0F 0x5C67 0x5D99 0x5D97 0x5D9F 0x5D92 0x5DA2 0x5D93 \ + 0x5D95 0x5DA0 0x5D9C 0x5DA1 0x5D9A 0x5D9E 0x5E69 0x5E5D \ + 0x5E60 0x5E5C 0x7DF3 0x5EDB 0x5EDE 0x5EE1 0x5F49 0x5FB2 \ + 0x618B 0x6183 0x6179 0x61B1 0x61B0 0x61A2 0x6189 0x7915 \ + 0x79AF 0x7AF5 0x7C2E 0x7C1B 0x7C1A 0x7C24 0x7CE6 0x7CE3 \ + 0x7E5D 0x7E4F 0x7E66 0x7E5B 0x7F47 0x7FB4 0x7FFA 0x802E \ + 0x81CE 0x8219 0x85CC 0x85B2 0x85BB 0x85C1 0x87E9 0x87EE \ + 0x87F0 0x87D6 0x880E 0x87DA 0x8948 0x894A 0x894E 0x894D \ + 0x619B 0x6193 0x61AF 0x61AD 0x619F 0x6192 0x61AA 0x61A1 \ + 0x618D 0x6166 0x61B3 0x622D 0x646E 0x6470 0x6496 0x64A0 \ + 0x6485 0x6497 0x649C 0x648F 0x648B 0x648A 0x648C 0x64A3 \ + 0x649F 0x6468 0x64B1 0x6498 0x6576 0x657A 0x6579 0x657B \ + 0x65B2 0x65B3 0x66B5 0x66B0 0x66A9 0x66B2 0x66B7 0x66AA \ + 0x66AF 0x6A00 0x6A06 0x6A17 0x69E5 0x69F8 0x6A15 0x69F1 \ + 0x69E4 0x6A20 0x69FF 0x69EC 0x69E2 0x6A1B 0x6A1D 0x69FE \ + 0x6A27 0x69F2 0x69EE 0x6A14 0x69F7 0x69E7 0x6A40 0x6A08 \ + 0x69E6 0x69FB 0x6A0D 0x69FC 0x69EB 0x6A09 0x6A04 0x6A18 \ + 0x6A25 0x6A0F 0x69F6 0x6A26 0x6A07 0x69F4 0x6A16 0x6B51 \ + 0x6BA5 0x6BA3 0x6BA2 0x6BA6 0x6C01 0x6C00 0x6BFF 0x6C02 \ + 0x6F41 0x6F26 0x6F7E 0x6F87 0x6FC6 0x6F92 0x6F8D 0x6F89 \ + 0x6F8C 0x6F62 0x6F4F 0x6F85 0x6F5A 0x6F96 0x6F76 0x6F6C +76 0x6F82 0x6F55 0x6F72 0x6F52 0x6F50 0x6F57 0x6F94 0x6F93 \ + 0x6F5D 0x6F00 0x6F61 0x6F6B 0x6F7D 0x6F67 0x6F90 0x6F53 \ + 0x6F8B 0x6F69 0x6F7F 0x6F95 0x6F63 0x6F77 0x6F6A 0x6F7B \ + 0x71B2 0x71AF 0x719B 0x71B0 0x71A0 0x719A 0x71A9 0x71B5 \ + 0x719D 0x71A5 0x719E 0x71A4 0x71A1 0x71AA 0x719C 0x71A7 \ + 0x71B3 0x7298 0x729A 0x7358 0x7352 0x735E 0x735F 0x7360 \ + 0x735D 0x735B 0x7361 0x735A 0x7359 0x89B1 0x89B0 0x89B3 \ + 0x8B38 0x8B32 0x8B2D 0x8B34 0x8B29 0x8C74 0x8D03 0x8DA9 \ + 0x8E58 0x8EBF 0x8EC1 0x8F4A 0x8FAC 0x9089 0x913D 0x913C \ + 0x91A9 0x93A0 0x9390 0x9393 0x938B 0x93AD 0x93BB 0x93B8 \ + 0x939C 0x95D8 0x95D7 0x975D 0x97A9 0x97DA 0x7362 0x7487 \ + 0x7489 0x748A 0x7486 0x7481 0x747D 0x7485 0x7488 0x747C \ + 0x7479 0x7508 0x7507 0x757E 0x7625 0x761E 0x7619 0x761D \ + 0x761C 0x7623 0x761A 0x7628 0x761B 0x769C 0x769D 0x769E \ + 0x769B 0x778D 0x778F 0x7789 0x7788 0x78CD 0x78BB 0x78CF \ + 0x78CC 0x78D1 0x78CE 0x78D4 0x78C8 0x78C3 0x78C4 0x78C9 \ + 0x799A 0x79A1 0x79A0 0x799C 0x79A2 0x799B 0x6B76 0x7A39 \ + 0x7AB2 0x7AB4 0x7AB3 0x7BB7 0x7BCB 0x7BBE 0x7BAC 0x7BCE \ + 0x7BAF 0x7BB9 0x7BCA 0x7BB5 0x7CC5 0x7CC8 0x7CCC 0x7CCB \ + 0x7DF7 0x7DDB 0x7DEA 0x7DE7 0x7DD7 0x7DE1 0x7E03 0x7DFA \ + 0x7DE6 0x7DF6 0x7DF1 0x7DF0 0x7DEE 0x7DDF 0x7F76 0x7FAC \ + 0x7FB0 0x7FAD 0x7FED 0x7FEB 0x7FEA 0x7FEC 0x7FE6 0x7FE8 \ + 0x8064 0x8067 0x81A3 0x819F 0x819E 0x8195 0x81A2 0x8199 \ + 0x8197 0x8216 0x824F 0x8253 0x8252 0x8250 0x824E 0x8251 \ + 0x8524 0x853B 0x850F 0x8500 0x8529 0x850E 0x8509 0x850D \ + 0x851F 0x850A 0x8527 0x851C 0x84FB 0x852B 0x84FA 0x8508 \ + 0x850C 0x84F4 0x852A 0x84F2 0x8515 0x84F7 0x84EB 0x84F3 \ + 0x84FC 0x8512 0x84EA 0x84E9 0x8516 0x84FE 0x8528 0x851D \ + 0x852E 0x8502 0x84FD 0x851E 0x84F6 0x8531 0x8526 0x84E7 \ + 0x84E8 0x84F0 0x84EF 0x84F9 0x8518 0x8520 0x8530 0x850B \ + 0x8519 0x852F 0x8662 0x9854 0x9855 0x984B 0x983F 0x98B9 \ + 0x9938 0x9936 0x9940 0x993B 0x9939 0x99A4 0x9A08 0x9A0C +77 0x9A10 0x9B07 0x9BD2 0x9BC2 0x9BBB 0x9BCC 0x9BCB 0x9D4D \ + 0x9D63 0x9D4E 0x9D50 0x9D55 0x9D5E 0x9E90 0x9EB2 0x9EB1 \ + 0x9ECA 0x9F02 0x9F27 0x9F26 0x8756 0x8763 0x8764 0x8777 \ + 0x87E1 0x8773 0x8758 0x8754 0x875B 0x8752 0x8761 0x875A \ + 0x8751 0x875E 0x876D 0x876A 0x8750 0x874E 0x875F 0x875D \ + 0x876F 0x876C 0x877A 0x876E 0x875C 0x8765 0x874F 0x877B \ + 0x8775 0x8762 0x8767 0x8769 0x885A 0x8905 0x890C 0x8914 \ + 0x890B 0x8917 0x8918 0x8919 0x8906 0x8916 0x8911 0x890E \ + 0x8909 0x89A2 0x89A4 0x89A3 0x89ED 0x89F0 0x89EC 0x8ACF \ + 0x8AC6 0x8AB8 0x8AD3 0x8AD1 0x8AD4 0x8AD5 0x8ABB 0x8AD7 \ + 0x8ABE 0x8AC0 0x8AC5 0x8AD8 0x8AC3 0x8ABA 0x8ABD 0x8AD9 \ + 0x8C3E 0x8C4D 0x8C8F 0x8CE5 0x8CDF 0x8CD9 0x8CE8 0x8CDA \ + 0x8CDD 0x8CE7 0x8DA0 0x8D9C 0x8DA1 0x8D9B 0x8E20 0x8E23 \ + 0x8E25 0x8E24 0x8E2E 0x8E15 0x8E1B 0x8E16 0x8E11 0x8E19 \ + 0x8E26 0x8E27 0x8E14 0x8E12 0x8E18 0x8E13 0x8E1C 0x8E17 \ + 0x8E1A 0x8F2C 0x8F24 0x8F18 0x8F1A 0x8F20 0x8F23 0x8F16 \ + 0x8F17 0x9073 0x9070 0x906F 0x9067 0x906B 0x912F 0x912B \ + 0x9129 0x912A 0x9132 0x9126 0x912E 0x9185 0x9186 0x918A \ + 0x9181 0x9182 0x9184 0x9180 0x92D0 0x92C3 0x92C4 0x92C0 \ + 0x92D9 0x92B6 0x92CF 0x92F1 0x92DF 0x92D8 0x92E9 0x92D7 \ + 0x92DD 0x92CC 0x92EF 0x92C2 0x92E8 0x92CA 0x92C8 0x92CE \ + 0x92E6 0x92CD 0x92D5 0x92C9 0x92E0 0x92DE 0x92E7 0x92D1 \ + 0x92D3 0x56AF 0x58E0 0x58DC 0x5B39 0x5B7C 0x5BF3 0x5C6B \ + 0x5DC4 0x650B 0x6508 0x650A 0x65DC 0x66E1 0x66DF 0x6ACE \ + 0x6AD4 0x6AE3 0x6AD7 0x6AE2 0x6AD8 0x6AD5 0x6AD2 0x701E \ + 0x702C 0x7025 0x6FF3 0x7204 0x7208 0x7215 0x74C4 0x74C9 \ + 0x74C7 0x74C8 0x92B5 0x92E1 0x92C6 0x92B4 0x957C 0x95AC \ + 0x95AB 0x95AE 0x95B0 0x96A4 0x96A2 0x96D3 0x9705 0x9708 \ + 0x9702 0x975A 0x978A 0x978E 0x9788 0x97D0 0x97CF 0x981E \ + 0x981D 0x9826 0x9829 0x9828 0x9820 0x981B 0x9827 0x98B2 \ + 0x9908 0x98FA 0x9911 0x9914 0x9916 0x9917 0x9915 0x99DC \ + 0x99CD 0x99CF 0x99D3 0x99D4 0x99CE 0x99C9 0x99D6 0x99D8 +78 0x99CB 0x99D7 0x99CC 0x9AB3 0x9AEC 0x9AEB 0x9AF3 0x9AF2 \ + 0x9AF1 0x9B46 0x9B43 0x9B67 0x9B74 0x9B71 0x9B66 0x9B76 \ + 0x9B75 0x9B70 0x9B68 0x9B64 0x9B6C 0x9CFC 0x9CFA 0x9CFD \ + 0x9CFF 0x9CF7 0x9D07 0x9D00 0x9CF9 0x9CFB 0x9D08 0x9D05 \ + 0x9D04 0x9E83 0x9ED3 0x9F0F 0x9F10 0x511C 0x5113 0x5117 \ + 0x511A 0x5111 0x51DE 0x5334 0x53E1 0x5670 0x5660 0x566E \ + 0x5673 0x5666 0x5663 0x566D 0x5672 0x565E 0x5677 0x571C \ + 0x571B 0x58C8 0x58BD 0x58C9 0x58BF 0x58BA 0x58C2 0x58BC \ + 0x58C6 0x5B17 0x5B19 0x5B1B 0x5B21 0x5B14 0x5B13 0x5B10 \ + 0x5B16 0x5B28 0x5B1A 0x5B20 0x5B1E 0x5BEF 0x5DAC 0x5DB1 \ + 0x5DA9 0x5DA7 0x5DB5 0x5DB0 0x5DAE 0x5DAA 0x5DA8 0x5DB2 \ + 0x5DAD 0x5DAF 0x5DB4 0x5E67 0x5E68 0x5E66 0x5E6F 0x5EE9 \ + 0x5EE7 0x5EE6 0x5EE8 0x5EE5 0x5F4B 0x5FBC 0x619D 0x61A8 \ + 0x6196 0x61C5 0x61B4 0x61C6 0x61C1 0x61CC 0x61BA 0x76A9 \ + 0x77C6 0x77C5 0x7918 0x791A 0x7920 0x7A66 0x7A64 0x7A6A \ + 0x7C35 0x7C34 0x7E6C 0x7E6E 0x7E71 0x81D4 0x81D6 0x821A \ + 0x8262 0x8265 0x8276 0x85DB 0x85D6 0x85E7 0x85F4 0x87FD \ + 0x87D5 0x8807 0x880F 0x87F8 0x8987 0x89B5 0x89F5 0x8B3F \ + 0x61BF 0x61B8 0x618C 0x64D7 0x64D6 0x64D0 0x64CF 0x64C9 \ + 0x64BD 0x6489 0x64C3 0x64DB 0x64F3 0x64D9 0x6533 0x657F \ + 0x657C 0x65A2 0x66C8 0x66BE 0x66C0 0x66CA 0x66CB 0x66CF \ + 0x66BD 0x66BB 0x66BA 0x66CC 0x6723 0x6A34 0x6A66 0x6A49 \ + 0x6A67 0x6A32 0x6A68 0x6A3E 0x6A5D 0x6A6D 0x6A76 0x6A5B \ + 0x6A51 0x6A28 0x6A5A 0x6A3B 0x6A3F 0x6A41 0x6A6A 0x6A64 \ + 0x6A50 0x6A4F 0x6A54 0x6A6F 0x6A69 0x6A60 0x6A3C 0x6A5E \ + 0x6A56 0x6A55 0x6A4D 0x6A4E 0x6A46 0x6B55 0x6B54 0x6B56 \ + 0x6BA7 0x6BAA 0x6BAB 0x6BC8 0x6BC7 0x6C04 0x6C03 0x6C06 \ + 0x6FAD 0x6FCB 0x6FA3 0x6FC7 0x6FBC 0x6FCE 0x6FC8 0x6F5E \ + 0x6FC4 0x6FBD 0x6F9E 0x6FCA 0x6FA8 0x7004 0x6FA5 0x6FAE \ + 0x6FBA 0x6FAC 0x6FAA 0x6FCF 0x6FBF 0x6FB8 0x6FA2 0x6FC9 \ + 0x6FAB 0x6FCD 0x6FAF 0x6FB2 0x6FB0 0x71C5 0x71C2 0x71BF \ + 0x71B8 0x71D6 0x71C0 0x71C1 0x71CB 0x71D4 0x71CA 0x71C7 +79 0x71CF 0x71BD 0x71D8 0x71BC 0x71C6 0x71DA 0x71DB 0x729D \ + 0x729E 0x7369 0x7366 0x7367 0x736C 0x7365 0x736B 0x736A \ + 0x747F 0x749A 0x74A0 0x7494 0x7492 0x7495 0x74A1 0x750B \ + 0x7580 0x762F 0x762D 0x7631 0x763D 0x7633 0x763C 0x7635 \ + 0x7632 0x7630 0x76BB 0x76E6 0x779A 0x779D 0x77A1 0x779C \ + 0x779B 0x77A2 0x77A3 0x7795 0x7799 0x8B43 0x8B4C 0x8D0B \ + 0x8E6B 0x8E68 0x8E70 0x8E75 0x8E77 0x8EC3 0x93E9 0x93EA \ + 0x93CB 0x93C5 0x93C6 0x93ED 0x93D3 0x93E5 0x93DB 0x93EB \ + 0x93E0 0x93C1 0x95DD 0x97B2 0x97B4 0x97B1 0x97B5 0x97F2 \ + 0x9856 0x9944 0x9A26 0x9A1F 0x9A18 0x9A21 0x7797 0x78DD \ + 0x78E9 0x78E5 0x78EA 0x78DE 0x78E3 0x78DB 0x78E1 0x78E2 \ + 0x78ED 0x78DF 0x78E0 0x79A4 0x7A44 0x7A48 0x7A47 0x7AB6 \ + 0x7AB8 0x7AB5 0x7AB1 0x7AB7 0x7BDE 0x7BE3 0x7BE7 0x7BDD \ + 0x7BD5 0x7BE5 0x7BDA 0x7BE8 0x7BF9 0x7BD4 0x7BEA 0x7BE2 \ + 0x7BDC 0x7BEB 0x7BD8 0x7BDF 0x7CD2 0x7CD4 0x7CD7 0x7CD0 \ + 0x7CD1 0x7E12 0x7E21 0x7E17 0x7E0C 0x7E1F 0x7E20 0x7E13 \ + 0x7E0E 0x7E1C 0x7E15 0x7E1A 0x7E22 0x7E0B 0x7E0F 0x7E16 \ + 0x7E0D 0x7E14 0x7E25 0x7E24 0x7F43 0x7F7B 0x7F7C 0x7F7A \ + 0x7FB1 0x7FEF 0x802A 0x8029 0x806C 0x81B1 0x81A6 0x81AE \ + 0x81B9 0x81B5 0x81AB 0x81B0 0x81AC 0x81B4 0x81B2 0x81B7 \ + 0x81A7 0x81F2 0x8255 0x8256 0x8257 0x8556 0x8545 0x856B \ + 0x854D 0x8553 0x8561 0x8558 0x8540 0x8546 0x8564 0x8541 \ + 0x8562 0x8544 0x8551 0x8547 0x8563 0x853E 0x855B 0x8571 \ + 0x854E 0x856E 0x8575 0x8555 0x8567 0x8560 0x858C 0x8566 \ + 0x855D 0x8554 0x8565 0x856C 0x8663 0x8665 0x8664 0x879B \ + 0x878F 0x8797 0x8793 0x8792 0x8788 0x8781 0x8796 0x8798 \ + 0x8779 0x8787 0x87A3 0x8785 0x8790 0x8791 0x879D 0x8784 \ + 0x8794 0x879C 0x879A 0x8789 0x891E 0x8926 0x8930 0x892D \ + 0x892E 0x8927 0x8931 0x8922 0x8929 0x8923 0x892F 0x892C \ + 0x891F 0x89F1 0x8AE0 0x9A17 0x9B09 0x9BC5 0x9BDF 0x9BE3 \ + 0x9BE9 0x9BEE 0x9D66 0x9D7A 0x9D6E 0x9D91 0x9D83 0x9D76 \ + 0x9D7E 0x9D6D 0x9E95 0x9EE3 0x9F03 0x9F04 0x9F17 0x5136 +80 0x5336 0x5B42 0x5B44 0x5B46 0x5B7E 0x5DCA 0x5DC8 0x5DCC \ + 0x5EF0 0x6585 0x66E5 0x66E7 0x8AE2 0x8AF2 0x8AF4 0x8AF5 \ + 0x8ADD 0x8B14 0x8AE4 0x8ADF 0x8AF0 0x8AC8 0x8ADE 0x8AE1 \ + 0x8AE8 0x8AFF 0x8AEF 0x8AFB 0x8C91 0x8C92 0x8C90 0x8CF5 \ + 0x8CEE 0x8CF1 0x8CF0 0x8CF3 0x8D6C 0x8D6E 0x8DA5 0x8DA7 \ + 0x8E33 0x8E3E 0x8E38 0x8E40 0x8E45 0x8E36 0x8E3C 0x8E3D \ + 0x8E41 0x8E30 0x8E3F 0x8EBD 0x8F36 0x8F2E 0x8F35 0x8F32 \ + 0x8F39 0x8F37 0x8F34 0x9076 0x9079 0x907B 0x9086 0x90FA \ + 0x9133 0x9135 0x9136 0x9193 0x9190 0x9191 0x918D 0x918F \ + 0x9327 0x931E 0x9308 0x931F 0x9306 0x930F 0x937A 0x9338 \ + 0x933C 0x931B 0x9323 0x9312 0x9301 0x9346 0x932D 0x930E \ + 0x930D 0x92CB 0x931D 0x92FA 0x9325 0x9313 0x92F9 0x92F7 \ + 0x9334 0x9302 0x9324 0x92FF 0x9329 0x9339 0x9335 0x932A \ + 0x9314 0x930C 0x930B 0x92FE 0x9309 0x9300 0x92FB 0x9316 \ + 0x95BC 0x95CD 0x95BE 0x95B9 0x95BA 0x95B6 0x95BF 0x95B5 \ + 0x95BD 0x96A9 0x96D4 0x970B 0x9712 0x9710 0x9799 0x9797 \ + 0x9794 0x97F0 0x97F8 0x9835 0x982F 0x9832 0x9924 0x991F \ + 0x9927 0x9929 0x999E 0x99EE 0x99EC 0x99E5 0x99E4 0x99F0 \ + 0x99E3 0x99EA 0x99E9 0x99E7 0x9AB9 0x9ABF 0x9AB4 0x9ABB \ + 0x9AF6 0x9AFA 0x9AF9 0x9AF7 0x9B33 0x9B80 0x9B85 0x9B87 \ + 0x9B7C 0x9B7E 0x9B7B 0x9B82 0x9B93 0x9B92 0x9B90 0x9B7A \ + 0x9B95 0x6AF4 0x6AE9 0x703D 0x7036 0x7216 0x7212 0x720F \ + 0x7217 0x7211 0x720B 0x74CD 0x74D0 0x74CC 0x74CE 0x74D1 \ + 0x7589 0x7A6F 0x7C4B 0x7C44 0x7C55 0x7E7F 0x8B71 0x802F \ + 0x807A 0x807B 0x807C 0x85FC 0x8610 0x8602 0x85EE 0x8603 \ + 0x860D 0x8613 0x9B7D 0x9B88 0x9D25 0x9D17 0x9D20 0x9D1E \ + 0x9D14 0x9D29 0x9D1D 0x9D18 0x9D22 0x9D10 0x9D19 0x9D1F \ + 0x9E88 0x9E86 0x9E87 0x9EAE 0x9EAD 0x9ED5 0x9ED6 0x9EFA \ + 0x9F12 0x9F3D 0x5126 0x5125 0x5122 0x5124 0x5120 0x5129 \ + 0x52F4 0x5693 0x568C 0x568D 0x5686 0x5684 0x5683 0x567E \ + 0x5682 0x567F 0x5681 0x58D6 0x58D4 0x58CF 0x58D2 0x5B2D \ + 0x5B25 0x5B32 0x5B23 0x5B2C 0x5B27 0x5B26 0x5B2F 0x5B2E +81 0x5B7B 0x5BF1 0x5BF2 0x5DB7 0x5E6C 0x5E6A 0x5FBE 0x5FBB \ + 0x61C3 0x61B5 0x61BC 0x61E7 0x61E0 0x61E5 0x61E4 0x61E8 \ + 0x61DE 0x64EF 0x64E9 0x64E3 0x64EB 0x64E4 0x64E8 0x6581 \ + 0x6580 0x65B6 0x65DA 0x66D2 0x6A8D 0x6A96 0x6A81 0x6AA5 \ + 0x6A89 0x6A9F 0x6A9B 0x6AA1 0x6A9E 0x6A87 0x6A93 0x6A8E \ + 0x6A95 0x6A83 0x6AA8 0x6AA4 0x6A91 0x6A7F 0x6AA6 0x6A9A \ + 0x6A85 0x6A8C 0x6A92 0x6B5B 0x6BAD 0x6C09 0x6FCC 0x6FA9 \ + 0x6FF4 0x6FD4 0x6FE3 0x6FDC 0x6FED 0x6FE7 0x6FE6 0x6FDE \ + 0x6FF2 0x6FDD 0x6FE2 0x6FE8 0x71E1 0x71F1 0x71E8 0x71F2 \ + 0x71E4 0x71F0 0x71E2 0x7373 0x736E 0x736F 0x7497 0x74B2 \ + 0x74AB 0x7490 0x74AA 0x74AD 0x74B1 0x74A5 0x74AF 0x7510 \ + 0x7511 0x7512 0x750F 0x7584 0x7643 0x7648 0x7649 0x7647 \ + 0x76A4 0x76E9 0x77B5 0x77AB 0x77B2 0x77B7 0x77B6 0x8608 \ + 0x860F 0x8818 0x8812 0x8967 0x8965 0x89BB 0x8B69 0x8B62 \ + 0x8B6E 0x8B61 0x8B64 0x8B4D 0x8C51 0x8E83 0x8EC6 0x941F \ + 0x9404 0x9417 0x9408 0x9405 0x93F3 0x941E 0x9402 0x941A \ + 0x941B 0x9427 0x941C 0x96B5 0x9733 0x9734 0x9731 0x97B8 \ + 0x77B4 0x77B1 0x77A8 0x77F0 0x78F3 0x78FD 0x7902 0x78FB \ + 0x78FC 0x78F2 0x7905 0x78F9 0x78FE 0x7904 0x79AB 0x79A8 \ + 0x7A5C 0x7A5B 0x7A56 0x7A58 0x7A54 0x7A5A 0x7ABE 0x7AC0 \ + 0x7AC1 0x7C05 0x7C0F 0x7BF2 0x7C00 0x7BFF 0x7BFB 0x7C0E \ + 0x7BF4 0x7C0B 0x7BF3 0x7C02 0x7C09 0x7C03 0x7C01 0x7BF8 \ + 0x7BFD 0x7C06 0x7BF0 0x7BF1 0x7C10 0x7C0A 0x7CE8 0x7E2D \ + 0x7E3C 0x7E42 0x7E33 0x9848 0x7E38 0x7E2A 0x7E49 0x7E40 \ + 0x7E47 0x7E29 0x7E4C 0x7E30 0x7E3B 0x7E36 0x7E44 0x7E3A \ + 0x7F45 0x7F7F 0x7F7E 0x7F7D 0x7FF4 0x7FF2 0x802C 0x81BB \ + 0x81C4 0x81CC 0x81CA 0x81C5 0x81C7 0x81BC 0x81E9 0x825B \ + 0x825A 0x825C 0x8583 0x8580 0x858F 0x85A7 0x8595 0x85A0 \ + 0x858B 0x85A3 0x857B 0x85A4 0x859A 0x859E 0x8577 0x857C \ + 0x8589 0x85A1 0x857A 0x8578 0x8557 0x858E 0x8596 0x8586 \ + 0x858D 0x8599 0x859D 0x8581 0x85A2 0x8582 0x8588 0x8585 \ + 0x8579 0x8576 0x8598 0x8590 0x859F 0x8668 0x87BE 0x87AA +82 0x87AD 0x87C5 0x87B0 0x87AC 0x87B9 0x87B5 0x87BC 0x87AE \ + 0x87C9 0x87C3 0x87C2 0x87CC 0x87B7 0x87AF 0x87C4 0x87CA \ + 0x87B4 0x87B6 0x87BF 0x87B8 0x87BD 0x87DE 0x87B2 0x8935 \ + 0x8933 0x893C 0x893E 0x8941 0x8952 0x8937 0x8942 0x89AD \ + 0x89AF 0x89AE 0x89F2 0x89F3 0x8B1E 0x97BA 0x97FC 0x98C3 \ + 0x994D 0x9A2F 0x9AC9 0x9AC8 0x9AC4 0x9B2A 0x9B38 0x9B50 \ + 0x9C0A 0x9BFB 0x9C04 0x9BFC 0x9BFE 0x9C02 0x9BF6 0x9C1B \ + 0x9BF9 0x9C15 0x9C10 0x9BFF 0x9C00 0x9C0C 0x9D95 0x9DA5 \ + 0x9E98 0x9EC1 0x9F5A 0x5164 0x56BB 0x58E6 0x8B18 0x8B16 \ + 0x8B11 0x8B05 0x8B0B 0x8B22 0x8B0F 0x8B12 0x8B15 0x8B07 \ + 0x8B0D 0x8B08 0x8B06 0x8B1C 0x8B13 0x8B1A 0x8C4F 0x8C70 \ + 0x8C72 0x8C71 0x8C6F 0x8C95 0x8C94 0x8CF9 0x8D6F 0x8E4E \ + 0x8E4D 0x8E53 0x8E50 0x8E4C 0x8E47 0x8F43 0x8F40 0x9085 \ + 0x907E 0x9138 0x919A 0x91A2 0x919B 0x9199 0x919F 0x91A1 \ + 0x919D 0x91A0 0x93A1 0x9383 0x93AF 0x9364 0x9356 0x9347 \ + 0x937C 0x9358 0x935C 0x9376 0x9349 0x9350 0x9351 0x9360 \ + 0x936D 0x938F 0x934C 0x936A 0x9379 0x9357 0x9355 0x9352 \ + 0x934F 0x9371 0x9377 0x937B 0x9361 0x935E 0x9363 0x9367 \ + 0x9380 0x934E 0x9359 0x95C7 0x95C0 0x95C9 0x95C3 0x95C5 \ + 0x95B7 0x96AE 0x96B0 0x96AC 0x9720 0x971F 0x9718 0x971D \ + 0x9719 0x979A 0x97A1 0x979C 0x979E 0x979D 0x97D5 0x97D4 \ + 0x97F1 0x9841 0x9844 0x984A 0x9849 0x9845 0x9843 0x9925 \ + 0x992B 0x992C 0x992A 0x9933 0x9932 0x992F 0x992D 0x9931 \ + 0x9930 0x9998 0x99A3 0x99A1 0x9A02 0x99FA 0x99F4 0x99F7 \ + 0x99F9 0x99F8 0x99F6 0x99FB 0x99FD 0x99FE 0x99FC 0x9A03 \ + 0x9ABE 0x9AFE 0x9AFD 0x9B01 0x9AFC 0x9B48 0x9B9A 0x9BA8 \ + 0x9B9E 0x9B9B 0x9BA6 0x9BA1 0x9BA5 0x9BA4 0x9B86 0x9BA2 \ + 0x9BA0 0x9BAF 0x9D33 0x9D41 0x9D67 0x9D36 0x9D2E 0x9D2F \ + 0x9D31 0x9D38 0x9D30 0x5B49 0x5BF7 0x5DD0 0x5FC2 0x6511 \ + 0x6AFF 0x6AFE 0x6AFD 0x6B01 0x704B 0x704D 0x7047 0x74D3 \ + 0x7668 0x7667 0x77D1 0x7930 0x7932 0x792E 0x9F9D 0x7AC9 \ + 0x7AC8 0x7C56 0x7C51 0x7E85 0x7E89 0x7E8E 0x7E84 0x826A +83 0x862B 0x862F 0x8628 0x8616 0x9D45 0x9D42 0x9D43 0x9D3E \ + 0x9D37 0x9D40 0x9D3D 0x7FF5 0x9D2D 0x9E8A 0x9E89 0x9E8D \ + 0x9EB0 0x9EC8 0x9EDA 0x9EFB 0x9EFF 0x9F24 0x9F23 0x9F22 \ + 0x9F54 0x9FA0 0x5131 0x512D 0x512E 0x5698 0x569C 0x5697 \ + 0x569A 0x569D 0x5699 0x5970 0x5B3C 0x5C69 0x5C6A 0x5DC0 \ + 0x5E6D 0x5E6E 0x61D8 0x61DF 0x61ED 0x61EE 0x61F1 0x61EA \ + 0x61F0 0x61EB 0x61D6 0x61E9 0x64FF 0x6504 0x64FD 0x64F8 \ + 0x6501 0x6503 0x64FC 0x6594 0x65DB 0x66DA 0x66DB 0x66D8 \ + 0x6AC5 0x6AB9 0x6ABD 0x6AE1 0x6AC6 0x6ABA 0x6AB6 0x6AB7 \ + 0x6AC7 0x6AB4 0x6AAD 0x6B5E 0x6BC9 0x6C0B 0x7007 0x700C \ + 0x700D 0x7001 0x7005 0x7014 0x700E 0x6FFF 0x7000 0x6FFB \ + 0x7026 0x6FFC 0x6FF7 0x700A 0x7201 0x71FF 0x71F9 0x7203 \ + 0x71FD 0x7376 0x74B8 0x74C0 0x74B5 0x74C1 0x74BE 0x74B6 \ + 0x74BB 0x74C2 0x7514 0x7513 0x765C 0x7664 0x7659 0x7650 \ + 0x7653 0x7657 0x765A 0x76A6 0x76BD 0x76EC 0x77C2 0x77BA \ + 0x78FF 0x790C 0x7913 0x7914 0x7909 0x7910 0x7912 0x7911 \ + 0x79AD 0x79AC 0x7A5F 0x7C1C 0x7C29 0x7C19 0x7C20 0x7C1F \ + 0x7C2D 0x7C1D 0x7C26 0x7C28 0x7C22 0x7C25 0x7C30 0x7E5C \ + 0x7E50 0x7E56 0x7E63 0x7E58 0x7E62 0x7E5F 0x7E51 0x7E60 \ + 0x7E57 0x7E53 0x7FB5 0x7FB3 0x7FF7 0x7FF8 0x8075 0x81D1 \ + 0x81D2 0x8615 0x861D 0x881A 0x89BC 0x8B75 0x8B7C 0x8D11 \ + 0x8D12 0x8F5C 0x91BB 0x93F4 0x942D 0x96E4 0x9737 0x9736 \ + 0x9767 0x97BE 0x97BD 0x97E2 0x9868 0x9866 0x98C8 0x98CA \ + 0x98C7 0x98DC 0x994F 0x99A9 0x9A3C 0x9A3B 0x9ACE 0x9B14 \ + 0x9B53 0x9C2E 0x81D0 0x825F 0x825E 0x85B4 0x85C6 0x85C0 \ + 0x85C3 0x85C2 0x85B3 0x85B5 0x85BD 0x85C7 0x85C4 0x85BF \ + 0x85CB 0x85CE 0x85C8 0x85C5 0x85B1 0x85B6 0x85D2 0x8624 \ + 0x85B8 0x85B7 0x85BE 0x8669 0x87E7 0x87E6 0x87E2 0x87DB \ + 0x87EB 0x87EA 0x87E5 0x87DF 0x87F3 0x87E4 0x87D4 0x87DC \ + 0x87D3 0x87ED 0x87D8 0x87E3 0x87A4 0x87D7 0x87D9 0x8801 \ + 0x87F4 0x87E8 0x87DD 0x8953 0x894B 0x894F 0x894C 0x8946 \ + 0x8950 0x8951 0x8949 0x8B2A 0x8B27 0x8B23 0x8B33 0x8B30 +84 0x8B35 0x8B47 0x8B2F 0x8B3C 0x8B3E 0x8B31 0x8B25 0x8B37 \ + 0x8B26 0x8B36 0x8B2E 0x8B24 0x8B3B 0x8B3D 0x8B3A 0x8C42 \ + 0x8C75 0x8C99 0x8C98 0x8C97 0x8CFE 0x8D04 0x8D02 0x8D00 \ + 0x8E5C 0x8E62 0x8E60 0x8E57 0x8E56 0x8E5E 0x8E65 0x8E67 \ + 0x8E5B 0x8E5A 0x8E61 0x8E5D 0x8E69 0x8E54 0x8F46 0x8F47 \ + 0x8F48 0x8F4B 0x9128 0x913A 0x913B 0x913E 0x91A8 0x91A5 \ + 0x91A7 0x91AF 0x91AA 0x93B5 0x938C 0x9392 0x93B7 0x939B \ + 0x939D 0x9389 0x93A7 0x938E 0x93AA 0x939E 0x93A6 0x9395 \ + 0x9388 0x9399 0x939F 0x938D 0x93B1 0x9391 0x93B2 0x93A4 \ + 0x93A8 0x93B4 0x93A3 0x93A5 0x95D2 0x95D3 0x95D1 0x96B3 \ + 0x96D7 0x96DA 0x5DC2 0x96DF 0x96D8 0x96DD 0x9723 0x9722 \ + 0x9725 0x97AC 0x97AE 0x97A8 0x97AB 0x97A4 0x97AA 0x9C1F \ + 0x9DB0 0x9DBD 0x9DAE 0x9DC4 0x9E7B 0x9E9E 0x9F05 0x9F69 \ + 0x9FA1 0x56C7 0x571D 0x5B4A 0x5DD3 0x5F72 0x6202 0x6235 \ + 0x6527 0x651E 0x651F 0x6B07 0x6B06 0x7054 0x721C 0x7220 \ + 0x7AF8 0x7C5D 0x7C58 0x7E92 0x7F4E 0x8827 0x8B81 0x8B83 \ + 0x97A2 0x97A5 0x97D7 0x97D9 0x97D6 0x97D8 0x97FA 0x9850 \ + 0x9851 0x9852 0x98B8 0x9941 0x993C 0x993A 0x9A0F 0x9A0B \ + 0x9A09 0x9A0D 0x9A04 0x9A11 0x9A0A 0x9A05 0x9A07 0x9A06 \ + 0x9AC0 0x9ADC 0x9B08 0x9B04 0x9B05 0x9B29 0x9B35 0x9B4A \ + 0x9B4C 0x9B4B 0x9BC7 0x9BC6 0x9BC3 0x9BBF 0x9BC1 0x9BB5 \ + 0x9BB8 0x9BD3 0x9BB6 0x9BC4 0x9BB9 0x9BBD 0x9D5C 0x9D53 \ + 0x9D4F 0x9D4A 0x9D5B 0x9D4B 0x9D59 0x9D56 0x9D4C 0x9D57 \ + 0x9D52 0x9D54 0x9D5F 0x9D58 0x9D5A 0x9E8E 0x9E8C 0x9EDF \ + 0x9F01 0x9F00 0x9F16 0x9F25 0x9F2B 0x9F2A 0x9F29 0x9F28 \ + 0x9F4C 0x9F55 0x5134 0x5135 0x5296 0x52F7 0x53B4 0x56AB \ + 0x56AD 0x56A6 0x56A7 0x56AA 0x56AC 0x58DA 0x58DD 0x58DB \ + 0x5912 0x5B3D 0x5B3E 0x5B3F 0x5DC3 0x5E70 0x5FBF 0x61FB \ + 0x6507 0x6510 0x650D 0x6509 0x650C 0x650E 0x6584 0x65DE \ + 0x65DD 0x66DE 0x6AE7 0x6AE0 0x6ACC 0x6AD1 0x6AD9 0x6ACB \ + 0x6ADF 0x6ADC 0x6AD0 0x6AEB 0x6ACF 0x6ACD 0x6ADE 0x6B60 \ + 0x6BB0 0x6C0C 0x7019 0x7027 0x7020 0x7016 0x702B 0x7021 +85 0x7022 0x7023 0x7029 0x7017 0x7024 0x701C 0x702A 0x720C \ + 0x720A 0x7207 0x7202 0x7205 0x72A5 0x72A6 0x72A4 0x72A3 \ + 0x72A1 0x74CB 0x74C5 0x74B7 0x74C3 0x7516 0x7660 0x77C9 \ + 0x77CA 0x77C4 0x77F1 0x791D 0x791B 0x8C44 0x9442 0x944D \ + 0x9454 0x944E 0x9443 0x973C 0x9740 0x97C0 0x995A 0x9A51 \ + 0x9ADD 0x9C38 0x9C45 0x9C3A 0x9C35 0x9EF1 0x9F93 0x529A \ + 0x8641 0x5DD7 0x6528 0x7053 0x7059 0x7221 0x766F 0x7937 \ + 0x79B5 0x7C62 0x7C5E 0x7CF5 0x863D 0x882D 0x7921 0x791C \ + 0x7917 0x791E 0x79B0 0x7A67 0x7A68 0x7C33 0x7C3C 0x7C39 \ + 0x7C2C 0x7C3B 0x7CEC 0x7CEA 0x7E76 0x7E75 0x7E78 0x7E70 \ + 0x7E77 0x7E6F 0x7E7A 0x7E72 0x7E74 0x7E68 0x7F4B 0x7F4A \ + 0x7F83 0x7F86 0x7FB7 0x7FFD 0x7FFE 0x8078 0x81D7 0x81D5 \ + 0x8264 0x8261 0x8263 0x85EB 0x85F1 0x85ED 0x85D9 0x85E1 \ + 0x85E8 0x85DA 0x85D7 0x85EC 0x85F2 0x85F8 0x85D8 0x85DF \ + 0x85E3 0x85DC 0x85D1 0x85F0 0x85E6 0x85EF 0x85DE 0x85E2 \ + 0x8800 0x87FA 0x8803 0x87F6 0x87F7 0x8809 0x880C 0x880B \ + 0x8806 0x87FC 0x8808 0x87FF 0x880A 0x8802 0x8962 0x895A \ + 0x895B 0x8957 0x8961 0x895C 0x8958 0x895D 0x8959 0x8988 \ + 0x89B7 0x89B6 0x89F6 0x8B50 0x8B48 0x8B4A 0x8B40 0x8B53 \ + 0x8B56 0x8B54 0x8B4B 0x8B55 0x8B51 0x8B42 0x8B52 0x8B57 \ + 0x8C43 0x8C77 0x8C76 0x8C9A 0x8D06 0x8D07 0x8D09 0x8DAC \ + 0x8DAA 0x8DAD 0x8DAB 0x8E6D 0x8E78 0x8E73 0x8E6A 0x8E6F \ + 0x8E7B 0x8EC2 0x8F52 0x8F51 0x8F4F 0x8F50 0x8F53 0x8FB4 \ + 0x9140 0x913F 0x91B0 0x91AD 0x93DE 0x93C7 0x93CF 0x93C2 \ + 0x93DA 0x93D0 0x93F9 0x93EC 0x93CC 0x93D9 0x93A9 0x93E6 \ + 0x93CA 0x93D4 0x93EE 0x93E3 0x93D5 0x93C4 0x93CE 0x93C0 \ + 0x93D2 0x93E7 0x957D 0x95DA 0x95DB 0x96E1 0x9729 0x972B \ + 0x972C 0x9728 0x9726 0x8989 0x8B8D 0x8B87 0x8B90 0x8D1A \ + 0x8E99 0x945F 0x9456 0x9461 0x945B 0x945A 0x945C 0x9465 \ + 0x9741 0x986E 0x986C 0x986D 0x99AA 0x9A5C 0x9A58 0x9ADE \ + 0x9C4F 0x9C51 0x9C53 0x9DFC 0x9F39 0x513E 0x56D2 0x5B4F \ + 0x6B14 0x7A72 0x7A73 0x8B91 0x97B3 0x97B7 0x97B6 0x97DD +86 0x97DE 0x97DF 0x985C 0x9859 0x985D 0x9857 0x98BF 0x98BD \ + 0x98BB 0x98BE 0x9948 0x9947 0x9943 0x99A6 0x99A7 0x9A1A \ + 0x9A15 0x9A25 0x9A1D 0x9A24 0x9A1B 0x9A22 0x9A20 0x9A27 \ + 0x9A23 0x9A1E 0x9A1C 0x9A14 0x9AC2 0x9B0B 0x9B0A 0x9B0E \ + 0x9B0C 0x9B37 0x9BEA 0x9BEB 0x9BE0 0x9BDE 0x9BE4 0x9BE6 \ + 0x9BE2 0x9BF0 0x9BD4 0x9BD7 0x9BEC 0x9BDC 0x9BD9 0x9BE5 \ + 0x9BD5 0x9BE1 0x9BDA 0x9D77 0x9D81 0x9D8A 0x9D84 0x9D88 \ + 0x9D71 0x9D80 0x9D78 0x9D86 0x9D8B 0x9D8C 0x9D7D 0x9D6B \ + 0x9D74 0x9D75 0x9D70 0x9D69 0x9D85 0x9D73 0x9D7B 0x9D82 \ + 0x9D6F 0x9D79 0x9D7F 0x9D87 0x9D68 0x9E94 0x9E91 0x9EC0 \ + 0x9EFC 0x9F2D 0x9F40 0x9F41 0x9F4D 0x9F56 0x9F57 0x9F58 \ + 0x5337 0x56B2 0x56B5 0x56B3 0x58E3 0x5B45 0x5DC6 0x5DC7 \ + 0x5EEE 0x5EEF 0x5FC0 0x5FC1 0x61F9 0x6517 0x6516 0x6515 \ + 0x6513 0x65DF 0x66E8 0x66E3 0x66E4 0x6AF3 0x6AF0 0x6AEA \ + 0x6AE8 0x6AF9 0x6AF1 0x6AEE 0x6AEF 0x703C 0x7035 0x702F \ + 0x7037 0x7034 0x7031 0x7042 0x7038 0x703F 0x703A 0x7039 \ + 0x7040 0x703B 0x7033 0x7041 0x7213 0x7214 0x72A8 0x737D \ + 0x737C 0x74BA 0x76AB 0x76AA 0x76BE 0x76ED 0x77CC 0x77CE \ + 0x77CF 0x77CD 0x77F2 0x7925 0x7923 0x7927 0x7928 0x7924 \ + 0x7929 0x91BF 0x946C 0x96E6 0x9745 0x97C8 0x97E4 0x995D \ + 0x9B21 0x9B2C 0x9B57 0x9C5D 0x9C61 0x9C65 0x9E08 0x9F45 \ + 0x6205 0x66EF 0x6B1B 0x6B1D 0x7225 0x7224 0x7C6D 0x8642 \ + 0x8649 0x8978 0x898A 0x8B97 0x8C9B 0x8D1C 0x8EA2 0x9C6C \ + 0x9C6F 0x9E0E 0x79B2 0x7A6E 0x7A6C 0x7A6D 0x7AF7 0x7C49 \ + 0x7C48 0x7C4A 0x7C47 0x7C45 0x7CEE 0x7E7B 0x7E7E 0x7E81 \ + 0x7E80 0x7FBA 0x7FFF 0x8079 0x81DB 0x81D9 0x820B 0x8268 \ + 0x8269 0x8622 0x85FF 0x8601 0x85FE 0x861B 0x8600 0x85F6 \ + 0x8604 0x8609 0x8605 0x860C 0x85FD 0x8819 0x8810 0x8811 \ + 0x8817 0x8813 0x8816 0x8963 0x8966 0x89B9 0x89F7 0x8B60 \ + 0x8B6A 0x8B5D 0x8B68 0x8B63 0x8B65 0x8B67 0x8B6D 0x8DAE \ + 0x8E86 0x8E88 0x8E84 0x8F59 0x8F56 0x8F57 0x8F55 0x8F58 \ + 0x8F5A 0x908D 0x9143 0x9141 0x91B7 0x91B5 0x91B2 0x91B3 +87 0x940B 0x9413 0x93FB 0x9420 0x940F 0x9414 0x93FE 0x9415 \ + 0x9410 0x9428 0x9419 0x940D 0x93F5 0x9400 0x93F7 0x9407 \ + 0x940E 0x9416 0x9412 0x93FA 0x9409 0x93F8 0x940A 0x93FF \ + 0x93FC 0x940C 0x93F6 0x9411 0x9406 0x95DE 0x95E0 0x95DF \ + 0x972E 0x972F 0x97B9 0x97BB 0x97FD 0x97FE 0x9860 0x9862 \ + 0x9863 0x985F 0x98C1 0x98C2 0x9950 0x994E 0x9959 0x994C \ + 0x994B 0x9953 0x9A32 0x9A34 0x9A31 0x9A2C 0x9A2A 0x9A36 \ + 0x9A29 0x9A2E 0x9A38 0x9A2D 0x9AC7 0x9ACA 0x9AC6 0x9B10 \ + 0x9B12 0x9B11 0x9C0B 0x9C08 0x9BF7 0x9C05 0x9C12 0x9BF8 \ + 0x9C40 0x9C07 0x9C0E 0x9C06 0x9C17 0x9C14 0x9C09 0x9D9F \ + 0x9D99 0x9DA4 0x9D9D 0x9D92 0x9D98 0x9D90 0x9D9B 0x9F08 \ + 0x9F1D 0x9FA3 0x5F60 0x6B1C 0x7CF3 0x8B9B 0x8EA7 0x91C4 \ + 0x947A 0x9A61 0x9A63 0x9AD7 0x9C76 0x9FA5 0x7067 0x72AB \ + 0x864A 0x897D 0x8B9D 0x8C53 0x8F65 0x947B 0x98CD 0x98DD \ + 0x9B30 0x9E16 0x96E7 0x9E18 0x9EA2 0x9F7C 0x7E9E 0x9484 \ + 0x9DA0 0x9D94 0x9D9C 0x9DAA 0x9D97 0x9DA1 0x9D9A 0x9DA2 \ + 0x9DA8 0x9D9E 0x9DA3 0x9DBF 0x9DA9 0x9D96 0x9DA6 0x9DA7 \ + 0x9E99 0x9E9B 0x9E9A 0x9EE5 0x9EE4 0x9EE7 0x9EE6 0x9F30 \ + 0x9F2E 0x9F5B 0x9F60 0x9F5E 0x9F5D 0x9F59 0x9F91 0x513A \ + 0x5139 0x5298 0x5297 0x56C3 0x56BD 0x56BE 0x5B48 0x5B47 \ + 0x5DCB 0x5DCF 0x5EF1 0x61FD 0x651B 0x6B02 0x6AFC 0x6B03 \ + 0x6AF8 0x6B00 0x7043 0x7044 0x704A 0x7048 0x7049 0x7045 \ + 0x7046 0x721D 0x721A 0x7219 0x737E 0x7517 0x766A 0x77D0 \ + 0x792D 0x7931 0x792F 0x7C54 0x7C53 0x7CF2 0x7E8A 0x7E87 \ + 0x7E88 0x7E8B 0x7E86 0x7E8D 0x7F4D 0x7FBB 0x8030 0x81DD \ + 0x8618 0x862A 0x8626 0x861F 0x8623 0x861C 0x8619 0x8627 \ + 0x862E 0x8621 0x8620 0x8629 0x861E 0x8625 0x8829 0x881D \ + 0x881B 0x8820 0x8824 0x881C 0x882B 0x884A 0x896D 0x8969 \ + 0x896E 0x896B 0x89FA 0x8B79 0x8B78 0x8B45 0x8B7A 0x8B7B \ + 0x8D10 0x8D14 0x8DAF 0x8E8E 0x8E8C 0x8F5E 0x8F5B 0x8F5D \ + 0x9146 0x9144 0x9145 0x91B9 0x943F 0x943B 0x9436 0x9429 \ + 0x943D 0x943C 0x9430 0x9439 0x942A 0x9437 0x942C 0x9440 +88 0x9431 0x95E5 0x95E4 0x95E3 0x9735 0x973A 0x97BF 0x97E1 \ + 0x9864 0x98C9 0x98C6 0x98C0 0x9958 0x9956 0x9A39 0x9A3D \ + 0x9A46 0x9A44 0x9A42 0x9A41 0x9A3A 0x9E1C 0x7C71 0x97CA \ + 0x9EA3 0x9C7B 0x9F97 0x9750 0x4E40 0x4E41 0x4E5A 0x4E02 \ + 0x4E29 0x5202 0x5DDC 0x5342 0x536A 0x5B52 0x5FC4 0x624C \ + 0x72AD 0x4E12 0x4E2F 0x4E96 0x4ED0 0x5142 0x5183 0x5383 \ + 0x53B8 0x5928 0x5C23 0x5E01 0x5F00 0x706C 0x9A3F 0x9ACD \ + 0x9B15 0x9B17 0x9B18 0x9B16 0x9B3A 0x9B52 0x9C2B 0x9C1D \ + 0x9C1C 0x9C2C 0x9C23 0x9C28 0x9C29 0x9C24 0x9C21 0x9DB7 \ + 0x9DB6 0x9DBC 0x9DC1 0x9DC7 0x9DCA 0x9DCF 0x9DBE 0x9DC5 \ + 0x9DC3 0x9DBB 0x9DB5 0x9DCE 0x9DB9 0x9DBA 0x9DAC 0x9DC8 \ + 0x9DB1 0x9DAD 0x9DCC 0x9DB3 0x9DCD 0x9DB2 0x9E7A 0x9E9C \ + 0x9EEB 0x9EEE 0x9EED 0x9F1B 0x9F18 0x9F1A 0x9F31 0x9F4E \ + 0x9F65 0x9F64 0x9F92 0x4EB9 0x56C6 0x56C5 0x56CB 0x5971 \ + 0x5B4B 0x5B4C 0x5DD5 0x5DD1 0x5EF2 0x6521 0x6520 0x6526 \ + 0x6522 0x6B0B 0x6B08 0x6B09 0x6C0D 0x7055 0x7056 0x7057 \ + 0x7052 0x721E 0x721F 0x72A9 0x737F 0x74D8 0x74D5 0x74D9 \ + 0x74D7 0x766D 0x76AD 0x7935 0x79B4 0x7A70 0x7A71 0x7C57 \ + 0x7C5C 0x7C59 0x7C5B 0x7C5A 0x7CF4 0x7CF1 0x7E91 0x7F4F \ + 0x7F87 0x81DE 0x826B 0x8634 0x8635 0x8633 0x862C 0x8632 \ + 0x8636 0x882C 0x8828 0x8826 0x882A 0x8825 0x8971 0x89BF \ + 0x89BE 0x89FB 0x8B7E 0x8B84 0x8B82 0x8B86 0x8B85 0x8B7F \ + 0x8D15 0x8E95 0x8E94 0x8E9A 0x8E92 0x8E90 0x8E96 0x8E97 \ + 0x8F60 0x8F62 0x9147 0x944C 0x9450 0x944A 0x944B 0x944F \ + 0x9447 0x9445 0x9448 0x9449 0x9446 0x973F 0x97E3 0x986A \ + 0x9869 0x98CB 0x9954 0x995B 0x9A4E 0x9A53 0x9A54 0x9A4C \ + 0x9A4F 0x9A48 0x9A4A 0x722B 0x5188 0x8279 0x8FB6 0x4E17 \ + 0x4EE2 0x4EDB 0x51AD 0x51F7 0x531B 0x5388 0x5387 0x53CF \ + 0x53FD 0x53E7 0x56DC 0x56D9 0x5725 0x5727 0x5933 0x5C13 \ + 0x5C75 0x66F1 0x7F52 0x4E51 0x4E6A 0x4F0C 0x4EFE 0x4F1B \ + 0x5173 0x518E 0x52A5 0x52A7 0x9A49 0x9A52 0x9A50 0x9AD0 \ + 0x9B19 0x9B2B 0x9B3B 0x9B56 0x9B55 0x9C46 0x9C48 0x9C3F +89 0x9C44 0x9C39 0x9C33 0x9C41 0x9C3C 0x9C37 0x9C34 0x9C32 \ + 0x9C3D 0x9C36 0x9DDB 0x9DD2 0x9DDE 0x9DDA 0x9DCB 0x9DD0 \ + 0x9DDC 0x9DD1 0x9DDF 0x9DE9 0x9DD9 0x9DD8 0x9DD6 0x9DF5 \ + 0x9DD5 0x9DDD 0x9EB6 0x9EF0 0x9F35 0x9F33 0x9F32 0x9F42 \ + 0x9F6B 0x9F95 0x9FA2 0x513D 0x5299 0x58E8 0x58E7 0x5972 \ + 0x5B4D 0x5DD8 0x882F 0x5F4F 0x6201 0x6203 0x6204 0x6529 \ + 0x6525 0x6596 0x66EB 0x6B11 0x6B12 0x6B0F 0x6BCA 0x705B \ + 0x705A 0x7222 0x7382 0x7381 0x7383 0x7670 0x77D4 0x7C67 \ + 0x7C66 0x7E95 0x826C 0x863A 0x8640 0x8639 0x863C 0x8631 \ + 0x863B 0x863E 0x8830 0x8832 0x882E 0x8833 0x8976 0x8974 \ + 0x8973 0x89FE 0x8B8C 0x8B8E 0x8B8B 0x8B88 0x8C45 0x8D19 \ + 0x8E98 0x8F64 0x8F63 0x91BC 0x9462 0x9455 0x945D 0x9457 \ + 0x945E 0x97C4 0x97C5 0x9800 0x9A56 0x9A59 0x9B1E 0x9B1F \ + 0x9B20 0x9C52 0x9C58 0x9C50 0x9C4A 0x9C4D 0x9C4B 0x9C55 \ + 0x9C59 0x9C4C 0x9C4E 0x9DFB 0x9DF7 0x9DEF 0x9DE3 0x9DEB \ + 0x9DF8 0x9DE4 0x9DF6 0x9DE1 0x9DEE 0x9DE6 0x9DF2 0x9DF0 \ + 0x9DE2 0x9DEC 0x9DF4 0x9DF3 0x9DE8 0x9DED 0x9EC2 0x9ED0 \ + 0x9EF2 0x9EF3 0x9F06 0x9F1C 0x9F38 0x9F37 0x9F36 0x9F43 \ + 0x9F4F 0x52A4 0x53BD 0x5402 0x572B 0x591B 0x5935 0x5C17 \ + 0x5C70 0x5C7D 0x5DE9 0x5F19 0x5F1C 0x5F75 0x5FC8 0x6C12 \ + 0x72B3 0x7390 0x7536 0x8281 0x8FB8 0x4E23 0x4F2E 0x514F \ + 0x51BA 0x5222 0x52AF 0x52B0 0x52B1 0x5364 0x53D3 0x593F \ + 0x598B 0x5991 0x9F71 0x9F70 0x9F6E 0x9F6F 0x56D3 0x56CD \ + 0x5B4E 0x5C6D 0x652D 0x66ED 0x66EE 0x6B13 0x705F 0x7061 \ + 0x705D 0x7060 0x7223 0x74DB 0x74E5 0x77D5 0x7938 0x79B7 \ + 0x79B6 0x7C6A 0x7E97 0x7F89 0x826D 0x8643 0x8838 0x8837 \ + 0x8835 0x884B 0x8B94 0x8B95 0x8E9E 0x8E9F 0x8EA0 0x8E9D \ + 0x91BE 0x91BD 0x91C2 0x946B 0x9468 0x9469 0x96E5 0x9746 \ + 0x9743 0x9747 0x97C7 0x97E5 0x9A5E 0x9AD5 0x9B59 0x9C63 \ + 0x9C67 0x9C66 0x9C62 0x9C5E 0x9C60 0x9E02 0x9DFE 0x9E07 \ + 0x9E03 0x9E06 0x9E05 0x9E00 0x9E01 0x9E09 0x9DFF 0x9DFD \ + 0x9E04 0x9EA0 0x9F1E 0x9F46 0x9F74 0x9F75 0x9F76 0x56D4 +90 0x652E 0x65B8 0x6B18 0x6B19 0x6B17 0x6B1A 0x7062 0x7226 \ + 0x72AA 0x77D8 0x77D9 0x7939 0x7C69 0x7C6B 0x7CF6 0x7E9A \ + 0x7E98 0x7E9B 0x7E99 0x81E0 0x81E1 0x8646 0x8647 0x8648 \ + 0x8979 0x897A 0x897C 0x897B 0x89FF 0x8B98 0x8B99 0x8EA5 \ + 0x8EA4 0x8EA3 0x946E 0x946D 0x946F 0x9471 0x9473 0x9749 \ + 0x9872 0x995F 0x9C68 0x9C6E 0x9C6D 0x9E0B 0x9E0D 0x9E10 \ + 0x9E0F 0x9E12 0x9E11 0x9EA1 0x9EF5 0x9F09 0x9F47 0x9F78 \ + 0x9F7B 0x9F7A 0x9F79 0x571E 0x7066 0x7C6F 0x883C 0x8DB2 \ + 0x8EA6 0x91C3 0x9474 0x9478 0x9476 0x9475 0x9A60 0x9C74 \ + 0x9C73 0x9C71 0x9C75 0x9E14 0x9E13 0x9EF6 0x9F0A 0x5995 \ + 0x5B8A 0x5C87 0x5E0D 0x5E8E 0x5F7A 0x6290 0x629A 0x653C \ + 0x653A 0x6598 0x6765 0x79C2 0x809E 0x81EB 0x8289 0x8296 \ + 0x8287 0x8FC0 0x8FC3 0x9578 0x9625 0x4E75 0x4E74 0x4F99 \ + 0x4F71 0x5153 0x51BF 0x51C0 0x51EE 0x523D 0x52BD 0x530C \ + 0x9FA4 0x7068 0x7065 0x7CF7 0x866A 0x883E 0x883D 0x883F \ + 0x8B9E 0x8C9C 0x8EA9 0x8EC9 0x974B 0x9873 0x9874 0x98CC \ + 0x9961 0x99AB 0x9A64 0x9A66 0x9A67 0x9B24 0x9E15 0x9E17 \ + 0x9F48 0x6207 0x6B1E 0x7227 0x864C 0x8EA8 0x9482 0x9480 \ + 0x9481 0x9A69 0x9A68 0x9B2E 0x9E19 0x7229 0x864B 0x8B9F \ + 0x9483 0x9C79 0x9EB7 0x7675 0x9A6B 0x9C7A 0x9E1D 0x7069 \ + 0x706A 0x9EA4 0x9F7E 0x9F49 0x9F98 0x7881 0x92B9 0x88CF \ + 0x58BB 0x6052 0x7CA7 0x5AFA 0x2554 0x2566 0x2557 0x2560 \ + 0x256C 0x2563 0x255A 0x2569 0x255D 0x2552 0x2564 0x2555 \ + 0x255E 0x256A 0x2561 0x2558 0x2567 0x255B 0x2553 0x2565 \ + 0x2556 0x255F 0x256B 0x2562 0x2559 0x2568 0x255C 0x2551 \ + 0x2550 0x2554 0x2557 0x255A 0x255D 0x2588 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +91 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x7F37 0x53C0 0x546E \ + 0x5483 0x545E 0x545D 0x577E 0x5779 0x577A 0x576C 0x5787 \ + 0x591D 0x5946 0x5943 0x5B61 0x5B66 0x5B90 0x5C29 0x5CB2 \ + 0x5CC0 0x601F 0x5FE2 0x6616 0x65F9 0x6788 0x679B 0x676E \ + 0x679E 0x6B24 0x6B7D 0x6CE6 0x6CCB 0x6CB5 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x7097 0x709B 0x726B 0x72D5 0x7543 \ + 0x759C 0x77E4 0x7ACE 0x8013 0x80B7 0x80B9 0x81E4 0x81FD \ + 0x820F 0x82BF 0x82CA 0x82C1 0x8FD0 0x90AE 0x9638 0x4FBC \ + 0x4FE9 0x4FBD 0x4FE2 0x5158 0x52C6 0x52C8 0x5328 0x5329 \ + 0x57B4 0x57A9 0x5B68 0x5F2B 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +92 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x5F8D 0x6018 0x6057 0x6048 0x6038 0x6071 0x6312 \ + 0x630A 0x6323 0x662A 0x67E0 0x67BE 0x6B29 0x6D43 0x70A6 \ + 0x70C0 0x722F 0x7271 0x74EA 0x7520 0x75A9 0x7685 0x7706 \ + 0x76F6 0x7700 0x7702 0x8009 0x82DA 0x830A 0x9655 0x9652 \ + 0x4E35 0x5034 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +93 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x5001 \ + 0x500A 0x5258 0x532B 0x54EC 0x5515 0x54FE 0x54E3 0x5516 \ + 0x57D3 0x5959 0x5A27 0x5A28 0x5A10 0x5A0E 0x5BAF 0x5BBA \ + 0x5BB1 0x5CFC 0x5CF2 0x5CFE 0x5DF8 0x5F2C 0x6082 0x6091 \ + 0x608F 0x6547 0x654C 0x658A 0x67E1 0x684A 0x683F 0x67BD \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +94 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x70C9 0x73BA 0x75C6 \ + 0x75B7 0x768C 0x768D 0x7717 0x771C 0x7714 0x7B0C 0x7D23 \ + 0x7F98 0x7F90 0x803A 0x8226 0x832E 0x8355 0x831A 0x833D \ + 0x8330 0x8651 0x8688 0x898E 0x898D 0x8A09 0x8A14 0x9007 \ + 0x9579 0x9584 0x9657 0x96BA 0x5067 0x5318 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UBig5.sfd b/contrib/ttf2pk/data/UBig5.sfd new file mode 100644 index 0000000..84cae62 --- /dev/null +++ b/contrib/ttf2pk/data/UBig5.sfd @@ -0,0 +1,1854 @@ +# UBig5.sfd +# +# subfont numbers for Big 5 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x3000 0xFF0C 0x3001 0x3002 0xFF0E 0x2022 0xFF1B 0xFF1A \ + 0xFF1F 0xFF01 0xFE30 0x2026 0x2025 0xFE50 0xFF64 0xFE52 \ + 0x00B7 0xFE54 0xFE55 0xFE56 0xFE57 0xFF5C 0x2013 0xFE31 \ + 0x2014 0xFE33 0xFFFD 0xFE34 0xFE4F 0xFF08 0xFF09 0xFE35 \ + 0xFE36 0xFF5B 0xFF5D 0xFE37 0xFE38 0x3014 0x3015 0xFE39 \ + 0xFE3A 0x3010 0x3011 0xFE3B 0xFE3C 0x300A 0x300B 0xFE3D \ + 0xFE3E 0x3008 0x3009 0xFE3F 0xFE40 0x300C 0x300D 0xFE41 \ + 0xFE42 0x300E 0x300F 0xFE43 0xFE44 0xFE59 0xFE5A 0xFE5B \ + 0xFE5C 0xFE5D 0xFE5E 0x2018 0x2019 0x201C 0x201D 0x301D \ + 0x301E 0x2035 0x2032 0xFF03 0xFF06 0xFF0A 0x203B 0x00A7 \ + 0x3003 0x25CB 0x25CF 0x25B3 0x25B2 0x25CE 0x2606 0x2605 \ + 0x25C7 0x25C6 0x25A1 0x25A0 0x25BD 0x25BC 0x32A3 0x2105 \ + 0x203E 0xFFFD 0xFF3F 0xFFFD 0xFE49 0xFE4A 0xFE4D 0xFE4E \ + 0xFE4B 0xFE4C 0xFE5F 0xFE60 0xFE61 0xFF0B 0xFF0D 0x00D7 \ + 0x00F7 0x00B1 0x221A 0xFF1C 0xFF1E 0xFF1D 0x2266 0x2267 \ + 0x2260 0x221E 0x2252 0x2261 0xFE62 0xFE63 0xFE64 0xFE65 \ + 0xFE66 0x223C 0x2229 0x222A 0x22A5 0x2220 0x221F 0x22BF \ + 0x33D2 0x33D1 0x222B 0x222E 0x2235 0x2234 0x2640 0x2642 \ + 0x2641 0x2609 0x2191 0x2193 0x2190 0x2192 0x2196 0x2197 \ + 0x2199 0x2198 0x2225 0x2223 0xFFFD 0xFFFD 0xFF0F 0xFF3C \ + 0xFF04 0x00A5 0x3012 0x00A2 0x00A3 0xFF05 0xFF20 0x2103 \ + 0x2109 0xFE69 0xFE6A 0xFE6B 0x33D5 0x339C 0x339D 0x339E \ + 0x33CE 0x33A1 0x338E 0x338F 0x33C4 0x00B0 0x5159 0x515B \ + 0x515E 0x515D 0x5161 0x5163 0x55E7 0x74E9 0x7CCE 0x2581 \ + 0x2582 0x2583 0x2584 0x2585 0x2586 0x2587 0x2588 0x258F \ + 0x258E 0x258D 0x258C 0x258B 0x258A 0x2589 0x253C 0x2534 \ + 0x252C 0x2524 0x251C 0x2594 0x2500 0x2502 0x2595 0x250C \ + 0x2510 0x2514 0x2518 0x256D 0x256E 0x2570 0x256F 0x2550 \ + 0x255E 0x256A 0x2561 0x25E2 0x25E3 0x25E5 0x25E4 0x2571 \ + 0x2572 0x2573 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 0xFF15 \ + 0xFF16 0xFF17 0xFF18 0xFF19 0x2160 0x2161 0x2162 0x2163 \ + 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 0x3021 0x3022 +02 0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 0x3029 0xFFFD \ + 0x5344 0xFFFD 0xFF21 0xFF22 0xFF23 0xFF24 0xFF25 0xFF26 \ + 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C 0xFF2D 0xFF2E \ + 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 0xFF35 0xFF36 \ + 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF41 0xFF42 0xFF43 0xFF44 \ + 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0x0391 0x0392 \ + 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A \ + 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 \ + 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0x03B1 0x03B2 \ + 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA \ + 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 \ + 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0x3105 0x3106 \ + 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E \ + 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 0x3115 0x3116 \ + 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E \ + 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 0x3125 0x3126 \ + 0x3127 0x3128 0x3129 0x02D9 0x02C9 0x02CA 0x02C7 0x02CB \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x4E00 \ + 0x4E59 0x4E01 0x4E03 0x4E43 0x4E5D 0x4E86 0x4E8C 0x4EBA \ + 0x513F 0x5165 0x516B 0x51E0 0x5200 0x5201 0x529B 0x5315 \ + 0x5341 0x535C 0x53C8 0x4E09 0x4E0B 0x4E08 0x4E0A 0x4E2B \ + 0x4E38 0x51E1 0x4E45 0x4E48 0x4E5F 0x4E5E 0x4E8E 0x4EA1 \ + 0x5140 0x5203 0x52FA 0x5343 0x53C9 0x53E3 0x571F 0x58EB +03 0x5915 0x5927 0x5973 0x5B50 0x5B51 0x5B53 0x5BF8 0x5C0F \ + 0x5C22 0x5C38 0x5C71 0x5DDD 0x5DE5 0x5DF1 0x5DF2 0x5DF3 \ + 0x5DFE 0x5E72 0x5EFE 0x5F0B 0x5F13 0x624D 0x4E11 0x4E10 \ + 0x4E0D 0x4E2D 0x4E30 0x4E39 0x4E4B 0x5C39 0x4E88 0x4E91 \ + 0x4E95 0x4E92 0x4E94 0x4EA2 0x4EC1 0x4EC0 0x4EC3 0x4EC6 \ + 0x4EC7 0x4ECD 0x4ECA 0x4ECB 0x4EC4 0x5143 0x5141 0x5167 \ + 0x516D 0x516E 0x516C 0x5197 0x51F6 0x5206 0x5207 0x5208 \ + 0x52FB 0x52FE 0x52FF 0x5316 0x5339 0x5348 0x5347 0x5345 \ + 0x535E 0x5384 0x53CB 0x53CA 0x53CD 0x58EC 0x5929 0x592B \ + 0x592A 0x592D 0x5B54 0x5C11 0x5C24 0x5C3A 0x5C6F 0x5DF4 \ + 0x5E7B 0x5EFF 0x5F14 0x5F15 0x5FC3 0x6208 0x6236 0x624B \ + 0x624E 0x652F 0x6587 0x6597 0x65A4 0x65B9 0x65E5 0x66F0 \ + 0x6708 0x6728 0x6B20 0x6B62 0x6B79 0x6BCB 0x6BD4 0x6BDB \ + 0x6C0F 0x6C34 0x706B 0x722A 0x7236 0x723B 0x7247 0x7259 \ + 0x725B 0x72AC 0x738B 0x4E19 0x4E16 0x4E15 0x4E14 0x4E18 \ + 0x4E3B 0x4E4D 0x4E4F 0x4E4E 0x4EE5 0x4ED8 0x4ED4 0x4ED5 \ + 0x4ED6 0x4ED7 0x4EE3 0x4EE4 0x4ED9 0x4EDE 0x5145 0x5144 \ + 0x5189 0x518A 0x51AC 0x51F9 0x51FA 0x51F8 0x520A 0x52A0 \ + 0x529F 0x5305 0x5306 0x5317 0x531D 0x4EDF 0x534A 0x5349 \ + 0x5361 0x5360 0x536F 0x536E 0x53BB 0x53EF 0x53E4 0x53F3 \ + 0x53EC 0x53EE 0x53E9 0x53E8 0x53FC 0x53F8 0x53F5 0x53EB \ + 0x53E6 0x53EA 0x53F2 0x53F1 0x53F0 0x53E5 0x53ED 0x53FB \ + 0x56DB 0x56DA 0x5916 0x592E 0x5931 0x5974 0x5976 0x5B55 \ + 0x5B83 0x5C3C 0x5DE8 0x5DE7 0x5DE6 0x5E02 0x5E03 0x5E73 \ + 0x5E7C 0x5F01 0x5F18 0x5F17 0x5FC5 0x620A 0x6253 0x6254 \ + 0x6252 0x6251 0x65A5 0x65E6 0x672E 0x672C 0x672A 0x672B \ + 0x672D 0x6B63 0x6BCD 0x6C11 0x6C10 0x6C38 0x6C41 0x6C40 \ + 0x6C3E 0x72AF 0x7384 0x7389 0x74DC 0x74E6 0x7518 0x751F \ + 0x7528 0x7529 0x7530 0x7531 0x7532 0x7533 0x758B 0x767D \ + 0x76AE 0x76BF 0x76EE 0x77DB 0x77E2 0x77F3 0x793A 0x79BE \ + 0x7A74 0x7ACB 0x4E1E 0x4E1F 0x4E52 0x4E53 0x4E69 0x4E99 \ + 0x4EA4 0x4EA6 0x4EA5 0x4EFF 0x4F09 0x4F19 0x4F0A 0x4F15 +04 0x4F0D 0x4F10 0x4F11 0x4F0F 0x4EF2 0x4EF6 0x4EFB 0x4EF0 \ + 0x4EF3 0x4EFD 0x4F01 0x4F0B 0x5149 0x5147 0x5146 0x5148 \ + 0x5168 0x5171 0x518D 0x51B0 0x5217 0x5211 0x5212 0x520E \ + 0x5216 0x52A3 0x5308 0x5321 0x5320 0x5370 0x5371 0x5409 \ + 0x540F 0x540C 0x540A 0x5410 0x5401 0x540B 0x5404 0x5411 \ + 0x540D 0x5408 0x5403 0x540E 0x5406 0x5412 0x56E0 0x56DE \ + 0x56DD 0x5733 0x5730 0x5728 0x572D 0x572C 0x572F 0x5729 \ + 0x5919 0x591A 0x5937 0x5938 0x5984 0x5978 0x5983 0x597D \ + 0x5979 0x5982 0x5981 0x5B57 0x5B58 0x5B87 0x5B88 0x5B85 \ + 0x5B89 0x5BFA 0x5C16 0x5C79 0x5DDE 0x5E06 0x5E76 0x5E74 \ + 0x5F0F 0x5F1B 0x5FD9 0x5FD6 0x620E 0x620C 0x620D 0x6210 \ + 0x6263 0x625B 0x6258 0x6536 0x65E9 0x65E8 0x65EC 0x65ED \ + 0x66F2 0x66F3 0x6709 0x673D 0x6734 0x6731 0x6735 0x6B21 \ + 0x6B64 0x6B7B 0x6C16 0x6C5D 0x6C57 0x6C59 0x6C5F 0x6C60 \ + 0x6C50 0x6C55 0x6C61 0x6C5B 0x6C4D 0x6C4E 0x7070 0x725F \ + 0x725D 0x767E 0x7AF9 0x7C73 0x7CF8 0x7F36 0x7F8A 0x7FBD \ + 0x8001 0x8003 0x800C 0x8012 0x8033 0x807F 0x8089 0x808B \ + 0x808C 0x81E3 0x81EA 0x81F3 0x81FC 0x820C 0x821B 0x821F \ + 0x826E 0x8272 0x827E 0x866B 0x8840 0x884C 0x8863 0x897F \ + 0x9621 0x4E32 0x4EA8 0x4F4D 0x4F4F 0x4F47 0x4F57 0x4F5E \ + 0x4F34 0x4F5B 0x4F55 0x4F30 0x4F50 0x4F51 0x4F3D 0x4F3A \ + 0x4F38 0x4F43 0x4F54 0x4F3C 0x4F46 0x4F63 0x4F5C 0x4F60 \ + 0x4F2F 0x4F4E 0x4F36 0x4F59 0x4F5D 0x4F48 0x4F5A 0x514C \ + 0x514B 0x514D 0x5175 0x51B6 0x51B7 0x5225 0x5224 0x5229 \ + 0x522A 0x5228 0x52AB 0x52A9 0x52AA 0x52AC 0x5323 0x5373 \ + 0x5375 0x541D 0x542D 0x541E 0x543E 0x5426 0x544E 0x5427 \ + 0x5446 0x5443 0x5433 0x5448 0x5442 0x541B 0x5429 0x544A \ + 0x5439 0x543B 0x5438 0x542E 0x5435 0x5436 0x5420 0x543C \ + 0x5440 0x5431 0x542B 0x541F 0x542C 0x56EA 0x56F0 0x56E4 \ + 0x56EB 0x574A 0x5751 0x5740 0x574D 0x5747 0x574E 0x573E \ + 0x5750 0x574F 0x573B 0x58EF 0x593E 0x599D 0x5992 0x59A8 \ + 0x599E 0x59A3 0x5999 0x5996 0x598D 0x59A4 0x5993 0x598A +05 0x59A5 0x5B5D 0x5B5C 0x5B5A 0x5B5B 0x5B8C 0x5B8B 0x5B8F \ + 0x5C2C 0x5C40 0x5C41 0x5C3F 0x5C3E 0x5C90 0x5C91 0x5C94 \ + 0x5C8C 0x5DEB 0x5E0C 0x5E8F 0x5E87 0x5E8A 0x5EF7 0x5F04 \ + 0x5F1F 0x5F64 0x5F62 0x5F77 0x5F79 0x5FD8 0x5FCC 0x5FD7 \ + 0x5FCD 0x5FF1 0x5FEB 0x5FF8 0x5FEA 0x6212 0x6211 0x6284 \ + 0x6297 0x6296 0x6280 0x6276 0x6289 0x626D 0x628A 0x627C \ + 0x627E 0x6279 0x6273 0x6292 0x626F 0x6298 0x626E 0x6295 \ + 0x6293 0x6291 0x6286 0x6539 0x653B 0x6538 0x65F1 0x66F4 \ + 0x675F 0x674E 0x674F 0x6750 0x6751 0x675C 0x6756 0x675E \ + 0x6749 0x6746 0x6760 0x6753 0x6757 0x6B65 0x6BCF 0x6C42 \ + 0x6C5E 0x6C99 0x6C81 0x6C88 0x6C89 0x6C85 0x6C9B 0x6C6A \ + 0x6C7A 0x6C90 0x6C70 0x6C8C 0x6C68 0x6C96 0x6C92 0x6C7D \ + 0x6C83 0x6C72 0x6C7E 0x6C74 0x6C86 0x6C76 0x6C8D 0x6C94 \ + 0x6C98 0x6C82 0x7076 0x707C 0x707D 0x7078 0x7262 0x7261 \ + 0x7260 0x72C4 0x72C2 0x7396 0x752C 0x752B 0x7537 0x7538 \ + 0x7682 0x76EF 0x77E3 0x79C1 0x79C0 0x79BF 0x7A76 0x7CFB \ + 0x7F55 0x8096 0x8093 0x809D 0x8098 0x809B 0x809A 0x80B2 \ + 0x826F 0x8292 0x828B 0x828D 0x898B 0x89D2 0x8A00 0x8C37 \ + 0x8C46 0x8C55 0x8C9D 0x8D64 0x8D70 0x8DB3 0x8EAB 0x8ECA \ + 0x8F9B 0x8FB0 0x8FC2 0x8FC6 0x8FC5 0x8FC4 0x5DE1 0x9091 \ + 0x90A2 0x90AA 0x90A6 0x90A3 0x9149 0x91C6 0x91CC 0x9632 \ + 0x962E 0x9631 0x962A 0x962C 0x4E26 0x4E56 0x4E73 0x4E8B \ + 0x4E9B 0x4E9E 0x4EAB 0x4EAC 0x4F6F 0x4F9D 0x4F8D 0x4F73 \ + 0x4F7F 0x4F6C 0x4F9B 0x4F8B 0x4F86 0x4F83 0x4F70 0x4F75 \ + 0x4F88 0x4F69 0x4F7B 0x4F96 0x4F7E 0x4F8F 0x4F91 0x4F7A \ + 0x5154 0x5152 0x5155 0x5169 0x5177 0x5176 0x5178 0x51BD \ + 0x51FD 0x523B 0x5238 0x5237 0x523A 0x5230 0x522E 0x5236 \ + 0x5241 0x52BE 0x52BB 0x5352 0x5354 0x5353 0x5351 0x5366 \ + 0x5377 0x5378 0x5379 0x53D6 0x53D4 0x53D7 0x5473 0x5475 \ + 0x5496 0x5478 0x5495 0x5480 0x547B 0x5477 0x5484 0x5492 \ + 0x5486 0x547C 0x5490 0x5471 0x5476 0x548C 0x549A 0x5462 \ + 0x5468 0x548B 0x547D 0x548E 0x56FA 0x5783 0x5777 0x576A +06 0x5769 0x5761 0x5766 0x5764 0x577C 0x591C 0x5949 0x5947 \ + 0x5948 0x5944 0x5954 0x59BE 0x59BB 0x59D4 0x59B9 0x59AE \ + 0x59D1 0x59C6 0x59D0 0x59CD 0x59CB 0x59D3 0x59CA 0x59AF \ + 0x59B3 0x59D2 0x59C5 0x5B5F 0x5B64 0x5B63 0x5B97 0x5B9A \ + 0x5B98 0x5B9C 0x5B99 0x5B9B 0x5C1A 0x5C48 0x5C45 0x5C46 \ + 0x5CB7 0x5CA1 0x5CB8 0x5CA9 0x5CAB 0x5CB1 0x5CB3 0x5E18 \ + 0x5E1A 0x5E16 0x5E15 0x5E1B 0x5E11 0x5E78 0x5E9A 0x5E97 \ + 0x5E9C 0x5E95 0x5E96 0x5EF6 0x5F26 0x5F27 0x5F29 0x5F80 \ + 0x5F81 0x5F7F 0x5F7C 0x5FDD 0x5FE0 0x5FFD 0x5FF5 0x5FFF \ + 0x600F 0x6014 0x602F 0x6035 0x6016 0x602A 0x6015 0x6021 \ + 0x6027 0x6029 0x602B 0x601B 0x6216 0x6215 0x623F 0x623E \ + 0x6240 0x627F 0x62C9 0x62CC 0x62C4 0x62BF 0x62C2 0x62B9 \ + 0x62D2 0x62DB 0x62AB 0x62D3 0x62D4 0x62CB 0x62C8 0x62A8 \ + 0x62BD 0x62BC 0x62D0 0x62D9 0x62C7 0x62CD 0x62B5 0x62DA \ + 0x62B1 0x62D8 0x62D6 0x62D7 0x62C6 0x62AC 0x62CE 0x653E \ + 0x65A7 0x65BC 0x65FA 0x6614 0x6613 0x660C 0x6606 0x6602 \ + 0x660E 0x6600 0x660F 0x6615 0x660A 0x6607 0x670D 0x670B \ + 0x676D 0x678B 0x6795 0x6771 0x679C 0x6773 0x6777 0x6787 \ + 0x679D 0x6797 0x676F 0x6770 0x677F 0x6789 0x677E 0x6790 \ + 0x6775 0x679A 0x6793 0x677C 0x676A 0x6772 0x6B23 0x6B66 \ + 0x6B67 0x6B7F 0x6C13 0x6C1B 0x6CE3 0x6CE8 0x6CF3 0x6CB1 \ + 0x6CCC 0x6CE5 0x6CB3 0x6CBD 0x6CBE 0x6CBC 0x6CE2 0x6CAB \ + 0x6CD5 0x6CD3 0x6CB8 0x6CC4 0x6CB9 0x6CC1 0x6CAE 0x6CD7 \ + 0x6CC5 0x6CF1 0x6CBF 0x6CBB 0x6CE1 0x6CDB 0x6CCA 0x6CAC \ + 0x6CEF 0x6CDC 0x6CD6 0x6CE0 0x7095 0x708E 0x7092 0x708A \ + 0x7099 0x722C 0x722D 0x7238 0x7248 0x7267 0x7269 0x72C0 \ + 0x72CE 0x72D9 0x72D7 0x72D0 0x73A9 0x73A8 0x739F 0x73AB \ + 0x73A5 0x753D 0x759D 0x7599 0x759A 0x7684 0x76C2 0x76F2 \ + 0x76F4 0x77E5 0x77FD 0x793E 0x7940 0x7941 0x79C9 0x79C8 \ + 0x7A7A 0x7A79 0x7AFA 0x7CFE 0x7F54 0x7F8C 0x7F8B 0x8005 \ + 0x80BA 0x80A5 0x80A2 0x80B1 0x80A1 0x80AB 0x80A9 0x80B4 \ + 0x80AA 0x80AF 0x81E5 0x81FE 0x820D 0x82B3 0x829D 0x8299 +07 0x82AD 0x82BD 0x829F 0x82B9 0x82B1 0x82AC 0x82A5 0x82AF \ + 0x82B8 0x82A3 0x82B0 0x82BE 0x82B7 0x864E 0x8671 0x521D \ + 0x8868 0x8ECB 0x8FCE 0x8FD4 0x8FD1 0x90B5 0x90B8 0x90B1 \ + 0x90B6 0x91C7 0x91D1 0x9577 0x9580 0x961C 0x9640 0x963F \ + 0x963B 0x9644 0x9642 0x96B9 0x96E8 0x9752 0x975E 0x4E9F \ + 0x4EAD 0x4EAE 0x4FE1 0x4FB5 0x4FAF 0x4FBF 0x4FE0 0x4FD1 \ + 0x4FCF 0x4FDD 0x4FC3 0x4FB6 0x4FD8 0x4FDF 0x4FCA 0x4FD7 \ + 0x4FAE 0x4FD0 0x4FC4 0x4FC2 0x4FDA 0x4FCE 0x4FDE 0x4FB7 \ + 0x5157 0x5192 0x5191 0x51A0 0x524E 0x5243 0x524A 0x524D \ + 0x524C 0x524B 0x5247 0x52C7 0x52C9 0x52C3 0x52C1 0x530D \ + 0x5357 0x537B 0x539A 0x53DB 0x54AC 0x54C0 0x54A8 0x54CE \ + 0x54C9 0x54B8 0x54A6 0x54B3 0x54C7 0x54C2 0x54BD 0x54AA \ + 0x54C1 0x54C4 0x54C8 0x54AF 0x54AB 0x54B1 0x54BB 0x54A9 \ + 0x54A7 0x54BF 0x56FF 0x5782 0x578B 0x57A0 0x57A3 0x57A2 \ + 0x57CE 0x57AE 0x5793 0x5955 0x5951 0x594F 0x594E 0x5950 \ + 0x59DC 0x59D8 0x59FF 0x59E3 0x59E8 0x5A03 0x59E5 0x59EA \ + 0x59DA 0x59E6 0x5A01 0x59FB 0x5B69 0x5BA3 0x5BA6 0x5BA4 \ + 0x5BA2 0x5BA5 0x5C01 0x5C4E 0x5C4F 0x5C4D 0x5C4B 0x5CD9 \ + 0x5CD2 0x5DF7 0x5E1D 0x5E25 0x5E1F 0x5E7D 0x5EA0 0x5EA6 \ + 0x5EFA 0x5F08 0x5F2D 0x5F65 0x5F88 0x5F85 0x5F8A 0x5F8B \ + 0x5F87 0x5F8C 0x5F89 0x6012 0x601D 0x6020 0x6025 0x600E \ + 0x6028 0x604D 0x6070 0x6068 0x6062 0x6046 0x6043 0x606C \ + 0x606B 0x606A 0x6064 0x6241 0x62DC 0x6316 0x6309 0x62FC \ + 0x62ED 0x6301 0x62EE 0x62FD 0x6307 0x62F1 0x62F7 0x62EF \ + 0x62EC 0x62FE 0x62F4 0x6311 0x6302 0x653F 0x6545 0x65AB \ + 0x65BD 0x65E2 0x6625 0x662D 0x6620 0x6627 0x662F 0x661F \ + 0x6628 0x6631 0x6624 0x66F7 0x67FF 0x67D3 0x67F1 0x67D4 \ + 0x67D0 0x67EC 0x67B6 0x67AF 0x67F5 0x67E9 0x67EF 0x67C4 \ + 0x67D1 0x67B4 0x67DA 0x67E5 0x67B8 0x67CF 0x67DE 0x67F3 \ + 0x67B0 0x67D9 0x67E2 0x67DD 0x67D2 0x6B6A 0x6B83 0x6B86 \ + 0x6BB5 0x6BD2 0x6BD7 0x6C1F 0x6CC9 0x6D0B 0x6D32 0x6D2A \ + 0x6D41 0x6D25 0x6D0C 0x6D31 0x6D1E 0x6D17 0x6D3B 0x6D3D +08 0x6D3E 0x6D36 0x6D1B 0x6CF5 0x6D39 0x6D27 0x6D38 0x6D29 \ + 0x6D2E 0x6D35 0x6D0E 0x6D2B 0x70AB 0x70BA 0x70B3 0x70AC \ + 0x70AF 0x70AD 0x70B8 0x70AE 0x70A4 0x7230 0x7272 0x726F \ + 0x7274 0x72E9 0x72E0 0x72E1 0x73B7 0x73CA 0x73BB 0x73B2 \ + 0x73CD 0x73C0 0x73B3 0x751A 0x752D 0x754F 0x754C 0x754E \ + 0x754B 0x75AB 0x75A4 0x75A5 0x75A2 0x75A3 0x7678 0x7686 \ + 0x7687 0x7688 0x76C8 0x76C6 0x76C3 0x76C5 0x7701 0x76F9 \ + 0x76F8 0x7709 0x770B 0x76FE 0x76FC 0x7707 0x77DC 0x7802 \ + 0x7814 0x780C 0x780D 0x7946 0x7949 0x7948 0x7947 0x79B9 \ + 0x79BA 0x79D1 0x79D2 0x79CB 0x7A7F 0x7A81 0x7AFF 0x7AFD \ + 0x7C7D 0x7D02 0x7D05 0x7D00 0x7D09 0x7D07 0x7D04 0x7D06 \ + 0x7F38 0x7F8E 0x7FBF 0x8004 0x8010 0x800D 0x8011 0x8036 \ + 0x80D6 0x80E5 0x80DA 0x80C3 0x80C4 0x80CC 0x80E1 0x80DB \ + 0x80CE 0x80DE 0x80E4 0x80DD 0x81F4 0x8222 0x82E7 0x8303 \ + 0x8305 0x82E3 0x82DB 0x82E6 0x8304 0x82E5 0x8302 0x8309 \ + 0x82D2 0x82D7 0x82F1 0x8301 0x82DC 0x82D4 0x82D1 0x82DE \ + 0x82D3 0x82DF 0x82EF 0x8306 0x8650 0x8679 0x867B 0x867A \ + 0x884D 0x886B 0x8981 0x89D4 0x8A08 0x8A02 0x8A03 0x8C9E \ + 0x8CA0 0x8D74 0x8D73 0x8DB4 0x8ECD 0x8ECC 0x8FF0 0x8FE6 \ + 0x8FE2 0x8FEA 0x8FE5 0x8FED 0x8FEB 0x8FE4 0x8FE8 0x90CA \ + 0x90CE 0x90C1 0x90C3 0x914B 0x914A 0x91CD 0x9582 0x9650 \ + 0x964B 0x964C 0x964D 0x9762 0x9769 0x97CB 0x97ED 0x97F3 \ + 0x9801 0x98A8 0x98DB 0x98DF 0x9996 0x9999 0x4E58 0x4EB3 \ + 0x500C 0x500D 0x5023 0x4FEF 0x5026 0x5025 0x4FF8 0x5029 \ + 0x5016 0x5006 0x503C 0x501F 0x501A 0x5012 0x5011 0x4FFA \ + 0x5000 0x5014 0x5028 0x4FF1 0x5021 0x500B 0x5019 0x5018 \ + 0x4FF3 0x4FEE 0x502D 0x502A 0x4FFE 0x502B 0x5009 0x517C \ + 0x51A4 0x51A5 0x51A2 0x51CD 0x51CC 0x51C6 0x51CB 0x5256 \ + 0x525C 0x5254 0x525B 0x525D 0x532A 0x537F 0x539F 0x539D \ + 0x53DF 0x54E8 0x5510 0x5501 0x5537 0x54FC 0x54E5 0x54F2 \ + 0x5506 0x54FA 0x5514 0x54E9 0x54ED 0x54E1 0x5509 0x54EE \ + 0x54EA 0x54E6 0x5527 0x5507 0x54FD 0x550F 0x5703 0x5704 +09 0x57C2 0x57D4 0x57CB 0x57C3 0x5809 0x590F 0x5957 0x5958 \ + 0x595A 0x5A11 0x5A18 0x5A1C 0x5A1F 0x5A1B 0x5A13 0x59EC \ + 0x5A20 0x5A23 0x5A29 0x5A25 0x5A0C 0x5A09 0x5B6B 0x5C58 \ + 0x5BB0 0x5BB3 0x5BB6 0x5BB4 0x5BAE 0x5BB5 0x5BB9 0x5BB8 \ + 0x5C04 0x5C51 0x5C55 0x5C50 0x5CED 0x5CFD 0x5CFB 0x5CEA \ + 0x5CE8 0x5CF0 0x5CF6 0x5D01 0x5CF4 0x5DEE 0x5E2D 0x5E2B \ + 0x5EAB 0x5EAD 0x5EA7 0x5F31 0x5F92 0x5F91 0x5F90 0x6059 \ + 0x6063 0x6065 0x6050 0x6055 0x606D 0x6069 0x606F 0x6084 \ + 0x609F 0x609A 0x608D 0x6094 0x608C 0x6085 0x6096 0x6247 \ + 0x62F3 0x6308 0x62FF 0x634E 0x633E 0x632F 0x6355 0x6342 \ + 0x6346 0x634F 0x6349 0x633A 0x6350 0x633D 0x632A 0x632B \ + 0x6328 0x634D 0x634C 0x6548 0x6549 0x6599 0x65C1 0x65C5 \ + 0x6642 0x6649 0x664F 0x6643 0x6652 0x664C 0x6645 0x6641 \ + 0x66F8 0x6714 0x6715 0x6717 0x6821 0x6838 0x6848 0x6846 \ + 0x6853 0x6839 0x6842 0x6854 0x6829 0x68B3 0x6817 0x684C \ + 0x6851 0x683D 0x67F4 0x6850 0x6840 0x683C 0x6843 0x682A \ + 0x6845 0x6813 0x6818 0x6841 0x6B8A 0x6B89 0x6BB7 0x6C23 \ + 0x6C27 0x6C28 0x6C26 0x6C24 0x6CF0 0x6D6A 0x6D95 0x6D88 \ + 0x6D87 0x6D66 0x6D78 0x6D77 0x6D59 0x6D93 0x6D6C 0x6D89 \ + 0x6D6E 0x6D5A 0x6D74 0x6D69 0x6D8C 0x6D8A 0x6D79 0x6D85 \ + 0x6D65 0x6D94 0x70CA 0x70D8 0x70E4 0x70D9 0x70C8 0x70CF \ + 0x7239 0x7279 0x72FC 0x72F9 0x72FD 0x72F8 0x72F7 0x7386 \ + 0x73ED 0x7409 0x73EE 0x73E0 0x73EA 0x73DE 0x7554 0x755D \ + 0x755C 0x755A 0x7559 0x75BE 0x75C5 0x75C7 0x75B2 0x75B3 \ + 0x75BD 0x75BC 0x75B9 0x75C2 0x75B8 0x768B 0x76B0 0x76CA \ + 0x76CD 0x76CE 0x7729 0x771F 0x7720 0x7728 0x77E9 0x7830 \ + 0x7827 0x7838 0x781D 0x7834 0x7837 0x7825 0x782D 0x7820 \ + 0x781F 0x7832 0x7955 0x7950 0x7960 0x795F 0x7956 0x795E \ + 0x795D 0x7957 0x795A 0x79E4 0x79E3 0x79E7 0x79DF 0x79E6 \ + 0x79E9 0x79D8 0x7A84 0x7A88 0x7AD9 0x7B06 0x7B11 0x7C89 \ + 0x7D21 0x7D17 0x7D0B 0x7D0A 0x7D20 0x7D22 0x7D14 0x7D10 \ + 0x7D15 0x7D1A 0x7D1C 0x7D0D 0x7D19 0x7D1B 0x7F3A 0x7F5F +10 0x7F94 0x7FC5 0x7FC1 0x8006 0x8018 0x8015 0x8019 0x8017 \ + 0x803D 0x803F 0x80F1 0x8102 0x80F0 0x8105 0x80ED 0x80F4 \ + 0x8106 0x80F8 0x80F3 0x8108 0x80FD 0x810A 0x80FC 0x80EF \ + 0x81ED 0x81EC 0x8200 0x8210 0x822A 0x822B 0x8228 0x822C \ + 0x82BB 0x832B 0x8352 0x8354 0x834A 0x8338 0x8350 0x8349 \ + 0x8335 0x8334 0x834F 0x8332 0x8339 0x8336 0x8317 0x8340 \ + 0x8331 0x8328 0x8343 0x8654 0x868A 0x86AA 0x8693 0x86A4 \ + 0x86A9 0x868C 0x86A3 0x869C 0x8870 0x8877 0x8881 0x8882 \ + 0x887D 0x8879 0x8A18 0x8A10 0x8A0E 0x8A0C 0x8A15 0x8A0A \ + 0x8A17 0x8A13 0x8A16 0x8A0F 0x8A11 0x8C48 0x8C7A 0x8C79 \ + 0x8CA1 0x8CA2 0x8D77 0x8EAC 0x8ED2 0x8ED4 0x8ECF 0x8FB1 \ + 0x9001 0x9006 0x8FF7 0x9000 0x8FFA 0x8FF4 0x9003 0x8FFD \ + 0x9005 0x8FF8 0x9095 0x90E1 0x90DD 0x90E2 0x9152 0x914D \ + 0x914C 0x91D8 0x91DD 0x91D7 0x91DC 0x91D9 0x9583 0x9662 \ + 0x9663 0x9661 0x965B 0x965D 0x9664 0x9658 0x965E 0x96BB \ + 0x98E2 0x99AC 0x9AA8 0x9AD8 0x9B25 0x9B32 0x9B3C 0x4E7E \ + 0x507A 0x507D 0x505C 0x5047 0x5043 0x504C 0x505A 0x5049 \ + 0x5065 0x5076 0x504E 0x5055 0x5075 0x5074 0x5077 0x504F \ + 0x500F 0x506F 0x506D 0x515C 0x5195 0x51F0 0x526A 0x526F \ + 0x52D2 0x52D9 0x52D8 0x52D5 0x5310 0x530F 0x5319 0x533F \ + 0x5340 0x533E 0x53C3 0x66FC 0x5546 0x556A 0x5566 0x5544 \ + 0x555E 0x5561 0x5543 0x554A 0x5531 0x5556 0x554F 0x5555 \ + 0x552F 0x5564 0x5538 0x552E 0x555C 0x552C 0x5563 0x5533 \ + 0x5541 0x5557 0x5708 0x570B 0x5709 0x57DF 0x5805 0x580A \ + 0x5806 0x57E0 0x57E4 0x57FA 0x5802 0x5835 0x57F7 0x57F9 \ + 0x5920 0x5962 0x5A36 0x5A41 0x5A49 0x5A66 0x5A6A 0x5A40 \ + 0x5A3C 0x5A62 0x5A5A 0x5A46 0x5A4A 0x5B70 0x5BC7 0x5BC5 \ + 0x5BC4 0x5BC2 0x5BBF 0x5BC6 0x5C09 0x5C08 0x5C07 0x5C60 \ + 0x5C5C 0x5C5D 0x5D07 0x5D06 0x5D0E 0x5D1B 0x5D16 0x5D22 \ + 0x5D11 0x5D29 0x5D14 0x5D19 0x5D24 0x5D27 0x5D17 0x5DE2 \ + 0x5E38 0x5E36 0x5E33 0x5E37 0x5EB7 0x5EB8 0x5EB6 0x5EB5 \ + 0x5EBE 0x5F35 0x5F37 0x5F57 0x5F6C 0x5F69 0x5F6B 0x5F97 +11 0x5F99 0x5F9E 0x5F98 0x5FA1 0x5FA0 0x5F9C 0x607F 0x60A3 \ + 0x6089 0x60A0 0x60A8 0x60CB 0x60B4 0x60E6 0x60BD 0x60C5 \ + 0x60BB 0x60B5 0x60DC 0x60BC 0x60D8 0x60D5 0x60C6 0x60DF \ + 0x60B8 0x60DA 0x60C7 0x621A 0x621B 0x6248 0x63A0 0x63A7 \ + 0x6372 0x6396 0x63A2 0x63A5 0x6377 0x6367 0x6398 0x63AA \ + 0x6371 0x63A9 0x6389 0x6383 0x639B 0x636B 0x63A8 0x6384 \ + 0x6388 0x6399 0x63A1 0x63AC 0x6392 0x638F 0x6380 0x637B \ + 0x6369 0x6368 0x637A 0x655D 0x6556 0x6551 0x6559 0x6557 \ + 0x555F 0x654F 0x6558 0x6555 0x6554 0x659C 0x659B 0x65AC \ + 0x65CF 0x65CB 0x65CC 0x65CE 0x665D 0x665A 0x6664 0x6668 \ + 0x6666 0x665E 0x66F9 0x52D7 0x671B 0x6881 0x68AF 0x68A2 \ + 0x6893 0x68B5 0x687F 0x6876 0x68B1 0x68A7 0x6897 0x68B0 \ + 0x6883 0x68C4 0x68AD 0x6886 0x6885 0x6894 0x689D 0x68A8 \ + 0x689F 0x68A1 0x6882 0x6B32 0x6BBA 0x6BEB 0x6BEC 0x6C2B \ + 0x6D8E 0x6DBC 0x6DF3 0x6DD9 0x6DB2 0x6DE1 0x6DCC 0x6DE4 \ + 0x6DFB 0x6DFA 0x6E05 0x6DC7 0x6DCB 0x6DAF 0x6DD1 0x6DAE \ + 0x6DDE 0x6DF9 0x6DB8 0x6DF7 0x6DF5 0x6DC5 0x6DD2 0x6E1A \ + 0x6DB5 0x6DDA 0x6DEB 0x6DD8 0x6DEA 0x6DF1 0x6DEE 0x6DE8 \ + 0x6DC6 0x6DC4 0x6DAA 0x6DEC 0x6DBF 0x6DE6 0x70F9 0x7109 \ + 0x710A 0x70FD 0x70EF 0x723D 0x727D 0x7281 0x731C 0x731B \ + 0x7316 0x7313 0x7319 0x7387 0x7405 0x740A 0x7403 0x7406 \ + 0x73FE 0x740D 0x74E0 0x74F6 0x74F7 0x751C 0x7522 0x7565 \ + 0x7566 0x7562 0x7570 0x758F 0x75D4 0x75D5 0x75B5 0x75CA \ + 0x75CD 0x768E 0x76D4 0x76D2 0x76DB 0x7737 0x773E 0x773C \ + 0x7736 0x7738 0x773A 0x786B 0x7843 0x784E 0x7965 0x7968 \ + 0x796D 0x79FB 0x7A92 0x7A95 0x7B20 0x7B28 0x7B1B 0x7B2C \ + 0x7B26 0x7B19 0x7B1E 0x7B2E 0x7C92 0x7C97 0x7C95 0x7D46 \ + 0x7D43 0x7D71 0x7D2E 0x7D39 0x7D3C 0x7D40 0x7D30 0x7D33 \ + 0x7D44 0x7D2F 0x7D42 0x7D32 0x7D31 0x7F3D 0x7F9E 0x7F9A \ + 0x7FCC 0x7FCE 0x7FD2 0x801C 0x804A 0x8046 0x812F 0x8116 \ + 0x8123 0x812B 0x8129 0x8130 0x8124 0x8202 0x8235 0x8237 \ + 0x8236 0x8239 0x838E 0x839E 0x8398 0x8378 0x83A2 0x8396 +12 0x83BD 0x83AB 0x8392 0x838A 0x8393 0x8389 0x83A0 0x8377 \ + 0x837B 0x837C 0x8386 0x83A7 0x8655 0x5F6A 0x86C7 0x86C0 \ + 0x86B6 0x86C4 0x86B5 0x86C6 0x86CB 0x86B1 0x86AF 0x86C9 \ + 0x8853 0x889E 0x8888 0x88AB 0x8892 0x8896 0x888D 0x888B \ + 0x8993 0x898F 0x8A2A 0x8A1D 0x8A23 0x8A25 0x8A31 0x8A2D \ + 0x8A1F 0x8A1B 0x8A22 0x8C49 0x8C5A 0x8CA9 0x8CAC 0x8CAB \ + 0x8CA8 0x8CAA 0x8CA7 0x8D67 0x8D66 0x8DBE 0x8DBA 0x8EDB \ + 0x8EDF 0x9019 0x900D 0x901A 0x9017 0x9023 0x901F 0x901D \ + 0x9010 0x9015 0x901E 0x9020 0x900F 0x9022 0x9016 0x901B \ + 0x9014 0x90E8 0x90ED 0x90FD 0x9157 0x91CE 0x91F5 0x91E6 \ + 0x91E3 0x91E7 0x91ED 0x91E9 0x9589 0x966A 0x9675 0x9673 \ + 0x9678 0x9670 0x9674 0x9676 0x9677 0x966C 0x96C0 0x96EA \ + 0x96E9 0x7AE0 0x7ADF 0x9802 0x9803 0x9B5A 0x9CE5 0x9E75 \ + 0x9E7F 0x9EA5 0x9EBB 0x50A2 0x508D 0x5085 0x5099 0x5091 \ + 0x5080 0x5096 0x5098 0x509A 0x6700 0x51F1 0x5272 0x5274 \ + 0x5275 0x5269 0x52DE 0x52DD 0x52DB 0x535A 0x53A5 0x557B \ + 0x5580 0x55A7 0x557C 0x558A 0x559D 0x5598 0x5582 0x559C \ + 0x55AA 0x5594 0x5587 0x558B 0x5583 0x55B3 0x55AE 0x559F \ + 0x553E 0x55B2 0x559A 0x55BB 0x55AC 0x55B1 0x557E 0x5589 \ + 0x55AB 0x5599 0x570D 0x582F 0x582A 0x5834 0x5824 0x5830 \ + 0x5831 0x5821 0x581D 0x5820 0x58F9 0x58FA 0x5960 0x5A77 \ + 0x5A9A 0x5A7F 0x5A92 0x5A9B 0x5AA7 0x5B73 0x5B71 0x5BD2 \ + 0x5BCC 0x5BD3 0x5BD0 0x5C0A 0x5C0B 0x5C31 0x5D4C 0x5D50 \ + 0x5D34 0x5D47 0x5DFD 0x5E45 0x5E3D 0x5E40 0x5E43 0x5E7E \ + 0x5ECA 0x5EC1 0x5EC2 0x5EC4 0x5F3C 0x5F6D 0x5FA9 0x5FAA \ + 0x5FA8 0x60D1 0x60E1 0x60B2 0x60B6 0x60E0 0x611C 0x6123 \ + 0x60FA 0x6115 0x60F0 0x60FB 0x60F4 0x6168 0x60F1 0x610E \ + 0x60F6 0x6109 0x6100 0x6112 0x621F 0x6249 0x63A3 0x638C \ + 0x63CF 0x63C0 0x63E9 0x63C9 0x63C6 0x63CD 0x63D2 0x63E3 \ + 0x63D0 0x63E1 0x63D6 0x63ED 0x63EE 0x6376 0x63F4 0x63EA \ + 0x63DB 0x6452 0x63DA 0x63F9 0x655E 0x6566 0x6562 0x6563 \ + 0x6591 0x6590 0x65AF 0x666E 0x6670 0x6674 0x6676 0x666F +13 0x6691 0x667A 0x667E 0x6677 0x66FE 0x66FF 0x671F 0x671D \ + 0x68FA 0x68D5 0x68E0 0x68D8 0x68D7 0x6905 0x68DF 0x68F5 \ + 0x68EE 0x68E7 0x68F9 0x68D2 0x68F2 0x68E3 0x68CB 0x68CD \ + 0x690D 0x6912 0x690E 0x68C9 0x68DA 0x696E 0x68FB 0x6B3E \ + 0x6B3A 0x6B3D 0x6B98 0x6B96 0x6BBC 0x6BEF 0x6C2E 0x6C2F \ + 0x6C2C 0x6E2F 0x6E38 0x6E54 0x6E21 0x6E32 0x6E67 0x6E4A \ + 0x6E20 0x6E25 0x6E23 0x6E1B 0x6E5B 0x6E58 0x6E24 0x6E56 \ + 0x6E6E 0x6E2D 0x6E26 0x6E6F 0x6E34 0x6E4D 0x6E3A 0x6E2C \ + 0x6E43 0x6E1D 0x6E3E 0x6ECB 0x6E89 0x6E19 0x6E4E 0x6E63 \ + 0x6E44 0x6E72 0x6E69 0x6E5F 0x7119 0x711A 0x7126 0x7130 \ + 0x7121 0x7136 0x716E 0x711C 0x724C 0x7284 0x7280 0x7336 \ + 0x7325 0x7334 0x7329 0x743A 0x742A 0x7433 0x7422 0x7425 \ + 0x7435 0x7436 0x7434 0x742F 0x741B 0x7426 0x7428 0x7525 \ + 0x7526 0x756B 0x756A 0x75E2 0x75DB 0x75E3 0x75D9 0x75D8 \ + 0x75DE 0x75E0 0x767B 0x767C 0x7696 0x7693 0x76B4 0x76DC \ + 0x774F 0x77ED 0x785D 0x786C 0x786F 0x7A0D 0x7A08 0x7A0B \ + 0x7A05 0x7A00 0x7A98 0x7A97 0x7A96 0x7AE5 0x7AE3 0x7B49 \ + 0x7B56 0x7B46 0x7B50 0x7B52 0x7B54 0x7B4D 0x7B4B 0x7B4F \ + 0x7B51 0x7C9F 0x7CA5 0x7D5E 0x7D50 0x7D68 0x7D55 0x7D2B \ + 0x7D6E 0x7D72 0x7D61 0x7D66 0x7D62 0x7D70 0x7D73 0x5584 \ + 0x7FD4 0x7FD5 0x800B 0x8052 0x8085 0x8155 0x8154 0x814B \ + 0x8151 0x814E 0x8139 0x8146 0x813E 0x814C 0x8153 0x8174 \ + 0x8212 0x821C 0x83E9 0x8403 0x83F8 0x840D 0x83E0 0x83C5 \ + 0x840B 0x83C1 0x83EF 0x83F1 0x83F4 0x8457 0x840A 0x83F0 \ + 0x840C 0x83CC 0x83FD 0x83F2 0x83CA 0x8438 0x840E 0x8404 \ + 0x83DC 0x8407 0x83D4 0x83DF 0x865B 0x86DF 0x86D9 0x86ED \ + 0x86D4 0x86DB 0x86E4 0x86D0 0x86DE 0x8857 0x88C1 0x88C2 \ + 0x88B1 0x8983 0x8996 0x8A3B 0x8A60 0x8A55 0x8A5E 0x8A3C \ + 0x8A41 0x8A54 0x8A5B 0x8A50 0x8A46 0x8A34 0x8A3A 0x8A36 \ + 0x8A56 0x8C61 0x8C82 0x8CAF 0x8CBC 0x8CB3 0x8CBD 0x8CC1 \ + 0x8CBB 0x8CC0 0x8CB4 0x8CB7 0x8CB6 0x8CBF 0x8CB8 0x8D8A \ + 0x8D85 0x8D81 0x8DCE 0x8DDD 0x8DCB 0x8DDA 0x8DD1 0x8DCC +14 0x8DDB 0x8DC6 0x8EFB 0x8EF8 0x8EFC 0x8F9C 0x902E 0x9035 \ + 0x9031 0x9038 0x9032 0x9036 0x9102 0x90F5 0x9109 0x90FE \ + 0x9163 0x9165 0x91CF 0x9214 0x9215 0x9223 0x9209 0x921E \ + 0x920D 0x9210 0x9207 0x9211 0x9594 0x958F 0x958B 0x9591 \ + 0x9593 0x9592 0x958E 0x968A 0x968E 0x968B 0x967D 0x9685 \ + 0x9686 0x968D 0x9672 0x9684 0x96C1 0x96C5 0x96C4 0x96C6 \ + 0x96C7 0x96EF 0x96F2 0x97CC 0x9805 0x9806 0x9808 0x98E7 \ + 0x98EA 0x98EF 0x98E9 0x98F2 0x98ED 0x99AE 0x99AD 0x9EC3 \ + 0x9ECD 0x9ED1 0x4E82 0x50AD 0x50B5 0x50B2 0x50B3 0x50C5 \ + 0x50BE 0x50AC 0x50B7 0x50BB 0x50AF 0x50C7 0x527F 0x5277 \ + 0x527D 0x52DF 0x52E6 0x52E4 0x52E2 0x52E3 0x532F 0x55DF \ + 0x55E8 0x55D3 0x55E6 0x55CE 0x55DC 0x55C7 0x55D1 0x55E3 \ + 0x55E4 0x55EF 0x55DA 0x55E1 0x55C5 0x55C6 0x55E5 0x55C9 \ + 0x5712 0x5713 0x585E 0x5851 0x5858 0x5857 0x585A 0x5854 \ + 0x586B 0x584C 0x586D 0x584A 0x5862 0x5852 0x584B 0x5967 \ + 0x5AC1 0x5AC9 0x5ACC 0x5ABE 0x5ABD 0x5ABC 0x5AB3 0x5AC2 \ + 0x5AB2 0x5D69 0x5D6F 0x5E4C 0x5E79 0x5EC9 0x5EC8 0x5F12 \ + 0x5F59 0x5FAC 0x5FAE 0x611A 0x610F 0x6148 0x611F 0x60F3 \ + 0x611B 0x60F9 0x6101 0x6108 0x614E 0x614C 0x6144 0x614D \ + 0x613E 0x6134 0x6127 0x610D 0x6106 0x6137 0x6221 0x6222 \ + 0x6413 0x643E 0x641E 0x642A 0x642D 0x643D 0x642C 0x640F \ + 0x641C 0x6414 0x640D 0x6436 0x6416 0x6417 0x6406 0x656C \ + 0x659F 0x65B0 0x6697 0x6689 0x6687 0x6688 0x6696 0x6684 \ + 0x6698 0x668D 0x6703 0x6994 0x696D 0x695A 0x6977 0x6960 \ + 0x6954 0x6975 0x6930 0x6982 0x694A 0x6968 0x696B 0x695E \ + 0x6953 0x6979 0x6986 0x695D 0x6963 0x695B 0x6B47 0x6B72 \ + 0x6BC0 0x6BBF 0x6BD3 0x6BFD 0x6EA2 0x6EAF 0x6ED3 0x6EB6 \ + 0x6EC2 0x6E90 0x6E9D 0x6EC7 0x6EC5 0x6EA5 0x6E98 0x6EBC \ + 0x6EBA 0x6EAB 0x6ED1 0x6E96 0x6E9C 0x6EC4 0x6ED4 0x6EAA \ + 0x6EA7 0x6EB4 0x714E 0x7159 0x7169 0x7164 0x7149 0x7167 \ + 0x715C 0x716C 0x7166 0x714C 0x7165 0x715E 0x7146 0x7168 \ + 0x7156 0x723A 0x7252 0x7337 0x7345 0x733F 0x733E 0x746F +15 0x745A 0x7455 0x745F 0x745E 0x7441 0x743F 0x7459 0x745B \ + 0x745C 0x7576 0x7578 0x7600 0x75F0 0x7601 0x75F2 0x75F1 \ + 0x75FA 0x75FF 0x75F4 0x75F3 0x76DE 0x76DF 0x775B 0x776B \ + 0x7766 0x775E 0x7763 0x7779 0x776A 0x776C 0x775C 0x7765 \ + 0x7768 0x7762 0x77EE 0x788E 0x78B0 0x7897 0x7898 0x788C \ + 0x7889 0x787C 0x7891 0x7893 0x787F 0x797A 0x797F 0x7981 \ + 0x842C 0x79BD 0x7A1C 0x7A1A 0x7A20 0x7A14 0x7A1F 0x7A1E \ + 0x7A9F 0x7AA0 0x7B77 0x7BC0 0x7B60 0x7B6E 0x7B67 0x7CB1 \ + 0x7CB3 0x7CB5 0x7D93 0x7D79 0x7D91 0x7D81 0x7D8F 0x7D5B \ + 0x7F6E 0x7F69 0x7F6A 0x7F72 0x7FA9 0x7FA8 0x7FA4 0x8056 \ + 0x8058 0x8086 0x8084 0x8171 0x8170 0x8178 0x8165 0x816E \ + 0x8173 0x816B 0x8179 0x817A 0x8166 0x8205 0x8247 0x8482 \ + 0x8477 0x843D 0x8431 0x8475 0x8466 0x846B 0x8449 0x846C \ + 0x845B 0x843C 0x8435 0x8461 0x8463 0x8469 0x846D 0x8446 \ + 0x865E 0x865C 0x865F 0x86F9 0x8713 0x8708 0x8707 0x8700 \ + 0x86FE 0x86FB 0x8702 0x8703 0x8706 0x870A 0x8859 0x88DF \ + 0x88D4 0x88D9 0x88DC 0x88D8 0x88DD 0x88E1 0x88CA 0x88D5 \ + 0x88D2 0x899C 0x89E3 0x8A6B 0x8A72 0x8A73 0x8A66 0x8A69 \ + 0x8A70 0x8A87 0x8A7C 0x8A63 0x8AA0 0x8A71 0x8A85 0x8A6D \ + 0x8A62 0x8A6E 0x8A6C 0x8A79 0x8A7B 0x8A3E 0x8A68 0x8C62 \ + 0x8C8A 0x8C89 0x8CCA 0x8CC7 0x8CC8 0x8CC4 0x8CB2 0x8CC3 \ + 0x8CC2 0x8CC5 0x8DE1 0x8DDF 0x8DE8 0x8DEF 0x8DF3 0x8DFA \ + 0x8DEA 0x8DE4 0x8DE6 0x8EB2 0x8F03 0x8F09 0x8EFE 0x8F0A \ + 0x8F9F 0x8FB2 0x904B 0x904A 0x9053 0x9042 0x9054 0x903C \ + 0x9055 0x9050 0x9047 0x904F 0x904E 0x904D 0x9051 0x903E \ + 0x9041 0x9112 0x9117 0x916C 0x916A 0x9169 0x91C9 0x9237 \ + 0x9257 0x9238 0x923D 0x9240 0x923E 0x925B 0x924B 0x9264 \ + 0x9251 0x9234 0x9249 0x924D 0x9245 0x9239 0x923F 0x925A \ + 0x9598 0x9698 0x9694 0x9695 0x96CD 0x96CB 0x96C9 0x96CA \ + 0x96F7 0x96FB 0x96F9 0x96F6 0x9756 0x9774 0x9776 0x9810 \ + 0x9811 0x9813 0x980A 0x9812 0x980C 0x98FC 0x98F4 0x98FD \ + 0x98FE 0x99B3 0x99B1 0x99B4 0x9AE1 0x9CE9 0x9E82 0x9F0E +16 0x9F13 0x9F20 0x50E7 0x50EE 0x50E5 0x50D6 0x50ED 0x50DA \ + 0x50D5 0x50CF 0x50D1 0x50F1 0x50CE 0x50E9 0x5162 0x51F3 \ + 0x5283 0x5282 0x5331 0x53AD 0x55FE 0x5600 0x561B 0x5617 \ + 0x55FD 0x5614 0x5606 0x5609 0x560D 0x560E 0x55F7 0x5616 \ + 0x561F 0x5608 0x5610 0x55F6 0x5718 0x5716 0x5875 0x587E \ + 0x5883 0x5893 0x588A 0x5879 0x5885 0x587D 0x58FD 0x5925 \ + 0x5922 0x5924 0x596A 0x5969 0x5AE1 0x5AE6 0x5AE9 0x5AD7 \ + 0x5AD6 0x5AD8 0x5AE3 0x5B75 0x5BDE 0x5BE7 0x5BE1 0x5BE5 \ + 0x5BE6 0x5BE8 0x5BE2 0x5BE4 0x5BDF 0x5C0D 0x5C62 0x5D84 \ + 0x5D87 0x5E5B 0x5E63 0x5E55 0x5E57 0x5E54 0x5ED3 0x5ED6 \ + 0x5F0A 0x5F46 0x5F70 0x5FB9 0x6147 0x613F 0x614B 0x6177 \ + 0x6162 0x6163 0x615F 0x615A 0x6158 0x6175 0x622A 0x6487 \ + 0x6458 0x6454 0x64A4 0x6478 0x645F 0x647A 0x6451 0x6467 \ + 0x6434 0x646D 0x647B 0x6572 0x65A1 0x65D7 0x65D6 0x66A2 \ + 0x66A8 0x669D 0x699C 0x69A8 0x6995 0x69C1 0x69AE 0x69D3 \ + 0x69CB 0x699B 0x69B7 0x69BB 0x69AB 0x69B4 0x69D0 0x69CD \ + 0x69AD 0x69CC 0x69A6 0x69C3 0x69A3 0x6B49 0x6B4C 0x6C33 \ + 0x6F33 0x6F14 0x6EFE 0x6F13 0x6EF4 0x6F29 0x6F3E 0x6F20 \ + 0x6F2C 0x6F0F 0x6F02 0x6F22 0x6EFF 0x6EEF 0x6F06 0x6F31 \ + 0x6F38 0x6F32 0x6F23 0x6F15 0x6F2B 0x6F2F 0x6F88 0x6F2A \ + 0x6EEC 0x6F01 0x6EF2 0x6ECC 0x6EF7 0x7194 0x7199 0x717D \ + 0x718A 0x7184 0x7192 0x723E 0x7292 0x7296 0x7344 0x7350 \ + 0x7464 0x7463 0x746A 0x7470 0x746D 0x7504 0x7591 0x7627 \ + 0x760D 0x760B 0x7609 0x7613 0x76E1 0x76E3 0x7784 0x777D \ + 0x777F 0x7761 0x78C1 0x789F 0x78A7 0x78B3 0x78A9 0x78A3 \ + 0x798E 0x798F 0x798D 0x7A2E 0x7A31 0x7AAA 0x7AA9 0x7AED \ + 0x7AEF 0x7BA1 0x7B95 0x7B8B 0x7B75 0x7B97 0x7B9D 0x7B94 \ + 0x7B8F 0x7BB8 0x7B87 0x7B84 0x7CB9 0x7CBD 0x7CBE 0x7DBB \ + 0x7DB0 0x7D9C 0x7DBD 0x7DBE 0x7DA0 0x7DCA 0x7DB4 0x7DB2 \ + 0x7DB1 0x7DBA 0x7DA2 0x7DBF 0x7DB5 0x7DB8 0x7DAD 0x7DD2 \ + 0x7DC7 0x7DAC 0x7F70 0x7FE0 0x7FE1 0x7FDF 0x805E 0x805A \ + 0x8087 0x8150 0x8180 0x818F 0x8188 0x818A 0x817F 0x8182 +17 0x81E7 0x81FA 0x8207 0x8214 0x821E 0x824B 0x84C9 0x84BF \ + 0x84C6 0x84C4 0x8499 0x849E 0x84B2 0x849C 0x84CB 0x84B8 \ + 0x84C0 0x84D3 0x8490 0x84BC 0x84D1 0x84CA 0x873F 0x871C \ + 0x873B 0x8722 0x8725 0x8734 0x8718 0x8755 0x8737 0x8729 \ + 0x88F3 0x8902 0x88F4 0x88F9 0x88F8 0x88FD 0x88E8 0x891A \ + 0x88EF 0x8AA6 0x8A8C 0x8A9E 0x8AA3 0x8A8D 0x8AA1 0x8A93 \ + 0x8AA4 0x8AAA 0x8AA5 0x8AA8 0x8A98 0x8A91 0x8A9A 0x8AA7 \ + 0x8C6A 0x8C8D 0x8C8C 0x8CD3 0x8CD1 0x8CD2 0x8D6B 0x8D99 \ + 0x8D95 0x8DFC 0x8F14 0x8F12 0x8F15 0x8F13 0x8FA3 0x9060 \ + 0x9058 0x905C 0x9063 0x9059 0x905E 0x9062 0x905D 0x905B \ + 0x9119 0x9118 0x911E 0x9175 0x9178 0x9177 0x9174 0x9278 \ + 0x9280 0x9285 0x9298 0x9296 0x927B 0x9293 0x929C 0x92A8 \ + 0x927C 0x9291 0x95A1 0x95A8 0x95A9 0x95A3 0x95A5 0x95A4 \ + 0x9699 0x969C 0x969B 0x96CC 0x96D2 0x9700 0x977C 0x9785 \ + 0x97F6 0x9817 0x9818 0x98AF 0x98B1 0x9903 0x9905 0x990C \ + 0x9909 0x99C1 0x9AAF 0x9AB0 0x9AE6 0x9B41 0x9B42 0x9CF4 \ + 0x9CF6 0x9CF3 0x9EBC 0x9F3B 0x9F4A 0x5104 0x5100 0x50FB \ + 0x50F5 0x50F9 0x5102 0x5108 0x5109 0x5105 0x51DC 0x5287 \ + 0x5288 0x5289 0x528D 0x528A 0x52F0 0x53B2 0x562E 0x563B \ + 0x5639 0x5632 0x563F 0x5634 0x5629 0x5653 0x564E 0x5657 \ + 0x5674 0x5636 0x562F 0x5630 0x5880 0x589F 0x589E 0x58B3 \ + 0x589C 0x58AE 0x58A9 0x58A6 0x596D 0x5B09 0x5AFB 0x5B0B \ + 0x5AF5 0x5B0C 0x5B08 0x5BEE 0x5BEC 0x5BE9 0x5BEB 0x5C64 \ + 0x5C65 0x5D9D 0x5D94 0x5E62 0x5E5F 0x5E61 0x5EE2 0x5EDA \ + 0x5EDF 0x5EDD 0x5EE3 0x5EE0 0x5F48 0x5F71 0x5FB7 0x5FB5 \ + 0x6176 0x6167 0x616E 0x615D 0x6155 0x6182 0x617C 0x6170 \ + 0x616B 0x617E 0x61A7 0x6190 0x61AB 0x618E 0x61AC 0x619A \ + 0x61A4 0x6194 0x61AE 0x622E 0x6469 0x646F 0x6479 0x649E \ + 0x64B2 0x6488 0x6490 0x64B0 0x64A5 0x6493 0x6495 0x64A9 \ + 0x6492 0x64AE 0x64AD 0x64AB 0x649A 0x64AC 0x6499 0x64A2 \ + 0x64B3 0x6575 0x6577 0x6578 0x66AE 0x66AB 0x66B4 0x66B1 \ + 0x6A23 0x6A1F 0x69E8 0x6A01 0x6A1E 0x6A19 0x69FD 0x6A21 +18 0x6A13 0x6A0A 0x69F3 0x6A02 0x6A05 0x69ED 0x6A11 0x6B50 \ + 0x6B4E 0x6BA4 0x6BC5 0x6BC6 0x6F3F 0x6F7C 0x6F84 0x6F51 \ + 0x6F66 0x6F54 0x6F86 0x6F6D 0x6F5B 0x6F78 0x6F6E 0x6F8E \ + 0x6F7A 0x6F70 0x6F64 0x6F97 0x6F58 0x6ED5 0x6F6F 0x6F60 \ + 0x6F5F 0x719F 0x71AC 0x71B1 0x71A8 0x7256 0x729B 0x734E \ + 0x7357 0x7469 0x748B 0x7483 0x747E 0x7480 0x757F 0x7620 \ + 0x7629 0x761F 0x7624 0x7626 0x7621 0x7622 0x769A 0x76BA \ + 0x76E4 0x778E 0x7787 0x778C 0x7791 0x778B 0x78CB 0x78C5 \ + 0x78BA 0x78CA 0x78BE 0x78D5 0x78BC 0x78D0 0x7A3F 0x7A3C \ + 0x7A40 0x7A3D 0x7A37 0x7A3B 0x7AAF 0x7AAE 0x7BAD 0x7BB1 \ + 0x7BC4 0x7BB4 0x7BC6 0x7BC7 0x7BC1 0x7BA0 0x7BCC 0x7CCA \ + 0x7DE0 0x7DF4 0x7DEF 0x7DFB 0x7DD8 0x7DEC 0x7DDD 0x7DE8 \ + 0x7DE3 0x7DDA 0x7DDE 0x7DE9 0x7D9E 0x7DD9 0x7DF2 0x7DF9 \ + 0x7F75 0x7F77 0x7FAF 0x7FE9 0x8026 0x819B 0x819C 0x819D \ + 0x81A0 0x819A 0x8198 0x8517 0x853D 0x851A 0x84EE 0x852C \ + 0x852D 0x8513 0x8511 0x8523 0x8521 0x8514 0x84EC 0x8525 \ + 0x84FF 0x8506 0x8782 0x8774 0x8776 0x8760 0x8766 0x8778 \ + 0x8768 0x8759 0x8757 0x874C 0x8753 0x885B 0x885D 0x8910 \ + 0x8907 0x8912 0x8913 0x8915 0x890A 0x8ABC 0x8AD2 0x8AC7 \ + 0x8AC4 0x8A95 0x8ACB 0x8AF8 0x8AB2 0x8AC9 0x8AC2 0x8ABF \ + 0x8AB0 0x8AD6 0x8ACD 0x8AB6 0x8AB9 0x8ADB 0x8C4C 0x8C4E \ + 0x8C6C 0x8CE0 0x8CDE 0x8CE6 0x8CE4 0x8CEC 0x8CED 0x8CE2 \ + 0x8CE3 0x8CDC 0x8CEA 0x8CE1 0x8D6D 0x8D9F 0x8DA3 0x8E2B \ + 0x8E10 0x8E1D 0x8E22 0x8E0F 0x8E29 0x8E1F 0x8E21 0x8E1E \ + 0x8EBA 0x8F1D 0x8F1B 0x8F1F 0x8F29 0x8F26 0x8F2A 0x8F1C \ + 0x8F1E 0x8F25 0x9069 0x906E 0x9068 0x906D 0x9077 0x9130 \ + 0x912D 0x9127 0x9131 0x9187 0x9189 0x918B 0x9183 0x92C5 \ + 0x92BB 0x92B7 0x92EA 0x92AC 0x92E4 0x92C1 0x92B3 0x92BC \ + 0x92D2 0x92C7 0x92F0 0x92B2 0x95AD 0x95B1 0x9704 0x9706 \ + 0x9707 0x9709 0x9760 0x978D 0x978B 0x978F 0x9821 0x982B \ + 0x981C 0x98B3 0x990A 0x9913 0x9912 0x9918 0x99DD 0x99D0 \ + 0x99DF 0x99DB 0x99D1 0x99D5 0x99D2 0x99D9 0x9AB7 0x9AEE +19 0x9AEF 0x9B27 0x9B45 0x9B44 0x9B77 0x9B6F 0x9D06 0x9D09 \ + 0x9D03 0x9EA9 0x9EBE 0x9ECE 0x58A8 0x9F52 0x5112 0x5118 \ + 0x5114 0x5110 0x5115 0x5180 0x51AA 0x51DD 0x5291 0x5293 \ + 0x52F3 0x5659 0x566B 0x5679 0x5669 0x5664 0x5678 0x566A \ + 0x5668 0x5665 0x5671 0x566F 0x566C 0x5662 0x5676 0x58C1 \ + 0x58BE 0x58C7 0x58C5 0x596E 0x5B1D 0x5B34 0x5B78 0x5BF0 \ + 0x5C0E 0x5F4A 0x61B2 0x6191 0x61A9 0x618A 0x61CD 0x61B6 \ + 0x61BE 0x61CA 0x61C8 0x6230 0x64C5 0x64C1 0x64CB 0x64BB \ + 0x64BC 0x64DA 0x64C4 0x64C7 0x64C2 0x64CD 0x64BF 0x64D2 \ + 0x64D4 0x64BE 0x6574 0x66C6 0x66C9 0x66B9 0x66C4 0x66C7 \ + 0x66B8 0x6A3D 0x6A38 0x6A3A 0x6A59 0x6A6B 0x6A58 0x6A39 \ + 0x6A44 0x6A62 0x6A61 0x6A4B 0x6A47 0x6A35 0x6A5F 0x6A48 \ + 0x6B59 0x6B77 0x6C05 0x6FC2 0x6FB1 0x6FA1 0x6FC3 0x6FA4 \ + 0x6FC1 0x6FA7 0x6FB3 0x6FC0 0x6FB9 0x6FB6 0x6FA6 0x6FA0 \ + 0x6FB4 0x71BE 0x71C9 0x71D0 0x71D2 0x71C8 0x71D5 0x71B9 \ + 0x71CE 0x71D9 0x71DC 0x71C3 0x71C4 0x7368 0x749C 0x74A3 \ + 0x7498 0x749F 0x749E 0x74E2 0x750C 0x750D 0x7634 0x7638 \ + 0x763A 0x76E7 0x76E5 0x77A0 0x779E 0x779F 0x77A5 0x78E8 \ + 0x78DA 0x78EC 0x78E7 0x79A6 0x7A4D 0x7A4E 0x7A46 0x7A4C \ + 0x7A4B 0x7ABA 0x7BD9 0x7C11 0x7BC9 0x7BE4 0x7BDB 0x7BE1 \ + 0x7BE9 0x7BE6 0x7CD5 0x7CD6 0x7E0A 0x7E11 0x7E08 0x7E1B \ + 0x7E23 0x7E1E 0x7E1D 0x7E09 0x7E10 0x7F79 0x7FB2 0x7FF0 \ + 0x7FF1 0x7FEE 0x8028 0x81B3 0x81A9 0x81A8 0x81FB 0x8208 \ + 0x8258 0x8259 0x854A 0x8559 0x8548 0x8568 0x8569 0x8543 \ + 0x8549 0x856D 0x856A 0x855E 0x8783 0x879F 0x879E 0x87A2 \ + 0x878D 0x8861 0x892A 0x8932 0x8925 0x892B 0x8921 0x89AA \ + 0x89A6 0x8AE6 0x8AFA 0x8AEB 0x8AF1 0x8B00 0x8ADC 0x8AE7 \ + 0x8AEE 0x8AFE 0x8B01 0x8B02 0x8AF7 0x8AED 0x8AF3 0x8AF6 \ + 0x8AFC 0x8C6B 0x8C6D 0x8C93 0x8CF4 0x8E44 0x8E31 0x8E34 \ + 0x8E42 0x8E39 0x8E35 0x8F3B 0x8F2F 0x8F38 0x8F33 0x8FA8 \ + 0x8FA6 0x9075 0x9074 0x9078 0x9072 0x907C 0x907A 0x9134 \ + 0x9192 0x9320 0x9336 0x92F8 0x9333 0x932F 0x9322 0x92FC +20 0x932B 0x9304 0x931A 0x9310 0x9326 0x9321 0x9315 0x932E \ + 0x9319 0x95BB 0x96A7 0x96A8 0x96AA 0x96D5 0x970E 0x9711 \ + 0x9716 0x970D 0x9713 0x970F 0x975B 0x975C 0x9766 0x9798 \ + 0x9830 0x9838 0x983B 0x9837 0x982D 0x9839 0x9824 0x9910 \ + 0x9928 0x991E 0x991B 0x9921 0x991A 0x99ED 0x99E2 0x99F1 \ + 0x9AB8 0x9ABC 0x9AFB 0x9AED 0x9B28 0x9B91 0x9D15 0x9D23 \ + 0x9D26 0x9D28 0x9D12 0x9D1B 0x9ED8 0x9ED4 0x9F8D 0x9F9C \ + 0x512A 0x511F 0x5121 0x5132 0x52F5 0x568E 0x5680 0x5690 \ + 0x5685 0x5687 0x568F 0x58D5 0x58D3 0x58D1 0x58CE 0x5B30 \ + 0x5B2A 0x5B24 0x5B7A 0x5C37 0x5C68 0x5DBC 0x5DBA 0x5DBD \ + 0x5DB8 0x5E6B 0x5F4C 0x5FBD 0x61C9 0x61C2 0x61C7 0x61E6 \ + 0x61CB 0x6232 0x6234 0x64CE 0x64CA 0x64D8 0x64E0 0x64F0 \ + 0x64E6 0x64EC 0x64F1 0x64E2 0x64ED 0x6582 0x6583 0x66D9 \ + 0x66D6 0x6A80 0x6A94 0x6A84 0x6AA2 0x6A9C 0x6ADB 0x6AA3 \ + 0x6A7E 0x6A97 0x6A90 0x6AA0 0x6B5C 0x6BAE 0x6BDA 0x6C08 \ + 0x6FD8 0x6FF1 0x6FDF 0x6FE0 0x6FDB 0x6FE4 0x6FEB 0x6FEF \ + 0x6F80 0x6FEC 0x6FE1 0x6FE9 0x6FD5 0x6FEE 0x6FF0 0x71E7 \ + 0x71DF 0x71EE 0x71E6 0x71E5 0x71ED 0x71EC 0x71F4 0x71E0 \ + 0x7235 0x7246 0x7370 0x7372 0x74A9 0x74B0 0x74A6 0x74A8 \ + 0x7646 0x7642 0x764C 0x76EA 0x77B3 0x77AA 0x77B0 0x77AC \ + 0x77A7 0x77AD 0x77EF 0x78F7 0x78FA 0x78F4 0x78EF 0x7901 \ + 0x79A7 0x79AA 0x7A57 0x7ABF 0x7C07 0x7C0D 0x7BFE 0x7BF7 \ + 0x7C0C 0x7BE0 0x7CE0 0x7CDC 0x7CDE 0x7CE2 0x7CDF 0x7CD9 \ + 0x7CDD 0x7E2E 0x7E3E 0x7E46 0x7E37 0x7E32 0x7E43 0x7E2B \ + 0x7E3D 0x7E31 0x7E45 0x7E41 0x7E34 0x7E39 0x7E48 0x7E35 \ + 0x7E3F 0x7E2F 0x7F44 0x7FF3 0x7FFC 0x8071 0x8072 0x8070 \ + 0x806F 0x8073 0x81C6 0x81C3 0x81BA 0x81C2 0x81C0 0x81BF \ + 0x81BD 0x81C9 0x81BE 0x81E8 0x8209 0x8271 0x85AA 0x8584 \ + 0x857E 0x859C 0x8591 0x8594 0x85AF 0x859B 0x8587 0x85A8 \ + 0x858A 0x8667 0x87C0 0x87D1 0x87B3 0x87D2 0x87C6 0x87AB \ + 0x87BB 0x87BA 0x87C8 0x87CB 0x893B 0x8936 0x8944 0x8938 \ + 0x893D 0x89AC 0x8B0E 0x8B17 0x8B19 0x8B1B 0x8B0A 0x8B20 +21 0x8B1D 0x8B04 0x8B10 0x8C41 0x8C3F 0x8C73 0x8CFA 0x8CFD \ + 0x8CFC 0x8CF8 0x8CFB 0x8DA8 0x8E49 0x8E4B 0x8E48 0x8E4A \ + 0x8F44 0x8F3E 0x8F42 0x8F45 0x8F3F 0x907F 0x907D 0x9084 \ + 0x9081 0x9082 0x9080 0x9139 0x91A3 0x919E 0x919C 0x934D \ + 0x9382 0x9328 0x9375 0x934A 0x9365 0x934B 0x9318 0x937E \ + 0x936C 0x935B 0x9370 0x935A 0x9354 0x95CA 0x95CB 0x95CC \ + 0x95C8 0x95C6 0x96B1 0x96B8 0x96D6 0x971C 0x971E 0x97A0 \ + 0x97D3 0x9846 0x98B6 0x9935 0x9A01 0x99FF 0x9BAE 0x9BAB \ + 0x9BAA 0x9BAD 0x9D3B 0x9D3F 0x9E8B 0x9ECF 0x9EDE 0x9EDC \ + 0x9EDD 0x9EDB 0x9F3E 0x9F4B 0x53E2 0x5695 0x56AE 0x58D9 \ + 0x58D8 0x5B38 0x5F5D 0x61E3 0x6233 0x64F4 0x64F2 0x64FE \ + 0x6506 0x64FA 0x64FB 0x64F7 0x65B7 0x66DC 0x6726 0x6AB3 \ + 0x6AAC 0x6AC3 0x6ABB 0x6AB8 0x6AC2 0x6AAE 0x6AAF 0x6B5F \ + 0x6B78 0x6BAF 0x7009 0x700B 0x6FFE 0x7006 0x6FFA 0x7011 \ + 0x700F 0x71FB 0x71FC 0x71FE 0x71F8 0x7377 0x7375 0x74A7 \ + 0x74BF 0x7515 0x7656 0x7658 0x7652 0x77BD 0x77BF 0x77BB \ + 0x77BC 0x790E 0x79AE 0x7A61 0x7A62 0x7A60 0x7AC4 0x7AC5 \ + 0x7C2B 0x7C27 0x7C2A 0x7C1E 0x7C23 0x7C21 0x7CE7 0x7E54 \ + 0x7E55 0x7E5E 0x7E5A 0x7E61 0x7E52 0x7E59 0x7F48 0x7FF9 \ + 0x7FFB 0x8077 0x8076 0x81CD 0x81CF 0x820A 0x85CF 0x85A9 \ + 0x85CD 0x85D0 0x85C9 0x85B0 0x85BA 0x85B9 0x85A6 0x87EF \ + 0x87EC 0x87F2 0x87E0 0x8986 0x89B2 0x89F4 0x8B28 0x8B39 \ + 0x8B2C 0x8B2B 0x8C50 0x8D05 0x8E59 0x8E63 0x8E66 0x8E64 \ + 0x8E5F 0x8E55 0x8EC0 0x8F49 0x8F4D 0x9087 0x9083 0x9088 \ + 0x91AB 0x91AC 0x91D0 0x9394 0x938A 0x9396 0x93A2 0x93B3 \ + 0x93AE 0x93AC 0x93B0 0x9398 0x939A 0x9397 0x95D4 0x95D6 \ + 0x95D0 0x95D5 0x96E2 0x96DC 0x96D9 0x96DB 0x96DE 0x9724 \ + 0x97A3 0x97A6 0x97AD 0x97F9 0x984D 0x984F 0x984C 0x984E \ + 0x9853 0x98BA 0x993E 0x993F 0x993D 0x992E 0x99A5 0x9A0E \ + 0x9AC1 0x9B03 0x9B06 0x9B4F 0x9B4E 0x9B4D 0x9BCA 0x9BC9 \ + 0x9BFD 0x9BC8 0x9BC0 0x9D51 0x9D5D 0x9D60 0x9EE0 0x9F15 \ + 0x9F2C 0x5133 0x56A5 0x58DE 0x58DF 0x58E2 0x5BF5 0x9F90 +22 0x5EEC 0x61F2 0x61F7 0x61F6 0x61F5 0x6500 0x650F 0x66E0 \ + 0x66DD 0x6AE5 0x6ADD 0x6ADA 0x6AD3 0x701B 0x701F 0x7028 \ + 0x701A 0x701D 0x7015 0x7018 0x7206 0x720D 0x7258 0x72A2 \ + 0x7378 0x737A 0x74BD 0x74CA 0x74E3 0x7587 0x7586 0x765F \ + 0x7661 0x77C7 0x7919 0x79B1 0x7A6B 0x7A69 0x7C3E 0x7C3F \ + 0x7C38 0x7C3D 0x7C37 0x7C40 0x7E6B 0x7E6D 0x7E79 0x7E69 \ + 0x7E6A 0x7F85 0x7E73 0x7FB6 0x7FB9 0x7FB8 0x81D8 0x85E9 \ + 0x85DD 0x85EA 0x85D5 0x85E4 0x85E5 0x85F7 0x87FB 0x8805 \ + 0x880D 0x87F9 0x87FE 0x8960 0x895F 0x8956 0x895E 0x8B41 \ + 0x8B5C 0x8B58 0x8B49 0x8B5A 0x8B4E 0x8B4F 0x8B46 0x8B59 \ + 0x8D08 0x8D0A 0x8E7C 0x8E72 0x8E87 0x8E76 0x8E6C 0x8E7A \ + 0x8E74 0x8F54 0x8F4E 0x8FAD 0x908A 0x908B 0x91B1 0x91AE \ + 0x93E1 0x93D1 0x93DF 0x93C3 0x93C8 0x93DC 0x93DD 0x93D6 \ + 0x93E2 0x93CD 0x93D8 0x93E4 0x93D7 0x93E8 0x95DC 0x96B4 \ + 0x96E3 0x972A 0x9727 0x9761 0x97DC 0x97FB 0x985E 0x9858 \ + 0x985B 0x98BC 0x9945 0x9949 0x9A16 0x9A19 0x9B0D 0x9BE8 \ + 0x9BE7 0x9BD6 0x9BDB 0x9D89 0x9D61 0x9D72 0x9D6A 0x9D6C \ + 0x9E92 0x9E97 0x9E93 0x9EB4 0x52F8 0x56A8 0x56B7 0x56B6 \ + 0x56B4 0x56BC 0x58E4 0x5B40 0x5B43 0x5B7D 0x5BF6 0x5DC9 \ + 0x61F8 0x61FA 0x6518 0x6514 0x6519 0x66E6 0x6727 0x6AEC \ + 0x703E 0x7030 0x7032 0x7210 0x737B 0x74CF 0x7662 0x7665 \ + 0x7926 0x792A 0x792C 0x792B 0x7AC7 0x7AF6 0x7C4C 0x7C43 \ + 0x7C4D 0x7CEF 0x7CF0 0x8FAE 0x7E7D 0x7E7C 0x7E82 0x7F4C \ + 0x8000 0x81DA 0x8266 0x85FB 0x85F9 0x8611 0x85FA 0x8606 \ + 0x860B 0x8607 0x860A 0x8814 0x8815 0x8964 0x89BA 0x89F8 \ + 0x8B70 0x8B6C 0x8B66 0x8B6F 0x8B5F 0x8B6B 0x8D0F 0x8D0D \ + 0x8E89 0x8E81 0x8E85 0x8E82 0x91B4 0x91CB 0x9418 0x9403 \ + 0x93FD 0x95E1 0x9730 0x98C4 0x9952 0x9951 0x99A8 0x9A2B \ + 0x9A30 0x9A37 0x9A35 0x9C13 0x9C0D 0x9E79 0x9EB5 0x9EE8 \ + 0x9F2F 0x9F5F 0x9F63 0x9F61 0x5137 0x5138 0x56C1 0x56C0 \ + 0x56C2 0x5914 0x5C6C 0x5DCD 0x61FC 0x61FE 0x651D 0x651C \ + 0x6595 0x66E9 0x6AFB 0x6B04 0x6AFA 0x6BB2 0x704C 0x721B +23 0x72A7 0x74D6 0x74D4 0x7669 0x77D3 0x7C50 0x7E8F 0x7E8C \ + 0x7FBC 0x8617 0x862D 0x861A 0x8823 0x8822 0x8821 0x881F \ + 0x896A 0x896C 0x89BD 0x8B74 0x8B77 0x8B7D 0x8D13 0x8E8A \ + 0x8E8D 0x8E8B 0x8F5F 0x8FAF 0x91BA 0x942E 0x9433 0x9435 \ + 0x943A 0x9438 0x9432 0x942B 0x95E2 0x9738 0x9739 0x9732 \ + 0x97FF 0x9867 0x9865 0x9957 0x9A45 0x9A43 0x9A40 0x9A3E \ + 0x9ACF 0x9B54 0x9B51 0x9C2D 0x9C25 0x9DAF 0x9DB4 0x9DC2 \ + 0x9DB8 0x9E9D 0x9EEF 0x9F19 0x9F5C 0x9F66 0x9F67 0x513C \ + 0x513B 0x56C8 0x56CA 0x56C9 0x5B7F 0x5DD4 0x5DD2 0x5F4E \ + 0x61FF 0x6524 0x6B0A 0x6B61 0x7051 0x7058 0x7380 0x74E4 \ + 0x758A 0x766E 0x766C 0x79B3 0x7C60 0x7C5F 0x807E 0x807D \ + 0x81DF 0x8972 0x896F 0x89FC 0x8B80 0x8D16 0x8D17 0x8E91 \ + 0x8E93 0x8F61 0x9148 0x9444 0x9451 0x9452 0x973D 0x973E \ + 0x97C3 0x97C1 0x986B 0x9955 0x9A55 0x9A4D 0x9AD2 0x9B1A \ + 0x9C49 0x9C31 0x9C3E 0x9C3B 0x9DD3 0x9DD7 0x9F34 0x9F6C \ + 0x9F6A 0x9F94 0x56CC 0x5DD6 0x6200 0x6523 0x652B 0x652A \ + 0x66EC 0x6B10 0x74DA 0x7ACA 0x7C64 0x7C63 0x7C65 0x7E93 \ + 0x7E96 0x7E94 0x81E2 0x8638 0x863F 0x8831 0x8B8A 0x9090 \ + 0x908F 0x9463 0x9460 0x9464 0x9768 0x986F 0x995C 0x9A5A \ + 0x9A5B 0x9A57 0x9AD3 0x9AD4 0x9AD1 0x9C54 0x9C57 0x9C56 \ + 0x9DE5 0x9E9F 0x9EF4 0x56D1 0x58E9 0x652C 0x705E 0x7671 \ + 0x7672 0x77D7 0x7F50 0x7F88 0x8836 0x8839 0x8862 0x8B93 \ + 0x8B92 0x8B96 0x8277 0x8D1B 0x91C0 0x946A 0x9742 0x9748 \ + 0x9744 0x97C6 0x9870 0x9A5F 0x9B22 0x9B58 0x9C5F 0x9DF9 \ + 0x9DFA 0x9E7C 0x9E7D 0x9F07 0x9F77 0x9F72 0x5EF3 0x6B16 \ + 0x7063 0x7C6C 0x7C6E 0x883B 0x89C0 0x8EA1 0x91C1 0x9472 \ + 0x9470 0x9871 0x995E 0x9AD6 0x9B23 0x9ECC 0x7064 0x77DA \ + 0x8B9A 0x9477 0x97C9 0x9A62 0x9A65 0x7E9C 0x8B9C 0x8EAA \ + 0x91C5 0x947D 0x947E 0x947C 0x9C77 0x9C78 0x9EF7 0x8C54 \ + 0x947F 0x9E1A 0x7228 0x9A6A 0x9B31 0x9E1B 0x9E1E 0x7C72 \ + 0x30FE 0x309D 0x309E 0x3005 0x3041 0x3042 0x3043 0x3044 \ + 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C +24 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 \ + 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C \ + 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 \ + 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C \ + 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 \ + 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C \ + 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 \ + 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C \ + 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 0x3093 0x30A1 \ + 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 \ + 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 \ + 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 \ + 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 \ + 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 \ + 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 \ + 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 \ + 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 \ + 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 \ + 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 \ + 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0x0414 0x0415 0x0401 \ + 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C 0x0423 \ + 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B \ + 0x042C 0x042D 0x042E 0x042F 0x0430 0x0431 0x0432 0x0433 \ + 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A \ + 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 \ + 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A \ + 0x044B 0x044C 0x044D 0x044E 0x044F 0x2460 0x2461 0x2462 \ + 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 0x2474 \ + 0x2475 0x2476 0x2477 0x2478 0x2479 0x247A 0x247B 0x247C \ + 0x247D 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +25 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x4E42 0x4E5C 0x51F5 0x531A 0x5382 0x4E07 0x4E0C 0x4E47 \ + 0x4E8D 0x56D7 0xFA0C 0x5C6E 0x5F73 0x4E0F 0x5187 0x4E0E \ + 0x4E2E 0x4E93 0x4EC2 0x4EC9 0x4EC8 0x5198 0x52FC 0x536C \ + 0x53B9 0x5720 0x5903 0x592C 0x5C10 0x5DFF 0x65E1 0x6BB3 \ + 0x6BCC 0x6C14 0x723F 0x4E31 0x4E3C 0x4EE8 0x4EDC 0x4EE9 \ + 0x4EE1 0x4EDD 0x4EDA 0x520C 0x531C 0x534C 0x5722 0x5723 \ + 0x5917 0x592F 0x5B81 0x5B84 0x5C12 0x5C3B 0x5C74 0x5C73 \ + 0x5E04 0x5E80 0x5E82 0x5FC9 0x6209 0x6250 0x6C15 0x6C36 \ + 0x6C43 0x6C3F 0x6C3B 0x72AE 0x72B0 0x738A 0x79B8 0x808A \ + 0x961E 0x4F0E 0x4F18 0x4F2C 0x4EF5 0x4F14 0x4EF1 0x4F00 \ + 0x4EF7 0x4F08 0x4F1D 0x4F02 0x4F05 0x4F22 0x4F13 0x4F04 \ + 0x4EF4 0x4F12 0x51B1 0x5213 0x5209 0x5210 0x52A6 0x5322 \ + 0x531F 0x534D 0x538A 0x5407 0x56E1 0x56DF 0x572E 0x572A \ + 0x5734 0x593C 0x5980 0x597C 0x5985 0x597B 0x597E 0x5977 \ + 0x597F 0x5B56 0x5C15 0x5C25 0x5C7C 0x5C7A 0x5C7B 0x5C7E +26 0x5DDF 0x5E75 0x5E84 0x5F02 0x5F1A 0x5F74 0x5FD5 0x5FD4 \ + 0x5FCF 0x625C 0x625E 0x6264 0x6261 0x6266 0x6262 0x6259 \ + 0x6260 0x625A 0x6265 0x65EF 0x65EE 0x673E 0x6739 0x6738 \ + 0x673B 0x673A 0x673F 0x673C 0x6733 0x6C18 0x6C46 0x6C52 \ + 0x6C5C 0x6C4F 0x6C4A 0x6C54 0x6C4B 0x6C4C 0x7071 0x725E \ + 0x72B4 0x72B5 0x738E 0x752A 0x767F 0x7A75 0x7F51 0x8278 \ + 0x827C 0x8280 0x827D 0x827F 0x864D 0x897E 0x9099 0x9097 \ + 0x9098 0x909B 0x9094 0x9622 0x9624 0x9620 0x9623 0x4F56 \ + 0x4F3B 0x4F62 0x4F49 0x4F53 0x4F64 0x4F3E 0x4F67 0x4F52 \ + 0x4F5F 0x4F41 0x4F58 0x4F2D 0x4F33 0x4F3F 0x4F61 0x518F \ + 0x51B9 0x521C 0x521E 0x5221 0x52AD 0x52AE 0x5309 0x5363 \ + 0x5372 0x538E 0x538F 0x5430 0x5437 0x542A 0x5454 0x5445 \ + 0x5419 0x541C 0x5425 0x5418 0x543D 0x544F 0x5441 0x5428 \ + 0x5424 0x5447 0x56EE 0x56E7 0x56E5 0x5741 0x5745 0x574C \ + 0x5749 0x574B 0x5752 0x5906 0x5940 0x59A6 0x5998 0x59A0 \ + 0x5997 0x598E 0x59A2 0x5990 0x598F 0x59A7 0x59A1 0x5B8E \ + 0x5B92 0x5C28 0x5C2A 0x5C8D 0x5C8F 0x5C88 0x5C8B 0x5C89 \ + 0x5C92 0x5C8A 0x5C86 0x5C93 0x5C95 0x5DE0 0x5E0A 0x5E0E \ + 0x5E8B 0x5E89 0x5E8C 0x5E88 0x5E8D 0x5F05 0x5F1D 0x5F78 \ + 0x5F76 0x5FD2 0x5FD1 0x5FD0 0x5FED 0x5FE8 0x5FEE 0x5FF3 \ + 0x5FE1 0x5FE4 0x5FE3 0x5FFA 0x5FEF 0x5FF7 0x5FFB 0x6000 \ + 0x5FF4 0x623A 0x6283 0x628C 0x628E 0x628F 0x6294 0x6287 \ + 0x6271 0x627B 0x627A 0x6270 0x6281 0x6288 0x6277 0x627D \ + 0x6272 0x6274 0x6537 0x65F0 0x65F4 0x65F3 0x65F2 0x65F5 \ + 0x6745 0x6747 0x6759 0x6755 0x674C 0x6748 0x675D 0x674D \ + 0x675A 0x674B 0x6BD0 0x6C19 0x6C1A 0x6C78 0x6C67 0x6C6B \ + 0x6C84 0x6C8B 0x6C8F 0x6C71 0x6C6F 0x6C69 0x6C9A 0x6C6D \ + 0x6C87 0x6C95 0x6C9C 0x6C66 0x6C73 0x6C65 0x6C7B 0x6C8E \ + 0x7074 0x707A 0x7263 0x72BF 0x72BD 0x72C3 0x72C6 0x72C1 \ + 0x72BA 0x72C5 0x7395 0x7397 0x7393 0x7394 0x7392 0x753A \ + 0x7539 0x7594 0x7595 0x7681 0x793D 0x8034 0x8095 0x8099 \ + 0x8090 0x8092 0x809C 0x8290 0x828F 0x8285 0x828E 0x8291 +27 0x8293 0x828A 0x8283 0x8284 0x8C78 0x8FC9 0x8FBF 0x909F \ + 0x90A1 0x90A5 0x909E 0x90A7 0x90A0 0x9630 0x9628 0x962F \ + 0x962D 0x4E33 0x4F98 0x4F7C 0x4F85 0x4F7D 0x4F80 0x4F87 \ + 0x4F76 0x4F74 0x4F89 0x4F84 0x4F77 0x4F4C 0x4F97 0x4F6A \ + 0x4F9A 0x4F79 0x4F81 0x4F78 0x4F90 0x4F9C 0x4F94 0x4F9E \ + 0x4F92 0x4F82 0x4F95 0x4F6B 0x4F6E 0x519E 0x51BC 0x51BE \ + 0x5235 0x5232 0x5233 0x5246 0x5231 0x52BC 0x530A 0x530B \ + 0x533C 0x5392 0x5394 0x5487 0x547F 0x5481 0x5491 0x5482 \ + 0x5488 0x546B 0x547A 0x547E 0x5465 0x546C 0x5474 0x5466 \ + 0x548D 0x546F 0x5461 0x5460 0x5498 0x5463 0x5467 0x5464 \ + 0x56F7 0x56F9 0x576F 0x5772 0x576D 0x576B 0x5771 0x5770 \ + 0x5776 0x5780 0x5775 0x577B 0x5773 0x5774 0x5762 0x5768 \ + 0x577D 0x590C 0x5945 0x59B5 0x59BA 0x59CF 0x59CE 0x59B2 \ + 0x59CC 0x59C1 0x59B6 0x59BC 0x59C3 0x59D6 0x59B1 0x59BD \ + 0x59C0 0x59C8 0x59B4 0x59C7 0x5B62 0x5B65 0x5B93 0x5B95 \ + 0x5C44 0x5C47 0x5CAE 0x5CA4 0x5CA0 0x5CB5 0x5CAF 0x5CA8 \ + 0x5CAC 0x5C9F 0x5CA3 0x5CAD 0x5CA2 0x5CAA 0x5CA7 0x5C9D \ + 0x5CA5 0x5CB6 0x5CB0 0x5CA6 0x5E17 0x5E14 0x5E19 0x5F28 \ + 0x5F22 0x5F23 0x5F24 0x5F54 0x5F82 0x5F7E 0x5F7D 0x5FDE \ + 0x5FE5 0x602D 0x6026 0x6019 0x6032 0x600B 0x6034 0x600A \ + 0x6017 0x6033 0x601A 0x601E 0x602C 0x6022 0x600D 0x6010 \ + 0x602E 0x6013 0x6011 0x600C 0x6009 0x601C 0x6214 0x623D \ + 0x62AD 0x62B4 0x62D1 0x62BE 0x62AA 0x62B6 0x62CA 0x62AE \ + 0x62B3 0x62AF 0x62BB 0x62A9 0x62B0 0x62B8 0x653D 0x65A8 \ + 0x65BB 0x6609 0x65FC 0x6604 0x6612 0x6608 0x65FB 0x6603 \ + 0x660B 0x660D 0x6605 0x65FD 0x6611 0x6610 0x66F6 0x670A \ + 0x6785 0x676C 0x678E 0x6792 0x6776 0x677B 0x6798 0x6786 \ + 0x6784 0x6774 0x678D 0x678C 0x677A 0x679F 0x6791 0x6799 \ + 0x6783 0x677D 0x6781 0x6778 0x6779 0x6794 0x6B25 0x6B80 \ + 0x6B7E 0x6BDE 0x6C1D 0x6C93 0x6CEC 0x6CEB 0x6CEE 0x6CD9 \ + 0x6CB6 0x6CD4 0x6CAD 0x6CE7 0x6CB7 0x6CD0 0x6CC2 0x6CBA \ + 0x6CC3 0x6CC6 0x6CED 0x6CF2 0x6CD2 0x6CDD 0x6CB4 0x6C8A +28 0x6C9D 0x6C80 0x6CDE 0x6CC0 0x6D30 0x6CCD 0x6CC7 0x6CB0 \ + 0x6CF9 0x6CCF 0x6CE9 0x6CD1 0x7094 0x7098 0x7085 0x7093 \ + 0x7086 0x7084 0x7091 0x7096 0x7082 0x709A 0x7083 0x726A \ + 0x72D6 0x72CB 0x72D8 0x72C9 0x72DC 0x72D2 0x72D4 0x72DA \ + 0x72CC 0x72D1 0x73A4 0x73A1 0x73AD 0x73A6 0x73A2 0x73A0 \ + 0x73AC 0x739D 0x74DD 0x74E8 0x753F 0x7540 0x753E 0x758C \ + 0x7598 0x76AF 0x76F3 0x76F1 0x76F0 0x76F5 0x77F8 0x77FC \ + 0x77F9 0x77FB 0x77FA 0x77F7 0x7942 0x793F 0x79C5 0x7A78 \ + 0x7A7B 0x7AFB 0x7C75 0x7CFD 0x8035 0x808F 0x80AE 0x80A3 \ + 0x80B8 0x80B5 0x80AD 0x8220 0x82A0 0x82C0 0x82AB 0x829A \ + 0x8298 0x829B 0x82B5 0x82A7 0x82AE 0x82BC 0x829E 0x82BA \ + 0x82B4 0x82A8 0x82A1 0x82A9 0x82C2 0x82A4 0x82C3 0x82B6 \ + 0x82A2 0x8670 0x866F 0x866D 0x866E 0x8C56 0x8FD2 0x8FCB \ + 0x8FD3 0x8FCD 0x8FD6 0x8FD5 0x8FD7 0x90B2 0x90B4 0x90AF \ + 0x90B3 0x90B0 0x9639 0x963D 0x963C 0x963A 0x9643 0x4FCD \ + 0x4FC5 0x4FD3 0x4FB2 0x4FC9 0x4FCB 0x4FC1 0x4FD4 0x4FDC \ + 0x4FD9 0x4FBB 0x4FB3 0x4FDB 0x4FC7 0x4FD6 0x4FBA 0x4FC0 \ + 0x4FB9 0x4FEC 0x5244 0x5249 0x52C0 0x52C2 0x533D 0x537C \ + 0x5397 0x5396 0x5399 0x5398 0x54BA 0x54A1 0x54AD 0x54A5 \ + 0x54CF 0x54C3 0x830D 0x54B7 0x54AE 0x54D6 0x54B6 0x54C5 \ + 0x54C6 0x54A0 0x5470 0x54BC 0x54A2 0x54BE 0x5472 0x54DE \ + 0x54B0 0x57B5 0x579E 0x579F 0x57A4 0x578C 0x5797 0x579D \ + 0x579B 0x5794 0x5798 0x578F 0x5799 0x57A5 0x579A 0x5795 \ + 0x58F4 0x590D 0x5953 0x59E1 0x59DE 0x59EE 0x5A00 0x59F1 \ + 0x59DD 0x59FA 0x59FD 0x59FC 0x59F6 0x59E4 0x59F2 0x59F7 \ + 0x59DB 0x59E9 0x59F3 0x59F5 0x59E0 0x59FE 0x59F4 0x59ED \ + 0x5BA8 0x5C4C 0x5CD0 0x5CD8 0x5CCC 0x5CD7 0x5CCB 0x5CDB \ + 0x5CDE 0x5CDA 0x5CC9 0x5CC7 0x5CCA 0x5CD6 0x5CD3 0x5CD4 \ + 0x5CCF 0x5CC8 0x5CC6 0x5CCE 0x5CDF 0x5CF8 0x5DF9 0x5E21 \ + 0x5E22 0x5E23 0x5E20 0x5E24 0x5EB0 0x5EA4 0x5EA2 0x5E9B \ + 0x5EA3 0x5EA5 0x5F07 0x5F2E 0x5F56 0x5F86 0x6037 0x6039 \ + 0x6054 0x6072 0x605E 0x6045 0x6053 0x6047 0x6049 0x605B +29 0x604C 0x6040 0x6042 0x605F 0x6024 0x6044 0x6058 0x6066 \ + 0x606E 0x6242 0x6243 0x62CF 0x630D 0x630B 0x62F5 0x630E \ + 0x6303 0x62EB 0x62F9 0x630F 0x630C 0x62F8 0x62F6 0x6300 \ + 0x6313 0x6314 0x62FA 0x6315 0x62FB 0x62F0 0x6541 0x6543 \ + 0x65AA 0x65BF 0x6636 0x6621 0x6632 0x6635 0x661C 0x6626 \ + 0x6622 0x6633 0x662B 0x663A 0x661D 0x6634 0x6639 0x662E \ + 0x670F 0x6710 0x67C1 0x67F2 0x67C8 0x67BA 0x67DC 0x67BB \ + 0x67F8 0x67D8 0x67C0 0x67B7 0x67C5 0x67EB 0x67E4 0x67DF \ + 0x67B5 0x67CD 0x67B3 0x67F7 0x67F6 0x67EE 0x67E3 0x67C2 \ + 0x67B9 0x67CE 0x67E7 0x67F0 0x67B2 0x67FC 0x67C6 0x67ED \ + 0x67CC 0x67AE 0x67E6 0x67DB 0x67FA 0x67C9 0x67CA 0x67C3 \ + 0x67EA 0x67CB 0x6B28 0x6B82 0x6B84 0x6BB6 0x6BD6 0x6BD8 \ + 0x6BE0 0x6C20 0x6C21 0x6D28 0x6D34 0x6D2D 0x6D1F 0x6D3C \ + 0x6D3F 0x6D12 0x6D0A 0x6CDA 0x6D33 0x6D04 0x6D19 0x6D3A \ + 0x6D1A 0x6D11 0x6D00 0x6D1D 0x6D42 0x6D01 0x6D18 0x6D37 \ + 0x6D03 0x6D0F 0x6D40 0x6D07 0x6D20 0x6D2C 0x6D08 0x6D22 \ + 0x6D09 0x6D10 0x70B7 0x709F 0x70BE 0x70B1 0x70B0 0x70A1 \ + 0x70B4 0x70B5 0x70A9 0x7241 0x7249 0x724A 0x726C 0x7270 \ + 0x7273 0x726E 0x72CA 0x72E4 0x72E8 0x72EB 0x72DF 0x72EA \ + 0x72E6 0x72E3 0x7385 0x73CC 0x73C2 0x73C8 0x73C5 0x73B9 \ + 0x73B6 0x73B5 0x73B4 0x73EB 0x73BF 0x73C7 0x73BE 0x73C3 \ + 0x73C6 0x73B8 0x73CB 0x74EC 0x74EE 0x752E 0x7547 0x7548 \ + 0x75A7 0x75AA 0x7679 0x76C4 0x7708 0x7703 0x7704 0x7705 \ + 0x770A 0x76F7 0x76FB 0x76FA 0x77E7 0x77E8 0x7806 0x7811 \ + 0x7812 0x7805 0x7810 0x780F 0x780E 0x7809 0x7803 0x7813 \ + 0x794A 0x794C 0x794B 0x7945 0x7944 0x79D5 0x79CD 0x79CF \ + 0x79D6 0x79CE 0x7A80 0x7A7E 0x7AD1 0x7B00 0x7B01 0x7C7A \ + 0x7C78 0x7C79 0x7C7F 0x7C80 0x7C81 0x7D03 0x7D08 0x7D01 \ + 0x7F58 0x7F91 0x7F8D 0x7FBE 0x8007 0x800E 0x800F 0x8014 \ + 0x8037 0x80D8 0x80C7 0x80E0 0x80D1 0x80C8 0x80C2 0x80D0 \ + 0x80C5 0x80E3 0x80D9 0x80DC 0x80CA 0x80D5 0x80C9 0x80CF \ + 0x80D7 0x80E6 0x80CD 0x81FF 0x8221 0x8294 0x82D9 0x82FE +30 0x82F9 0x8307 0x82E8 0x8300 0x82D5 0x833A 0x82EB 0x82D6 \ + 0x82F4 0x82EC 0x82E1 0x82F2 0x82F5 0x830C 0x82FB 0x82F6 \ + 0x82F0 0x82EA 0x82E4 0x82E0 0x82FA 0x82F3 0x82ED 0x8677 \ + 0x8674 0x867C 0x8673 0x8841 0x884E 0x8867 0x886A 0x8869 \ + 0x89D3 0x8A04 0x8A07 0x8D72 0x8FE3 0x8FE1 0x8FEE 0x8FE0 \ + 0x90F1 0x90BD 0x90BF 0x90D5 0x90C5 0x90BE 0x90C7 0x90CB \ + 0x90C8 0x91D4 0x91D3 0x9654 0x964F 0x9651 0x9653 0x964A \ + 0x964E 0x501E 0x5005 0x5007 0x5013 0x5022 0x5030 0x501B \ + 0x4FF5 0x4FF4 0x5033 0x5037 0x502C 0x4FF6 0x4FF7 0x5017 \ + 0x501C 0x5020 0x5027 0x5035 0x502F 0x5031 0x500E 0x515A \ + 0x5194 0x5193 0x51CA 0x51C4 0x51C5 0x51C8 0x51CE 0x5261 \ + 0x525A 0x5252 0x525E 0x525F 0x5255 0x5262 0x52CD 0x530E \ + 0x539E 0x5526 0x54E2 0x5517 0x5512 0x54E7 0x54F3 0x54E4 \ + 0x551A 0x54FF 0x5504 0x5508 0x54EB 0x5511 0x5505 0x54F1 \ + 0x550A 0x54FB 0x54F7 0x54F8 0x54E0 0x550E 0x5503 0x550B \ + 0x5701 0x5702 0x57CC 0x5832 0x57D5 0x57D2 0x57BA 0x57C6 \ + 0x57BD 0x57BC 0x57B8 0x57B6 0x57BF 0x57C7 0x57D0 0x57B9 \ + 0x57C1 0x590E 0x594A 0x5A19 0x5A16 0x5A2D 0x5A2E 0x5A15 \ + 0x5A0F 0x5A17 0x5A0A 0x5A1E 0x5A33 0x5B6C 0x5BA7 0x5BAD \ + 0x5BAC 0x5C03 0x5C56 0x5C54 0x5CEC 0x5CFF 0x5CEE 0x5CF1 \ + 0x5CF7 0x5D00 0x5CF9 0x5E29 0x5E28 0x5EA8 0x5EAE 0x5EAA \ + 0x5EAC 0x5F33 0x5F30 0x5F67 0x605D 0x605A 0x6067 0x6041 \ + 0x60A2 0x6088 0x6080 0x6092 0x6081 0x609D 0x6083 0x6095 \ + 0x609B 0x6097 0x6087 0x609C 0x608E 0x6219 0x6246 0x62F2 \ + 0x6310 0x6356 0x632C 0x6344 0x6345 0x6336 0x6343 0x63E4 \ + 0x6339 0x634B 0x634A 0x633C 0x6329 0x6341 0x6334 0x6358 \ + 0x6354 0x6359 0x632D 0x6347 0x6333 0x635A 0x6351 0x6338 \ + 0x6357 0x6340 0x6348 0x654A 0x6546 0x65C6 0x65C3 0x65C4 \ + 0x65C2 0x664A 0x665F 0x6647 0x6651 0x6712 0x6713 0x681F \ + 0x681A 0x6849 0x6832 0x6833 0x683B 0x684B 0x684F 0x6816 \ + 0x6831 0x681C 0x6835 0x682B 0x682D 0x682F 0x684E 0x6844 \ + 0x6834 0x681D 0x6812 0x6814 0x6826 0x6828 0x682E 0x684D +31 0x683A 0x6825 0x6820 0x6B2C 0x6B2F 0x6B2D 0x6B31 0x6B34 \ + 0x6B6D 0x8082 0x6B88 0x6BE6 0x6BE4 0x6BE8 0x6BE3 0x6BE2 \ + 0x6BE7 0x6C25 0x6D7A 0x6D63 0x6D64 0x6D76 0x6D0D 0x6D61 \ + 0x6D92 0x6D58 0x6D62 0x6D6D 0x6D6F 0x6D91 0x6D8D 0x6DEF \ + 0x6D7F 0x6D86 0x6D5E 0x6D67 0x6D60 0x6D97 0x6D70 0x6D7C \ + 0x6D5F 0x6D82 0x6D98 0x6D2F 0x6D68 0x6D8B 0x6D7E 0x6D80 \ + 0x6D84 0x6D16 0x6D83 0x6D7B 0x6D7D 0x6D75 0x6D90 0x70DC \ + 0x70D3 0x70D1 0x70DD 0x70CB 0x7F39 0x70E2 0x70D7 0x70D2 \ + 0x70DE 0x70E0 0x70D4 0x70CD 0x70C5 0x70C6 0x70C7 0x70DA \ + 0x70CE 0x70E1 0x7242 0x7278 0x7277 0x7276 0x7300 0x72FA \ + 0x72F4 0x72FE 0x72F6 0x72F3 0x72FB 0x7301 0x73D3 0x73D9 \ + 0x73E5 0x73D6 0x73BC 0x73E7 0x73E3 0x73E9 0x73DC 0x73D2 \ + 0x73DB 0x73D4 0x73DD 0x73DA 0x73D7 0x73D8 0x73E8 0x74DE \ + 0x74DF 0x74F4 0x74F5 0x7521 0x755B 0x755F 0x75B0 0x75C1 \ + 0x75BB 0x75C4 0x75C0 0x75BF 0x75B6 0x75BA 0x768A 0x76C9 \ + 0x771D 0x771B 0x7710 0x7713 0x7712 0x7723 0x7711 0x7715 \ + 0x7719 0x771A 0x7722 0x7727 0x7823 0x782C 0x7822 0x7835 \ + 0x782F 0x7828 0x782E 0x782B 0x7821 0x7829 0x7833 0x782A \ + 0x7831 0x7954 0x795B 0x794F 0x795C 0x7953 0x7952 0x7951 \ + 0x79EB 0x79EC 0x79E0 0x79EE 0x79ED 0x79EA 0x79DC 0x79DE \ + 0x79DD 0x7A86 0x7A89 0x7A85 0x7A8B 0x7A8C 0x7A8A 0x7A87 \ + 0x7AD8 0x7B10 0x7B04 0x7B13 0x7B05 0x7B0F 0x7B08 0x7B0A \ + 0x7B0E 0x7B09 0x7B12 0x7C84 0x7C91 0x7C8A 0x7C8C 0x7C88 \ + 0x7C8D 0x7C85 0x7D1E 0x7D1D 0x7D11 0x7D0E 0x7D18 0x7D16 \ + 0x7D13 0x7D1F 0x7D12 0x7D0F 0x7D0C 0x7F5C 0x7F61 0x7F5E \ + 0x7F60 0x7F5D 0x7F5B 0x7F96 0x7F92 0x7FC3 0x7FC2 0x7FC0 \ + 0x8016 0x803E 0x8039 0x80FA 0x80F2 0x80F9 0x80F5 0x8101 \ + 0x80FB 0x8100 0x8201 0x822F 0x8225 0x8333 0x832D 0x8344 \ + 0x8319 0x8351 0x8325 0x8356 0x833F 0x8341 0x8326 0x831C \ + 0x8322 0x8342 0x834E 0x831B 0x832A 0x8308 0x833C 0x834D \ + 0x8316 0x8324 0x8320 0x8337 0x832F 0x8329 0x8347 0x8345 \ + 0x834C 0x8353 0x831E 0x832C 0x834B 0x8327 0x8348 0x8653 +32 0x8652 0x86A2 0x86A8 0x8696 0x868D 0x8691 0x869E 0x8687 \ + 0x8697 0x8686 0x868B 0x869A 0x8685 0x86A5 0x8699 0x86A1 \ + 0x86A7 0x8695 0x8698 0x868E 0x869D 0x8690 0x8694 0x8843 \ + 0x8844 0x886D 0x8875 0x8876 0x8872 0x8880 0x8871 0x887F \ + 0x886F 0x8883 0x887E 0x8874 0x887C 0x8A12 0x8C47 0x8C57 \ + 0x8C7B 0x8CA4 0x8CA3 0x8D76 0x8D78 0x8DB5 0x8DB7 0x8DB6 \ + 0x8ED1 0x8ED3 0x8FFE 0x8FF5 0x9002 0x8FFF 0x8FFB 0x9004 \ + 0x8FFC 0x8FF6 0x90D6 0x90E0 0x90D9 0x90DA 0x90E3 0x90DF \ + 0x90E5 0x90D8 0x90DB 0x90D7 0x90DC 0x90E4 0x9150 0x914E \ + 0x914F 0x91D5 0x91E2 0x91DA 0x965C 0x965F 0x96BC 0x98E3 \ + 0x9ADF 0x9B2F 0x4E7F 0x5070 0x506A 0x5061 0x505E 0x5060 \ + 0x5053 0x504B 0x505D 0x5072 0x5048 0x504D 0x5041 0x505B \ + 0x504A 0x5062 0x5015 0x5045 0x505F 0x5069 0x506B 0x5063 \ + 0x5064 0x5046 0x5040 0x506E 0x5073 0x5057 0x5051 0x51D0 \ + 0x526B 0x526D 0x526C 0x526E 0x52D6 0x52D3 0x532D 0x539C \ + 0x5575 0x5576 0x553C 0x554D 0x5550 0x5534 0x552A 0x5551 \ + 0x5562 0x5536 0x5535 0x5530 0x5552 0x5545 0x550C 0x5532 \ + 0x5565 0x554E 0x5539 0x5548 0x552D 0x553B 0x5540 0x554B \ + 0x570A 0x5707 0x57FB 0x5814 0x57E2 0x57F6 0x57DC 0x57F4 \ + 0x5800 0x57ED 0x57FD 0x5808 0x57F8 0x580B 0x57F3 0x57CF \ + 0x5807 0x57EE 0x57E3 0x57F2 0x57E5 0x57EC 0x57E1 0x580E \ + 0x57FC 0x5810 0x57E7 0x5801 0x580C 0x57F1 0x57E9 0x57F0 \ + 0x580D 0x5804 0x595C 0x5A60 0x5A58 0x5A55 0x5A67 0x5A5E \ + 0x5A38 0x5A35 0x5A6D 0x5A50 0x5A5F 0x5A65 0x5A6C 0x5A53 \ + 0x5A64 0x5A57 0x5A43 0x5A5D 0x5A52 0x5A44 0x5A5B 0x5A48 \ + 0x5A8E 0x5A3E 0x5A4D 0x5A39 0x5A4C 0x5A70 0x5A69 0x5A47 \ + 0x5A51 0x5A56 0x5A42 0x5A5C 0x5B72 0x5B6E 0x5BC1 0x5BC0 \ + 0x5C59 0x5D1E 0x5D0B 0x5D1D 0x5D1A 0x5D20 0x5D0C 0x5D28 \ + 0x5D0D 0x5D26 0x5D25 0x5D0F 0x5D30 0x5D12 0x5D23 0x5D1F \ + 0x5D2E 0x5E3E 0x5E34 0x5EB1 0x5EB4 0x5EB9 0x5EB2 0x5EB3 \ + 0x5F36 0x5F38 0x5F9B 0x5F96 0x5F9F 0x608A 0x6090 0x6086 \ + 0x60BE 0x60B0 0x60BA 0x60D3 0x60D4 0x60CF 0x60E4 0x60D9 +33 0x60DD 0x60C8 0x60B1 0x60DB 0x60B7 0x60CA 0x60BF 0x60C3 \ + 0x60CD 0x60C0 0x6332 0x6365 0x638A 0x6382 0x637D 0x63BD \ + 0x639E 0x63AD 0x639D 0x6397 0x63AB 0x638E 0x636F 0x6387 \ + 0x6390 0x636E 0x63AF 0x6375 0x639C 0x636D 0x63AE 0x637C \ + 0x63A4 0x633B 0x639F 0x6378 0x6385 0x6381 0x6391 0x638D \ + 0x6370 0x6553 0x65CD 0x6665 0x6661 0x665B 0x6659 0x665C \ + 0x6662 0x6718 0x6879 0x6887 0x6890 0x689C 0x686D 0x686E \ + 0x68AE 0x68AB 0x6956 0x686F 0x68A3 0x68AC 0x68A9 0x6875 \ + 0x6874 0x68B2 0x688F 0x6877 0x6892 0x687C 0x686B 0x6872 \ + 0x68AA 0x6880 0x6871 0x687E 0x689B 0x6896 0x688B 0x68A0 \ + 0x6889 0x68A4 0x6878 0x687B 0x6891 0x688C 0x688A 0x687D \ + 0x6B36 0x6B33 0x6B37 0x6B38 0x6B91 0x6B8F 0x6B8D 0x6B8E \ + 0x6B8C 0x6C2A 0x6DC0 0x6DAB 0x6DB4 0x6DB3 0x6E74 0x6DAC \ + 0x6DE9 0x6DE2 0x6DB7 0x6DF6 0x6DD4 0x6E00 0x6DC8 0x6DE0 \ + 0x6DDF 0x6DD6 0x6DBE 0x6DE5 0x6DDC 0x6DDD 0x6DDB 0x6DF4 \ + 0x6DCA 0x6DBD 0x6DED 0x6DF0 0x6DBA 0x6DD5 0x6DC2 0x6DCF \ + 0x6DC9 0x6DD0 0x6DF2 0x6DD3 0x6DFD 0x6DD7 0x6DCD 0x6DE3 \ + 0x6DBB 0x70FA 0x710D 0x70F7 0x7117 0x70F4 0x710C 0x70F0 \ + 0x7104 0x70F3 0x7110 0x70FC 0x70FF 0x7106 0x7113 0x7100 \ + 0x70F8 0x70F6 0x710B 0x7102 0x710E 0x727E 0x727B 0x727C \ + 0x727F 0x731D 0x7317 0x7307 0x7311 0x7318 0x730A 0x7308 \ + 0x72FF 0x730F 0x731E 0x7388 0x73F6 0x73F8 0x73F5 0x7404 \ + 0x7401 0x73FD 0x7407 0x7400 0x73FA 0x73FC 0x73FF 0x740C \ + 0x740B 0x73F4 0x7408 0x7564 0x7563 0x75CE 0x75D2 0x75CF \ + 0x75CB 0x75CC 0x75D1 0x75D0 0x768F 0x7689 0x76D3 0x7739 \ + 0x772F 0x772D 0x7731 0x7732 0x7734 0x7733 0x773D 0x7725 \ + 0x773B 0x7735 0x7848 0x7852 0x7849 0x784D 0x784A 0x784C \ + 0x7826 0x7845 0x7850 0x7964 0x7967 0x7969 0x796A 0x7963 \ + 0x796B 0x7961 0x79BB 0x79FA 0x79F8 0x79F6 0x79F7 0x7A8F \ + 0x7A94 0x7A90 0x7B35 0x7B47 0x7B34 0x7B25 0x7B30 0x7B22 \ + 0x7B24 0x7B33 0x7B18 0x7B2A 0x7B1D 0x7B31 0x7B2B 0x7B2D \ + 0x7B2F 0x7B32 0x7B38 0x7B1A 0x7B23 0x7C94 0x7C98 0x7C96 +34 0x7CA3 0x7D35 0x7D3D 0x7D38 0x7D36 0x7D3A 0x7D45 0x7D2C \ + 0x7D29 0x7D41 0x7D47 0x7D3E 0x7D3F 0x7D4A 0x7D3B 0x7D28 \ + 0x7F63 0x7F95 0x7F9C 0x7F9D 0x7F9B 0x7FCA 0x7FCB 0x7FCD \ + 0x7FD0 0x7FD1 0x7FC7 0x7FCF 0x7FC9 0x801F 0x801E 0x801B \ + 0x8047 0x8043 0x8048 0x8118 0x8125 0x8119 0x811B 0x812D \ + 0x811F 0x812C 0x811E 0x8121 0x8115 0x8127 0x811D 0x8122 \ + 0x8211 0x8238 0x8233 0x823A 0x8234 0x8232 0x8274 0x8390 \ + 0x83A3 0x83A8 0x838D 0x837A 0x8373 0x83A4 0x8374 0x838F \ + 0x8381 0x8395 0x8399 0x8375 0x8394 0x83A9 0x837D 0x8383 \ + 0x838C 0x839D 0x839B 0x83AA 0x838B 0x837E 0x83A5 0x83AF \ + 0x8388 0x8397 0x83B0 0x837F 0x83A6 0x8387 0x83AE 0x8376 \ + 0x839A 0x8659 0x8656 0x86BF 0x86B7 0x86C2 0x86C1 0x86C5 \ + 0x86BA 0x86B0 0x86C8 0x86B9 0x86B3 0x86B8 0x86CC 0x86B4 \ + 0x86BB 0x86BC 0x86C3 0x86BD 0x86BE 0x8852 0x8889 0x8895 \ + 0x88A8 0x88A2 0x88AA 0x889A 0x8891 0x88A1 0x889F 0x8898 \ + 0x88A7 0x8899 0x889B 0x8897 0x88A4 0x88AC 0x888C 0x8893 \ + 0x888E 0x8982 0x89D6 0x89D9 0x89D5 0x8A30 0x8A27 0x8A2C \ + 0x8A1E 0x8C39 0x8C3B 0x8C5C 0x8C5D 0x8C7D 0x8CA5 0x8D7D \ + 0x8D7B 0x8D79 0x8DBC 0x8DC2 0x8DB9 0x8DBF 0x8DC1 0x8ED8 \ + 0x8EDE 0x8EDD 0x8EDC 0x8ED7 0x8EE0 0x8EE1 0x9024 0x900B \ + 0x9011 0x901C 0x900C 0x9021 0x90EF 0x90EA 0x90F0 0x90F4 \ + 0x90F2 0x90F3 0x90D4 0x90EB 0x90EC 0x90E9 0x9156 0x9158 \ + 0x915A 0x9153 0x9155 0x91EC 0x91F4 0x91F1 0x91F3 0x91F8 \ + 0x91E4 0x91F9 0x91EA 0x91EB 0x91F7 0x91E8 0x91EE 0x957A \ + 0x9586 0x9588 0x967C 0x966D 0x966B 0x9671 0x966F 0x96BF \ + 0x976A 0x9804 0x98E5 0x9997 0x509B 0x5095 0x5094 0x509E \ + 0x508B 0x50A3 0x5083 0x508C 0x508E 0x509D 0x5068 0x509C \ + 0x5092 0x5082 0x5087 0x515F 0x51D4 0x5312 0x5311 0x53A4 \ + 0x53A7 0x5591 0x55A8 0x55A5 0x55AD 0x5577 0x5645 0x55A2 \ + 0x5593 0x5588 0x558F 0x55B5 0x5581 0x55A3 0x5592 0x55A4 \ + 0x557D 0x558C 0x55A6 0x557F 0x5595 0x55A1 0x558E 0x570C \ + 0x5829 0x5837 0x5819 0x581E 0x5827 0x5823 0x5828 0x57F5 +35 0x5848 0x5825 0x581C 0x581B 0x5833 0x583F 0x5836 0x582E \ + 0x5839 0x5838 0x582D 0x582C 0x583B 0x5961 0x5AAF 0x5A94 \ + 0x5A9F 0x5A7A 0x5AA2 0x5A9E 0x5A78 0x5AA6 0x5A7C 0x5AA5 \ + 0x5AAC 0x5A95 0x5AAE 0x5A37 0x5A84 0x5A8A 0x5A97 0x5A83 \ + 0x5A8B 0x5AA9 0x5A7B 0x5A7D 0x5A8C 0x5A9C 0x5A8F 0x5A93 \ + 0x5A9D 0x5BEA 0x5BCD 0x5BCB 0x5BD4 0x5BD1 0x5BCA 0x5BCE \ + 0x5C0C 0x5C30 0x5D37 0x5D43 0x5D6B 0x5D41 0x5D4B 0x5D3F \ + 0x5D35 0x5D51 0x5D4E 0x5D55 0x5D33 0x5D3A 0x5D52 0x5D3D \ + 0x5D31 0x5D59 0x5D42 0x5D39 0x5D49 0x5D38 0x5D3C 0x5D32 \ + 0x5D36 0x5D40 0x5D45 0x5E44 0x5E41 0x5F58 0x5FA6 0x5FA5 \ + 0x5FAB 0x60C9 0x60B9 0x60CC 0x60E2 0x60CE 0x60C4 0x6114 \ + 0x60F2 0x610A 0x6116 0x6105 0x60F5 0x6113 0x60F8 0x60FC \ + 0x60FE 0x60C1 0x6103 0x6118 0x611D 0x6110 0x60FF 0x6104 \ + 0x610B 0x624A 0x6394 0x63B1 0x63B0 0x63CE 0x63E5 0x63E8 \ + 0x63EF 0x63C3 0x649D 0x63F3 0x63CA 0x63E0 0x63F6 0x63D5 \ + 0x63F2 0x63F5 0x6461 0x63DF 0x63BE 0x63DD 0x63DC 0x63C4 \ + 0x63D8 0x63D3 0x63C2 0x63C7 0x63CC 0x63CB 0x63C8 0x63F0 \ + 0x63D7 0x63D9 0x6532 0x6567 0x656A 0x6564 0x655C 0x6568 \ + 0x6565 0x658C 0x659D 0x659E 0x65AE 0x65D0 0x65D2 0x667C \ + 0x666C 0x667B 0x6680 0x6671 0x6679 0x666A 0x6672 0x6701 \ + 0x690C 0x68D3 0x6904 0x68DC 0x692A 0x68EC 0x68EA 0x68F1 \ + 0x690F 0x68D6 0x68F7 0x68EB 0x68E4 0x68F6 0x6913 0x6910 \ + 0x68F3 0x68E1 0x6907 0x68CC 0x6908 0x6970 0x68B4 0x6911 \ + 0x68EF 0x68C6 0x6914 0x68F8 0x68D0 0x68FD 0x68FC 0x68E8 \ + 0x690B 0x690A 0x6917 0x68CE 0x68C8 0x68DD 0x68DE 0x68E6 \ + 0x68F4 0x68D1 0x6906 0x68D4 0x68E9 0x6915 0x6925 0x68C7 \ + 0x6B39 0x6B3B 0x6B3F 0x6B3C 0x6B94 0x6B97 0x6B99 0x6B95 \ + 0x6BBD 0x6BF0 0x6BF2 0x6BF3 0x6C30 0x6DFC 0x6E46 0x6E47 \ + 0x6E1F 0x6E49 0x6E88 0x6E3C 0x6E3D 0x6E45 0x6E62 0x6E2B \ + 0x6E3F 0x6E41 0x6E5D 0x6E73 0x6E1C 0x6E33 0x6E4B 0x6E40 \ + 0x6E51 0x6E3B 0x6E03 0x6E2E 0x6E5E 0x6E68 0x6E5C 0x6E61 \ + 0x6E31 0x6E28 0x6E60 0x6E71 0x6E6B 0x6E39 0x6E22 0x6E30 +36 0x6E53 0x6E65 0x6E27 0x6E78 0x6E64 0x6E77 0x6E55 0x6E79 \ + 0x6E52 0x6E66 0x6E35 0x6E36 0x6E5A 0x7120 0x711E 0x712F \ + 0x70FB 0x712E 0x7131 0x7123 0x7125 0x7122 0x7132 0x711F \ + 0x7128 0x713A 0x711B 0x724B 0x725A 0x7288 0x7289 0x7286 \ + 0x7285 0x728B 0x7312 0x730B 0x7330 0x7322 0x7331 0x7333 \ + 0x7327 0x7332 0x732D 0x7326 0x7323 0x7335 0x730C 0x742E \ + 0x742C 0x7430 0x742B 0x7416 0x741A 0x7421 0x742D 0x7431 \ + 0x7424 0x7423 0x741D 0x7429 0x7420 0x7432 0x74FB 0x752F \ + 0x756F 0x756C 0x75E7 0x75DA 0x75E1 0x75E6 0x75DD 0x75DF \ + 0x75E4 0x75D7 0x7695 0x7692 0x76DA 0x7746 0x7747 0x7744 \ + 0x774D 0x7745 0x774A 0x774E 0x774B 0x774C 0x77DE 0x77EC \ + 0x7860 0x7864 0x7865 0x785C 0x786D 0x7871 0x786A 0x786E \ + 0x7870 0x7869 0x7868 0x785E 0x7862 0x7974 0x7973 0x7972 \ + 0x7970 0x7A02 0x7A0A 0x7A03 0x7A0C 0x7A04 0x7A99 0x7AE6 \ + 0x7AE4 0x7B4A 0x7B3B 0x7B44 0x7B48 0x7B4C 0x7B4E 0x7B40 \ + 0x7B58 0x7B45 0x7CA2 0x7C9E 0x7CA8 0x7CA1 0x7D58 0x7D6F \ + 0x7D63 0x7D53 0x7D56 0x7D67 0x7D6A 0x7D4F 0x7D6D 0x7D5C \ + 0x7D6B 0x7D52 0x7D54 0x7D69 0x7D51 0x7D5F 0x7D4E 0x7F3E \ + 0x7F3F 0x7F65 0x7F66 0x7FA2 0x7FA0 0x7FA1 0x7FD7 0x8051 \ + 0x804F 0x8050 0x80FE 0x80D4 0x8143 0x814A 0x8152 0x814F \ + 0x8147 0x813D 0x814D 0x813A 0x81E6 0x81EE 0x81F7 0x81F8 \ + 0x81F9 0x8204 0x823C 0x823D 0x823F 0x8275 0x833B 0x83CF \ + 0x83F9 0x8423 0x83C0 0x83E8 0x8412 0x83E7 0x83E4 0x83FC \ + 0x83F6 0x8410 0x83C6 0x83C8 0x83EB 0x83E3 0x83BF 0x8401 \ + 0x83DD 0x83E5 0x83D8 0x83FF 0x83E1 0x83CB 0x83CE 0x83D6 \ + 0x83F5 0x83C9 0x8409 0x840F 0x83DE 0x8411 0x8406 0x83C2 \ + 0x83F3 0x83D5 0x83FA 0x83C7 0x83D1 0x83EA 0x8413 0x83C3 \ + 0x83EC 0x83EE 0x83C4 0x83FB 0x83D7 0x83E2 0x841B 0x83DB \ + 0x83FE 0x86D8 0x86E2 0x86E6 0x86D3 0x86E3 0x86DA 0x86EA \ + 0x86DD 0x86EB 0x86DC 0x86EC 0x86E9 0x86D7 0x86E8 0x86D1 \ + 0x8848 0x8856 0x8855 0x88BA 0x88D7 0x88B9 0x88B8 0x88C0 \ + 0x88BE 0x88B6 0x88BC 0x88B7 0x88BD 0x88B2 0x8901 0x88C9 +37 0x8995 0x8998 0x8997 0x89DD 0x89DA 0x89DB 0x8A4E 0x8A4D \ + 0x8A39 0x8A59 0x8A40 0x8A57 0x8A58 0x8A44 0x8A45 0x8A52 \ + 0x8A48 0x8A51 0x8A4A 0x8A4C 0x8A4F 0x8C5F 0x8C81 0x8C80 \ + 0x8CBA 0x8CBE 0x8CB0 0x8CB9 0x8CB5 0x8D84 0x8D80 0x8D89 \ + 0x8DD8 0x8DD3 0x8DCD 0x8DC7 0x8DD6 0x8DDC 0x8DCF 0x8DD5 \ + 0x8DD9 0x8DC8 0x8DD7 0x8DC5 0x8EEF 0x8EF7 0x8EFA 0x8EF9 \ + 0x8EE6 0x8EEE 0x8EE5 0x8EF5 0x8EE7 0x8EE8 0x8EF6 0x8EEB \ + 0x8EF1 0x8EEC 0x8EF4 0x8EE9 0x902D 0x9034 0x902F 0x9106 \ + 0x912C 0x9104 0x90FF 0x90FC 0x9108 0x90F9 0x90FB 0x9101 \ + 0x9100 0x9107 0x9105 0x9103 0x9161 0x9164 0x915F 0x9162 \ + 0x9160 0x9201 0x920A 0x9225 0x9203 0x921A 0x9226 0x920F \ + 0x920C 0x9200 0x9212 0x91FF 0x91FD 0x9206 0x9204 0x9227 \ + 0x9202 0x921C 0x9224 0x9219 0x9217 0x9205 0x9216 0x957B \ + 0x958D 0x958C 0x9590 0x9687 0x967E 0x9688 0x9689 0x9683 \ + 0x9680 0x96C2 0x96C8 0x96C3 0x96F1 0x96F0 0x976C 0x9770 \ + 0x976E 0x9807 0x98A9 0x98EB 0x9CE6 0x9EF9 0x4E83 0x4E84 \ + 0x4EB6 0x50BD 0x50BF 0x50C6 0x50AE 0x50C4 0x50CA 0x50B4 \ + 0x50C8 0x50C2 0x50B0 0x50C1 0x50BA 0x50B1 0x50CB 0x50C9 \ + 0x50B6 0x50B8 0x51D7 0x527A 0x5278 0x527B 0x527C 0x55C3 \ + 0x55DB 0x55CC 0x55D0 0x55CB 0x55CA 0x55DD 0x55C0 0x55D4 \ + 0x55C4 0x55E9 0x55BF 0x55D2 0x558D 0x55CF 0x55D5 0x55E2 \ + 0x55D6 0x55C8 0x55F2 0x55CD 0x55D9 0x55C2 0x5714 0x5853 \ + 0x5868 0x5864 0x584F 0x584D 0x5849 0x586F 0x5855 0x584E \ + 0x585D 0x5859 0x5865 0x585B 0x583D 0x5863 0x5871 0x58FC \ + 0x5AC7 0x5AC4 0x5ACB 0x5ABA 0x5AB8 0x5AB1 0x5AB5 0x5AB0 \ + 0x5ABF 0x5AC8 0x5ABB 0x5AC6 0x5AB7 0x5AC0 0x5ACA 0x5AB4 \ + 0x5AB6 0x5ACD 0x5AB9 0x5A90 0x5BD6 0x5BD8 0x5BD9 0x5C1F \ + 0x5C33 0x5D71 0x5D63 0x5D4A 0x5D65 0x5D72 0x5D6C 0x5D5E \ + 0x5D68 0x5D67 0x5D62 0x5DF0 0x5E4F 0x5E4E 0x5E4A 0x5E4D \ + 0x5E4B 0x5EC5 0x5ECC 0x5EC6 0x5ECB 0x5EC7 0x5F40 0x5FAF \ + 0x5FAD 0x60F7 0x6149 0x614A 0x612B 0x6145 0x6136 0x6132 \ + 0x612E 0x6146 0x612F 0x614F 0x6129 0x6140 0x6220 0x9168 +38 0x6223 0x6225 0x6224 0x63C5 0x63F1 0x63EB 0x6410 0x6412 \ + 0x6409 0x6420 0x6424 0x6433 0x6443 0x641F 0x6415 0x6418 \ + 0x6439 0x6437 0x6422 0x6423 0x640C 0x6426 0x6430 0x6428 \ + 0x6441 0x6435 0x642F 0x640A 0x641A 0x6440 0x6425 0x6427 \ + 0x640B 0x63E7 0x641B 0x642E 0x6421 0x640E 0x656F 0x6592 \ + 0x65D3 0x6686 0x668C 0x6695 0x6690 0x668B 0x668A 0x6699 \ + 0x6694 0x6678 0x6720 0x6966 0x695F 0x6938 0x694E 0x6962 \ + 0x6971 0x693F 0x6945 0x696A 0x6939 0x6942 0x6957 0x6959 \ + 0x697A 0x6948 0x6949 0x6935 0x696C 0x6933 0x693D 0x6965 \ + 0x68F0 0x6978 0x6934 0x6969 0x6940 0x696F 0x6944 0x6976 \ + 0x6958 0x6941 0x6974 0x694C 0x693B 0x694B 0x6937 0x695C \ + 0x694F 0x6951 0x6932 0x6952 0x692F 0x697B 0x693C 0x6B46 \ + 0x6B45 0x6B43 0x6B42 0x6B48 0x6B41 0x6B9B 0xFA0D 0x6BFB \ + 0x6BFC 0x6BF9 0x6BF7 0x6BF8 0x6E9B 0x6ED6 0x6EC8 0x6E8F \ + 0x6EC0 0x6E9F 0x6E93 0x6E94 0x6EA0 0x6EB1 0x6EB9 0x6EC6 \ + 0x6ED2 0x6EBD 0x6EC1 0x6E9E 0x6EC9 0x6EB7 0x6EB0 0x6ECD \ + 0x6EA6 0x6ECF 0x6EB2 0x6EBE 0x6EC3 0x6EDC 0x6ED8 0x6E99 \ + 0x6E92 0x6E8E 0x6E8D 0x6EA4 0x6EA1 0x6EBF 0x6EB3 0x6ED0 \ + 0x6ECA 0x6E97 0x6EAE 0x6EA3 0x7147 0x7154 0x7152 0x7163 \ + 0x7160 0x7141 0x715D 0x7162 0x7172 0x7178 0x716A 0x7161 \ + 0x7142 0x7158 0x7143 0x714B 0x7170 0x715F 0x7150 0x7153 \ + 0x7144 0x714D 0x715A 0x724F 0x728D 0x728C 0x7291 0x7290 \ + 0x728E 0x733C 0x7342 0x733B 0x733A 0x7340 0x734A 0x7349 \ + 0x7444 0x744A 0x744B 0x7452 0x7451 0x7457 0x7440 0x744F \ + 0x7450 0x744E 0x7442 0x7446 0x744D 0x7454 0x74E1 0x74FF \ + 0x74FE 0x74FD 0x751D 0x7579 0x7577 0x6983 0x75EF 0x760F \ + 0x7603 0x75F7 0x75FE 0x75FC 0x75F9 0x75F8 0x7610 0x75FB \ + 0x75F6 0x75ED 0x75F5 0x75FD 0x7699 0x76B5 0x76DD 0x7755 \ + 0x775F 0x7760 0x7752 0x7756 0x775A 0x7769 0x7767 0x7754 \ + 0x7759 0x776D 0x77E0 0x7887 0x789A 0x7894 0x788F 0x7884 \ + 0x7895 0x7885 0x7886 0x78A1 0x7883 0x7879 0x7899 0x7880 \ + 0x7896 0x787B 0x797C 0x7982 0x797D 0x7979 0x7A11 0x7A18 +39 0x7A19 0x7A12 0x7A17 0x7A15 0x7A22 0x7A13 0x7A1B 0x7A10 \ + 0x7AA3 0x7AA2 0x7A9E 0x7AEB 0x7B66 0x7B64 0x7B6D 0x7B74 \ + 0x7B69 0x7B72 0x7B65 0x7B73 0x7B71 0x7B70 0x7B61 0x7B78 \ + 0x7B76 0x7B63 0x7CB2 0x7CB4 0x7CAF 0x7D88 0x7D86 0x7D80 \ + 0x7D8D 0x7D7F 0x7D85 0x7D7A 0x7D8E 0x7D7B 0x7D83 0x7D7C \ + 0x7D8C 0x7D94 0x7D84 0x7D7D 0x7D92 0x7F6D 0x7F6B 0x7F67 \ + 0x7F68 0x7F6C 0x7FA6 0x7FA5 0x7FA7 0x7FDB 0x7FDC 0x8021 \ + 0x8164 0x8160 0x8177 0x815C 0x8169 0x815B 0x8162 0x8172 \ + 0x6721 0x815E 0x8176 0x8167 0x816F 0x8144 0x8161 0x821D \ + 0x8249 0x8244 0x8240 0x8242 0x8245 0x84F1 0x843F 0x8456 \ + 0x8476 0x8479 0x848F 0x848D 0x8465 0x8451 0x8440 0x8486 \ + 0x8467 0x8430 0x844D 0x847D 0x845A 0x8459 0x8474 0x8473 \ + 0x845D 0x8507 0x845E 0x8437 0x843A 0x8434 0x847A 0x8443 \ + 0x8478 0x8432 0x8445 0x8429 0x83D9 0x844B 0x842F 0x8442 \ + 0x842D 0x845F 0x8470 0x8439 0x844E 0x844C 0x8452 0x846F \ + 0x84C5 0x848E 0x843B 0x8447 0x8436 0x8433 0x8468 0x847E \ + 0x8444 0x842B 0x8460 0x8454 0x846E 0x8450 0x870B 0x8704 \ + 0x86F7 0x870C 0x86FA 0x86D6 0x86F5 0x874D 0x86F8 0x870E \ + 0x8709 0x8701 0x86F6 0x870D 0x8705 0x88D6 0x88CB 0x88CD \ + 0x88CE 0x88DE 0x88DB 0x88DA 0x88CC 0x88D0 0x8985 0x899B \ + 0x89DF 0x89E5 0x89E4 0x89E1 0x89E0 0x89E2 0x89DC 0x89E6 \ + 0x8A76 0x8A86 0x8A7F 0x8A61 0x8A3F 0x8A77 0x8A82 0x8A84 \ + 0x8A75 0x8A83 0x8A81 0x8A74 0x8A7A 0x8C3C 0x8C4B 0x8C4A \ + 0x8C65 0x8C64 0x8C66 0x8C86 0x8C84 0x8C85 0x8CCC 0x8D68 \ + 0x8D69 0x8D91 0x8D8C 0x8D8E 0x8D8F 0x8D8D 0x8D93 0x8D94 \ + 0x8D90 0x8D92 0x8DF0 0x8DE0 0x8DEC 0x8DF1 0x8DEE 0x8DD0 \ + 0x8DE9 0x8DE3 0x8DE2 0x8DE7 0x8DF2 0x8DEB 0x8DF4 0x8F06 \ + 0x8EFF 0x8F01 0x8F00 0x8F05 0x8F07 0x8F08 0x8F02 0x8F0B \ + 0x9052 0x903F 0x9044 0x9049 0x903D 0x9110 0x910D 0x910F \ + 0x9111 0x9116 0x9114 0x910B 0x910E 0x916E 0x916F 0x9248 \ + 0x9252 0x9230 0x923A 0x9266 0x9233 0x9265 0x925E 0x9283 \ + 0x922E 0x924A 0x9246 0x926D 0x926C 0x924F 0x9260 0x9267 +40 0x926F 0x9236 0x9261 0x9270 0x9231 0x9254 0x9263 0x9250 \ + 0x9272 0x924E 0x9253 0x924C 0x9256 0x9232 0x959F 0x959C \ + 0x959E 0x959B 0x9692 0x9693 0x9691 0x9697 0x96CE 0x96FA \ + 0x96FD 0x96F8 0x96F5 0x9773 0x9777 0x9778 0x9772 0x980F \ + 0x980D 0x980E 0x98AC 0x98F6 0x98F9 0x99AF 0x99B2 0x99B0 \ + 0x99B5 0x9AAD 0x9AAB 0x9B5B 0x9CEA 0x9CED 0x9CE7 0x9E80 \ + 0x9EFD 0x50E6 0x50D4 0x50D7 0x50E8 0x50F3 0x50DB 0x50EA \ + 0x50DD 0x50E4 0x50D3 0x50EC 0x50F0 0x50EF 0x50E3 0x50E0 \ + 0x51D8 0x5280 0x5281 0x52E9 0x52EB 0x5330 0x53AC 0x5627 \ + 0x5615 0x560C 0x5612 0x55FC 0x560F 0x561C 0x5601 0x5613 \ + 0x5602 0x55FA 0x561D 0x5604 0x55FF 0x55F9 0x5889 0x587C \ + 0x5890 0x5898 0x5886 0x5881 0x587F 0x5874 0x588B 0x587A \ + 0x5887 0x5891 0x588E 0x5876 0x5882 0x5888 0x587B 0x5894 \ + 0x588F 0x58FE 0x596B 0x5ADC 0x5AEE 0x5AE5 0x5AD5 0x5AEA \ + 0x5ADA 0x5AED 0x5AEB 0x5AF3 0x5AE2 0x5AE0 0x5ADB 0x5AEC \ + 0x5ADE 0x5ADD 0x5AD9 0x5AE8 0x5ADF 0x5B77 0x5BE0 0x5BE3 \ + 0x5C63 0x5D82 0x5D80 0x5D7D 0x5D86 0x5D7A 0x5D81 0x5D77 \ + 0x5D8A 0x5D89 0x5D88 0x5D7E 0x5D7C 0x5D8D 0x5D79 0x5D7F \ + 0x5E58 0x5E59 0x5E53 0x5ED8 0x5ED1 0x5ED7 0x5ECE 0x5EDC \ + 0x5ED5 0x5ED9 0x5ED2 0x5ED4 0x5F44 0x5F43 0x5F6F 0x5FB6 \ + 0x612C 0x6128 0x6141 0x615E 0x6171 0x6173 0x6152 0x6153 \ + 0x6172 0x616C 0x6180 0x6174 0x6154 0x617A 0x615B 0x6165 \ + 0x613B 0x616A 0x6161 0x6156 0x6229 0x6227 0x622B 0x642B \ + 0x644D 0x645B 0x645D 0x6474 0x6476 0x6472 0x6473 0x647D \ + 0x6475 0x6466 0x64A6 0x644E 0x6482 0x645E 0x645C 0x644B \ + 0x6453 0x6460 0x6450 0x647F 0x643F 0x646C 0x646B 0x6459 \ + 0x6465 0x6477 0x6573 0x65A0 0x66A1 0x66A0 0x669F 0x6705 \ + 0x6704 0x6722 0x69B1 0x69B6 0x69C9 0x69A0 0x69CE 0x6996 \ + 0x69B0 0x69AC 0x69BC 0x6991 0x6999 0x698E 0x69A7 0x698D \ + 0x69A9 0x69BE 0x69AF 0x69BF 0x69C4 0x69BD 0x69A4 0x69D4 \ + 0x69B9 0x69CA 0x699A 0x69CF 0x69B3 0x6993 0x69AA 0x69A1 \ + 0x699E 0x69D9 0x6997 0x6990 0x69C2 0x69B5 0x69A5 0x69C6 +41 0x6B4A 0x6B4D 0x6B4B 0x6B9E 0x6B9F 0x6BA0 0x6BC3 0x6BC4 \ + 0x6BFE 0x6ECE 0x6EF5 0x6EF1 0x6F03 0x6F25 0x6EF8 0x6F37 \ + 0x6EFB 0x6F2E 0x6F09 0x6F4E 0x6F19 0x6F1A 0x6F27 0x6F18 \ + 0x6F3B 0x6F12 0x6EED 0x6F0A 0x6F36 0x6F73 0x6EF9 0x6EEE \ + 0x6F2D 0x6F40 0x6F30 0x6F3C 0x6F35 0x6EEB 0x6F07 0x6F0E \ + 0x6F43 0x6F05 0x6EFD 0x6EF6 0x6F39 0x6F1C 0x6EFC 0x6F3A \ + 0x6F1F 0x6F0D 0x6F1E 0x6F08 0x6F21 0x7187 0x7190 0x7189 \ + 0x7180 0x7185 0x7182 0x718F 0x717B 0x7186 0x7181 0x7197 \ + 0x7244 0x7253 0x7297 0x7295 0x7293 0x7343 0x734D 0x7351 \ + 0x734C 0x7462 0x7473 0x7471 0x7475 0x7472 0x7467 0x746E \ + 0x7500 0x7502 0x7503 0x757D 0x7590 0x7616 0x7608 0x760C \ + 0x7615 0x7611 0x760A 0x7614 0x76B8 0x7781 0x777C 0x7785 \ + 0x7782 0x776E 0x7780 0x776F 0x777E 0x7783 0x78B2 0x78AA \ + 0x78B4 0x78AD 0x78A8 0x787E 0x78AB 0x789E 0x78A5 0x78A0 \ + 0x78AC 0x78A2 0x78A4 0x7998 0x798A 0x798B 0x7996 0x7995 \ + 0x7994 0x7993 0x7997 0x7988 0x7992 0x7990 0x7A2B 0x7A4A \ + 0x7A30 0x7A2F 0x7A28 0x7A26 0x7AA8 0x7AAB 0x7AAC 0x7AEE \ + 0x7B88 0x7B9C 0x7B8A 0x7B91 0x7B90 0x7B96 0x7B8D 0x7B8C \ + 0x7B9B 0x7B8E 0x7B85 0x7B98 0x5284 0x7B99 0x7BA4 0x7B82 \ + 0x7CBB 0x7CBF 0x7CBC 0x7CBA 0x7DA7 0x7DB7 0x7DC2 0x7DA3 \ + 0x7DAA 0x7DC1 0x7DC0 0x7DC5 0x7D9D 0x7DCE 0x7DC4 0x7DC6 \ + 0x7DCB 0x7DCC 0x7DAF 0x7DB9 0x7D96 0x7DBC 0x7D9F 0x7DA6 \ + 0x7DAE 0x7DA9 0x7DA1 0x7DC9 0x7F73 0x7FE2 0x7FE3 0x7FE5 \ + 0x7FDE 0x8024 0x805D 0x805C 0x8189 0x8186 0x8183 0x8187 \ + 0x818D 0x818C 0x818B 0x8215 0x8497 0x84A4 0x84A1 0x849F \ + 0x84BA 0x84CE 0x84C2 0x84AC 0x84AE 0x84AB 0x84B9 0x84B4 \ + 0x84C1 0x84CD 0x84AA 0x849A 0x84B1 0x84D0 0x849D 0x84A7 \ + 0x84BB 0x84A2 0x8494 0x84C7 0x84CC 0x849B 0x84A9 0x84AF \ + 0x84A8 0x84D6 0x8498 0x84B6 0x84CF 0x84A0 0x84D7 0x84D4 \ + 0x84D2 0x84DB 0x84B0 0x8491 0x8661 0x8733 0x8723 0x8728 \ + 0x876B 0x8740 0x872E 0x871E 0x8721 0x8719 0x871B 0x8743 \ + 0x872C 0x8741 0x873E 0x8746 0x8720 0x8732 0x872A 0x872D +42 0x873C 0x8712 0x873A 0x8731 0x8735 0x8742 0x8726 0x8727 \ + 0x8738 0x8724 0x871A 0x8730 0x8711 0x88F7 0x88E7 0x88F1 \ + 0x88F2 0x88FA 0x88FE 0x88EE 0x88FC 0x88F6 0x88FB 0x88F0 \ + 0x88EC 0x88EB 0x899D 0x89A1 0x899F 0x899E 0x89E9 0x89EB \ + 0x89E8 0x8AAB 0x8A99 0x8A8B 0x8A92 0x8A8F 0x8A96 0x8C3D \ + 0x8C68 0x8C69 0x8CD5 0x8CCF 0x8CD7 0x8D96 0x8E09 0x8E02 \ + 0x8DFF 0x8E0D 0x8DFD 0x8E0A 0x8E03 0x8E07 0x8E06 0x8E05 \ + 0x8DFE 0x8E00 0x8E04 0x8F10 0x8F11 0x8F0E 0x8F0D 0x9123 \ + 0x911C 0x9120 0x9122 0x911F 0x911D 0x911A 0x9124 0x9121 \ + 0x911B 0x917A 0x9172 0x9179 0x9173 0x92A5 0x92A4 0x9276 \ + 0x929B 0x927A 0x92A0 0x9294 0x92AA 0x928D 0x92A6 0x929A \ + 0x92AB 0x9279 0x9297 0x927F 0x92A3 0x92EE 0x928E 0x9282 \ + 0x9295 0x92A2 0x927D 0x9288 0x92A1 0x928A 0x9286 0x928C \ + 0x9299 0x92A7 0x927E 0x9287 0x92A9 0x929D 0x928B 0x922D \ + 0x969E 0x96A1 0x96FF 0x9758 0x977D 0x977A 0x977E 0x9783 \ + 0x9780 0x9782 0x977B 0x9784 0x9781 0x977F 0x97CE 0x97CD \ + 0x9816 0x98AD 0x98AE 0x9902 0x9900 0x9907 0x999D 0x999C \ + 0x99C3 0x99B9 0x99BB 0x99BA 0x99C2 0x99BD 0x99C7 0x9AB1 \ + 0x9AE3 0x9AE7 0x9B3E 0x9B3F 0x9B60 0x9B61 0x9B5F 0x9CF1 \ + 0x9CF2 0x9CF5 0x9EA7 0x50FF 0x5103 0x5130 0x50F8 0x5106 \ + 0x5107 0x50F6 0x50FE 0x510B 0x510C 0x50FD 0x510A 0x528B \ + 0x528C 0x52F1 0x52EF 0x5648 0x5642 0x564C 0x5635 0x5641 \ + 0x564A 0x5649 0x5646 0x5658 0x565A 0x5640 0x5633 0x563D \ + 0x562C 0x563E 0x5638 0x562A 0x563A 0x571A 0x58AB 0x589D \ + 0x58B1 0x58A0 0x58A3 0x58AF 0x58AC 0x58A5 0x58A1 0x58FF \ + 0x5AFF 0x5AF4 0x5AFD 0x5AF7 0x5AF6 0x5B03 0x5AF8 0x5B02 \ + 0x5AF9 0x5B01 0x5B07 0x5B05 0x5B0F 0x5C67 0x5D99 0x5D97 \ + 0x5D9F 0x5D92 0x5DA2 0x5D93 0x5D95 0x5DA0 0x5D9C 0x5DA1 \ + 0x5D9A 0x5D9E 0x5E69 0x5E5D 0x5E60 0x5E5C 0x7DF3 0x5EDB \ + 0x5EDE 0x5EE1 0x5F49 0x5FB2 0x618B 0x6183 0x6179 0x61B1 \ + 0x61B0 0x61A2 0x6189 0x619B 0x6193 0x61AF 0x61AD 0x619F \ + 0x6192 0x61AA 0x61A1 0x618D 0x6166 0x61B3 0x622D 0x646E +43 0x6470 0x6496 0x64A0 0x6485 0x6497 0x649C 0x648F 0x648B \ + 0x648A 0x648C 0x64A3 0x649F 0x6468 0x64B1 0x6498 0x6576 \ + 0x657A 0x6579 0x657B 0x65B2 0x65B3 0x66B5 0x66B0 0x66A9 \ + 0x66B2 0x66B7 0x66AA 0x66AF 0x6A00 0x6A06 0x6A17 0x69E5 \ + 0x69F8 0x6A15 0x69F1 0x69E4 0x6A20 0x69FF 0x69EC 0x69E2 \ + 0x6A1B 0x6A1D 0x69FE 0x6A27 0x69F2 0x69EE 0x6A14 0x69F7 \ + 0x69E7 0x6A40 0x6A08 0x69E6 0x69FB 0x6A0D 0x69FC 0x69EB \ + 0x6A09 0x6A04 0x6A18 0x6A25 0x6A0F 0x69F6 0x6A26 0x6A07 \ + 0x69F4 0x6A16 0x6B51 0x6BA5 0x6BA3 0x6BA2 0x6BA6 0x6C01 \ + 0x6C00 0x6BFF 0x6C02 0x6F41 0x6F26 0x6F7E 0x6F87 0x6FC6 \ + 0x6F92 0x6F8D 0x6F89 0x6F8C 0x6F62 0x6F4F 0x6F85 0x6F5A \ + 0x6F96 0x6F76 0x6F6C 0x6F82 0x6F55 0x6F72 0x6F52 0x6F50 \ + 0x6F57 0x6F94 0x6F93 0x6F5D 0x6F00 0x6F61 0x6F6B 0x6F7D \ + 0x6F67 0x6F90 0x6F53 0x6F8B 0x6F69 0x6F7F 0x6F95 0x6F63 \ + 0x6F77 0x6F6A 0x6F7B 0x71B2 0x71AF 0x719B 0x71B0 0x71A0 \ + 0x719A 0x71A9 0x71B5 0x719D 0x71A5 0x719E 0x71A4 0x71A1 \ + 0x71AA 0x719C 0x71A7 0x71B3 0x7298 0x729A 0x7358 0x7352 \ + 0x735E 0x735F 0x7360 0x735D 0x735B 0x7361 0x735A 0x7359 \ + 0x7362 0x7487 0x7489 0x748A 0x7486 0x7481 0x747D 0x7485 \ + 0x7488 0x747C 0x7479 0x7508 0x7507 0x757E 0x7625 0x761E \ + 0x7619 0x761D 0x761C 0x7623 0x761A 0x7628 0x761B 0x769C \ + 0x769D 0x769E 0x769B 0x778D 0x778F 0x7789 0x7788 0x78CD \ + 0x78BB 0x78CF 0x78CC 0x78D1 0x78CE 0x78D4 0x78C8 0x78C3 \ + 0x78C4 0x78C9 0x799A 0x79A1 0x79A0 0x799C 0x79A2 0x799B \ + 0x6B76 0x7A39 0x7AB2 0x7AB4 0x7AB3 0x7BB7 0x7BCB 0x7BBE \ + 0x7BAC 0x7BCE 0x7BAF 0x7BB9 0x7BCA 0x7BB5 0x7CC5 0x7CC8 \ + 0x7CCC 0x7CCB 0x7DF7 0x7DDB 0x7DEA 0x7DE7 0x7DD7 0x7DE1 \ + 0x7E03 0x7DFA 0x7DE6 0x7DF6 0x7DF1 0x7DF0 0x7DEE 0x7DDF \ + 0x7F76 0x7FAC 0x7FB0 0x7FAD 0x7FED 0x7FEB 0x7FEA 0x7FEC \ + 0x7FE6 0x7FE8 0x8064 0x8067 0x81A3 0x819F 0x819E 0x8195 \ + 0x81A2 0x8199 0x8197 0x8216 0x824F 0x8253 0x8252 0x8250 \ + 0x824E 0x8251 0x8524 0x853B 0x850F 0x8500 0x8529 0x850E +44 0x8509 0x850D 0x851F 0x850A 0x8527 0x851C 0x84FB 0x852B \ + 0x84FA 0x8508 0x850C 0x84F4 0x852A 0x84F2 0x8515 0x84F7 \ + 0x84EB 0x84F3 0x84FC 0x8512 0x84EA 0x84E9 0x8516 0x84FE \ + 0x8528 0x851D 0x852E 0x8502 0x84FD 0x851E 0x84F6 0x8531 \ + 0x8526 0x84E7 0x84E8 0x84F0 0x84EF 0x84F9 0x8518 0x8520 \ + 0x8530 0x850B 0x8519 0x852F 0x8662 0x8756 0x8763 0x8764 \ + 0x8777 0x87E1 0x8773 0x8758 0x8754 0x875B 0x8752 0x8761 \ + 0x875A 0x8751 0x875E 0x876D 0x876A 0x8750 0x874E 0x875F \ + 0x875D 0x876F 0x876C 0x877A 0x876E 0x875C 0x8765 0x874F \ + 0x877B 0x8775 0x8762 0x8767 0x8769 0x885A 0x8905 0x890C \ + 0x8914 0x890B 0x8917 0x8918 0x8919 0x8906 0x8916 0x8911 \ + 0x890E 0x8909 0x89A2 0x89A4 0x89A3 0x89ED 0x89F0 0x89EC \ + 0x8ACF 0x8AC6 0x8AB8 0x8AD3 0x8AD1 0x8AD4 0x8AD5 0x8ABB \ + 0x8AD7 0x8ABE 0x8AC0 0x8AC5 0x8AD8 0x8AC3 0x8ABA 0x8ABD \ + 0x8AD9 0x8C3E 0x8C4D 0x8C8F 0x8CE5 0x8CDF 0x8CD9 0x8CE8 \ + 0x8CDA 0x8CDD 0x8CE7 0x8DA0 0x8D9C 0x8DA1 0x8D9B 0x8E20 \ + 0x8E23 0x8E25 0x8E24 0x8E2E 0x8E15 0x8E1B 0x8E16 0x8E11 \ + 0x8E19 0x8E26 0x8E27 0x8E14 0x8E12 0x8E18 0x8E13 0x8E1C \ + 0x8E17 0x8E1A 0x8F2C 0x8F24 0x8F18 0x8F1A 0x8F20 0x8F23 \ + 0x8F16 0x8F17 0x9073 0x9070 0x906F 0x9067 0x906B 0x912F \ + 0x912B 0x9129 0x912A 0x9132 0x9126 0x912E 0x9185 0x9186 \ + 0x918A 0x9181 0x9182 0x9184 0x9180 0x92D0 0x92C3 0x92C4 \ + 0x92C0 0x92D9 0x92B6 0x92CF 0x92F1 0x92DF 0x92D8 0x92E9 \ + 0x92D7 0x92DD 0x92CC 0x92EF 0x92C2 0x92E8 0x92CA 0x92C8 \ + 0x92CE 0x92E6 0x92CD 0x92D5 0x92C9 0x92E0 0x92DE 0x92E7 \ + 0x92D1 0x92D3 0x92B5 0x92E1 0x92C6 0x92B4 0x957C 0x95AC \ + 0x95AB 0x95AE 0x95B0 0x96A4 0x96A2 0x96D3 0x9705 0x9708 \ + 0x9702 0x975A 0x978A 0x978E 0x9788 0x97D0 0x97CF 0x981E \ + 0x981D 0x9826 0x9829 0x9828 0x9820 0x981B 0x9827 0x98B2 \ + 0x9908 0x98FA 0x9911 0x9914 0x9916 0x9917 0x9915 0x99DC \ + 0x99CD 0x99CF 0x99D3 0x99D4 0x99CE 0x99C9 0x99D6 0x99D8 \ + 0x99CB 0x99D7 0x99CC 0x9AB3 0x9AEC 0x9AEB 0x9AF3 0x9AF2 +45 0x9AF1 0x9B46 0x9B43 0x9B67 0x9B74 0x9B71 0x9B66 0x9B76 \ + 0x9B75 0x9B70 0x9B68 0x9B64 0x9B6C 0x9CFC 0x9CFA 0x9CFD \ + 0x9CFF 0x9CF7 0x9D07 0x9D00 0x9CF9 0x9CFB 0x9D08 0x9D05 \ + 0x9D04 0x9E83 0x9ED3 0x9F0F 0x9F10 0x511C 0x5113 0x5117 \ + 0x511A 0x5111 0x51DE 0x5334 0x53E1 0x5670 0x5660 0x566E \ + 0x5673 0x5666 0x5663 0x566D 0x5672 0x565E 0x5677 0x571C \ + 0x571B 0x58C8 0x58BD 0x58C9 0x58BF 0x58BA 0x58C2 0x58BC \ + 0x58C6 0x5B17 0x5B19 0x5B1B 0x5B21 0x5B14 0x5B13 0x5B10 \ + 0x5B16 0x5B28 0x5B1A 0x5B20 0x5B1E 0x5BEF 0x5DAC 0x5DB1 \ + 0x5DA9 0x5DA7 0x5DB5 0x5DB0 0x5DAE 0x5DAA 0x5DA8 0x5DB2 \ + 0x5DAD 0x5DAF 0x5DB4 0x5E67 0x5E68 0x5E66 0x5E6F 0x5EE9 \ + 0x5EE7 0x5EE6 0x5EE8 0x5EE5 0x5F4B 0x5FBC 0x619D 0x61A8 \ + 0x6196 0x61C5 0x61B4 0x61C6 0x61C1 0x61CC 0x61BA 0x61BF \ + 0x61B8 0x618C 0x64D7 0x64D6 0x64D0 0x64CF 0x64C9 0x64BD \ + 0x6489 0x64C3 0x64DB 0x64F3 0x64D9 0x6533 0x657F 0x657C \ + 0x65A2 0x66C8 0x66BE 0x66C0 0x66CA 0x66CB 0x66CF 0x66BD \ + 0x66BB 0x66BA 0x66CC 0x6723 0x6A34 0x6A66 0x6A49 0x6A67 \ + 0x6A32 0x6A68 0x6A3E 0x6A5D 0x6A6D 0x6A76 0x6A5B 0x6A51 \ + 0x6A28 0x6A5A 0x6A3B 0x6A3F 0x6A41 0x6A6A 0x6A64 0x6A50 \ + 0x6A4F 0x6A54 0x6A6F 0x6A69 0x6A60 0x6A3C 0x6A5E 0x6A56 \ + 0x6A55 0x6A4D 0x6A4E 0x6A46 0x6B55 0x6B54 0x6B56 0x6BA7 \ + 0x6BAA 0x6BAB 0x6BC8 0x6BC7 0x6C04 0x6C03 0x6C06 0x6FAD \ + 0x6FCB 0x6FA3 0x6FC7 0x6FBC 0x6FCE 0x6FC8 0x6F5E 0x6FC4 \ + 0x6FBD 0x6F9E 0x6FCA 0x6FA8 0x7004 0x6FA5 0x6FAE 0x6FBA \ + 0x6FAC 0x6FAA 0x6FCF 0x6FBF 0x6FB8 0x6FA2 0x6FC9 0x6FAB \ + 0x6FCD 0x6FAF 0x6FB2 0x6FB0 0x71C5 0x71C2 0x71BF 0x71B8 \ + 0x71D6 0x71C0 0x71C1 0x71CB 0x71D4 0x71CA 0x71C7 0x71CF \ + 0x71BD 0x71D8 0x71BC 0x71C6 0x71DA 0x71DB 0x729D 0x729E \ + 0x7369 0x7366 0x7367 0x736C 0x7365 0x736B 0x736A 0x747F \ + 0x749A 0x74A0 0x7494 0x7492 0x7495 0x74A1 0x750B 0x7580 \ + 0x762F 0x762D 0x7631 0x763D 0x7633 0x763C 0x7635 0x7632 \ + 0x7630 0x76BB 0x76E6 0x779A 0x779D 0x77A1 0x779C 0x779B +46 0x77A2 0x77A3 0x7795 0x7799 0x7797 0x78DD 0x78E9 0x78E5 \ + 0x78EA 0x78DE 0x78E3 0x78DB 0x78E1 0x78E2 0x78ED 0x78DF \ + 0x78E0 0x79A4 0x7A44 0x7A48 0x7A47 0x7AB6 0x7AB8 0x7AB5 \ + 0x7AB1 0x7AB7 0x7BDE 0x7BE3 0x7BE7 0x7BDD 0x7BD5 0x7BE5 \ + 0x7BDA 0x7BE8 0x7BF9 0x7BD4 0x7BEA 0x7BE2 0x7BDC 0x7BEB \ + 0x7BD8 0x7BDF 0x7CD2 0x7CD4 0x7CD7 0x7CD0 0x7CD1 0x7E12 \ + 0x7E21 0x7E17 0x7E0C 0x7E1F 0x7E20 0x7E13 0x7E0E 0x7E1C \ + 0x7E15 0x7E1A 0x7E22 0x7E0B 0x7E0F 0x7E16 0x7E0D 0x7E14 \ + 0x7E25 0x7E24 0x7F43 0x7F7B 0x7F7C 0x7F7A 0x7FB1 0x7FEF \ + 0x802A 0x8029 0x806C 0x81B1 0x81A6 0x81AE 0x81B9 0x81B5 \ + 0x81AB 0x81B0 0x81AC 0x81B4 0x81B2 0x81B7 0x81A7 0x81F2 \ + 0x8255 0x8256 0x8257 0x8556 0x8545 0x856B 0x854D 0x8553 \ + 0x8561 0x8558 0x8540 0x8546 0x8564 0x8541 0x8562 0x8544 \ + 0x8551 0x8547 0x8563 0x853E 0x855B 0x8571 0x854E 0x856E \ + 0x8575 0x8555 0x8567 0x8560 0x858C 0x8566 0x855D 0x8554 \ + 0x8565 0x856C 0x8663 0x8665 0x8664 0x879B 0x878F 0x8797 \ + 0x8793 0x8792 0x8788 0x8781 0x8796 0x8798 0x8779 0x8787 \ + 0x87A3 0x8785 0x8790 0x8791 0x879D 0x8784 0x8794 0x879C \ + 0x879A 0x8789 0x891E 0x8926 0x8930 0x892D 0x892E 0x8927 \ + 0x8931 0x8922 0x8929 0x8923 0x892F 0x892C 0x891F 0x89F1 \ + 0x8AE0 0x8AE2 0x8AF2 0x8AF4 0x8AF5 0x8ADD 0x8B14 0x8AE4 \ + 0x8ADF 0x8AF0 0x8AC8 0x8ADE 0x8AE1 0x8AE8 0x8AFF 0x8AEF \ + 0x8AFB 0x8C91 0x8C92 0x8C90 0x8CF5 0x8CEE 0x8CF1 0x8CF0 \ + 0x8CF3 0x8D6C 0x8D6E 0x8DA5 0x8DA7 0x8E33 0x8E3E 0x8E38 \ + 0x8E40 0x8E45 0x8E36 0x8E3C 0x8E3D 0x8E41 0x8E30 0x8E3F \ + 0x8EBD 0x8F36 0x8F2E 0x8F35 0x8F32 0x8F39 0x8F37 0x8F34 \ + 0x9076 0x9079 0x907B 0x9086 0x90FA 0x9133 0x9135 0x9136 \ + 0x9193 0x9190 0x9191 0x918D 0x918F 0x9327 0x931E 0x9308 \ + 0x931F 0x9306 0x930F 0x937A 0x9338 0x933C 0x931B 0x9323 \ + 0x9312 0x9301 0x9346 0x932D 0x930E 0x930D 0x92CB 0x931D \ + 0x92FA 0x9325 0x9313 0x92F9 0x92F7 0x9334 0x9302 0x9324 \ + 0x92FF 0x9329 0x9339 0x9335 0x932A 0x9314 0x930C 0x930B +47 0x92FE 0x9309 0x9300 0x92FB 0x9316 0x95BC 0x95CD 0x95BE \ + 0x95B9 0x95BA 0x95B6 0x95BF 0x95B5 0x95BD 0x96A9 0x96D4 \ + 0x970B 0x9712 0x9710 0x9799 0x9797 0x9794 0x97F0 0x97F8 \ + 0x9835 0x982F 0x9832 0x9924 0x991F 0x9927 0x9929 0x999E \ + 0x99EE 0x99EC 0x99E5 0x99E4 0x99F0 0x99E3 0x99EA 0x99E9 \ + 0x99E7 0x9AB9 0x9ABF 0x9AB4 0x9ABB 0x9AF6 0x9AFA 0x9AF9 \ + 0x9AF7 0x9B33 0x9B80 0x9B85 0x9B87 0x9B7C 0x9B7E 0x9B7B \ + 0x9B82 0x9B93 0x9B92 0x9B90 0x9B7A 0x9B95 0x9B7D 0x9B88 \ + 0x9D25 0x9D17 0x9D20 0x9D1E 0x9D14 0x9D29 0x9D1D 0x9D18 \ + 0x9D22 0x9D10 0x9D19 0x9D1F 0x9E88 0x9E86 0x9E87 0x9EAE \ + 0x9EAD 0x9ED5 0x9ED6 0x9EFA 0x9F12 0x9F3D 0x5126 0x5125 \ + 0x5122 0x5124 0x5120 0x5129 0x52F4 0x5693 0x568C 0x568D \ + 0x5686 0x5684 0x5683 0x567E 0x5682 0x567F 0x5681 0x58D6 \ + 0x58D4 0x58CF 0x58D2 0x5B2D 0x5B25 0x5B32 0x5B23 0x5B2C \ + 0x5B27 0x5B26 0x5B2F 0x5B2E 0x5B7B 0x5BF1 0x5BF2 0x5DB7 \ + 0x5E6C 0x5E6A 0x5FBE 0x5FBB 0x61C3 0x61B5 0x61BC 0x61E7 \ + 0x61E0 0x61E5 0x61E4 0x61E8 0x61DE 0x64EF 0x64E9 0x64E3 \ + 0x64EB 0x64E4 0x64E8 0x6581 0x6580 0x65B6 0x65DA 0x66D2 \ + 0x6A8D 0x6A96 0x6A81 0x6AA5 0x6A89 0x6A9F 0x6A9B 0x6AA1 \ + 0x6A9E 0x6A87 0x6A93 0x6A8E 0x6A95 0x6A83 0x6AA8 0x6AA4 \ + 0x6A91 0x6A7F 0x6AA6 0x6A9A 0x6A85 0x6A8C 0x6A92 0x6B5B \ + 0x6BAD 0x6C09 0x6FCC 0x6FA9 0x6FF4 0x6FD4 0x6FE3 0x6FDC \ + 0x6FED 0x6FE7 0x6FE6 0x6FDE 0x6FF2 0x6FDD 0x6FE2 0x6FE8 \ + 0x71E1 0x71F1 0x71E8 0x71F2 0x71E4 0x71F0 0x71E2 0x7373 \ + 0x736E 0x736F 0x7497 0x74B2 0x74AB 0x7490 0x74AA 0x74AD \ + 0x74B1 0x74A5 0x74AF 0x7510 0x7511 0x7512 0x750F 0x7584 \ + 0x7643 0x7648 0x7649 0x7647 0x76A4 0x76E9 0x77B5 0x77AB \ + 0x77B2 0x77B7 0x77B6 0x77B4 0x77B1 0x77A8 0x77F0 0x78F3 \ + 0x78FD 0x7902 0x78FB 0x78FC 0x78F2 0x7905 0x78F9 0x78FE \ + 0x7904 0x79AB 0x79A8 0x7A5C 0x7A5B 0x7A56 0x7A58 0x7A54 \ + 0x7A5A 0x7ABE 0x7AC0 0x7AC1 0x7C05 0x7C0F 0x7BF2 0x7C00 \ + 0x7BFF 0x7BFB 0x7C0E 0x7BF4 0x7C0B 0x7BF3 0x7C02 0x7C09 +48 0x7C03 0x7C01 0x7BF8 0x7BFD 0x7C06 0x7BF0 0x7BF1 0x7C10 \ + 0x7C0A 0x7CE8 0x7E2D 0x7E3C 0x7E42 0x7E33 0x9848 0x7E38 \ + 0x7E2A 0x7E49 0x7E40 0x7E47 0x7E29 0x7E4C 0x7E30 0x7E3B \ + 0x7E36 0x7E44 0x7E3A 0x7F45 0x7F7F 0x7F7E 0x7F7D 0x7FF4 \ + 0x7FF2 0x802C 0x81BB 0x81C4 0x81CC 0x81CA 0x81C5 0x81C7 \ + 0x81BC 0x81E9 0x825B 0x825A 0x825C 0x8583 0x8580 0x858F \ + 0x85A7 0x8595 0x85A0 0x858B 0x85A3 0x857B 0x85A4 0x859A \ + 0x859E 0x8577 0x857C 0x8589 0x85A1 0x857A 0x8578 0x8557 \ + 0x858E 0x8596 0x8586 0x858D 0x8599 0x859D 0x8581 0x85A2 \ + 0x8582 0x8588 0x8585 0x8579 0x8576 0x8598 0x8590 0x859F \ + 0x8668 0x87BE 0x87AA 0x87AD 0x87C5 0x87B0 0x87AC 0x87B9 \ + 0x87B5 0x87BC 0x87AE 0x87C9 0x87C3 0x87C2 0x87CC 0x87B7 \ + 0x87AF 0x87C4 0x87CA 0x87B4 0x87B6 0x87BF 0x87B8 0x87BD \ + 0x87DE 0x87B2 0x8935 0x8933 0x893C 0x893E 0x8941 0x8952 \ + 0x8937 0x8942 0x89AD 0x89AF 0x89AE 0x89F2 0x89F3 0x8B1E \ + 0x8B18 0x8B16 0x8B11 0x8B05 0x8B0B 0x8B22 0x8B0F 0x8B12 \ + 0x8B15 0x8B07 0x8B0D 0x8B08 0x8B06 0x8B1C 0x8B13 0x8B1A \ + 0x8C4F 0x8C70 0x8C72 0x8C71 0x8C6F 0x8C95 0x8C94 0x8CF9 \ + 0x8D6F 0x8E4E 0x8E4D 0x8E53 0x8E50 0x8E4C 0x8E47 0x8F43 \ + 0x8F40 0x9085 0x907E 0x9138 0x919A 0x91A2 0x919B 0x9199 \ + 0x919F 0x91A1 0x919D 0x91A0 0x93A1 0x9383 0x93AF 0x9364 \ + 0x9356 0x9347 0x937C 0x9358 0x935C 0x9376 0x9349 0x9350 \ + 0x9351 0x9360 0x936D 0x938F 0x934C 0x936A 0x9379 0x9357 \ + 0x9355 0x9352 0x934F 0x9371 0x9377 0x937B 0x9361 0x935E \ + 0x9363 0x9367 0x9380 0x934E 0x9359 0x95C7 0x95C0 0x95C9 \ + 0x95C3 0x95C5 0x95B7 0x96AE 0x96B0 0x96AC 0x9720 0x971F \ + 0x9718 0x971D 0x9719 0x979A 0x97A1 0x979C 0x979E 0x979D \ + 0x97D5 0x97D4 0x97F1 0x9841 0x9844 0x984A 0x9849 0x9845 \ + 0x9843 0x9925 0x992B 0x992C 0x992A 0x9933 0x9932 0x992F \ + 0x992D 0x9931 0x9930 0x9998 0x99A3 0x99A1 0x9A02 0x99FA \ + 0x99F4 0x99F7 0x99F9 0x99F8 0x99F6 0x99FB 0x99FD 0x99FE \ + 0x99FC 0x9A03 0x9ABE 0x9AFE 0x9AFD 0x9B01 0x9AFC 0x9B48 +49 0x9B9A 0x9BA8 0x9B9E 0x9B9B 0x9BA6 0x9BA1 0x9BA5 0x9BA4 \ + 0x9B86 0x9BA2 0x9BA0 0x9BAF 0x9D33 0x9D41 0x9D67 0x9D36 \ + 0x9D2E 0x9D2F 0x9D31 0x9D38 0x9D30 0x9D45 0x9D42 0x9D43 \ + 0x9D3E 0x9D37 0x9D40 0x9D3D 0x7FF5 0x9D2D 0x9E8A 0x9E89 \ + 0x9E8D 0x9EB0 0x9EC8 0x9EDA 0x9EFB 0x9EFF 0x9F24 0x9F23 \ + 0x9F22 0x9F54 0x9FA0 0x5131 0x512D 0x512E 0x5698 0x569C \ + 0x5697 0x569A 0x569D 0x5699 0x5970 0x5B3C 0x5C69 0x5C6A \ + 0x5DC0 0x5E6D 0x5E6E 0x61D8 0x61DF 0x61ED 0x61EE 0x61F1 \ + 0x61EA 0x61F0 0x61EB 0x61D6 0x61E9 0x64FF 0x6504 0x64FD \ + 0x64F8 0x6501 0x6503 0x64FC 0x6594 0x65DB 0x66DA 0x66DB \ + 0x66D8 0x6AC5 0x6AB9 0x6ABD 0x6AE1 0x6AC6 0x6ABA 0x6AB6 \ + 0x6AB7 0x6AC7 0x6AB4 0x6AAD 0x6B5E 0x6BC9 0x6C0B 0x7007 \ + 0x700C 0x700D 0x7001 0x7005 0x7014 0x700E 0x6FFF 0x7000 \ + 0x6FFB 0x7026 0x6FFC 0x6FF7 0x700A 0x7201 0x71FF 0x71F9 \ + 0x7203 0x71FD 0x7376 0x74B8 0x74C0 0x74B5 0x74C1 0x74BE \ + 0x74B6 0x74BB 0x74C2 0x7514 0x7513 0x765C 0x7664 0x7659 \ + 0x7650 0x7653 0x7657 0x765A 0x76A6 0x76BD 0x76EC 0x77C2 \ + 0x77BA 0x78FF 0x790C 0x7913 0x7914 0x7909 0x7910 0x7912 \ + 0x7911 0x79AD 0x79AC 0x7A5F 0x7C1C 0x7C29 0x7C19 0x7C20 \ + 0x7C1F 0x7C2D 0x7C1D 0x7C26 0x7C28 0x7C22 0x7C25 0x7C30 \ + 0x7E5C 0x7E50 0x7E56 0x7E63 0x7E58 0x7E62 0x7E5F 0x7E51 \ + 0x7E60 0x7E57 0x7E53 0x7FB5 0x7FB3 0x7FF7 0x7FF8 0x8075 \ + 0x81D1 0x81D2 0x81D0 0x825F 0x825E 0x85B4 0x85C6 0x85C0 \ + 0x85C3 0x85C2 0x85B3 0x85B5 0x85BD 0x85C7 0x85C4 0x85BF \ + 0x85CB 0x85CE 0x85C8 0x85C5 0x85B1 0x85B6 0x85D2 0x8624 \ + 0x85B8 0x85B7 0x85BE 0x8669 0x87E7 0x87E6 0x87E2 0x87DB \ + 0x87EB 0x87EA 0x87E5 0x87DF 0x87F3 0x87E4 0x87D4 0x87DC \ + 0x87D3 0x87ED 0x87D8 0x87E3 0x87A4 0x87D7 0x87D9 0x8801 \ + 0x87F4 0x87E8 0x87DD 0x8953 0x894B 0x894F 0x894C 0x8946 \ + 0x8950 0x8951 0x8949 0x8B2A 0x8B27 0x8B23 0x8B33 0x8B30 \ + 0x8B35 0x8B47 0x8B2F 0x8B3C 0x8B3E 0x8B31 0x8B25 0x8B37 \ + 0x8B26 0x8B36 0x8B2E 0x8B24 0x8B3B 0x8B3D 0x8B3A 0x8C42 +50 0x8C75 0x8C99 0x8C98 0x8C97 0x8CFE 0x8D04 0x8D02 0x8D00 \ + 0x8E5C 0x8E62 0x8E60 0x8E57 0x8E56 0x8E5E 0x8E65 0x8E67 \ + 0x8E5B 0x8E5A 0x8E61 0x8E5D 0x8E69 0x8E54 0x8F46 0x8F47 \ + 0x8F48 0x8F4B 0x9128 0x913A 0x913B 0x913E 0x91A8 0x91A5 \ + 0x91A7 0x91AF 0x91AA 0x93B5 0x938C 0x9392 0x93B7 0x939B \ + 0x939D 0x9389 0x93A7 0x938E 0x93AA 0x939E 0x93A6 0x9395 \ + 0x9388 0x9399 0x939F 0x938D 0x93B1 0x9391 0x93B2 0x93A4 \ + 0x93A8 0x93B4 0x93A3 0x93A5 0x95D2 0x95D3 0x95D1 0x96B3 \ + 0x96D7 0x96DA 0x5DC2 0x96DF 0x96D8 0x96DD 0x9723 0x9722 \ + 0x9725 0x97AC 0x97AE 0x97A8 0x97AB 0x97A4 0x97AA 0x97A2 \ + 0x97A5 0x97D7 0x97D9 0x97D6 0x97D8 0x97FA 0x9850 0x9851 \ + 0x9852 0x98B8 0x9941 0x993C 0x993A 0x9A0F 0x9A0B 0x9A09 \ + 0x9A0D 0x9A04 0x9A11 0x9A0A 0x9A05 0x9A07 0x9A06 0x9AC0 \ + 0x9ADC 0x9B08 0x9B04 0x9B05 0x9B29 0x9B35 0x9B4A 0x9B4C \ + 0x9B4B 0x9BC7 0x9BC6 0x9BC3 0x9BBF 0x9BC1 0x9BB5 0x9BB8 \ + 0x9BD3 0x9BB6 0x9BC4 0x9BB9 0x9BBD 0x9D5C 0x9D53 0x9D4F \ + 0x9D4A 0x9D5B 0x9D4B 0x9D59 0x9D56 0x9D4C 0x9D57 0x9D52 \ + 0x9D54 0x9D5F 0x9D58 0x9D5A 0x9E8E 0x9E8C 0x9EDF 0x9F01 \ + 0x9F00 0x9F16 0x9F25 0x9F2B 0x9F2A 0x9F29 0x9F28 0x9F4C \ + 0x9F55 0x5134 0x5135 0x5296 0x52F7 0x53B4 0x56AB 0x56AD \ + 0x56A6 0x56A7 0x56AA 0x56AC 0x58DA 0x58DD 0x58DB 0x5912 \ + 0x5B3D 0x5B3E 0x5B3F 0x5DC3 0x5E70 0x5FBF 0x61FB 0x6507 \ + 0x6510 0x650D 0x6509 0x650C 0x650E 0x6584 0x65DE 0x65DD \ + 0x66DE 0x6AE7 0x6AE0 0x6ACC 0x6AD1 0x6AD9 0x6ACB 0x6ADF \ + 0x6ADC 0x6AD0 0x6AEB 0x6ACF 0x6ACD 0x6ADE 0x6B60 0x6BB0 \ + 0x6C0C 0x7019 0x7027 0x7020 0x7016 0x702B 0x7021 0x7022 \ + 0x7023 0x7029 0x7017 0x7024 0x701C 0x702A 0x720C 0x720A \ + 0x7207 0x7202 0x7205 0x72A5 0x72A6 0x72A4 0x72A3 0x72A1 \ + 0x74CB 0x74C5 0x74B7 0x74C3 0x7516 0x7660 0x77C9 0x77CA \ + 0x77C4 0x77F1 0x791D 0x791B 0x7921 0x791C 0x7917 0x791E \ + 0x79B0 0x7A67 0x7A68 0x7C33 0x7C3C 0x7C39 0x7C2C 0x7C3B \ + 0x7CEC 0x7CEA 0x7E76 0x7E75 0x7E78 0x7E70 0x7E77 0x7E6F +51 0x7E7A 0x7E72 0x7E74 0x7E68 0x7F4B 0x7F4A 0x7F83 0x7F86 \ + 0x7FB7 0x7FFD 0x7FFE 0x8078 0x81D7 0x81D5 0x8264 0x8261 \ + 0x8263 0x85EB 0x85F1 0x85ED 0x85D9 0x85E1 0x85E8 0x85DA \ + 0x85D7 0x85EC 0x85F2 0x85F8 0x85D8 0x85DF 0x85E3 0x85DC \ + 0x85D1 0x85F0 0x85E6 0x85EF 0x85DE 0x85E2 0x8800 0x87FA \ + 0x8803 0x87F6 0x87F7 0x8809 0x880C 0x880B 0x8806 0x87FC \ + 0x8808 0x87FF 0x880A 0x8802 0x8962 0x895A 0x895B 0x8957 \ + 0x8961 0x895C 0x8958 0x895D 0x8959 0x8988 0x89B7 0x89B6 \ + 0x89F6 0x8B50 0x8B48 0x8B4A 0x8B40 0x8B53 0x8B56 0x8B54 \ + 0x8B4B 0x8B55 0x8B51 0x8B42 0x8B52 0x8B57 0x8C43 0x8C77 \ + 0x8C76 0x8C9A 0x8D06 0x8D07 0x8D09 0x8DAC 0x8DAA 0x8DAD \ + 0x8DAB 0x8E6D 0x8E78 0x8E73 0x8E6A 0x8E6F 0x8E7B 0x8EC2 \ + 0x8F52 0x8F51 0x8F4F 0x8F50 0x8F53 0x8FB4 0x9140 0x913F \ + 0x91B0 0x91AD 0x93DE 0x93C7 0x93CF 0x93C2 0x93DA 0x93D0 \ + 0x93F9 0x93EC 0x93CC 0x93D9 0x93A9 0x93E6 0x93CA 0x93D4 \ + 0x93EE 0x93E3 0x93D5 0x93C4 0x93CE 0x93C0 0x93D2 0x93E7 \ + 0x957D 0x95DA 0x95DB 0x96E1 0x9729 0x972B 0x972C 0x9728 \ + 0x9726 0x97B3 0x97B7 0x97B6 0x97DD 0x97DE 0x97DF 0x985C \ + 0x9859 0x985D 0x9857 0x98BF 0x98BD 0x98BB 0x98BE 0x9948 \ + 0x9947 0x9943 0x99A6 0x99A7 0x9A1A 0x9A15 0x9A25 0x9A1D \ + 0x9A24 0x9A1B 0x9A22 0x9A20 0x9A27 0x9A23 0x9A1E 0x9A1C \ + 0x9A14 0x9AC2 0x9B0B 0x9B0A 0x9B0E 0x9B0C 0x9B37 0x9BEA \ + 0x9BEB 0x9BE0 0x9BDE 0x9BE4 0x9BE6 0x9BE2 0x9BF0 0x9BD4 \ + 0x9BD7 0x9BEC 0x9BDC 0x9BD9 0x9BE5 0x9BD5 0x9BE1 0x9BDA \ + 0x9D77 0x9D81 0x9D8A 0x9D84 0x9D88 0x9D71 0x9D80 0x9D78 \ + 0x9D86 0x9D8B 0x9D8C 0x9D7D 0x9D6B 0x9D74 0x9D75 0x9D70 \ + 0x9D69 0x9D85 0x9D73 0x9D7B 0x9D82 0x9D6F 0x9D79 0x9D7F \ + 0x9D87 0x9D68 0x9E94 0x9E91 0x9EC0 0x9EFC 0x9F2D 0x9F40 \ + 0x9F41 0x9F4D 0x9F56 0x9F57 0x9F58 0x5337 0x56B2 0x56B5 \ + 0x56B3 0x58E3 0x5B45 0x5DC6 0x5DC7 0x5EEE 0x5EEF 0x5FC0 \ + 0x5FC1 0x61F9 0x6517 0x6516 0x6515 0x6513 0x65DF 0x66E8 \ + 0x66E3 0x66E4 0x6AF3 0x6AF0 0x6AEA 0x6AE8 0x6AF9 0x6AF1 +52 0x6AEE 0x6AEF 0x703C 0x7035 0x702F 0x7037 0x7034 0x7031 \ + 0x7042 0x7038 0x703F 0x703A 0x7039 0x7040 0x703B 0x7033 \ + 0x7041 0x7213 0x7214 0x72A8 0x737D 0x737C 0x74BA 0x76AB \ + 0x76AA 0x76BE 0x76ED 0x77CC 0x77CE 0x77CF 0x77CD 0x77F2 \ + 0x7925 0x7923 0x7927 0x7928 0x7924 0x7929 0x79B2 0x7A6E \ + 0x7A6C 0x7A6D 0x7AF7 0x7C49 0x7C48 0x7C4A 0x7C47 0x7C45 \ + 0x7CEE 0x7E7B 0x7E7E 0x7E81 0x7E80 0x7FBA 0x7FFF 0x8079 \ + 0x81DB 0x81D9 0x820B 0x8268 0x8269 0x8622 0x85FF 0x8601 \ + 0x85FE 0x861B 0x8600 0x85F6 0x8604 0x8609 0x8605 0x860C \ + 0x85FD 0x8819 0x8810 0x8811 0x8817 0x8813 0x8816 0x8963 \ + 0x8966 0x89B9 0x89F7 0x8B60 0x8B6A 0x8B5D 0x8B68 0x8B63 \ + 0x8B65 0x8B67 0x8B6D 0x8DAE 0x8E86 0x8E88 0x8E84 0x8F59 \ + 0x8F56 0x8F57 0x8F55 0x8F58 0x8F5A 0x908D 0x9143 0x9141 \ + 0x91B7 0x91B5 0x91B2 0x91B3 0x940B 0x9413 0x93FB 0x9420 \ + 0x940F 0x9414 0x93FE 0x9415 0x9410 0x9428 0x9419 0x940D \ + 0x93F5 0x9400 0x93F7 0x9407 0x940E 0x9416 0x9412 0x93FA \ + 0x9409 0x93F8 0x940A 0x93FF 0x93FC 0x940C 0x93F6 0x9411 \ + 0x9406 0x95DE 0x95E0 0x95DF 0x972E 0x972F 0x97B9 0x97BB \ + 0x97FD 0x97FE 0x9860 0x9862 0x9863 0x985F 0x98C1 0x98C2 \ + 0x9950 0x994E 0x9959 0x994C 0x994B 0x9953 0x9A32 0x9A34 \ + 0x9A31 0x9A2C 0x9A2A 0x9A36 0x9A29 0x9A2E 0x9A38 0x9A2D \ + 0x9AC7 0x9ACA 0x9AC6 0x9B10 0x9B12 0x9B11 0x9C0B 0x9C08 \ + 0x9BF7 0x9C05 0x9C12 0x9BF8 0x9C40 0x9C07 0x9C0E 0x9C06 \ + 0x9C17 0x9C14 0x9C09 0x9D9F 0x9D99 0x9DA4 0x9D9D 0x9D92 \ + 0x9D98 0x9D90 0x9D9B 0x9DA0 0x9D94 0x9D9C 0x9DAA 0x9D97 \ + 0x9DA1 0x9D9A 0x9DA2 0x9DA8 0x9D9E 0x9DA3 0x9DBF 0x9DA9 \ + 0x9D96 0x9DA6 0x9DA7 0x9E99 0x9E9B 0x9E9A 0x9EE5 0x9EE4 \ + 0x9EE7 0x9EE6 0x9F30 0x9F2E 0x9F5B 0x9F60 0x9F5E 0x9F5D \ + 0x9F59 0x9F91 0x513A 0x5139 0x5298 0x5297 0x56C3 0x56BD \ + 0x56BE 0x5B48 0x5B47 0x5DCB 0x5DCF 0x5EF1 0x61FD 0x651B \ + 0x6B02 0x6AFC 0x6B03 0x6AF8 0x6B00 0x7043 0x7044 0x704A \ + 0x7048 0x7049 0x7045 0x7046 0x721D 0x721A 0x7219 0x737E +53 0x7517 0x766A 0x77D0 0x792D 0x7931 0x792F 0x7C54 0x7C53 \ + 0x7CF2 0x7E8A 0x7E87 0x7E88 0x7E8B 0x7E86 0x7E8D 0x7F4D \ + 0x7FBB 0x8030 0x81DD 0x8618 0x862A 0x8626 0x861F 0x8623 \ + 0x861C 0x8619 0x8627 0x862E 0x8621 0x8620 0x8629 0x861E \ + 0x8625 0x8829 0x881D 0x881B 0x8820 0x8824 0x881C 0x882B \ + 0x884A 0x896D 0x8969 0x896E 0x896B 0x89FA 0x8B79 0x8B78 \ + 0x8B45 0x8B7A 0x8B7B 0x8D10 0x8D14 0x8DAF 0x8E8E 0x8E8C \ + 0x8F5E 0x8F5B 0x8F5D 0x9146 0x9144 0x9145 0x91B9 0x943F \ + 0x943B 0x9436 0x9429 0x943D 0x943C 0x9430 0x9439 0x942A \ + 0x9437 0x942C 0x9440 0x9431 0x95E5 0x95E4 0x95E3 0x9735 \ + 0x973A 0x97BF 0x97E1 0x9864 0x98C9 0x98C6 0x98C0 0x9958 \ + 0x9956 0x9A39 0x9A3D 0x9A46 0x9A44 0x9A42 0x9A41 0x9A3A \ + 0x9A3F 0x9ACD 0x9B15 0x9B17 0x9B18 0x9B16 0x9B3A 0x9B52 \ + 0x9C2B 0x9C1D 0x9C1C 0x9C2C 0x9C23 0x9C28 0x9C29 0x9C24 \ + 0x9C21 0x9DB7 0x9DB6 0x9DBC 0x9DC1 0x9DC7 0x9DCA 0x9DCF \ + 0x9DBE 0x9DC5 0x9DC3 0x9DBB 0x9DB5 0x9DCE 0x9DB9 0x9DBA \ + 0x9DAC 0x9DC8 0x9DB1 0x9DAD 0x9DCC 0x9DB3 0x9DCD 0x9DB2 \ + 0x9E7A 0x9E9C 0x9EEB 0x9EEE 0x9EED 0x9F1B 0x9F18 0x9F1A \ + 0x9F31 0x9F4E 0x9F65 0x9F64 0x9F92 0x4EB9 0x56C6 0x56C5 \ + 0x56CB 0x5971 0x5B4B 0x5B4C 0x5DD5 0x5DD1 0x5EF2 0x6521 \ + 0x6520 0x6526 0x6522 0x6B0B 0x6B08 0x6B09 0x6C0D 0x7055 \ + 0x7056 0x7057 0x7052 0x721E 0x721F 0x72A9 0x737F 0x74D8 \ + 0x74D5 0x74D9 0x74D7 0x766D 0x76AD 0x7935 0x79B4 0x7A70 \ + 0x7A71 0x7C57 0x7C5C 0x7C59 0x7C5B 0x7C5A 0x7CF4 0x7CF1 \ + 0x7E91 0x7F4F 0x7F87 0x81DE 0x826B 0x8634 0x8635 0x8633 \ + 0x862C 0x8632 0x8636 0x882C 0x8828 0x8826 0x882A 0x8825 \ + 0x8971 0x89BF 0x89BE 0x89FB 0x8B7E 0x8B84 0x8B82 0x8B86 \ + 0x8B85 0x8B7F 0x8D15 0x8E95 0x8E94 0x8E9A 0x8E92 0x8E90 \ + 0x8E96 0x8E97 0x8F60 0x8F62 0x9147 0x944C 0x9450 0x944A \ + 0x944B 0x944F 0x9447 0x9445 0x9448 0x9449 0x9446 0x973F \ + 0x97E3 0x986A 0x9869 0x98CB 0x9954 0x995B 0x9A4E 0x9A53 \ + 0x9A54 0x9A4C 0x9A4F 0x9A48 0x9A4A 0x9A49 0x9A52 0x9A50 +54 0x9AD0 0x9B19 0x9B2B 0x9B3B 0x9B56 0x9B55 0x9C46 0x9C48 \ + 0x9C3F 0x9C44 0x9C39 0x9C33 0x9C41 0x9C3C 0x9C37 0x9C34 \ + 0x9C32 0x9C3D 0x9C36 0x9DDB 0x9DD2 0x9DDE 0x9DDA 0x9DCB \ + 0x9DD0 0x9DDC 0x9DD1 0x9DDF 0x9DE9 0x9DD9 0x9DD8 0x9DD6 \ + 0x9DF5 0x9DD5 0x9DDD 0x9EB6 0x9EF0 0x9F35 0x9F33 0x9F32 \ + 0x9F42 0x9F6B 0x9F95 0x9FA2 0x513D 0x5299 0x58E8 0x58E7 \ + 0x5972 0x5B4D 0x5DD8 0x882F 0x5F4F 0x6201 0x6203 0x6204 \ + 0x6529 0x6525 0x6596 0x66EB 0x6B11 0x6B12 0x6B0F 0x6BCA \ + 0x705B 0x705A 0x7222 0x7382 0x7381 0x7383 0x7670 0x77D4 \ + 0x7C67 0x7C66 0x7E95 0x826C 0x863A 0x8640 0x8639 0x863C \ + 0x8631 0x863B 0x863E 0x8830 0x8832 0x882E 0x8833 0x8976 \ + 0x8974 0x8973 0x89FE 0x8B8C 0x8B8E 0x8B8B 0x8B88 0x8C45 \ + 0x8D19 0x8E98 0x8F64 0x8F63 0x91BC 0x9462 0x9455 0x945D \ + 0x9457 0x945E 0x97C4 0x97C5 0x9800 0x9A56 0x9A59 0x9B1E \ + 0x9B1F 0x9B20 0x9C52 0x9C58 0x9C50 0x9C4A 0x9C4D 0x9C4B \ + 0x9C55 0x9C59 0x9C4C 0x9C4E 0x9DFB 0x9DF7 0x9DEF 0x9DE3 \ + 0x9DEB 0x9DF8 0x9DE4 0x9DF6 0x9DE1 0x9DEE 0x9DE6 0x9DF2 \ + 0x9DF0 0x9DE2 0x9DEC 0x9DF4 0x9DF3 0x9DE8 0x9DED 0x9EC2 \ + 0x9ED0 0x9EF2 0x9EF3 0x9F06 0x9F1C 0x9F38 0x9F37 0x9F36 \ + 0x9F43 0x9F4F 0x9F71 0x9F70 0x9F6E 0x9F6F 0x56D3 0x56CD \ + 0x5B4E 0x5C6D 0x652D 0x66ED 0x66EE 0x6B13 0x705F 0x7061 \ + 0x705D 0x7060 0x7223 0x74DB 0x74E5 0x77D5 0x7938 0x79B7 \ + 0x79B6 0x7C6A 0x7E97 0x7F89 0x826D 0x8643 0x8838 0x8837 \ + 0x8835 0x884B 0x8B94 0x8B95 0x8E9E 0x8E9F 0x8EA0 0x8E9D \ + 0x91BE 0x91BD 0x91C2 0x946B 0x9468 0x9469 0x96E5 0x9746 \ + 0x9743 0x9747 0x97C7 0x97E5 0x9A5E 0x9AD5 0x9B59 0x9C63 \ + 0x9C67 0x9C66 0x9C62 0x9C5E 0x9C60 0x9E02 0x9DFE 0x9E07 \ + 0x9E03 0x9E06 0x9E05 0x9E00 0x9E01 0x9E09 0x9DFF 0x9DFD \ + 0x9E04 0x9EA0 0x9F1E 0x9F46 0x9F74 0x9F75 0x9F76 0x56D4 \ + 0x652E 0x65B8 0x6B18 0x6B19 0x6B17 0x6B1A 0x7062 0x7226 \ + 0x72AA 0x77D8 0x77D9 0x7939 0x7C69 0x7C6B 0x7CF6 0x7E9A \ + 0x7E98 0x7E9B 0x7E99 0x81E0 0x81E1 0x8646 0x8647 0x8648 +55 0x8979 0x897A 0x897C 0x897B 0x89FF 0x8B98 0x8B99 0x8EA5 \ + 0x8EA4 0x8EA3 0x946E 0x946D 0x946F 0x9471 0x9473 0x9749 \ + 0x9872 0x995F 0x9C68 0x9C6E 0x9C6D 0x9E0B 0x9E0D 0x9E10 \ + 0x9E0F 0x9E12 0x9E11 0x9EA1 0x9EF5 0x9F09 0x9F47 0x9F78 \ + 0x9F7B 0x9F7A 0x9F79 0x571E 0x7066 0x7C6F 0x883C 0x8DB2 \ + 0x8EA6 0x91C3 0x9474 0x9478 0x9476 0x9475 0x9A60 0x9C74 \ + 0x9C73 0x9C71 0x9C75 0x9E14 0x9E13 0x9EF6 0x9F0A 0x9FA4 \ + 0x7068 0x7065 0x7CF7 0x866A 0x883E 0x883D 0x883F 0x8B9E \ + 0x8C9C 0x8EA9 0x8EC9 0x974B 0x9873 0x9874 0x98CC 0x9961 \ + 0x99AB 0x9A64 0x9A66 0x9A67 0x9B24 0x9E15 0x9E17 0x9F48 \ + 0x6207 0x6B1E 0x7227 0x864C 0x8EA8 0x9482 0x9480 0x9481 \ + 0x9A69 0x9A68 0x9B2E 0x9E19 0x7229 0x864B 0x8B9F 0x9483 \ + 0x9C79 0x9EB7 0x7675 0x9A6B 0x9C7A 0x9E1D 0x7069 0x706A \ + 0x9EA4 0x9F7E 0x9F49 0x9F98 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +56 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +57 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +58 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UGB.sfd b/contrib/ttf2pk/data/UGB.sfd new file mode 100644 index 0000000..136c6e7 --- /dev/null +++ b/contrib/ttf2pk/data/UGB.sfd @@ -0,0 +1,1114 @@ +# UGB.sfd +# +# subfont numbers for GB 2312 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x3000 0x3001 0x3002 0x30FB 0x02C9 0x02C7 0x00A8 0x3003 \ + 0x3005 0x2015 0xFF5E 0x2225 0x2026 0x2018 0x2019 0x201C \ + 0x201D 0x3014 0x3015 0x3008 0x3009 0x300A 0x300B 0x300C \ + 0x300D 0x300E 0x300F 0x3016 0x3017 0x3010 0x3011 0x00B1 \ + 0x00D7 0x00F7 0x2236 0x2227 0x2228 0x2211 0x220F 0x222A \ + 0x2229 0x2208 0x2237 0x221A 0x22A5 0x2225 0x2220 0x2312 \ + 0x2299 0x222B 0x222E 0x2261 0x224C 0x2248 0x223D 0x221D \ + 0x2260 0x226E 0x226F 0x2264 0x2265 0x221E 0x2235 0x2234 \ + 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFF04 0x00A4 \ + 0xFFE0 0xFFE1 0x2030 0x00A7 0x2116 0x2606 0x2605 0x25CB \ + 0x25CF 0x25CE 0x25C7 0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 \ + 0x203B 0x2192 0x2190 0x2191 0x2193 0x3013 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2488 0x2489 \ + 0x248A 0x248B 0x248C 0x248D 0x248E 0x248F 0x2490 0x2491 \ + 0x2492 0x2493 0x2494 0x2495 0x2496 0x2497 0x2498 0x2499 \ + 0x249A 0x249B 0x2474 0x2475 0x2476 0x2477 0x2478 0x2479 \ + 0x247A 0x247B 0x247C 0x247D 0x247E 0x247F 0x2480 0x2481 \ + 0x2482 0x2483 0x2484 0x2485 0x2486 0x2487 0x2460 0x2461 \ + 0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 \ + 0xFFFE 0xFFFE 0x3220 0x3221 0x3222 0x3223 0x3224 0x3225 \ + 0x3226 0x3227 0x3228 0x3229 0xFFFE 0xFFFE 0x2160 0x2161 \ + 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 \ + 0x216A 0x216B 0xFFFE 0xFFFE 0xFF01 0xFF02 0xFF03 0xFFE5 \ + 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C \ + 0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 \ + 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C \ + 0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFF3C \ + 0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 +02 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C \ + 0xFF5D 0xFFE3 0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 \ + 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E \ + 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 \ + 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E \ + 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 \ + 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E \ + 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 \ + 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E \ + 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 \ + 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E \ + 0x308F 0x3090 0x3091 0x3092 0x3093 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 \ + 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 \ + 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 \ + 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 \ + 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 \ + 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 \ + 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 \ + 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 \ + 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 \ + 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 \ + 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0391 0x0392 \ + 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A \ + 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 \ + 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x03B1 0x03B2 \ + 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA +03 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 \ + 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0410 0x0411 0x0412 0x0413 \ + 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A \ + 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 \ + 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A \ + 0x042B 0x042C 0x042D 0x042E 0x042F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0430 0x0431 0x0432 0x0433 \ + 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A \ + 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 \ + 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A \ + 0x044B 0x044C 0x044D 0x044E 0x044F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x0101 0x00E1 0x01CE 0x00E0 0x0113 0x00E9 \ + 0x011B 0x00E8 0x012B 0x00ED 0x01D0 0x00EC 0x014D 0x00F3 \ + 0x01D2 0x00F2 0x016B 0x00FA 0x01D4 0x00F9 0x01D6 0x01D8 \ + 0x01DA 0x01DC 0x00FC 0x00EA 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x3105 0x3106 \ + 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E \ + 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 0x3115 0x3116 \ + 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E \ + 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 0x3125 0x3126 \ + 0x3127 0x3128 0x3129 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x2500 0x2501 0x2502 0x2503 0x2504 \ + 0x2505 0x2506 0x2507 0x2508 0x2509 0x250A 0x250B 0x250C +04 0x250D 0x250E 0x250F 0x2510 0x2511 0x2512 0x2513 0x2514 \ + 0x2515 0x2516 0x2517 0x2518 0x2519 0x251A 0x251B 0x251C \ + 0x251D 0x251E 0x251F 0x2520 0x2521 0x2522 0x2523 0x2524 \ + 0x2525 0x2526 0x2527 0x2528 0x2529 0x252A 0x252B 0x252C \ + 0x252D 0x252E 0x252F 0x2530 0x2531 0x2532 0x2533 0x2534 \ + 0x2535 0x2536 0x2537 0x2538 0x2539 0x253A 0x253B 0x253C \ + 0x253D 0x253E 0x253F 0x2540 0x2541 0x2542 0x2543 0x2544 \ + 0x2545 0x2546 0x2547 0x2548 0x2549 0x254A 0x254B 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +05 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +06 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x554A 0x963F 0x57C3 0x6328 0x54CE 0x5509 \ + 0x54C0 0x7691 0x764C 0x853C 0x77EE 0x827E 0x788D 0x7231 \ + 0x9698 0x978D 0x6C28 0x5B89 0x4FFA 0x6309 0x6697 0x5CB8 \ + 0x80FA 0x6848 0x80AE 0x6602 0x76CE 0x51F9 0x6556 0x71AC \ + 0x7FF1 0x8884 0x50B2 0x5965 0x61CA 0x6FB3 0x82AD 0x634C \ + 0x6252 0x53ED 0x5427 0x7B06 0x516B 0x75A4 0x5DF4 0x62D4 \ + 0x8DCB 0x9776 0x628A 0x8019 0x575D 0x9738 0x7F62 0x7238 \ + 0x767D 0x67CF 0x767E 0x6446 0x4F70 0x8D25 0x62DC 0x7A17 \ + 0x6591 0x73ED 0x642C 0x6273 0x822C 0x9881 0x677F 0x7248 \ + 0x626E 0x62CC 0x4F34 0x74E3 0x534A 0x529E 0x7ECA 0x90A6 \ + 0x5E2E 0x6886 0x699C 0x8180 0x7ED1 0x68D2 0x78C5 0x868C \ + 0x9551 0x508D 0x8C24 0x82DE 0x80DE 0x5305 0x8912 0x5265 \ + 0x8584 0x96F9 0x4FDD 0x5821 0x9971 0x5B9D 0x62B1 0x62A5 \ + 0x66B4 0x8C79 0x9C8D 0x7206 0x676F 0x7891 0x60B2 0x5351 \ + 0x5317 0x8F88 0x80CC 0x8D1D 0x94A1 0x500D 0x72C8 0x5907 \ + 0x60EB 0x7119 0x88AB 0x5954 0x82EF 0x672C 0x7B28 0x5D29 +07 0x7EF7 0x752D 0x6CF5 0x8E66 0x8FF8 0x903C 0x9F3B 0x6BD4 \ + 0x9119 0x7B14 0x5F7C 0x78A7 0x84D6 0x853D 0x6BD5 0x6BD9 \ + 0x6BD6 0x5E01 0x5E87 0x75F9 0x95ED 0x655D 0x5F0A 0x5FC5 \ + 0x8F9F 0x58C1 0x81C2 0x907F 0x965B 0x97AD 0x8FB9 0x7F16 \ + 0x8D2C 0x6241 0x4FBF 0x53D8 0x535E 0x8FA8 0x8FA9 0x8FAB \ + 0x904D 0x6807 0x5F6A 0x8198 0x8868 0x9CD6 0x618B 0x522B \ + 0x762A 0x5F6C 0x658C 0x6FD2 0x6EE8 0x5BBE 0x6448 0x5175 \ + 0x51B0 0x67C4 0x4E19 0x79C9 0x997C 0x70B3 0x75C5 0x5E76 \ + 0x73BB 0x83E0 0x64AD 0x62E8 0x94B5 0x6CE2 0x535A 0x52C3 \ + 0x640F 0x94C2 0x7B94 0x4F2F 0x5E1B 0x8236 0x8116 0x818A \ + 0x6E24 0x6CCA 0x9A73 0x6355 0x535C 0x54FA 0x8865 0x57E0 \ + 0x4E0D 0x5E03 0x6B65 0x7C3F 0x90E8 0x6016 0x64E6 0x731C \ + 0x88C1 0x6750 0x624D 0x8D22 0x776C 0x8E29 0x91C7 0x5F69 \ + 0x83DC 0x8521 0x9910 0x53C2 0x8695 0x6B8B 0x60ED 0x60E8 \ + 0x707F 0x82CD 0x8231 0x4ED3 0x6CA7 0x85CF 0x64CD 0x7CD9 \ + 0x69FD 0x66F9 0x8349 0x5395 0x7B56 0x4FA7 0x518C 0x6D4B \ + 0x5C42 0x8E6D 0x63D2 0x53C9 0x832C 0x8336 0x67E5 0x78B4 \ + 0x643D 0x5BDF 0x5C94 0x5DEE 0x8BE7 0x62C6 0x67F4 0x8C7A \ + 0x6400 0x63BA 0x8749 0x998B 0x8C17 0x7F20 0x94F2 0x4EA7 \ + 0x9610 0x98A4 0x660C 0x7316 0x573A 0x5C1D 0x5E38 0x957F \ + 0x507F 0x80A0 0x5382 0x655E 0x7545 0x5531 0x5021 0x8D85 \ + 0x6284 0x949E 0x671D 0x5632 0x6F6E 0x5DE2 0x5435 0x7092 \ + 0x8F66 0x626F 0x64A4 0x63A3 0x5F7B 0x6F88 0x90F4 0x81E3 \ + 0x8FB0 0x5C18 0x6668 0x5FF1 0x6C89 0x9648 0x8D81 0x886C \ + 0x6491 0x79F0 0x57CE 0x6A59 0x6210 0x5448 0x4E58 0x7A0B \ + 0x60E9 0x6F84 0x8BDA 0x627F 0x901E 0x9A8B 0x79E4 0x5403 \ + 0x75F4 0x6301 0x5319 0x6C60 0x8FDF 0x5F1B 0x9A70 0x803B \ + 0x9F7F 0x4F88 0x5C3A 0x8D64 0x7FC5 0x65A5 0x70BD 0x5145 \ + 0x51B2 0x866B 0x5D07 0x5BA0 0x62BD 0x916C 0x7574 0x8E0C \ + 0x7A20 0x6101 0x7B79 0x4EC7 0x7EF8 0x7785 0x4E11 0x81ED \ + 0x521D 0x51FA 0x6A71 0x53A8 0x8E87 0x9504 0x96CF 0x6EC1 \ + 0x9664 0x695A 0x7840 0x50A8 0x77D7 0x6410 0x89E6 0x5904 +08 0x63E3 0x5DDD 0x7A7F 0x693D 0x4F20 0x8239 0x5598 0x4E32 \ + 0x75AE 0x7A97 0x5E62 0x5E8A 0x95EF 0x521B 0x5439 0x708A \ + 0x6376 0x9524 0x5782 0x6625 0x693F 0x9187 0x5507 0x6DF3 \ + 0x7EAF 0x8822 0x6233 0x7EF0 0x75B5 0x8328 0x78C1 0x96CC \ + 0x8F9E 0x6148 0x74F7 0x8BCD 0x6B64 0x523A 0x8D50 0x6B21 \ + 0x806A 0x8471 0x56F1 0x5306 0x4ECE 0x4E1B 0x51D1 0x7C97 \ + 0x918B 0x7C07 0x4FC3 0x8E7F 0x7BE1 0x7A9C 0x6467 0x5D14 \ + 0x50AC 0x8106 0x7601 0x7CB9 0x6DEC 0x7FE0 0x6751 0x5B58 \ + 0x5BF8 0x78CB 0x64AE 0x6413 0x63AA 0x632B 0x9519 0x642D \ + 0x8FBE 0x7B54 0x7629 0x6253 0x5927 0x5446 0x6B79 0x50A3 \ + 0x6234 0x5E26 0x6B86 0x4EE3 0x8D37 0x888B 0x5F85 0x902E \ + 0x6020 0x803D 0x62C5 0x4E39 0x5355 0x90F8 0x63B8 0x80C6 \ + 0x65E6 0x6C2E 0x4F46 0x60EE 0x6DE1 0x8BDE 0x5F39 0x86CB \ + 0x5F53 0x6321 0x515A 0x8361 0x6863 0x5200 0x6363 0x8E48 \ + 0x5012 0x5C9B 0x7977 0x5BFC 0x5230 0x7A3B 0x60BC 0x9053 \ + 0x76D7 0x5FB7 0x5F97 0x7684 0x8E6C 0x706F 0x767B 0x7B49 \ + 0x77AA 0x51F3 0x9093 0x5824 0x4F4E 0x6EF4 0x8FEA 0x654C \ + 0x7B1B 0x72C4 0x6DA4 0x7FDF 0x5AE1 0x62B5 0x5E95 0x5730 \ + 0x8482 0x7B2C 0x5E1D 0x5F1F 0x9012 0x7F14 0x98A0 0x6382 \ + 0x6EC7 0x7898 0x70B9 0x5178 0x975B 0x57AB 0x7535 0x4F43 \ + 0x7538 0x5E97 0x60E6 0x5960 0x6DC0 0x6BBF 0x7889 0x53FC \ + 0x96D5 0x51CB 0x5201 0x6389 0x540A 0x9493 0x8C03 0x8DCC \ + 0x7239 0x789F 0x8776 0x8FED 0x8C0D 0x53E0 0x4E01 0x76EF \ + 0x53EE 0x9489 0x9876 0x9F0E 0x952D 0x5B9A 0x8BA2 0x4E22 \ + 0x4E1C 0x51AC 0x8463 0x61C2 0x52A8 0x680B 0x4F97 0x606B \ + 0x51BB 0x6D1E 0x515C 0x6296 0x6597 0x9661 0x8C46 0x9017 \ + 0x75D8 0x90FD 0x7763 0x6BD2 0x728A 0x72EC 0x8BFB 0x5835 \ + 0x7779 0x8D4C 0x675C 0x9540 0x809A 0x5EA6 0x6E21 0x5992 \ + 0x7AEF 0x77ED 0x953B 0x6BB5 0x65AD 0x7F0E 0x5806 0x5151 \ + 0x961F 0x5BF9 0x58A9 0x5428 0x8E72 0x6566 0x987F 0x56E4 \ + 0x949D 0x76FE 0x9041 0x6387 0x54C6 0x591A 0x593A 0x579B \ + 0x8EB2 0x6735 0x8DFA 0x8235 0x5241 0x60F0 0x5815 0x86FE +09 0x5CE8 0x9E45 0x4FC4 0x989D 0x8BB9 0x5A25 0x6076 0x5384 \ + 0x627C 0x904F 0x9102 0x997F 0x6069 0x800C 0x513F 0x8033 \ + 0x5C14 0x9975 0x6D31 0x4E8C 0x8D30 0x53D1 0x7F5A 0x7B4F \ + 0x4F10 0x4E4F 0x9600 0x6CD5 0x73D0 0x85E9 0x5E06 0x756A \ + 0x7FFB 0x6A0A 0x77FE 0x9492 0x7E41 0x51E1 0x70E6 0x53CD \ + 0x8FD4 0x8303 0x8D29 0x72AF 0x996D 0x6CDB 0x574A 0x82B3 \ + 0x65B9 0x80AA 0x623F 0x9632 0x59A8 0x4EFF 0x8BBF 0x7EBA \ + 0x653E 0x83F2 0x975E 0x5561 0x98DE 0x80A5 0x532A 0x8BFD \ + 0x5420 0x80BA 0x5E9F 0x6CB8 0x8D39 0x82AC 0x915A 0x5429 \ + 0x6C1B 0x5206 0x7EB7 0x575F 0x711A 0x6C7E 0x7C89 0x594B \ + 0x4EFD 0x5FFF 0x6124 0x7CAA 0x4E30 0x5C01 0x67AB 0x8702 \ + 0x5CF0 0x950B 0x98CE 0x75AF 0x70FD 0x9022 0x51AF 0x7F1D \ + 0x8BBD 0x5949 0x51E4 0x4F5B 0x5426 0x592B 0x6577 0x80A4 \ + 0x5B75 0x6276 0x62C2 0x8F90 0x5E45 0x6C1F 0x7B26 0x4F0F \ + 0x4FD8 0x670D 0x6D6E 0x6DAA 0x798F 0x88B1 0x5F17 0x752B \ + 0x629A 0x8F85 0x4FEF 0x91DC 0x65A7 0x812F 0x8151 0x5E9C \ + 0x8150 0x8D74 0x526F 0x8986 0x8D4B 0x590D 0x5085 0x4ED8 \ + 0x961C 0x7236 0x8179 0x8D1F 0x5BCC 0x8BA3 0x9644 0x5987 \ + 0x7F1A 0x5490 0x5676 0x560E 0x8BE5 0x6539 0x6982 0x9499 \ + 0x76D6 0x6E89 0x5E72 0x7518 0x6746 0x67D1 0x7AFF 0x809D \ + 0x8D76 0x611F 0x79C6 0x6562 0x8D63 0x5188 0x521A 0x94A2 \ + 0x7F38 0x809B 0x7EB2 0x5C97 0x6E2F 0x6760 0x7BD9 0x768B \ + 0x9AD8 0x818F 0x7F94 0x7CD5 0x641E 0x9550 0x7A3F 0x544A \ + 0x54E5 0x6B4C 0x6401 0x6208 0x9E3D 0x80F3 0x7599 0x5272 \ + 0x9769 0x845B 0x683C 0x86E4 0x9601 0x9694 0x94EC 0x4E2A \ + 0x5404 0x7ED9 0x6839 0x8DDF 0x8015 0x66F4 0x5E9A 0x7FB9 \ + 0x57C2 0x803F 0x6897 0x5DE5 0x653B 0x529F 0x606D 0x9F9A \ + 0x4F9B 0x8EAC 0x516C 0x5BAB 0x5F13 0x5DE9 0x6C5E 0x62F1 \ + 0x8D21 0x5171 0x94A9 0x52FE 0x6C9F 0x82DF 0x72D7 0x57A2 \ + 0x6784 0x8D2D 0x591F 0x8F9C 0x83C7 0x5495 0x7B8D 0x4F30 \ + 0x6CBD 0x5B64 0x59D1 0x9F13 0x53E4 0x86CA 0x9AA8 0x8C37 \ + 0x80A1 0x6545 0x987E 0x56FA 0x96C7 0x522E 0x74DC 0x5250 +10 0x5BE1 0x6302 0x8902 0x4E56 0x62D0 0x602A 0x68FA 0x5173 \ + 0x5B98 0x51A0 0x89C2 0x7BA1 0x9986 0x7F50 0x60EF 0x704C \ + 0x8D2F 0x5149 0x5E7F 0x901B 0x7470 0x89C4 0x572D 0x7845 \ + 0x5F52 0x9F9F 0x95FA 0x8F68 0x9B3C 0x8BE1 0x7678 0x6842 \ + 0x67DC 0x8DEA 0x8D35 0x523D 0x8F8A 0x6EDA 0x68CD 0x9505 \ + 0x90ED 0x56FD 0x679C 0x88F9 0x8FC7 0x54C8 0x9AB8 0x5B69 \ + 0x6D77 0x6C26 0x4EA5 0x5BB3 0x9A87 0x9163 0x61A8 0x90AF \ + 0x97E9 0x542B 0x6DB5 0x5BD2 0x51FD 0x558A 0x7F55 0x7FF0 \ + 0x64BC 0x634D 0x65F1 0x61BE 0x608D 0x710A 0x6C57 0x6C49 \ + 0x592F 0x676D 0x822A 0x58D5 0x568E 0x8C6A 0x6BEB 0x90DD \ + 0x597D 0x8017 0x53F7 0x6D69 0x5475 0x559D 0x8377 0x83CF \ + 0x6838 0x79BE 0x548C 0x4F55 0x5408 0x76D2 0x8C89 0x9602 \ + 0x6CB3 0x6DB8 0x8D6B 0x8910 0x9E64 0x8D3A 0x563F 0x9ED1 \ + 0x75D5 0x5F88 0x72E0 0x6068 0x54FC 0x4EA8 0x6A2A 0x8861 \ + 0x6052 0x8F70 0x54C4 0x70D8 0x8679 0x9E3F 0x6D2A 0x5B8F \ + 0x5F18 0x7EA2 0x5589 0x4FAF 0x7334 0x543C 0x539A 0x5019 \ + 0x540E 0x547C 0x4E4E 0x5FFD 0x745A 0x58F6 0x846B 0x80E1 \ + 0x8774 0x72D0 0x7CCA 0x6E56 0x5F27 0x864E 0x552C 0x62A4 \ + 0x4E92 0x6CAA 0x6237 0x82B1 0x54D7 0x534E 0x733E 0x6ED1 \ + 0x753B 0x5212 0x5316 0x8BDD 0x69D0 0x5F8A 0x6000 0x6DEE \ + 0x574F 0x6B22 0x73AF 0x6853 0x8FD8 0x7F13 0x6362 0x60A3 \ + 0x5524 0x75EA 0x8C62 0x7115 0x6DA3 0x5BA6 0x5E7B 0x8352 \ + 0x614C 0x9EC4 0x78FA 0x8757 0x7C27 0x7687 0x51F0 0x60F6 \ + 0x714C 0x6643 0x5E4C 0x604D 0x8C0E 0x7070 0x6325 0x8F89 \ + 0x5FBD 0x6062 0x86D4 0x56DE 0x6BC1 0x6094 0x6167 0x5349 \ + 0x60E0 0x6666 0x8D3F 0x79FD 0x4F1A 0x70E9 0x6C47 0x8BB3 \ + 0x8BF2 0x7ED8 0x8364 0x660F 0x5A5A 0x9B42 0x6D51 0x6DF7 \ + 0x8C41 0x6D3B 0x4F19 0x706B 0x83B7 0x6216 0x60D1 0x970D \ + 0x8D27 0x7978 0x51FB 0x573E 0x57FA 0x673A 0x7578 0x7A3D \ + 0x79EF 0x7B95 0x808C 0x9965 0x8FF9 0x6FC0 0x8BA5 0x9E21 \ + 0x59EC 0x7EE9 0x7F09 0x5409 0x6781 0x68D8 0x8F91 0x7C4D \ + 0x96C6 0x53CA 0x6025 0x75BE 0x6C72 0x5373 0x5AC9 0x7EA7 +11 0x6324 0x51E0 0x810A 0x5DF1 0x84DF 0x6280 0x5180 0x5B63 \ + 0x4F0E 0x796D 0x5242 0x60B8 0x6D4E 0x5BC4 0x5BC2 0x8BA1 \ + 0x8BB0 0x65E2 0x5FCC 0x9645 0x5993 0x7EE7 0x7EAA 0x5609 \ + 0x67B7 0x5939 0x4F73 0x5BB6 0x52A0 0x835A 0x988A 0x8D3E \ + 0x7532 0x94BE 0x5047 0x7A3C 0x4EF7 0x67B6 0x9A7E 0x5AC1 \ + 0x6B7C 0x76D1 0x575A 0x5C16 0x7B3A 0x95F4 0x714E 0x517C \ + 0x80A9 0x8270 0x5978 0x7F04 0x8327 0x68C0 0x67EC 0x78B1 \ + 0x7877 0x62E3 0x6361 0x7B80 0x4FED 0x526A 0x51CF 0x8350 \ + 0x69DB 0x9274 0x8DF5 0x8D31 0x89C1 0x952E 0x7BAD 0x4EF6 \ + 0x5065 0x8230 0x5251 0x996F 0x6E10 0x6E85 0x6DA7 0x5EFA \ + 0x50F5 0x59DC 0x5C06 0x6D46 0x6C5F 0x7586 0x848B 0x6868 \ + 0x5956 0x8BB2 0x5320 0x9171 0x964D 0x8549 0x6912 0x7901 \ + 0x7126 0x80F6 0x4EA4 0x90CA 0x6D47 0x9A84 0x5A07 0x56BC \ + 0x6405 0x94F0 0x77EB 0x4FA5 0x811A 0x72E1 0x89D2 0x997A \ + 0x7F34 0x7EDE 0x527F 0x6559 0x9175 0x8F7F 0x8F83 0x53EB \ + 0x7A96 0x63ED 0x63A5 0x7686 0x79F8 0x8857 0x9636 0x622A \ + 0x52AB 0x8282 0x6854 0x6770 0x6377 0x776B 0x7AED 0x6D01 \ + 0x7ED3 0x89E3 0x59D0 0x6212 0x85C9 0x82A5 0x754C 0x501F \ + 0x4ECB 0x75A5 0x8BEB 0x5C4A 0x5DFE 0x7B4B 0x65A4 0x91D1 \ + 0x4ECA 0x6D25 0x895F 0x7D27 0x9526 0x4EC5 0x8C28 0x8FDB \ + 0x9773 0x664B 0x7981 0x8FD1 0x70EC 0x6D78 0x5C3D 0x52B2 \ + 0x8346 0x5162 0x830E 0x775B 0x6676 0x9CB8 0x4EAC 0x60CA \ + 0x7CBE 0x7CB3 0x7ECF 0x4E95 0x8B66 0x666F 0x9888 0x9759 \ + 0x5883 0x656C 0x955C 0x5F84 0x75C9 0x9756 0x7ADF 0x7ADE \ + 0x51C0 0x70AF 0x7A98 0x63EA 0x7A76 0x7EA0 0x7396 0x97ED \ + 0x4E45 0x7078 0x4E5D 0x9152 0x53A9 0x6551 0x65E7 0x81FC \ + 0x8205 0x548E 0x5C31 0x759A 0x97A0 0x62D8 0x72D9 0x75BD \ + 0x5C45 0x9A79 0x83CA 0x5C40 0x5480 0x77E9 0x4E3E 0x6CAE \ + 0x805A 0x62D2 0x636E 0x5DE8 0x5177 0x8DDD 0x8E1E 0x952F \ + 0x4FF1 0x53E5 0x60E7 0x70AC 0x5267 0x6350 0x9E43 0x5A1F \ + 0x5026 0x7737 0x5377 0x7EE2 0x6485 0x652B 0x6289 0x6398 \ + 0x5014 0x7235 0x89C9 0x51B3 0x8BC0 0x7EDD 0x5747 0x83CC +12 0x94A7 0x519B 0x541B 0x5CFB 0x4FCA 0x7AE3 0x6D5A 0x90E1 \ + 0x9A8F 0x5580 0x5496 0x5361 0x54AF 0x5F00 0x63E9 0x6977 \ + 0x51EF 0x6168 0x520A 0x582A 0x52D8 0x574E 0x780D 0x770B \ + 0x5EB7 0x6177 0x7CE0 0x625B 0x6297 0x4EA2 0x7095 0x8003 \ + 0x62F7 0x70E4 0x9760 0x5777 0x82DB 0x67EF 0x68F5 0x78D5 \ + 0x9897 0x79D1 0x58F3 0x54B3 0x53EF 0x6E34 0x514B 0x523B \ + 0x5BA2 0x8BFE 0x80AF 0x5543 0x57A6 0x6073 0x5751 0x542D \ + 0x7A7A 0x6050 0x5B54 0x63A7 0x62A0 0x53E3 0x6263 0x5BC7 \ + 0x67AF 0x54ED 0x7A9F 0x82E6 0x9177 0x5E93 0x88E4 0x5938 \ + 0x57AE 0x630E 0x8DE8 0x80EF 0x5757 0x7B77 0x4FA9 0x5FEB \ + 0x5BBD 0x6B3E 0x5321 0x7B50 0x72C2 0x6846 0x77FF 0x7736 \ + 0x65F7 0x51B5 0x4E8F 0x76D4 0x5CBF 0x7AA5 0x8475 0x594E \ + 0x9B41 0x5080 0x9988 0x6127 0x6E83 0x5764 0x6606 0x6346 \ + 0x56F0 0x62EC 0x6269 0x5ED3 0x9614 0x5783 0x62C9 0x5587 \ + 0x8721 0x814A 0x8FA3 0x5566 0x83B1 0x6765 0x8D56 0x84DD \ + 0x5A6A 0x680F 0x62E6 0x7BEE 0x9611 0x5170 0x6F9C 0x8C30 \ + 0x63FD 0x89C8 0x61D2 0x7F06 0x70C2 0x6EE5 0x7405 0x6994 \ + 0x72FC 0x5ECA 0x90CE 0x6717 0x6D6A 0x635E 0x52B3 0x7262 \ + 0x8001 0x4F6C 0x59E5 0x916A 0x70D9 0x6D9D 0x52D2 0x4E50 \ + 0x96F7 0x956D 0x857E 0x78CA 0x7D2F 0x5121 0x5792 0x64C2 \ + 0x808B 0x7C7B 0x6CEA 0x68F1 0x695E 0x51B7 0x5398 0x68A8 \ + 0x7281 0x9ECE 0x7BF1 0x72F8 0x79BB 0x6F13 0x7406 0x674E \ + 0x91CC 0x9CA4 0x793C 0x8389 0x8354 0x540F 0x6817 0x4E3D \ + 0x5389 0x52B1 0x783E 0x5386 0x5229 0x5088 0x4F8B 0x4FD0 \ + 0x75E2 0x7ACB 0x7C92 0x6CA5 0x96B6 0x529B 0x7483 0x54E9 \ + 0x4FE9 0x8054 0x83B2 0x8FDE 0x9570 0x5EC9 0x601C 0x6D9F \ + 0x5E18 0x655B 0x8138 0x94FE 0x604B 0x70BC 0x7EC3 0x7CAE \ + 0x51C9 0x6881 0x7CB1 0x826F 0x4E24 0x8F86 0x91CF 0x667E \ + 0x4EAE 0x8C05 0x64A9 0x804A 0x50DA 0x7597 0x71CE 0x5BE5 \ + 0x8FBD 0x6F66 0x4E86 0x6482 0x9563 0x5ED6 0x6599 0x5217 \ + 0x88C2 0x70C8 0x52A3 0x730E 0x7433 0x6797 0x78F7 0x9716 \ + 0x4E34 0x90BB 0x9CDE 0x6DCB 0x51DB 0x8D41 0x541D 0x62CE +13 0x73B2 0x83F1 0x96F6 0x9F84 0x94C3 0x4F36 0x7F9A 0x51CC \ + 0x7075 0x9675 0x5CAD 0x9886 0x53E6 0x4EE4 0x6E9C 0x7409 \ + 0x69B4 0x786B 0x998F 0x7559 0x5218 0x7624 0x6D41 0x67F3 \ + 0x516D 0x9F99 0x804B 0x5499 0x7B3C 0x7ABF 0x9686 0x5784 \ + 0x62E2 0x9647 0x697C 0x5A04 0x6402 0x7BD3 0x6F0F 0x964B \ + 0x82A6 0x5362 0x9885 0x5E90 0x7089 0x63B3 0x5364 0x864F \ + 0x9C81 0x9E93 0x788C 0x9732 0x8DEF 0x8D42 0x9E7F 0x6F5E \ + 0x7984 0x5F55 0x9646 0x622E 0x9A74 0x5415 0x94DD 0x4FA3 \ + 0x65C5 0x5C65 0x5C61 0x7F15 0x8651 0x6C2F 0x5F8B 0x7387 \ + 0x6EE4 0x7EFF 0x5CE6 0x631B 0x5B6A 0x6EE6 0x5375 0x4E71 \ + 0x63A0 0x7565 0x62A1 0x8F6E 0x4F26 0x4ED1 0x6CA6 0x7EB6 \ + 0x8BBA 0x841D 0x87BA 0x7F57 0x903B 0x9523 0x7BA9 0x9AA1 \ + 0x88F8 0x843D 0x6D1B 0x9A86 0x7EDC 0x5988 0x9EBB 0x739B \ + 0x7801 0x8682 0x9A6C 0x9A82 0x561B 0x5417 0x57CB 0x4E70 \ + 0x9EA6 0x5356 0x8FC8 0x8109 0x7792 0x9992 0x86EE 0x6EE1 \ + 0x8513 0x66FC 0x6162 0x6F2B 0x8C29 0x8292 0x832B 0x76F2 \ + 0x6C13 0x5FD9 0x83BD 0x732B 0x8305 0x951A 0x6BDB 0x77DB \ + 0x94C6 0x536F 0x8302 0x5192 0x5E3D 0x8C8C 0x8D38 0x4E48 \ + 0x73AB 0x679A 0x6885 0x9176 0x9709 0x7164 0x6CA1 0x7709 \ + 0x5A92 0x9541 0x6BCF 0x7F8E 0x6627 0x5BD0 0x59B9 0x5A9A \ + 0x95E8 0x95F7 0x4EEC 0x840C 0x8499 0x6AAC 0x76DF 0x9530 \ + 0x731B 0x68A6 0x5B5F 0x772F 0x919A 0x9761 0x7CDC 0x8FF7 \ + 0x8C1C 0x5F25 0x7C73 0x79D8 0x89C5 0x6CCC 0x871C 0x5BC6 \ + 0x5E42 0x68C9 0x7720 0x7EF5 0x5195 0x514D 0x52C9 0x5A29 \ + 0x7F05 0x9762 0x82D7 0x63CF 0x7784 0x85D0 0x79D2 0x6E3A \ + 0x5E99 0x5999 0x8511 0x706D 0x6C11 0x62BF 0x76BF 0x654F \ + 0x60AF 0x95FD 0x660E 0x879F 0x9E23 0x94ED 0x540D 0x547D \ + 0x8C2C 0x6478 0x6479 0x8611 0x6A21 0x819C 0x78E8 0x6469 \ + 0x9B54 0x62B9 0x672B 0x83AB 0x58A8 0x9ED8 0x6CAB 0x6F20 \ + 0x5BDE 0x964C 0x8C0B 0x725F 0x67D0 0x62C7 0x7261 0x4EA9 \ + 0x59C6 0x6BCD 0x5893 0x66AE 0x5E55 0x52DF 0x6155 0x6728 \ + 0x76EE 0x7766 0x7267 0x7A46 0x62FF 0x54EA 0x5450 0x94A0 +14 0x90A3 0x5A1C 0x7EB3 0x6C16 0x4E43 0x5976 0x8010 0x5948 \ + 0x5357 0x7537 0x96BE 0x56CA 0x6320 0x8111 0x607C 0x95F9 \ + 0x6DD6 0x5462 0x9981 0x5185 0x5AE9 0x80FD 0x59AE 0x9713 \ + 0x502A 0x6CE5 0x5C3C 0x62DF 0x4F60 0x533F 0x817B 0x9006 \ + 0x6EBA 0x852B 0x62C8 0x5E74 0x78BE 0x64B5 0x637B 0x5FF5 \ + 0x5A18 0x917F 0x9E1F 0x5C3F 0x634F 0x8042 0x5B7D 0x556E \ + 0x954A 0x954D 0x6D85 0x60A8 0x67E0 0x72DE 0x51DD 0x5B81 \ + 0x62E7 0x6CDE 0x725B 0x626D 0x94AE 0x7EBD 0x8113 0x6D53 \ + 0x519C 0x5F04 0x5974 0x52AA 0x6012 0x5973 0x6696 0x8650 \ + 0x759F 0x632A 0x61E6 0x7CEF 0x8BFA 0x54E6 0x6B27 0x9E25 \ + 0x6BB4 0x85D5 0x5455 0x5076 0x6CA4 0x556A 0x8DB4 0x722C \ + 0x5E15 0x6015 0x7436 0x62CD 0x6392 0x724C 0x5F98 0x6E43 \ + 0x6D3E 0x6500 0x6F58 0x76D8 0x78D0 0x76FC 0x7554 0x5224 \ + 0x53DB 0x4E53 0x5E9E 0x65C1 0x802A 0x80D6 0x629B 0x5486 \ + 0x5228 0x70AE 0x888D 0x8DD1 0x6CE1 0x5478 0x80DA 0x57F9 \ + 0x88F4 0x8D54 0x966A 0x914D 0x4F69 0x6C9B 0x55B7 0x76C6 \ + 0x7830 0x62A8 0x70F9 0x6F8E 0x5F6D 0x84EC 0x68DA 0x787C \ + 0x7BF7 0x81A8 0x670B 0x9E4F 0x6367 0x78B0 0x576F 0x7812 \ + 0x9739 0x6279 0x62AB 0x5288 0x7435 0x6BD7 0x5564 0x813E \ + 0x75B2 0x76AE 0x5339 0x75DE 0x50FB 0x5C41 0x8B6C 0x7BC7 \ + 0x504F 0x7247 0x9A97 0x98D8 0x6F02 0x74E2 0x7968 0x6487 \ + 0x77A5 0x62FC 0x9891 0x8D2B 0x54C1 0x8058 0x4E52 0x576A \ + 0x82F9 0x840D 0x5E73 0x51ED 0x74F6 0x8BC4 0x5C4F 0x5761 \ + 0x6CFC 0x9887 0x5A46 0x7834 0x9B44 0x8FEB 0x7C95 0x5256 \ + 0x6251 0x94FA 0x4EC6 0x8386 0x8461 0x83E9 0x84B2 0x57D4 \ + 0x6734 0x5703 0x666E 0x6D66 0x8C31 0x66DD 0x7011 0x671F \ + 0x6B3A 0x6816 0x621A 0x59BB 0x4E03 0x51C4 0x6F06 0x67D2 \ + 0x6C8F 0x5176 0x68CB 0x5947 0x6B67 0x7566 0x5D0E 0x8110 \ + 0x9F50 0x65D7 0x7948 0x7941 0x9A91 0x8D77 0x5C82 0x4E5E \ + 0x4F01 0x542F 0x5951 0x780C 0x5668 0x6C14 0x8FC4 0x5F03 \ + 0x6C7D 0x6CE3 0x8BAB 0x6390 0x6070 0x6D3D 0x7275 0x6266 \ + 0x948E 0x94C5 0x5343 0x8FC1 0x7B7E 0x4EDF 0x8C26 0x4E7E +15 0x9ED4 0x94B1 0x94B3 0x524D 0x6F5C 0x9063 0x6D45 0x8C34 \ + 0x5811 0x5D4C 0x6B20 0x6B49 0x67AA 0x545B 0x8154 0x7F8C \ + 0x5899 0x8537 0x5F3A 0x62A2 0x6A47 0x9539 0x6572 0x6084 \ + 0x6865 0x77A7 0x4E54 0x4FA8 0x5DE7 0x9798 0x64AC 0x7FD8 \ + 0x5CED 0x4FCF 0x7A8D 0x5207 0x8304 0x4E14 0x602F 0x7A83 \ + 0x94A6 0x4FB5 0x4EB2 0x79E6 0x7434 0x52E4 0x82B9 0x64D2 \ + 0x79BD 0x5BDD 0x6C81 0x9752 0x8F7B 0x6C22 0x503E 0x537F \ + 0x6E05 0x64CE 0x6674 0x6C30 0x60C5 0x9877 0x8BF7 0x5E86 \ + 0x743C 0x7A77 0x79CB 0x4E18 0x90B1 0x7403 0x6C42 0x56DA \ + 0x914B 0x6CC5 0x8D8B 0x533A 0x86C6 0x66F2 0x8EAF 0x5C48 \ + 0x9A71 0x6E20 0x53D6 0x5A36 0x9F8B 0x8DA3 0x53BB 0x5708 \ + 0x98A7 0x6743 0x919B 0x6CC9 0x5168 0x75CA 0x62F3 0x72AC \ + 0x5238 0x529D 0x7F3A 0x7094 0x7638 0x5374 0x9E4A 0x69B7 \ + 0x786E 0x96C0 0x88D9 0x7FA4 0x7136 0x71C3 0x5189 0x67D3 \ + 0x74E4 0x58E4 0x6518 0x56B7 0x8BA9 0x9976 0x6270 0x7ED5 \ + 0x60F9 0x70ED 0x58EC 0x4EC1 0x4EBA 0x5FCD 0x97E7 0x4EFB \ + 0x8BA4 0x5203 0x598A 0x7EAB 0x6254 0x4ECD 0x65E5 0x620E \ + 0x8338 0x84C9 0x8363 0x878D 0x7194 0x6EB6 0x5BB9 0x7ED2 \ + 0x5197 0x63C9 0x67D4 0x8089 0x8339 0x8815 0x5112 0x5B7A \ + 0x5982 0x8FB1 0x4E73 0x6C5D 0x5165 0x8925 0x8F6F 0x962E \ + 0x854A 0x745E 0x9510 0x95F0 0x6DA6 0x82E5 0x5F31 0x6492 \ + 0x6D12 0x8428 0x816E 0x9CC3 0x585E 0x8D5B 0x4E09 0x53C1 \ + 0x4F1E 0x6563 0x6851 0x55D3 0x4E27 0x6414 0x9A9A 0x626B \ + 0x5AC2 0x745F 0x8272 0x6DA9 0x68EE 0x50E7 0x838E 0x7802 \ + 0x6740 0x5239 0x6C99 0x7EB1 0x50BB 0x5565 0x715E 0x7B5B \ + 0x6652 0x73CA 0x82EB 0x6749 0x5C71 0x5220 0x717D 0x886B \ + 0x95EA 0x9655 0x64C5 0x8D61 0x81B3 0x5584 0x6C55 0x6247 \ + 0x7F2E 0x5892 0x4F24 0x5546 0x8D4F 0x664C 0x4E0A 0x5C1A \ + 0x88F3 0x68A2 0x634E 0x7A0D 0x70E7 0x828D 0x52FA 0x97F6 \ + 0x5C11 0x54E8 0x90B5 0x7ECD 0x5962 0x8D4A 0x86C7 0x820C \ + 0x820D 0x8D66 0x6444 0x5C04 0x6151 0x6D89 0x793E 0x8BBE \ + 0x7837 0x7533 0x547B 0x4F38 0x8EAB 0x6DF1 0x5A20 0x7EC5 +16 0x795E 0x6C88 0x5BA1 0x5A76 0x751A 0x80BE 0x614E 0x6E17 \ + 0x58F0 0x751F 0x7525 0x7272 0x5347 0x7EF3 0x7701 0x76DB \ + 0x5269 0x80DC 0x5723 0x5E08 0x5931 0x72EE 0x65BD 0x6E7F \ + 0x8BD7 0x5C38 0x8671 0x5341 0x77F3 0x62FE 0x65F6 0x4EC0 \ + 0x98DF 0x8680 0x5B9E 0x8BC6 0x53F2 0x77E2 0x4F7F 0x5C4E \ + 0x9A76 0x59CB 0x5F0F 0x793A 0x58EB 0x4E16 0x67FF 0x4E8B \ + 0x62ED 0x8A93 0x901D 0x52BF 0x662F 0x55DC 0x566C 0x9002 \ + 0x4ED5 0x4F8D 0x91CA 0x9970 0x6C0F 0x5E02 0x6043 0x5BA4 \ + 0x89C6 0x8BD5 0x6536 0x624B 0x9996 0x5B88 0x5BFF 0x6388 \ + 0x552E 0x53D7 0x7626 0x517D 0x852C 0x67A2 0x68B3 0x6B8A \ + 0x6292 0x8F93 0x53D4 0x8212 0x6DD1 0x758F 0x4E66 0x8D4E \ + 0x5B70 0x719F 0x85AF 0x6691 0x66D9 0x7F72 0x8700 0x9ECD \ + 0x9F20 0x5C5E 0x672F 0x8FF0 0x6811 0x675F 0x620D 0x7AD6 \ + 0x5885 0x5EB6 0x6570 0x6F31 0x6055 0x5237 0x800D 0x6454 \ + 0x8870 0x7529 0x5E05 0x6813 0x62F4 0x971C 0x53CC 0x723D \ + 0x8C01 0x6C34 0x7761 0x7A0E 0x542E 0x77AC 0x987A 0x821C \ + 0x8BF4 0x7855 0x6714 0x70C1 0x65AF 0x6495 0x5636 0x601D \ + 0x79C1 0x53F8 0x4E1D 0x6B7B 0x8086 0x5BFA 0x55E3 0x56DB \ + 0x4F3A 0x4F3C 0x9972 0x5DF3 0x677E 0x8038 0x6002 0x9882 \ + 0x9001 0x5B8B 0x8BBC 0x8BF5 0x641C 0x8258 0x64DE 0x55FD \ + 0x82CF 0x9165 0x4FD7 0x7D20 0x901F 0x7C9F 0x50F3 0x5851 \ + 0x6EAF 0x5BBF 0x8BC9 0x8083 0x9178 0x849C 0x7B97 0x867D \ + 0x968B 0x968F 0x7EE5 0x9AD3 0x788E 0x5C81 0x7A57 0x9042 \ + 0x96A7 0x795F 0x5B59 0x635F 0x7B0B 0x84D1 0x68AD 0x5506 \ + 0x7F29 0x7410 0x7D22 0x9501 0x6240 0x584C 0x4ED6 0x5B83 \ + 0x5979 0x5854 0x736D 0x631E 0x8E4B 0x8E0F 0x80CE 0x82D4 \ + 0x62AC 0x53F0 0x6CF0 0x915E 0x592A 0x6001 0x6C70 0x574D \ + 0x644A 0x8D2A 0x762B 0x6EE9 0x575B 0x6A80 0x75F0 0x6F6D \ + 0x8C2D 0x8C08 0x5766 0x6BEF 0x8892 0x78B3 0x63A2 0x53F9 \ + 0x70AD 0x6C64 0x5858 0x642A 0x5802 0x68E0 0x819B 0x5510 \ + 0x7CD6 0x5018 0x8EBA 0x6DCC 0x8D9F 0x70EB 0x638F 0x6D9B \ + 0x6ED4 0x7EE6 0x8404 0x6843 0x9003 0x6DD8 0x9676 0x8BA8 +17 0x5957 0x7279 0x85E4 0x817E 0x75BC 0x8A8A 0x68AF 0x5254 \ + 0x8E22 0x9511 0x63D0 0x9898 0x8E44 0x557C 0x4F53 0x66FF \ + 0x568F 0x60D5 0x6D95 0x5243 0x5C49 0x5929 0x6DFB 0x586B \ + 0x7530 0x751C 0x606C 0x8214 0x8146 0x6311 0x6761 0x8FE2 \ + 0x773A 0x8DF3 0x8D34 0x94C1 0x5E16 0x5385 0x542C 0x70C3 \ + 0x6C40 0x5EF7 0x505C 0x4EAD 0x5EAD 0x633A 0x8247 0x901A \ + 0x6850 0x916E 0x77B3 0x540C 0x94DC 0x5F64 0x7AE5 0x6876 \ + 0x6345 0x7B52 0x7EDF 0x75DB 0x5077 0x6295 0x5934 0x900F \ + 0x51F8 0x79C3 0x7A81 0x56FE 0x5F92 0x9014 0x6D82 0x5C60 \ + 0x571F 0x5410 0x5154 0x6E4D 0x56E2 0x63A8 0x9893 0x817F \ + 0x8715 0x892A 0x9000 0x541E 0x5C6F 0x81C0 0x62D6 0x6258 \ + 0x8131 0x9E35 0x9640 0x9A6E 0x9A7C 0x692D 0x59A5 0x62D3 \ + 0x553E 0x6316 0x54C7 0x86D9 0x6D3C 0x5A03 0x74E6 0x889C \ + 0x6B6A 0x5916 0x8C4C 0x5F2F 0x6E7E 0x73A9 0x987D 0x4E38 \ + 0x70F7 0x5B8C 0x7897 0x633D 0x665A 0x7696 0x60CB 0x5B9B \ + 0x5A49 0x4E07 0x8155 0x6C6A 0x738B 0x4EA1 0x6789 0x7F51 \ + 0x5F80 0x65FA 0x671B 0x5FD8 0x5984 0x5A01 0x5DCD 0x5FAE \ + 0x5371 0x97E6 0x8FDD 0x6845 0x56F4 0x552F 0x60DF 0x4E3A \ + 0x6F4D 0x7EF4 0x82C7 0x840E 0x59D4 0x4F1F 0x4F2A 0x5C3E \ + 0x7EAC 0x672A 0x851A 0x5473 0x754F 0x80C3 0x5582 0x9B4F \ + 0x4F4D 0x6E2D 0x8C13 0x5C09 0x6170 0x536B 0x761F 0x6E29 \ + 0x868A 0x6587 0x95FB 0x7EB9 0x543B 0x7A33 0x7D0A 0x95EE \ + 0x55E1 0x7FC1 0x74EE 0x631D 0x8717 0x6DA1 0x7A9D 0x6211 \ + 0x65A1 0x5367 0x63E1 0x6C83 0x5DEB 0x545C 0x94A8 0x4E4C \ + 0x6C61 0x8BEC 0x5C4B 0x65E0 0x829C 0x68A7 0x543E 0x5434 \ + 0x6BCB 0x6B66 0x4E94 0x6342 0x5348 0x821E 0x4F0D 0x4FAE \ + 0x575E 0x620A 0x96FE 0x6664 0x7269 0x52FF 0x52A1 0x609F \ + 0x8BEF 0x6614 0x7199 0x6790 0x897F 0x7852 0x77FD 0x6670 \ + 0x563B 0x5438 0x9521 0x727A 0x7A00 0x606F 0x5E0C 0x6089 \ + 0x819D 0x5915 0x60DC 0x7184 0x70EF 0x6EAA 0x6C50 0x7280 \ + 0x6A84 0x88AD 0x5E2D 0x4E60 0x5AB3 0x559C 0x94E3 0x6D17 \ + 0x7CFB 0x9699 0x620F 0x7EC6 0x778E 0x867E 0x5323 0x971E +18 0x8F96 0x6687 0x5CE1 0x4FA0 0x72ED 0x4E0B 0x53A6 0x590F \ + 0x5413 0x6380 0x9528 0x5148 0x4ED9 0x9C9C 0x7EA4 0x54B8 \ + 0x8D24 0x8854 0x8237 0x95F2 0x6D8E 0x5F26 0x5ACC 0x663E \ + 0x9669 0x73B0 0x732E 0x53BF 0x817A 0x9985 0x7FA1 0x5BAA \ + 0x9677 0x9650 0x7EBF 0x76F8 0x53A2 0x9576 0x9999 0x7BB1 \ + 0x8944 0x6E58 0x4E61 0x7FD4 0x7965 0x8BE6 0x60F3 0x54CD \ + 0x4EAB 0x9879 0x5DF7 0x6A61 0x50CF 0x5411 0x8C61 0x8427 \ + 0x785D 0x9704 0x524A 0x54EE 0x56A3 0x9500 0x6D88 0x5BB5 \ + 0x6DC6 0x6653 0x5C0F 0x5B5D 0x6821 0x8096 0x5578 0x7B11 \ + 0x6548 0x6954 0x4E9B 0x6B47 0x874E 0x978B 0x534F 0x631F \ + 0x643A 0x90AA 0x659C 0x80C1 0x8C10 0x5199 0x68B0 0x5378 \ + 0x87F9 0x61C8 0x6CC4 0x6CFB 0x8C22 0x5C51 0x85AA 0x82AF \ + 0x950C 0x6B23 0x8F9B 0x65B0 0x5FFB 0x5FC3 0x4FE1 0x8845 \ + 0x661F 0x8165 0x7329 0x60FA 0x5174 0x5211 0x578B 0x5F62 \ + 0x90A2 0x884C 0x9192 0x5E78 0x674F 0x6027 0x59D3 0x5144 \ + 0x51F6 0x80F8 0x5308 0x6C79 0x96C4 0x718A 0x4F11 0x4FEE \ + 0x7F9E 0x673D 0x55C5 0x9508 0x79C0 0x8896 0x7EE3 0x589F \ + 0x620C 0x9700 0x865A 0x5618 0x987B 0x5F90 0x8BB8 0x84C4 \ + 0x9157 0x53D9 0x65ED 0x5E8F 0x755C 0x6064 0x7D6E 0x5A7F \ + 0x7EEA 0x7EED 0x8F69 0x55A7 0x5BA3 0x60AC 0x65CB 0x7384 \ + 0x9009 0x7663 0x7729 0x7EDA 0x9774 0x859B 0x5B66 0x7A74 \ + 0x96EA 0x8840 0x52CB 0x718F 0x5FAA 0x65EC 0x8BE2 0x5BFB \ + 0x9A6F 0x5DE1 0x6B89 0x6C5B 0x8BAD 0x8BAF 0x900A 0x8FC5 \ + 0x538B 0x62BC 0x9E26 0x9E2D 0x5440 0x4E2B 0x82BD 0x7259 \ + 0x869C 0x5D16 0x8859 0x6DAF 0x96C5 0x54D1 0x4E9A 0x8BB6 \ + 0x7109 0x54BD 0x9609 0x70DF 0x6DF9 0x76D0 0x4E25 0x7814 \ + 0x8712 0x5CA9 0x5EF6 0x8A00 0x989C 0x960E 0x708E 0x6CBF \ + 0x5944 0x63A9 0x773C 0x884D 0x6F14 0x8273 0x5830 0x71D5 \ + 0x538C 0x781A 0x96C1 0x5501 0x5F66 0x7130 0x5BB4 0x8C1A \ + 0x9A8C 0x6B83 0x592E 0x9E2F 0x79E7 0x6768 0x626C 0x4F6F \ + 0x75A1 0x7F8A 0x6D0B 0x9633 0x6C27 0x4EF0 0x75D2 0x517B \ + 0x6837 0x6F3E 0x9080 0x8170 0x5996 0x7476 0x6447 0x5C27 +19 0x9065 0x7A91 0x8C23 0x59DA 0x54AC 0x8200 0x836F 0x8981 \ + 0x8000 0x6930 0x564E 0x8036 0x7237 0x91CE 0x51B6 0x4E5F \ + 0x9875 0x6396 0x4E1A 0x53F6 0x66F3 0x814B 0x591C 0x6DB2 \ + 0x4E00 0x58F9 0x533B 0x63D6 0x94F1 0x4F9D 0x4F0A 0x8863 \ + 0x9890 0x5937 0x9057 0x79FB 0x4EEA 0x80F0 0x7591 0x6C82 \ + 0x5B9C 0x59E8 0x5F5D 0x6905 0x8681 0x501A 0x5DF2 0x4E59 \ + 0x77E3 0x4EE5 0x827A 0x6291 0x6613 0x9091 0x5C79 0x4EBF \ + 0x5F79 0x81C6 0x9038 0x8084 0x75AB 0x4EA6 0x88D4 0x610F \ + 0x6BC5 0x5FC6 0x4E49 0x76CA 0x6EA2 0x8BE3 0x8BAE 0x8C0A \ + 0x8BD1 0x5F02 0x7FFC 0x7FCC 0x7ECE 0x8335 0x836B 0x56E0 \ + 0x6BB7 0x97F3 0x9634 0x59FB 0x541F 0x94F6 0x6DEB 0x5BC5 \ + 0x996E 0x5C39 0x5F15 0x9690 0x5370 0x82F1 0x6A31 0x5A74 \ + 0x9E70 0x5E94 0x7F28 0x83B9 0x8424 0x8425 0x8367 0x8747 \ + 0x8FCE 0x8D62 0x76C8 0x5F71 0x9896 0x786C 0x6620 0x54DF \ + 0x62E5 0x4F63 0x81C3 0x75C8 0x5EB8 0x96CD 0x8E0A 0x86F9 \ + 0x548F 0x6CF3 0x6D8C 0x6C38 0x607F 0x52C7 0x7528 0x5E7D \ + 0x4F18 0x60A0 0x5FE7 0x5C24 0x7531 0x90AE 0x94C0 0x72B9 \ + 0x6CB9 0x6E38 0x9149 0x6709 0x53CB 0x53F3 0x4F51 0x91C9 \ + 0x8BF1 0x53C8 0x5E7C 0x8FC2 0x6DE4 0x4E8E 0x76C2 0x6986 \ + 0x865E 0x611A 0x8206 0x4F59 0x4FDE 0x903E 0x9C7C 0x6109 \ + 0x6E1D 0x6E14 0x9685 0x4E88 0x5A31 0x96E8 0x4E0E 0x5C7F \ + 0x79B9 0x5B87 0x8BED 0x7FBD 0x7389 0x57DF 0x828B 0x90C1 \ + 0x5401 0x9047 0x55BB 0x5CEA 0x5FA1 0x6108 0x6B32 0x72F1 \ + 0x80B2 0x8A89 0x6D74 0x5BD3 0x88D5 0x9884 0x8C6B 0x9A6D \ + 0x9E33 0x6E0A 0x51A4 0x5143 0x57A3 0x8881 0x539F 0x63F4 \ + 0x8F95 0x56ED 0x5458 0x5706 0x733F 0x6E90 0x7F18 0x8FDC \ + 0x82D1 0x613F 0x6028 0x9662 0x66F0 0x7EA6 0x8D8A 0x8DC3 \ + 0x94A5 0x5CB3 0x7CA4 0x6708 0x60A6 0x9605 0x8018 0x4E91 \ + 0x90E7 0x5300 0x9668 0x5141 0x8FD0 0x8574 0x915D 0x6655 \ + 0x97F5 0x5B55 0x531D 0x7838 0x6742 0x683D 0x54C9 0x707E \ + 0x5BB0 0x8F7D 0x518D 0x5728 0x54B1 0x6512 0x6682 0x8D5E \ + 0x8D43 0x810F 0x846C 0x906D 0x7CDF 0x51FF 0x85FB 0x67A3 +20 0x65E9 0x6FA1 0x86A4 0x8E81 0x566A 0x9020 0x7682 0x7076 \ + 0x71E5 0x8D23 0x62E9 0x5219 0x6CFD 0x8D3C 0x600E 0x589E \ + 0x618E 0x66FE 0x8D60 0x624E 0x55B3 0x6E23 0x672D 0x8F67 \ + 0x94E1 0x95F8 0x7728 0x6805 0x69A8 0x548B 0x4E4D 0x70B8 \ + 0x8BC8 0x6458 0x658B 0x5B85 0x7A84 0x503A 0x5BE8 0x77BB \ + 0x6BE1 0x8A79 0x7C98 0x6CBE 0x76CF 0x65A9 0x8F97 0x5D2D \ + 0x5C55 0x8638 0x6808 0x5360 0x6218 0x7AD9 0x6E5B 0x7EFD \ + 0x6A1F 0x7AE0 0x5F70 0x6F33 0x5F20 0x638C 0x6DA8 0x6756 \ + 0x4E08 0x5E10 0x8D26 0x4ED7 0x80C0 0x7634 0x969C 0x62DB \ + 0x662D 0x627E 0x6CBC 0x8D75 0x7167 0x7F69 0x5146 0x8087 \ + 0x53EC 0x906E 0x6298 0x54F2 0x86F0 0x8F99 0x8005 0x9517 \ + 0x8517 0x8FD9 0x6D59 0x73CD 0x659F 0x771F 0x7504 0x7827 \ + 0x81FB 0x8D1E 0x9488 0x4FA6 0x6795 0x75B9 0x8BCA 0x9707 \ + 0x632F 0x9547 0x9635 0x84B8 0x6323 0x7741 0x5F81 0x72F0 \ + 0x4E89 0x6014 0x6574 0x62EF 0x6B63 0x653F 0x5E27 0x75C7 \ + 0x90D1 0x8BC1 0x829D 0x679D 0x652F 0x5431 0x8718 0x77E5 \ + 0x80A2 0x8102 0x6C41 0x4E4B 0x7EC7 0x804C 0x76F4 0x690D \ + 0x6B96 0x6267 0x503C 0x4F84 0x5740 0x6307 0x6B62 0x8DBE \ + 0x53EA 0x65E8 0x7EB8 0x5FD7 0x631A 0x63B7 0x81F3 0x81F4 \ + 0x7F6E 0x5E1C 0x5CD9 0x5236 0x667A 0x79E9 0x7A1A 0x8D28 \ + 0x7099 0x75D4 0x6EDE 0x6CBB 0x7A92 0x4E2D 0x76C5 0x5FE0 \ + 0x949F 0x8877 0x7EC8 0x79CD 0x80BF 0x91CD 0x4EF2 0x4F17 \ + 0x821F 0x5468 0x5DDE 0x6D32 0x8BCC 0x7CA5 0x8F74 0x8098 \ + 0x5E1A 0x5492 0x76B1 0x5B99 0x663C 0x9AA4 0x73E0 0x682A \ + 0x86DB 0x6731 0x732A 0x8BF8 0x8BDB 0x9010 0x7AF9 0x70DB \ + 0x716E 0x62C4 0x77A9 0x5631 0x4E3B 0x8457 0x67F1 0x52A9 \ + 0x86C0 0x8D2E 0x94F8 0x7B51 0x4F4F 0x6CE8 0x795D 0x9A7B \ + 0x6293 0x722A 0x62FD 0x4E13 0x7816 0x8F6C 0x64B0 0x8D5A \ + 0x7BC6 0x6869 0x5E84 0x88C5 0x5986 0x649E 0x58EE 0x72B6 \ + 0x690E 0x9525 0x8FFD 0x8D58 0x5760 0x7F00 0x8C06 0x51C6 \ + 0x6349 0x62D9 0x5353 0x684C 0x7422 0x8301 0x914C 0x5544 \ + 0x7740 0x707C 0x6D4A 0x5179 0x54A8 0x8D44 0x59FF 0x6ECB +21 0x6DC4 0x5B5C 0x7D2B 0x4ED4 0x7C7D 0x6ED3 0x5B50 0x81EA \ + 0x6E0D 0x5B57 0x9B03 0x68D5 0x8E2A 0x5B97 0x7EFC 0x603B \ + 0x7EB5 0x90B9 0x8D70 0x594F 0x63CD 0x79DF 0x8DB3 0x5352 \ + 0x65CF 0x7956 0x8BC5 0x963B 0x7EC4 0x94BB 0x7E82 0x5634 \ + 0x9189 0x6700 0x7F6A 0x5C0A 0x9075 0x6628 0x5DE6 0x4F50 \ + 0x67DE 0x505A 0x4F5C 0x5750 0x5EA7 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x4E8D 0x4E0C 0x5140 0x4E10 0x5EFF 0x5345 \ + 0x4E15 0x4E98 0x4E1E 0x9B32 0x5B6C 0x5669 0x4E28 0x79BA \ + 0x4E3F 0x5315 0x4E47 0x592D 0x723B 0x536E 0x6C10 0x56DF \ + 0x80E4 0x9997 0x6BD3 0x777E 0x9F17 0x4E36 0x4E9F 0x9F10 \ + 0x4E5C 0x4E69 0x4E93 0x8288 0x5B5B 0x556C 0x560F 0x4EC4 \ + 0x538D 0x539D 0x53A3 0x53A5 0x53AE 0x9765 0x8D5D 0x531A \ + 0x53F5 0x5326 0x532E 0x533E 0x8D5C 0x5366 0x5363 0x5202 \ + 0x5208 0x520E 0x522D 0x5233 0x523F 0x5240 0x524C 0x525E \ + 0x5261 0x525C 0x84AF 0x527D 0x5282 0x5281 0x5290 0x5293 \ + 0x5182 0x7F54 0x4EBB 0x4EC3 0x4EC9 0x4EC2 0x4EE8 0x4EE1 \ + 0x4EEB 0x4EDE 0x4F1B 0x4EF3 0x4F22 0x4F64 0x4EF5 0x4F25 \ + 0x4F27 0x4F09 0x4F2B 0x4F5E 0x4F67 0x6538 0x4F5A 0x4F5D \ + 0x4F5F 0x4F57 0x4F32 0x4F3D 0x4F76 0x4F74 0x4F91 0x4F89 \ + 0x4F83 0x4F8F 0x4F7E 0x4F7B 0x4FAA 0x4F7C 0x4FAC 0x4F94 \ + 0x4FE6 0x4FE8 0x4FEA 0x4FC5 0x4FDA 0x4FE3 0x4FDC 0x4FD1 \ + 0x4FDF 0x4FF8 0x5029 0x504C 0x4FF3 0x502C 0x500F 0x502E \ + 0x502D 0x4FFE 0x501C 0x500C 0x5025 0x5028 0x507E 0x5043 \ + 0x5055 0x5048 0x504E 0x506C 0x507B 0x50A5 0x50A7 0x50A9 \ + 0x50BA 0x50D6 0x5106 0x50ED 0x50EC 0x50E6 0x50EE 0x5107 \ + 0x510B 0x4EDD 0x6C3D 0x4F58 0x4F65 0x4FCE 0x9FA0 0x6C46 \ + 0x7C74 0x516E 0x5DFD 0x9EC9 0x9998 0x5181 0x5914 0x52F9 \ + 0x530D 0x8A07 0x5310 0x51EB 0x5919 0x5155 0x4EA0 0x5156 \ + 0x4EB3 0x886E 0x88A4 0x4EB5 0x8114 0x88D2 0x7980 0x5B34 \ + 0x8803 0x7FB8 0x51AB 0x51B1 0x51BD 0x51BC 0x51C7 0x5196 \ + 0x51A2 0x51A5 0x8BA0 0x8BA6 0x8BA7 0x8BAA 0x8BB4 0x8BB5 \ + 0x8BB7 0x8BC2 0x8BC3 0x8BCB 0x8BCF 0x8BCE 0x8BD2 0x8BD3 +22 0x8BD4 0x8BD6 0x8BD8 0x8BD9 0x8BDC 0x8BDF 0x8BE0 0x8BE4 \ + 0x8BE8 0x8BE9 0x8BEE 0x8BF0 0x8BF3 0x8BF6 0x8BF9 0x8BFC \ + 0x8BFF 0x8C00 0x8C02 0x8C04 0x8C07 0x8C0C 0x8C0F 0x8C11 \ + 0x8C12 0x8C14 0x8C15 0x8C16 0x8C19 0x8C1B 0x8C18 0x8C1D \ + 0x8C1F 0x8C20 0x8C21 0x8C25 0x8C27 0x8C2A 0x8C2B 0x8C2E \ + 0x8C2F 0x8C32 0x8C33 0x8C35 0x8C36 0x5369 0x537A 0x961D \ + 0x9622 0x9621 0x9631 0x962A 0x963D 0x963C 0x9642 0x9649 \ + 0x9654 0x965F 0x9667 0x966C 0x9672 0x9674 0x9688 0x968D \ + 0x9697 0x96B0 0x9097 0x909B 0x909D 0x9099 0x90AC 0x90A1 \ + 0x90B4 0x90B3 0x90B6 0x90BA 0x90B8 0x90B0 0x90CF 0x90C5 \ + 0x90BE 0x90D0 0x90C4 0x90C7 0x90D3 0x90E6 0x90E2 0x90DC \ + 0x90D7 0x90DB 0x90EB 0x90EF 0x90FE 0x9104 0x9122 0x911E \ + 0x9123 0x9131 0x912F 0x9139 0x9143 0x9146 0x520D 0x5942 \ + 0x52A2 0x52AC 0x52AD 0x52BE 0x54FF 0x52D0 0x52D6 0x52F0 \ + 0x53DF 0x71EE 0x77CD 0x5EF4 0x51F5 0x51FC 0x9B2F 0x53B6 \ + 0x5F01 0x755A 0x5DEF 0x574C 0x57A9 0x57A1 0x587E 0x58BC \ + 0x58C5 0x58D1 0x5729 0x572C 0x572A 0x5733 0x5739 0x572E \ + 0x572F 0x575C 0x573B 0x5742 0x5769 0x5785 0x576B 0x5786 \ + 0x577C 0x577B 0x5768 0x576D 0x5776 0x5773 0x57AD 0x57A4 \ + 0x578C 0x57B2 0x57CF 0x57A7 0x57B4 0x5793 0x57A0 0x57D5 \ + 0x57D8 0x57DA 0x57D9 0x57D2 0x57B8 0x57F4 0x57EF 0x57F8 \ + 0x57E4 0x57DD 0x580B 0x580D 0x57FD 0x57ED 0x5800 0x581E \ + 0x5819 0x5844 0x5820 0x5865 0x586C 0x5881 0x5889 0x589A \ + 0x5880 0x99A8 0x9F19 0x61FF 0x8279 0x827D 0x827F 0x828F \ + 0x828A 0x82A8 0x8284 0x828E 0x8291 0x8297 0x8299 0x82AB \ + 0x82B8 0x82BE 0x82B0 0x82C8 0x82CA 0x82E3 0x8298 0x82B7 \ + 0x82AE 0x82CB 0x82CC 0x82C1 0x82A9 0x82B4 0x82A1 0x82AA \ + 0x829F 0x82C4 0x82CE 0x82A4 0x82E1 0x8309 0x82F7 0x82E4 \ + 0x830F 0x8307 0x82DC 0x82F4 0x82D2 0x82D8 0x830C 0x82FB \ + 0x82D3 0x8311 0x831A 0x8306 0x8314 0x8315 0x82E0 0x82D5 \ + 0x831C 0x8351 0x835B 0x835C 0x8308 0x8392 0x833C 0x8334 \ + 0x8331 0x839B 0x835E 0x832F 0x834F 0x8347 0x8343 0x835F +23 0x8340 0x8317 0x8360 0x832D 0x833A 0x8333 0x8366 0x8365 \ + 0x8368 0x831B 0x8369 0x836C 0x836A 0x836D 0x836E 0x83B0 \ + 0x8378 0x83B3 0x83B4 0x83A0 0x83AA 0x8393 0x839C 0x8385 \ + 0x837C 0x83B6 0x83A9 0x837D 0x83B8 0x837B 0x8398 0x839E \ + 0x83A8 0x83BA 0x83BC 0x83C1 0x8401 0x83E5 0x83D8 0x5807 \ + 0x8418 0x840B 0x83DD 0x83FD 0x83D6 0x841C 0x8438 0x8411 \ + 0x8406 0x83D4 0x83DF 0x840F 0x8403 0x83F8 0x83F9 0x83EA \ + 0x83C5 0x83C0 0x8426 0x83F0 0x83E1 0x845C 0x8451 0x845A \ + 0x8459 0x8473 0x8487 0x8488 0x847A 0x8489 0x8478 0x843C \ + 0x8446 0x8469 0x8476 0x848C 0x848E 0x8431 0x846D 0x84C1 \ + 0x84CD 0x84D0 0x84E6 0x84BD 0x84D3 0x84CA 0x84BF 0x84BA \ + 0x84E0 0x84A1 0x84B9 0x84B4 0x8497 0x84E5 0x84E3 0x850C \ + 0x750D 0x8538 0x84F0 0x8539 0x851F 0x853A 0x8556 0x853B \ + 0x84FF 0x84FC 0x8559 0x8548 0x8568 0x8564 0x855E 0x857A \ + 0x77A2 0x8543 0x8572 0x857B 0x85A4 0x85A8 0x8587 0x858F \ + 0x8579 0x85AE 0x859C 0x8585 0x85B9 0x85B7 0x85B0 0x85D3 \ + 0x85C1 0x85DC 0x85FF 0x8627 0x8605 0x8629 0x8616 0x863C \ + 0x5EFE 0x5F08 0x593C 0x5941 0x8037 0x5955 0x595A 0x5958 \ + 0x530F 0x5C22 0x5C25 0x5C2C 0x5C34 0x624C 0x626A 0x629F \ + 0x62BB 0x62CA 0x62DA 0x62D7 0x62EE 0x6322 0x62F6 0x6339 \ + 0x634B 0x6343 0x63AD 0x63F6 0x6371 0x637A 0x638E 0x63B4 \ + 0x636D 0x63AC 0x638A 0x6369 0x63AE 0x63BC 0x63F2 0x63F8 \ + 0x63E0 0x63FF 0x63C4 0x63DE 0x63CE 0x6452 0x63C6 0x63BE \ + 0x6445 0x6441 0x640B 0x641B 0x6420 0x640C 0x6426 0x6421 \ + 0x645E 0x6484 0x646D 0x6496 0x647A 0x64B7 0x64B8 0x6499 \ + 0x64BA 0x64C0 0x64D0 0x64D7 0x64E4 0x64E2 0x6509 0x6525 \ + 0x652E 0x5F0B 0x5FD2 0x7519 0x5F11 0x535F 0x53F1 0x53FD \ + 0x53E9 0x53E8 0x53FB 0x5412 0x5416 0x5406 0x544B 0x5452 \ + 0x5453 0x5454 0x5456 0x5443 0x5421 0x5457 0x5459 0x5423 \ + 0x5432 0x5482 0x5494 0x5477 0x5471 0x5464 0x549A 0x549B \ + 0x5484 0x5476 0x5466 0x549D 0x54D0 0x54AD 0x54C2 0x54B4 \ + 0x54D2 0x54A7 0x54A6 0x54D3 0x54D4 0x5472 0x54A3 0x54D5 +24 0x54BB 0x54BF 0x54CC 0x54D9 0x54DA 0x54DC 0x54A9 0x54AA \ + 0x54A4 0x54DD 0x54CF 0x54DE 0x551B 0x54E7 0x5520 0x54FD \ + 0x5514 0x54F3 0x5522 0x5523 0x550F 0x5511 0x5527 0x552A \ + 0x5567 0x558F 0x55B5 0x5549 0x556D 0x5541 0x5555 0x553F \ + 0x5550 0x553C 0x5537 0x5556 0x5575 0x5576 0x5577 0x5533 \ + 0x5530 0x555C 0x558B 0x55D2 0x5583 0x55B1 0x55B9 0x5588 \ + 0x5581 0x559F 0x557E 0x55D6 0x5591 0x557B 0x55DF 0x55BD \ + 0x55BE 0x5594 0x5599 0x55EA 0x55F7 0x55C9 0x561F 0x55D1 \ + 0x55EB 0x55EC 0x55D4 0x55E6 0x55DD 0x55C4 0x55EF 0x55E5 \ + 0x55F2 0x55F3 0x55CC 0x55CD 0x55E8 0x55F5 0x55E4 0x8F94 \ + 0x561E 0x5608 0x560C 0x5601 0x5624 0x5623 0x55FE 0x5600 \ + 0x5627 0x562D 0x5658 0x5639 0x5657 0x562C 0x564D 0x5662 \ + 0x5659 0x565C 0x564C 0x5654 0x5686 0x5664 0x5671 0x566B \ + 0x567B 0x567C 0x5685 0x5693 0x56AF 0x56D4 0x56D7 0x56DD \ + 0x56E1 0x56F5 0x56EB 0x56F9 0x56FF 0x5704 0x570A 0x5709 \ + 0x571C 0x5E0F 0x5E19 0x5E14 0x5E11 0x5E31 0x5E3B 0x5E3C \ + 0x5E37 0x5E44 0x5E54 0x5E5B 0x5E5E 0x5E61 0x5C8C 0x5C7A \ + 0x5C8D 0x5C90 0x5C96 0x5C88 0x5C98 0x5C99 0x5C91 0x5C9A \ + 0x5C9C 0x5CB5 0x5CA2 0x5CBD 0x5CAC 0x5CAB 0x5CB1 0x5CA3 \ + 0x5CC1 0x5CB7 0x5CC4 0x5CD2 0x5CE4 0x5CCB 0x5CE5 0x5D02 \ + 0x5D03 0x5D27 0x5D26 0x5D2E 0x5D24 0x5D1E 0x5D06 0x5D1B \ + 0x5D58 0x5D3E 0x5D34 0x5D3D 0x5D6C 0x5D5B 0x5D6F 0x5D5D \ + 0x5D6B 0x5D4B 0x5D4A 0x5D69 0x5D74 0x5D82 0x5D99 0x5D9D \ + 0x8C73 0x5DB7 0x5DC5 0x5F73 0x5F77 0x5F82 0x5F87 0x5F89 \ + 0x5F8C 0x5F95 0x5F99 0x5F9C 0x5FA8 0x5FAD 0x5FB5 0x5FBC \ + 0x8862 0x5F61 0x72AD 0x72B0 0x72B4 0x72B7 0x72B8 0x72C3 \ + 0x72C1 0x72CE 0x72CD 0x72D2 0x72E8 0x72EF 0x72E9 0x72F2 \ + 0x72F4 0x72F7 0x7301 0x72F3 0x7303 0x72FA 0x72FB 0x7317 \ + 0x7313 0x7321 0x730A 0x731E 0x731D 0x7315 0x7322 0x7339 \ + 0x7325 0x732C 0x7338 0x7331 0x7350 0x734D 0x7357 0x7360 \ + 0x736C 0x736F 0x737E 0x821B 0x5925 0x98E7 0x5924 0x5902 \ + 0x9963 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x9974 +25 0x9977 0x997D 0x9980 0x9984 0x9987 0x998A 0x998D 0x9990 \ + 0x9991 0x9993 0x9994 0x9995 0x5E80 0x5E91 0x5E8B 0x5E96 \ + 0x5EA5 0x5EA0 0x5EB9 0x5EB5 0x5EBE 0x5EB3 0x8D53 0x5ED2 \ + 0x5ED1 0x5EDB 0x5EE8 0x5EEA 0x81BA 0x5FC4 0x5FC9 0x5FD6 \ + 0x5FCF 0x6003 0x5FEE 0x6004 0x5FE1 0x5FE4 0x5FFE 0x6005 \ + 0x6006 0x5FEA 0x5FED 0x5FF8 0x6019 0x6035 0x6026 0x601B \ + 0x600F 0x600D 0x6029 0x602B 0x600A 0x603F 0x6021 0x6078 \ + 0x6079 0x607B 0x607A 0x6042 0x606A 0x607D 0x6096 0x609A \ + 0x60AD 0x609D 0x6083 0x6092 0x608C 0x609B 0x60EC 0x60BB \ + 0x60B1 0x60DD 0x60D8 0x60C6 0x60DA 0x60B4 0x6120 0x6126 \ + 0x6115 0x6123 0x60F4 0x6100 0x610E 0x612B 0x614A 0x6175 \ + 0x61AC 0x6194 0x61A7 0x61B7 0x61D4 0x61F5 0x5FDD 0x96B3 \ + 0x95E9 0x95EB 0x95F1 0x95F3 0x95F5 0x95F6 0x95FC 0x95FE \ + 0x9603 0x9604 0x9606 0x9608 0x960A 0x960B 0x960C 0x960D \ + 0x960F 0x9612 0x9615 0x9616 0x9617 0x9619 0x961A 0x4E2C \ + 0x723F 0x6215 0x6C35 0x6C54 0x6C5C 0x6C4A 0x6CA3 0x6C85 \ + 0x6C90 0x6C94 0x6C8C 0x6C68 0x6C69 0x6C74 0x6C76 0x6C86 \ + 0x6CA9 0x6CD0 0x6CD4 0x6CAD 0x6CF7 0x6CF8 0x6CF1 0x6CD7 \ + 0x6CB2 0x6CE0 0x6CD6 0x6CFA 0x6CEB 0x6CEE 0x6CB1 0x6CD3 \ + 0x6CEF 0x6CFE 0x6D39 0x6D27 0x6D0C 0x6D43 0x6D48 0x6D07 \ + 0x6D04 0x6D19 0x6D0E 0x6D2B 0x6D4D 0x6D2E 0x6D35 0x6D1A \ + 0x6D4F 0x6D52 0x6D54 0x6D33 0x6D91 0x6D6F 0x6D9E 0x6DA0 \ + 0x6D5E 0x6D93 0x6D94 0x6D5C 0x6D60 0x6D7C 0x6D63 0x6E1A \ + 0x6DC7 0x6DC5 0x6DDE 0x6E0E 0x6DBF 0x6DE0 0x6E11 0x6DE6 \ + 0x6DDD 0x6DD9 0x6E16 0x6DAB 0x6E0C 0x6DAE 0x6E2B 0x6E6E \ + 0x6E4E 0x6E6B 0x6EB2 0x6E5F 0x6E86 0x6E53 0x6E54 0x6E32 \ + 0x6E25 0x6E44 0x6EDF 0x6EB1 0x6E98 0x6EE0 0x6F2D 0x6EE2 \ + 0x6EA5 0x6EA7 0x6EBD 0x6EBB 0x6EB7 0x6ED7 0x6EB4 0x6ECF \ + 0x6E8F 0x6EC2 0x6E9F 0x6F62 0x6F46 0x6F47 0x6F24 0x6F15 \ + 0x6EF9 0x6F2F 0x6F36 0x6F4B 0x6F74 0x6F2A 0x6F09 0x6F29 \ + 0x6F89 0x6F8D 0x6F8C 0x6F78 0x6F72 0x6F7C 0x6F7A 0x6FD1 \ + 0x6FC9 0x6FA7 0x6FB9 0x6FB6 0x6FC2 0x6FE1 0x6FEE 0x6FDE +26 0x6FE0 0x6FEF 0x701A 0x7023 0x701B 0x7039 0x7035 0x704F \ + 0x705E 0x5B80 0x5B84 0x5B95 0x5B93 0x5BA5 0x5BB8 0x752F \ + 0x9A9E 0x6434 0x5BE4 0x5BEE 0x8930 0x5BF0 0x8E47 0x8B07 \ + 0x8FB6 0x8FD3 0x8FD5 0x8FE5 0x8FEE 0x8FE4 0x8FE9 0x8FE6 \ + 0x8FF3 0x8FE8 0x9005 0x9004 0x900B 0x9026 0x9011 0x900D \ + 0x9016 0x9021 0x9035 0x9036 0x902D 0x902F 0x9044 0x9051 \ + 0x9052 0x9050 0x9068 0x9058 0x9062 0x905B 0x66B9 0x9074 \ + 0x907D 0x9082 0x9088 0x9083 0x908B 0x5F50 0x5F57 0x5F56 \ + 0x5F58 0x5C3B 0x54AB 0x5C50 0x5C59 0x5B71 0x5C63 0x5C66 \ + 0x7FBC 0x5F2A 0x5F29 0x5F2D 0x8274 0x5F3C 0x9B3B 0x5C6E \ + 0x5981 0x5983 0x598D 0x59A9 0x59AA 0x59A3 0x5997 0x59CA \ + 0x59AB 0x599E 0x59A4 0x59D2 0x59B2 0x59AF 0x59D7 0x59BE \ + 0x5A05 0x5A06 0x59DD 0x5A08 0x59E3 0x59D8 0x59F9 0x5A0C \ + 0x5A09 0x5A32 0x5A34 0x5A11 0x5A23 0x5A13 0x5A40 0x5A67 \ + 0x5A4A 0x5A55 0x5A3C 0x5A62 0x5A75 0x80EC 0x5AAA 0x5A9B \ + 0x5A77 0x5A7A 0x5ABE 0x5AEB 0x5AB2 0x5AD2 0x5AD4 0x5AB8 \ + 0x5AE0 0x5AE3 0x5AF1 0x5AD6 0x5AE6 0x5AD8 0x5ADC 0x5B09 \ + 0x5B17 0x5B16 0x5B32 0x5B37 0x5B40 0x5C15 0x5C1C 0x5B5A \ + 0x5B65 0x5B73 0x5B51 0x5B53 0x5B62 0x9A75 0x9A77 0x9A78 \ + 0x9A7A 0x9A7F 0x9A7D 0x9A80 0x9A81 0x9A85 0x9A88 0x9A8A \ + 0x9A90 0x9A92 0x9A93 0x9A96 0x9A98 0x9A9B 0x9A9C 0x9A9D \ + 0x9A9F 0x9AA0 0x9AA2 0x9AA3 0x9AA5 0x9AA7 0x7E9F 0x7EA1 \ + 0x7EA3 0x7EA5 0x7EA8 0x7EA9 0x7EAD 0x7EB0 0x7EBE 0x7EC0 \ + 0x7EC1 0x7EC2 0x7EC9 0x7ECB 0x7ECC 0x7ED0 0x7ED4 0x7ED7 \ + 0x7EDB 0x7EE0 0x7EE1 0x7EE8 0x7EEB 0x7EEE 0x7EEF 0x7EF1 \ + 0x7EF2 0x7F0D 0x7EF6 0x7EFA 0x7EFB 0x7EFE 0x7F01 0x7F02 \ + 0x7F03 0x7F07 0x7F08 0x7F0B 0x7F0C 0x7F0F 0x7F11 0x7F12 \ + 0x7F17 0x7F19 0x7F1C 0x7F1B 0x7F1F 0x7F21 0x7F22 0x7F23 \ + 0x7F24 0x7F25 0x7F26 0x7F27 0x7F2A 0x7F2B 0x7F2C 0x7F2D \ + 0x7F2F 0x7F30 0x7F31 0x7F32 0x7F33 0x7F35 0x5E7A 0x757F \ + 0x5DDB 0x753E 0x9095 0x738E 0x7391 0x73AE 0x73A2 0x739F \ + 0x73CF 0x73C2 0x73D1 0x73B7 0x73B3 0x73C0 0x73C9 0x73C8 +27 0x73E5 0x73D9 0x987C 0x740A 0x73E9 0x73E7 0x73DE 0x73BA \ + 0x73F2 0x740F 0x742A 0x745B 0x7426 0x7425 0x7428 0x7430 \ + 0x742E 0x742C 0x741B 0x741A 0x7441 0x745C 0x7457 0x7455 \ + 0x7459 0x7477 0x746D 0x747E 0x749C 0x748E 0x7480 0x7481 \ + 0x7487 0x748B 0x749E 0x74A8 0x74A9 0x7490 0x74A7 0x74D2 \ + 0x74BA 0x97EA 0x97EB 0x97EC 0x674C 0x6753 0x675E 0x6748 \ + 0x6769 0x67A5 0x6787 0x676A 0x6773 0x6798 0x67A7 0x6775 \ + 0x67A8 0x679E 0x67AD 0x678B 0x6777 0x677C 0x67F0 0x6809 \ + 0x67D8 0x680A 0x67E9 0x67B0 0x680C 0x67D9 0x67B5 0x67DA \ + 0x67B3 0x67DD 0x6800 0x67C3 0x67B8 0x67E2 0x680E 0x67C1 \ + 0x67FD 0x6832 0x6833 0x6860 0x6861 0x684E 0x6862 0x6844 \ + 0x6864 0x6883 0x681D 0x6855 0x6866 0x6841 0x6867 0x6840 \ + 0x683E 0x684A 0x6849 0x6829 0x68B5 0x688F 0x6874 0x6877 \ + 0x6893 0x686B 0x68C2 0x696E 0x68FC 0x691F 0x6920 0x68F9 \ + 0x6924 0x68F0 0x690B 0x6901 0x6957 0x68E3 0x6910 0x6971 \ + 0x6939 0x6960 0x6942 0x695D 0x6984 0x696B 0x6980 0x6998 \ + 0x6978 0x6934 0x69CC 0x6987 0x6988 0x69CE 0x6989 0x6966 \ + 0x6963 0x6979 0x699B 0x69A7 0x69BB 0x69AB 0x69AD 0x69D4 \ + 0x69B1 0x69C1 0x69CA 0x69DF 0x6995 0x69E0 0x698D 0x69FF \ + 0x6A2F 0x69ED 0x6A17 0x6A18 0x6A65 0x69F2 0x6A44 0x6A3E \ + 0x6AA0 0x6A50 0x6A5B 0x6A35 0x6A8E 0x6A79 0x6A3D 0x6A28 \ + 0x6A58 0x6A7C 0x6A91 0x6A90 0x6AA9 0x6A97 0x6AAB 0x7337 \ + 0x7352 0x6B81 0x6B82 0x6B87 0x6B84 0x6B92 0x6B93 0x6B8D \ + 0x6B9A 0x6B9B 0x6BA1 0x6BAA 0x8F6B 0x8F6D 0x8F71 0x8F72 \ + 0x8F73 0x8F75 0x8F76 0x8F78 0x8F77 0x8F79 0x8F7A 0x8F7C \ + 0x8F7E 0x8F81 0x8F82 0x8F84 0x8F87 0x8F8B 0x8F8D 0x8F8E \ + 0x8F8F 0x8F98 0x8F9A 0x8ECE 0x620B 0x6217 0x621B 0x621F \ + 0x6222 0x6221 0x6225 0x6224 0x622C 0x81E7 0x74EF 0x74F4 \ + 0x74FF 0x750F 0x7511 0x7513 0x6534 0x65EE 0x65EF 0x65F0 \ + 0x660A 0x6619 0x6772 0x6603 0x6615 0x6600 0x7085 0x66F7 \ + 0x661D 0x6634 0x6631 0x6636 0x6635 0x8006 0x665F 0x6654 \ + 0x6641 0x664F 0x6656 0x6661 0x6657 0x6677 0x6684 0x668C +28 0x66A7 0x669D 0x66BE 0x66DB 0x66DC 0x66E6 0x66E9 0x8D32 \ + 0x8D33 0x8D36 0x8D3B 0x8D3D 0x8D40 0x8D45 0x8D46 0x8D48 \ + 0x8D49 0x8D47 0x8D4D 0x8D55 0x8D59 0x89C7 0x89CA 0x89CB \ + 0x89CC 0x89CE 0x89CF 0x89D0 0x89D1 0x726E 0x729F 0x725D \ + 0x7266 0x726F 0x727E 0x727F 0x7284 0x728B 0x728D 0x728F \ + 0x7292 0x6308 0x6332 0x63B0 0x643F 0x64D8 0x8004 0x6BEA \ + 0x6BF3 0x6BFD 0x6BF5 0x6BF9 0x6C05 0x6C07 0x6C06 0x6C0D \ + 0x6C15 0x6C18 0x6C19 0x6C1A 0x6C21 0x6C29 0x6C24 0x6C2A \ + 0x6C32 0x6535 0x6555 0x656B 0x724D 0x7252 0x7256 0x7230 \ + 0x8662 0x5216 0x809F 0x809C 0x8093 0x80BC 0x670A 0x80BD \ + 0x80B1 0x80AB 0x80AD 0x80B4 0x80B7 0x80E7 0x80E8 0x80E9 \ + 0x80EA 0x80DB 0x80C2 0x80C4 0x80D9 0x80CD 0x80D7 0x6710 \ + 0x80DD 0x80EB 0x80F1 0x80F4 0x80ED 0x810D 0x810E 0x80F2 \ + 0x80FC 0x6715 0x8112 0x8C5A 0x8136 0x811E 0x812C 0x8118 \ + 0x8132 0x8148 0x814C 0x8153 0x8174 0x8159 0x815A 0x8171 \ + 0x8160 0x8169 0x817C 0x817D 0x816D 0x8167 0x584D 0x5AB5 \ + 0x8188 0x8182 0x8191 0x6ED5 0x81A3 0x81AA 0x81CC 0x6726 \ + 0x81CA 0x81BB 0x81C1 0x81A6 0x6B24 0x6B37 0x6B39 0x6B43 \ + 0x6B46 0x6B59 0x98D1 0x98D2 0x98D3 0x98D5 0x98D9 0x98DA \ + 0x6BB3 0x5F40 0x6BC2 0x89F3 0x6590 0x9F51 0x6593 0x65BC \ + 0x65C6 0x65C4 0x65C3 0x65CC 0x65CE 0x65D2 0x65D6 0x7080 \ + 0x709C 0x7096 0x709D 0x70BB 0x70C0 0x70B7 0x70AB 0x70B1 \ + 0x70E8 0x70CA 0x7110 0x7113 0x7116 0x712F 0x7131 0x7173 \ + 0x715C 0x7168 0x7145 0x7172 0x714A 0x7178 0x717A 0x7198 \ + 0x71B3 0x71B5 0x71A8 0x71A0 0x71E0 0x71D4 0x71E7 0x71F9 \ + 0x721D 0x7228 0x706C 0x7118 0x7166 0x71B9 0x623E 0x623D \ + 0x6243 0x6248 0x6249 0x793B 0x7940 0x7946 0x7949 0x795B \ + 0x795C 0x7953 0x795A 0x7962 0x7957 0x7960 0x796F 0x7967 \ + 0x797A 0x7985 0x798A 0x799A 0x79A7 0x79B3 0x5FD1 0x5FD0 \ + 0x603C 0x605D 0x605A 0x6067 0x6041 0x6059 0x6063 0x60AB \ + 0x6106 0x610D 0x615D 0x61A9 0x619D 0x61CB 0x61D1 0x6206 \ + 0x8080 0x807F 0x6C93 0x6CF6 0x6DFC 0x77F6 0x77F8 0x7800 +29 0x7809 0x7817 0x7818 0x7811 0x65AB 0x782D 0x781C 0x781D \ + 0x7839 0x783A 0x783B 0x781F 0x783C 0x7825 0x782C 0x7823 \ + 0x7829 0x784E 0x786D 0x7856 0x7857 0x7826 0x7850 0x7847 \ + 0x784C 0x786A 0x789B 0x7893 0x789A 0x7887 0x789C 0x78A1 \ + 0x78A3 0x78B2 0x78B9 0x78A5 0x78D4 0x78D9 0x78C9 0x78EC \ + 0x78F2 0x7905 0x78F4 0x7913 0x7924 0x791E 0x7934 0x9F9B \ + 0x9EF9 0x9EFB 0x9EFC 0x76F1 0x7704 0x770D 0x76F9 0x7707 \ + 0x7708 0x771A 0x7722 0x7719 0x772D 0x7726 0x7735 0x7738 \ + 0x7750 0x7751 0x7747 0x7743 0x775A 0x7768 0x7762 0x7765 \ + 0x777F 0x778D 0x777D 0x7780 0x778C 0x7791 0x779F 0x77A0 \ + 0x77B0 0x77B5 0x77BD 0x753A 0x7540 0x754E 0x754B 0x7548 \ + 0x755B 0x7572 0x7579 0x7583 0x7F58 0x7F61 0x7F5F 0x8A48 \ + 0x7F68 0x7F74 0x7F71 0x7F79 0x7F81 0x7F7E 0x76CD 0x76E5 \ + 0x8832 0x9485 0x9486 0x9487 0x948B 0x948A 0x948C 0x948D \ + 0x948F 0x9490 0x9494 0x9497 0x9495 0x949A 0x949B 0x949C \ + 0x94A3 0x94A4 0x94AB 0x94AA 0x94AD 0x94AC 0x94AF 0x94B0 \ + 0x94B2 0x94B4 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BC \ + 0x94BD 0x94BF 0x94C4 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC \ + 0x94CD 0x94CE 0x94D0 0x94D1 0x94D2 0x94D5 0x94D6 0x94D7 \ + 0x94D9 0x94D8 0x94DB 0x94DE 0x94DF 0x94E0 0x94E2 0x94E4 \ + 0x94E5 0x94E7 0x94E8 0x94EA 0x94E9 0x94EB 0x94EE 0x94EF \ + 0x94F3 0x94F4 0x94F5 0x94F7 0x94F9 0x94FC 0x94FD 0x94FF \ + 0x9503 0x9502 0x9506 0x9507 0x9509 0x950A 0x950D 0x950E \ + 0x950F 0x9512 0x9513 0x9514 0x9515 0x9516 0x9518 0x951B \ + 0x951D 0x951E 0x951F 0x9522 0x952A 0x952B 0x9529 0x952C \ + 0x9531 0x9532 0x9534 0x9536 0x9537 0x9538 0x953C 0x953E \ + 0x953F 0x9542 0x9535 0x9544 0x9545 0x9546 0x9549 0x954C \ + 0x954E 0x954F 0x9552 0x9553 0x9554 0x9556 0x9557 0x9558 \ + 0x9559 0x955B 0x955E 0x955F 0x955D 0x9561 0x9562 0x9564 \ + 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B 0x956C \ + 0x956F 0x9571 0x9572 0x9573 0x953A 0x77E7 0x77EC 0x96C9 \ + 0x79D5 0x79ED 0x79E3 0x79EB 0x7A06 0x5D47 0x7A03 0x7A02 +30 0x7A1E 0x7A14 0x7A39 0x7A37 0x7A51 0x9ECF 0x99A5 0x7A70 \ + 0x7688 0x768E 0x7693 0x7699 0x76A4 0x74DE 0x74E0 0x752C \ + 0x9E20 0x9E22 0x9E28 0x9E29 0x9E2A 0x9E2B 0x9E2C 0x9E32 \ + 0x9E31 0x9E36 0x9E38 0x9E37 0x9E39 0x9E3A 0x9E3E 0x9E41 \ + 0x9E42 0x9E44 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4B 0x9E4C \ + 0x9E4E 0x9E51 0x9E55 0x9E57 0x9E5A 0x9E5B 0x9E5C 0x9E5E \ + 0x9E63 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B 0x9E6C \ + 0x9E71 0x9E6D 0x9E73 0x7592 0x7594 0x7596 0x75A0 0x759D \ + 0x75AC 0x75A3 0x75B3 0x75B4 0x75B8 0x75C4 0x75B1 0x75B0 \ + 0x75C3 0x75C2 0x75D6 0x75CD 0x75E3 0x75E8 0x75E6 0x75E4 \ + 0x75EB 0x75E7 0x7603 0x75F1 0x75FC 0x75FF 0x7610 0x7600 \ + 0x7605 0x760C 0x7617 0x760A 0x7625 0x7618 0x7615 0x7619 \ + 0x761B 0x763C 0x7622 0x7620 0x7640 0x762D 0x7630 0x763F \ + 0x7635 0x7643 0x763E 0x7633 0x764D 0x765E 0x7654 0x765C \ + 0x7656 0x766B 0x766F 0x7FCA 0x7AE6 0x7A78 0x7A79 0x7A80 \ + 0x7A86 0x7A88 0x7A95 0x7AA6 0x7AA0 0x7AAC 0x7AA8 0x7AAD \ + 0x7AB3 0x8864 0x8869 0x8872 0x887D 0x887F 0x8882 0x88A2 \ + 0x88C6 0x88B7 0x88BC 0x88C9 0x88E2 0x88CE 0x88E3 0x88E5 \ + 0x88F1 0x891A 0x88FC 0x88E8 0x88FE 0x88F0 0x8921 0x8919 \ + 0x8913 0x891B 0x890A 0x8934 0x892B 0x8936 0x8941 0x8966 \ + 0x897B 0x758B 0x80E5 0x76B2 0x76B4 0x77DC 0x8012 0x8014 \ + 0x8016 0x801C 0x8020 0x8022 0x8025 0x8026 0x8027 0x8029 \ + 0x8028 0x8031 0x800B 0x8035 0x8043 0x8046 0x804D 0x8052 \ + 0x8069 0x8071 0x8983 0x9878 0x9880 0x9883 0x9889 0x988C \ + 0x988D 0x988F 0x9894 0x989A 0x989B 0x989E 0x989F 0x98A1 \ + 0x98A2 0x98A5 0x98A6 0x864D 0x8654 0x866C 0x866E 0x867F \ + 0x867A 0x867C 0x867B 0x86A8 0x868D 0x868B 0x86AC 0x869D \ + 0x86A7 0x86A3 0x86AA 0x8693 0x86A9 0x86B6 0x86C4 0x86B5 \ + 0x86CE 0x86B0 0x86BA 0x86B1 0x86AF 0x86C9 0x86CF 0x86B4 \ + 0x86E9 0x86F1 0x86F2 0x86ED 0x86F3 0x86D0 0x8713 0x86DE \ + 0x86F4 0x86DF 0x86D8 0x86D1 0x8703 0x8707 0x86F8 0x8708 \ + 0x870A 0x870D 0x8709 0x8723 0x873B 0x871E 0x8725 0x872E +31 0x871A 0x873E 0x8748 0x8734 0x8731 0x8729 0x8737 0x873F \ + 0x8782 0x8722 0x877D 0x877E 0x877B 0x8760 0x8770 0x874C \ + 0x876E 0x878B 0x8753 0x8763 0x877C 0x8764 0x8759 0x8765 \ + 0x8793 0x87AF 0x87A8 0x87D2 0x87C6 0x8788 0x8785 0x87AD \ + 0x8797 0x8783 0x87AB 0x87E5 0x87AC 0x87B5 0x87B3 0x87CB \ + 0x87D3 0x87BD 0x87D1 0x87C0 0x87CA 0x87DB 0x87EA 0x87E0 \ + 0x87EE 0x8816 0x8813 0x87FE 0x880A 0x881B 0x8821 0x8839 \ + 0x883C 0x7F36 0x7F42 0x7F44 0x7F45 0x8210 0x7AFA 0x7AFD \ + 0x7B08 0x7B03 0x7B04 0x7B15 0x7B0A 0x7B2B 0x7B0F 0x7B47 \ + 0x7B38 0x7B2A 0x7B19 0x7B2E 0x7B31 0x7B20 0x7B25 0x7B24 \ + 0x7B33 0x7B3E 0x7B1E 0x7B58 0x7B5A 0x7B45 0x7B75 0x7B4C \ + 0x7B5D 0x7B60 0x7B6E 0x7B7B 0x7B62 0x7B72 0x7B71 0x7B90 \ + 0x7BA6 0x7BA7 0x7BB8 0x7BAC 0x7B9D 0x7BA8 0x7B85 0x7BAA \ + 0x7B9C 0x7BA2 0x7BAB 0x7BB4 0x7BD1 0x7BC1 0x7BCC 0x7BDD \ + 0x7BDA 0x7BE5 0x7BE6 0x7BEA 0x7C0C 0x7BFE 0x7BFC 0x7C0F \ + 0x7C16 0x7C0B 0x7C1F 0x7C2A 0x7C26 0x7C38 0x7C41 0x7C40 \ + 0x81FE 0x8201 0x8202 0x8204 0x81EC 0x8844 0x8221 0x8222 \ + 0x8223 0x822D 0x822F 0x8228 0x822B 0x8238 0x823B 0x8233 \ + 0x8234 0x823E 0x8244 0x8249 0x824B 0x824F 0x825A 0x825F \ + 0x8268 0x887E 0x8885 0x8888 0x88D8 0x88DF 0x895E 0x7F9D \ + 0x7F9F 0x7FA7 0x7FAF 0x7FB0 0x7FB2 0x7C7C 0x6549 0x7C91 \ + 0x7C9D 0x7C9C 0x7C9E 0x7CA2 0x7CB2 0x7CBC 0x7CBD 0x7CC1 \ + 0x7CC7 0x7CCC 0x7CCD 0x7CC8 0x7CC5 0x7CD7 0x7CE8 0x826E \ + 0x66A8 0x7FBF 0x7FCE 0x7FD5 0x7FE5 0x7FE1 0x7FE6 0x7FE9 \ + 0x7FEE 0x7FF3 0x7CF8 0x7D77 0x7DA6 0x7DAE 0x7E47 0x7E9B \ + 0x9EB8 0x9EB4 0x8D73 0x8D84 0x8D94 0x8D91 0x8DB1 0x8D67 \ + 0x8D6D 0x8C47 0x8C49 0x914A 0x9150 0x914E 0x914F 0x9164 \ + 0x9162 0x9161 0x9170 0x9169 0x916F 0x917D 0x917E 0x9172 \ + 0x9174 0x9179 0x918C 0x9185 0x9190 0x918D 0x9191 0x91A2 \ + 0x91A3 0x91AA 0x91AD 0x91AE 0x91AF 0x91B5 0x91B4 0x91BA \ + 0x8C55 0x9E7E 0x8DB8 0x8DEB 0x8E05 0x8E59 0x8E69 0x8DB5 \ + 0x8DBF 0x8DBC 0x8DBA 0x8DC4 0x8DD6 0x8DD7 0x8DDA 0x8DDE +32 0x8DCE 0x8DCF 0x8DDB 0x8DC6 0x8DEC 0x8DF7 0x8DF8 0x8DE3 \ + 0x8DF9 0x8DFB 0x8DE4 0x8E09 0x8DFD 0x8E14 0x8E1D 0x8E1F \ + 0x8E2C 0x8E2E 0x8E23 0x8E2F 0x8E3A 0x8E40 0x8E39 0x8E35 \ + 0x8E3D 0x8E31 0x8E49 0x8E41 0x8E42 0x8E51 0x8E52 0x8E4A \ + 0x8E70 0x8E76 0x8E7C 0x8E6F 0x8E74 0x8E85 0x8E8F 0x8E94 \ + 0x8E90 0x8E9C 0x8E9E 0x8C78 0x8C82 0x8C8A 0x8C85 0x8C98 \ + 0x8C94 0x659B 0x89D6 0x89DE 0x89DA 0x89DC 0x89E5 0x89EB \ + 0x89EF 0x8A3E 0x8B26 0x9753 0x96E9 0x96F3 0x96EF 0x9706 \ + 0x9701 0x9708 0x970F 0x970E 0x972A 0x972D 0x9730 0x973E \ + 0x9F80 0x9F83 0x9F85 0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A \ + 0x9F8C 0x9EFE 0x9F0B 0x9F0D 0x96B9 0x96BC 0x96BD 0x96CE \ + 0x96D2 0x77BF 0x96E0 0x928E 0x92AE 0x92C8 0x933E 0x936A \ + 0x93CA 0x938F 0x943E 0x946B 0x9C7F 0x9C82 0x9C85 0x9C86 \ + 0x9C87 0x9C88 0x7A23 0x9C8B 0x9C8E 0x9C90 0x9C91 0x9C92 \ + 0x9C94 0x9C95 0x9C9A 0x9C9B 0x9C9E 0x9C9F 0x9CA0 0x9CA1 \ + 0x9CA2 0x9CA3 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAB \ + 0x9CAD 0x9CAE 0x9CB0 0x9CB1 0x9CB2 0x9CB3 0x9CB4 0x9CB5 \ + 0x9CB6 0x9CB7 0x9CBA 0x9CBB 0x9CBC 0x9CBD 0x9CC4 0x9CC5 \ + 0x9CC6 0x9CC7 0x9CCA 0x9CCB 0x9CCC 0x9CCD 0x9CCE 0x9CCF \ + 0x9CD0 0x9CD3 0x9CD4 0x9CD5 0x9CD7 0x9CD8 0x9CD9 0x9CDC \ + 0x9CDD 0x9CDF 0x9CE2 0x977C 0x9785 0x9791 0x9792 0x9794 \ + 0x97AF 0x97AB 0x97A3 0x97B2 0x97B4 0x9AB1 0x9AB0 0x9AB7 \ + 0x9E58 0x9AB6 0x9ABA 0x9ABC 0x9AC1 0x9AC0 0x9AC5 0x9AC2 \ + 0x9ACB 0x9ACC 0x9AD1 0x9B45 0x9B43 0x9B47 0x9B49 0x9B48 \ + 0x9B4D 0x9B51 0x98E8 0x990D 0x992E 0x9955 0x9954 0x9ADF \ + 0x9AE1 0x9AE6 0x9AEF 0x9AEB 0x9AFB 0x9AED 0x9AF9 0x9B08 \ + 0x9B0F 0x9B13 0x9B1F 0x9B23 0x9EBD 0x9EBE 0x7E3B 0x9E82 \ + 0x9E87 0x9E88 0x9E8B 0x9E92 0x93D6 0x9E9D 0x9E9F 0x9EDB \ + 0x9EDC 0x9EDD 0x9EE0 0x9EDF 0x9EE2 0x9EE9 0x9EE7 0x9EE5 \ + 0x9EEA 0x9EEF 0x9F22 0x9F2C 0x9F2F 0x9F39 0x9F37 0x9F3D \ + 0x9F3E 0x9F44 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +33 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +34 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +35 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UGBK.sfd b/contrib/ttf2pk/data/UGBK.sfd new file mode 100644 index 0000000..6fc99c9 --- /dev/null +++ b/contrib/ttf2pk/data/UGBK.sfd @@ -0,0 +1,3002 @@ +# UGBK.sfd +# +# subfont numbers for GBK encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x4E02 0x4E04 0x4E05 0x4E06 0x4E0F 0x4E12 0x4E17 0x4E1F \ + 0x4E20 0x4E21 0x4E23 0x4E26 0x4E29 0x4E2E 0x4E2F 0x4E31 \ + 0x4E33 0x4E35 0x4E37 0x4E3C 0x4E40 0x4E41 0x4E42 0x4E44 \ + 0x4E46 0x4E4A 0x4E51 0x4E55 0x4E57 0x4E5A 0x4E5B 0x4E62 \ + 0x4E63 0x4E64 0x4E65 0x4E67 0x4E68 0x4E6A 0x4E6B 0x4E6C \ + 0x4E6D 0x4E6E 0x4E6F 0x4E72 0x4E74 0x4E75 0x4E76 0x4E77 \ + 0x4E78 0x4E79 0x4E7A 0x4E7B 0x4E7C 0x4E7D 0x4E7F 0x4E80 \ + 0x4E81 0x4E82 0x4E83 0x4E84 0x4E85 0x4E87 0x4E8A 0x4E90 \ + 0x4E96 0x4E97 0x4E99 0x4E9C 0x4E9D 0x4E9E 0x4EA3 0x4EAA \ + 0x4EAF 0x4EB0 0x4EB1 0x4EB4 0x4EB6 0x4EB7 0x4EB8 0x4EB9 \ + 0x4EBC 0x4EBD 0x4EBE 0x4EC8 0x4ECC 0x4ECF 0x4ED0 0x4ED2 \ + 0x4EDA 0x4EDB 0x4EDC 0x4EE0 0x4EE2 0x4EE6 0x4EE7 0x4EE9 \ + 0x4EED 0x4EEE 0x4EEF 0x4EF1 0x4EF4 0x4EF8 0x4EF9 0x4EFA \ + 0x4EFC 0x4EFE 0x4F00 0x4F02 0x4F03 0x4F04 0x4F05 0x4F06 \ + 0x4F07 0x4F08 0x4F0B 0x4F0C 0x4F12 0x4F13 0x4F14 0x4F15 \ + 0x4F16 0x4F1C 0x4F1D 0x4F21 0x4F23 0x4F28 0x4F29 0x4F2C \ + 0x4F2D 0x4F2E 0x4F31 0x4F33 0x4F35 0x4F37 0x4F39 0x4F3B \ + 0x4F3E 0x4F3F 0x4F40 0x4F41 0x4F42 0x4F44 0x4F45 0x4F47 \ + 0x4F48 0x4F49 0x4F4A 0x4F4B 0x4F4C 0x4F52 0x4F54 0x4F56 \ + 0x4F61 0x4F62 0x4F66 0x4F68 0x4F6A 0x4F6B 0x4F6D 0x4F6E \ + 0x4F71 0x4F72 0x4F75 0x4F77 0x4F78 0x4F79 0x4F7A 0x4F7D \ + 0x4F80 0x4F81 0x4F82 0x4F85 0x4F86 0x4F87 0x4F8A 0x4F8C \ + 0x4F8E 0x4F90 0x4F92 0x4F93 0x4F95 0x4F96 0x4F98 0x4F99 \ + 0x4F9A 0x4F9C 0x4F9E 0x4F9F 0x4FA1 0x4FA2 0x4FA4 0x4FAB \ + 0x4FAD 0x4FB0 0x4FB1 0x4FB2 0x4FB3 0x4FB4 0x4FB6 0x4FB7 \ + 0x4FB8 0x4FB9 0x4FBA 0x4FBB 0x4FBC 0x4FBD 0x4FBE 0x4FC0 \ + 0x4FC1 0x4FC2 0x4FC6 0x4FC7 0x4FC8 0x4FC9 0x4FCB 0x4FCC \ + 0x4FCD 0x4FD2 0x4FD3 0x4FD4 0x4FD5 0x4FD6 0x4FD9 0x4FDB \ + 0x4FE0 0x4FE2 0x4FE4 0x4FE5 0x4FE7 0x4FEB 0x4FEC 0x4FF0 \ + 0x4FF2 0x4FF4 0x4FF5 0x4FF6 0x4FF7 0x4FF9 0x4FFB 0x4FFC \ + 0x4FFD 0x4FFF 0x5000 0x5001 0x5002 0x5003 0x5004 0x5005 \ + 0x5006 0x5007 0x5008 0x5009 0x500A 0x500B 0x500E 0x5010 +02 0x5011 0x5013 0x5015 0x5016 0x5017 0x501B 0x501D 0x501E \ + 0x5020 0x5022 0x5023 0x5024 0x5027 0x502B 0x502F 0x5030 \ + 0x5031 0x5032 0x5033 0x5034 0x5035 0x5036 0x5037 0x5038 \ + 0x5039 0x503B 0x503D 0x503F 0x5040 0x5041 0x5042 0x5044 \ + 0x5045 0x5046 0x5049 0x504A 0x504B 0x504D 0x5050 0x5051 \ + 0x5052 0x5053 0x5054 0x5056 0x5057 0x5058 0x5059 0x505B \ + 0x505D 0x505E 0x505F 0x5060 0x5061 0x5062 0x5063 0x5064 \ + 0x5066 0x5067 0x5068 0x5069 0x506A 0x506B 0x506D 0x506E \ + 0x506F 0x5070 0x5071 0x5072 0x5073 0x5074 0x5075 0x5078 \ + 0x5079 0x507A 0x507C 0x507D 0x5081 0x5082 0x5083 0x5084 \ + 0x5086 0x5087 0x5089 0x508A 0x508B 0x508C 0x508E 0x508F \ + 0x5090 0x5091 0x5092 0x5093 0x5094 0x5095 0x5096 0x5097 \ + 0x5098 0x5099 0x509A 0x509B 0x509C 0x509D 0x509E 0x509F \ + 0x50A0 0x50A1 0x50A2 0x50A4 0x50A6 0x50AA 0x50AB 0x50AD \ + 0x50AE 0x50AF 0x50B0 0x50B1 0x50B3 0x50B4 0x50B5 0x50B6 \ + 0x50B7 0x50B8 0x50B9 0x50BC 0x50BD 0x50BE 0x50BF 0x50C0 \ + 0x50C1 0x50C2 0x50C3 0x50C4 0x50C5 0x50C6 0x50C7 0x50C8 \ + 0x50C9 0x50CA 0x50CB 0x50CC 0x50CD 0x50CE 0x50D0 0x50D1 \ + 0x50D2 0x50D3 0x50D4 0x50D5 0x50D7 0x50D8 0x50D9 0x50DB \ + 0x50DC 0x50DD 0x50DE 0x50DF 0x50E0 0x50E1 0x50E2 0x50E3 \ + 0x50E4 0x50E5 0x50E8 0x50E9 0x50EA 0x50EB 0x50EF 0x50F0 \ + 0x50F1 0x50F2 0x50F4 0x50F6 0x50F7 0x50F8 0x50F9 0x50FA \ + 0x50FC 0x50FD 0x50FE 0x50FF 0x5100 0x5101 0x5102 0x5103 \ + 0x5104 0x5105 0x5108 0x5109 0x510A 0x510C 0x510D 0x510E \ + 0x510F 0x5110 0x5111 0x5113 0x5114 0x5115 0x5116 0x5117 \ + 0x5118 0x5119 0x511A 0x511B 0x511C 0x511D 0x511E 0x511F \ + 0x5120 0x5122 0x5123 0x5124 0x5125 0x5126 0x5127 0x5128 \ + 0x5129 0x512A 0x512B 0x512C 0x512D 0x512E 0x512F 0x5130 \ + 0x5131 0x5132 0x5133 0x5134 0x5135 0x5136 0x5137 0x5138 \ + 0x5139 0x513A 0x513B 0x513C 0x513D 0x513E 0x5142 0x5147 \ + 0x514A 0x514C 0x514E 0x514F 0x5150 0x5152 0x5153 0x5157 \ + 0x5158 0x5159 0x515B 0x515D 0x515E 0x515F 0x5160 0x5161 +03 0x5163 0x5164 0x5166 0x5167 0x5169 0x516A 0x516F 0x5172 \ + 0x517A 0x517E 0x517F 0x5183 0x5184 0x5186 0x5187 0x518A \ + 0x518B 0x518E 0x518F 0x5190 0x5191 0x5193 0x5194 0x5198 \ + 0x519A 0x519D 0x519E 0x519F 0x51A1 0x51A3 0x51A6 0x51A7 \ + 0x51A8 0x51A9 0x51AA 0x51AD 0x51AE 0x51B4 0x51B8 0x51B9 \ + 0x51BA 0x51BE 0x51BF 0x51C1 0x51C2 0x51C3 0x51C5 0x51C8 \ + 0x51CA 0x51CD 0x51CE 0x51D0 0x51D2 0x51D3 0x51D4 0x51D5 \ + 0x51D6 0x51D7 0x51D8 0x51D9 0x51DA 0x51DC 0x51DE 0x51DF \ + 0x51E2 0x51E3 0x51E5 0x51E6 0x51E7 0x51E8 0x51E9 0x51EA \ + 0x51EC 0x51EE 0x51F1 0x51F2 0x51F4 0x51F7 0x51FE 0x5204 \ + 0x5205 0x5209 0x520B 0x520C 0x520F 0x5210 0x5213 0x5214 \ + 0x5215 0x521C 0x521E 0x521F 0x5221 0x5222 0x5223 0x5225 \ + 0x5226 0x5227 0x522A 0x522C 0x522F 0x5231 0x5232 0x5234 \ + 0x5235 0x523C 0x523E 0x5244 0x5245 0x5246 0x5247 0x5248 \ + 0x5249 0x524B 0x524E 0x524F 0x5252 0x5253 0x5255 0x5257 \ + 0x5258 0x5259 0x525A 0x525B 0x525D 0x525F 0x5260 0x5262 \ + 0x5263 0x5264 0x5266 0x5268 0x526B 0x526C 0x526D 0x526E \ + 0x5270 0x5271 0x5273 0x5274 0x5275 0x5276 0x5277 0x5278 \ + 0x5279 0x527A 0x527B 0x527C 0x527E 0x5280 0x5283 0x5284 \ + 0x5285 0x5286 0x5287 0x5289 0x528A 0x528B 0x528C 0x528D \ + 0x528E 0x528F 0x5291 0x5292 0x5294 0x5295 0x5296 0x5297 \ + 0x5298 0x5299 0x529A 0x529C 0x52A4 0x52A5 0x52A6 0x52A7 \ + 0x52AE 0x52AF 0x52B0 0x52B4 0x52B5 0x52B6 0x52B7 0x52B8 \ + 0x52B9 0x52BA 0x52BB 0x52BC 0x52BD 0x52C0 0x52C1 0x52C2 \ + 0x52C4 0x52C5 0x52C6 0x52C8 0x52CA 0x52CC 0x52CD 0x52CE \ + 0x52CF 0x52D1 0x52D3 0x52D4 0x52D5 0x52D7 0x52D9 0x52DA \ + 0x52DB 0x52DC 0x52DD 0x52DE 0x52E0 0x52E1 0x52E2 0x52E3 \ + 0x52E5 0x52E6 0x52E7 0x52E8 0x52E9 0x52EA 0x52EB 0x52EC \ + 0x52ED 0x52EE 0x52EF 0x52F1 0x52F2 0x52F3 0x52F4 0x52F5 \ + 0x52F6 0x52F7 0x52F8 0x52FB 0x52FC 0x52FD 0x5301 0x5302 \ + 0x5303 0x5304 0x5307 0x5309 0x530A 0x530B 0x530C 0x530E \ + 0x5311 0x5312 0x5313 0x5314 0x5318 0x531B 0x531C 0x531E +04 0x531F 0x5322 0x5324 0x5325 0x5327 0x5328 0x5329 0x532B \ + 0x532C 0x532D 0x532F 0x5330 0x5331 0x5332 0x5333 0x5334 \ + 0x5335 0x5336 0x5337 0x5338 0x533C 0x533D 0x5340 0x5342 \ + 0x5344 0x5346 0x534B 0x534C 0x534D 0x5350 0x5354 0x5358 \ + 0x5359 0x535B 0x535D 0x5365 0x5368 0x536A 0x536C 0x536D \ + 0x5372 0x5376 0x5379 0x537B 0x537C 0x537D 0x537E 0x5380 \ + 0x5381 0x5383 0x5387 0x5388 0x538A 0x538E 0x538F 0x5390 \ + 0x5391 0x5392 0x5393 0x5394 0x5396 0x5397 0x5399 0x539B \ + 0x539C 0x539E 0x53A0 0x53A1 0x53A4 0x53A7 0x53AA 0x53AB \ + 0x53AC 0x53AD 0x53AF 0x53B0 0x53B1 0x53B2 0x53B3 0x53B4 \ + 0x53B5 0x53B7 0x53B8 0x53B9 0x53BA 0x53BC 0x53BD 0x53BE \ + 0x53C0 0x53C3 0x53C4 0x53C5 0x53C6 0x53C7 0x53CE 0x53CF \ + 0x53D0 0x53D2 0x53D3 0x53D5 0x53DA 0x53DC 0x53DD 0x53DE \ + 0x53E1 0x53E2 0x53E7 0x53F4 0x53FA 0x53FE 0x53FF 0x5400 \ + 0x5402 0x5405 0x5407 0x540B 0x5414 0x5418 0x5419 0x541A \ + 0x541C 0x5422 0x5424 0x5425 0x542A 0x5430 0x5433 0x5436 \ + 0x5437 0x543A 0x543D 0x543F 0x5441 0x5442 0x5444 0x5445 \ + 0x5447 0x5449 0x544C 0x544D 0x544E 0x544F 0x5451 0x545A \ + 0x545D 0x545E 0x545F 0x5460 0x5461 0x5463 0x5465 0x5467 \ + 0x5469 0x546A 0x546B 0x546C 0x546D 0x546E 0x546F 0x5470 \ + 0x5474 0x5479 0x547A 0x547E 0x547F 0x5481 0x5483 0x5485 \ + 0x5487 0x5488 0x5489 0x548A 0x548D 0x5491 0x5493 0x5497 \ + 0x5498 0x549C 0x549E 0x549F 0x54A0 0x54A1 0x54A2 0x54A5 \ + 0x54AE 0x54B0 0x54B2 0x54B5 0x54B6 0x54B7 0x54B9 0x54BA \ + 0x54BC 0x54BE 0x54C3 0x54C5 0x54CA 0x54CB 0x54D6 0x54D8 \ + 0x54DB 0x54E0 0x54E1 0x54E2 0x54E3 0x54E4 0x54EB 0x54EC \ + 0x54EF 0x54F0 0x54F1 0x54F4 0x54F5 0x54F6 0x54F7 0x54F8 \ + 0x54F9 0x54FB 0x54FE 0x5500 0x5502 0x5503 0x5504 0x5505 \ + 0x5508 0x550A 0x550B 0x550C 0x550D 0x550E 0x5512 0x5513 \ + 0x5515 0x5516 0x5517 0x5518 0x5519 0x551A 0x551C 0x551D \ + 0x551E 0x551F 0x5521 0x5525 0x5526 0x5528 0x5529 0x552B \ + 0x552D 0x5532 0x5534 0x5535 0x5536 0x5538 0x5539 0x553A +05 0x553B 0x553D 0x5540 0x5542 0x5545 0x5547 0x5548 0x554B \ + 0x554C 0x554D 0x554E 0x554F 0x5551 0x5552 0x5553 0x5554 \ + 0x5557 0x5558 0x5559 0x555A 0x555B 0x555D 0x555E 0x555F \ + 0x5560 0x5562 0x5563 0x5568 0x5569 0x556B 0x556F 0x5570 \ + 0x5571 0x5572 0x5573 0x5574 0x5579 0x557A 0x557D 0x557F \ + 0x5585 0x5586 0x558C 0x558D 0x558E 0x5590 0x5592 0x5593 \ + 0x5595 0x5596 0x5597 0x559A 0x559B 0x559E 0x55A0 0x55A1 \ + 0x55A2 0x55A3 0x55A4 0x55A5 0x55A6 0x55A8 0x55A9 0x55AA \ + 0x55AB 0x55AC 0x55AD 0x55AE 0x55AF 0x55B0 0x55B2 0x55B4 \ + 0x55B6 0x55B8 0x55BA 0x55BC 0x55BF 0x55C0 0x55C1 0x55C2 \ + 0x55C3 0x55C6 0x55C7 0x55C8 0x55CA 0x55CB 0x55CE 0x55CF \ + 0x55D0 0x55D5 0x55D7 0x55D8 0x55D9 0x55DA 0x55DB 0x55DE \ + 0x55E0 0x55E2 0x55E7 0x55E9 0x55ED 0x55EE 0x55F0 0x55F1 \ + 0x55F4 0x55F6 0x55F8 0x55F9 0x55FA 0x55FB 0x55FC 0x55FF \ + 0x5602 0x5603 0x5604 0x5605 0x5606 0x5607 0x560A 0x560B \ + 0x560D 0x5610 0x5611 0x5612 0x5613 0x5614 0x5615 0x5616 \ + 0x5617 0x5619 0x561A 0x561C 0x561D 0x5620 0x5621 0x5622 \ + 0x5625 0x5626 0x5628 0x5629 0x562A 0x562B 0x562E 0x562F \ + 0x5630 0x5633 0x5635 0x5637 0x5638 0x563A 0x563C 0x563D \ + 0x563E 0x5640 0x5641 0x5642 0x5643 0x5644 0x5645 0x5646 \ + 0x5647 0x5648 0x5649 0x564A 0x564B 0x564F 0x5650 0x5651 \ + 0x5652 0x5653 0x5655 0x5656 0x565A 0x565B 0x565D 0x565E \ + 0x565F 0x5660 0x5661 0x5663 0x5665 0x5666 0x5667 0x566D \ + 0x566E 0x566F 0x5670 0x5672 0x5673 0x5674 0x5675 0x5677 \ + 0x5678 0x5679 0x567A 0x567D 0x567E 0x567F 0x5680 0x5681 \ + 0x5682 0x5683 0x5684 0x5687 0x5688 0x5689 0x568A 0x568B \ + 0x568C 0x568D 0x5690 0x5691 0x5692 0x5694 0x5695 0x5696 \ + 0x5697 0x5698 0x5699 0x569A 0x569B 0x569C 0x569D 0x569E \ + 0x569F 0x56A0 0x56A1 0x56A2 0x56A4 0x56A5 0x56A6 0x56A7 \ + 0x56A8 0x56A9 0x56AA 0x56AB 0x56AC 0x56AD 0x56AE 0x56B0 \ + 0x56B1 0x56B2 0x56B3 0x56B4 0x56B5 0x56B6 0x56B8 0x56B9 \ + 0x56BA 0x56BB 0x56BD 0x56BE 0x56BF 0x56C0 0x56C1 0x56C2 +06 0x56C3 0x56C4 0x56C5 0x56C6 0x56C7 0x56C8 0x56C9 0x56CB \ + 0x56CC 0x56CD 0x56CE 0x56CF 0x56D0 0x56D1 0x56D2 0x56D3 \ + 0x56D5 0x56D6 0x56D8 0x56D9 0x56DC 0x56E3 0x56E5 0x56E6 \ + 0x56E7 0x56E8 0x56E9 0x56EA 0x56EC 0x56EE 0x56EF 0x56F2 \ + 0x56F3 0x56F6 0x56F7 0x56F8 0x56FB 0x56FC 0x5700 0x5701 \ + 0x5702 0x5705 0x5707 0x570B 0x570C 0x570D 0x570E 0x570F \ + 0x5710 0x5711 0x5712 0x5713 0x5714 0x5715 0x5716 0x5717 \ + 0x5718 0x5719 0x571A 0x571B 0x571D 0x571E 0x5720 0x5721 \ + 0x5722 0x5724 0x5725 0x5726 0x5727 0x572B 0x5731 0x5732 \ + 0x5734 0x5735 0x5736 0x5737 0x5738 0x573C 0x573D 0x573F \ + 0x5741 0x5743 0x5744 0x5745 0x5746 0x5748 0x5749 0x574B \ + 0x5752 0x5753 0x5754 0x5755 0x5756 0x5758 0x5759 0x5762 \ + 0x5763 0x5765 0x5767 0x576C 0x576E 0x5770 0x5771 0x5772 \ + 0x5774 0x5775 0x5778 0x5779 0x577A 0x577D 0x577E 0x577F \ + 0x5780 0x5781 0x5787 0x5788 0x5789 0x578A 0x578D 0x578E \ + 0x578F 0x5790 0x5791 0x5794 0x5795 0x5796 0x5797 0x5798 \ + 0x5799 0x579A 0x579C 0x579D 0x579E 0x579F 0x57A5 0x57A8 \ + 0x57AA 0x57AC 0x57AF 0x57B0 0x57B1 0x57B3 0x57B5 0x57B6 \ + 0x57B7 0x57B9 0x57BA 0x57BB 0x57BC 0x57BD 0x57BE 0x57BF \ + 0x57C0 0x57C1 0x57C4 0x57C5 0x57C6 0x57C7 0x57C8 0x57C9 \ + 0x57CA 0x57CC 0x57CD 0x57D0 0x57D1 0x57D3 0x57D6 0x57D7 \ + 0x57DB 0x57DC 0x57DE 0x57E1 0x57E2 0x57E3 0x57E5 0x57E6 \ + 0x57E7 0x57E8 0x57E9 0x57EA 0x57EB 0x57EC 0x57EE 0x57F0 \ + 0x57F1 0x57F2 0x57F3 0x57F5 0x57F6 0x57F7 0x57FB 0x57FC \ + 0x57FE 0x57FF 0x5801 0x5803 0x5804 0x5805 0x5808 0x5809 \ + 0x580A 0x580C 0x580E 0x580F 0x5810 0x5812 0x5813 0x5814 \ + 0x5816 0x5817 0x5818 0x581A 0x581B 0x581C 0x581D 0x581F \ + 0x5822 0x5823 0x5825 0x5826 0x5827 0x5828 0x5829 0x582B \ + 0x582C 0x582D 0x582E 0x582F 0x5831 0x5832 0x5833 0x5834 \ + 0x5836 0x5837 0x5838 0x5839 0x583A 0x583B 0x583C 0x583D \ + 0x583E 0x583F 0x5840 0x5841 0x5842 0x5843 0x5845 0x5846 \ + 0x5847 0x5848 0x5849 0x584A 0x584B 0x584E 0x584F 0x5850 +07 0x5852 0x5853 0x5855 0x5856 0x5857 0x5859 0x585A 0x585B \ + 0x585C 0x585D 0x585F 0x5860 0x5861 0x5862 0x5863 0x5864 \ + 0x5866 0x5867 0x5868 0x5869 0x586A 0x586D 0x586E 0x586F \ + 0x5870 0x5871 0x5872 0x5873 0x5874 0x5875 0x5876 0x5877 \ + 0x5878 0x5879 0x587A 0x587B 0x587C 0x587D 0x587F 0x5882 \ + 0x5884 0x5886 0x5887 0x5888 0x588A 0x588B 0x588C 0x588D \ + 0x588E 0x588F 0x5890 0x5891 0x5894 0x5895 0x5896 0x5897 \ + 0x5898 0x589B 0x589C 0x589D 0x58A0 0x58A1 0x58A2 0x58A3 \ + 0x58A4 0x58A5 0x58A6 0x58A7 0x58AA 0x58AB 0x58AC 0x58AD \ + 0x58AE 0x58AF 0x58B0 0x58B1 0x58B2 0x58B3 0x58B4 0x58B5 \ + 0x58B6 0x58B7 0x58B8 0x58B9 0x58BA 0x58BB 0x58BD 0x58BE \ + 0x58BF 0x58C0 0x58C2 0x58C3 0x58C4 0x58C6 0x58C7 0x58C8 \ + 0x58C9 0x58CA 0x58CB 0x58CC 0x58CD 0x58CE 0x58CF 0x58D0 \ + 0x58D2 0x58D3 0x58D4 0x58D6 0x58D7 0x58D8 0x58D9 0x58DA \ + 0x58DB 0x58DC 0x58DD 0x58DE 0x58DF 0x58E0 0x58E1 0x58E2 \ + 0x58E3 0x58E5 0x58E6 0x58E7 0x58E8 0x58E9 0x58EA 0x58ED \ + 0x58EF 0x58F1 0x58F2 0x58F4 0x58F5 0x58F7 0x58F8 0x58FA \ + 0x58FB 0x58FC 0x58FD 0x58FE 0x58FF 0x5900 0x5901 0x5903 \ + 0x5905 0x5906 0x5908 0x5909 0x590A 0x590B 0x590C 0x590E \ + 0x5910 0x5911 0x5912 0x5913 0x5917 0x5918 0x591B 0x591D \ + 0x591E 0x5920 0x5921 0x5922 0x5923 0x5926 0x5928 0x592C \ + 0x5930 0x5932 0x5933 0x5935 0x5936 0x593B 0x593D 0x593E \ + 0x593F 0x5940 0x5943 0x5945 0x5946 0x594A 0x594C 0x594D \ + 0x5950 0x5952 0x5953 0x5959 0x595B 0x595C 0x595D 0x595E \ + 0x595F 0x5961 0x5963 0x5964 0x5966 0x5967 0x5968 0x5969 \ + 0x596A 0x596B 0x596C 0x596D 0x596E 0x596F 0x5970 0x5971 \ + 0x5972 0x5975 0x5977 0x597A 0x597B 0x597C 0x597E 0x597F \ + 0x5980 0x5985 0x5989 0x598B 0x598C 0x598E 0x598F 0x5990 \ + 0x5991 0x5994 0x5995 0x5998 0x599A 0x599B 0x599C 0x599D \ + 0x599F 0x59A0 0x59A1 0x59A2 0x59A6 0x59A7 0x59AC 0x59AD \ + 0x59B0 0x59B1 0x59B3 0x59B4 0x59B5 0x59B6 0x59B7 0x59B8 \ + 0x59BA 0x59BC 0x59BD 0x59BF 0x59C0 0x59C1 0x59C2 0x59C3 +08 0x59C4 0x59C5 0x59C7 0x59C8 0x59C9 0x59CC 0x59CD 0x59CE \ + 0x59CF 0x59D5 0x59D6 0x59D9 0x59DB 0x59DE 0x59DF 0x59E0 \ + 0x59E1 0x59E2 0x59E4 0x59E6 0x59E7 0x59E9 0x59EA 0x59EB \ + 0x59ED 0x59EE 0x59EF 0x59F0 0x59F1 0x59F2 0x59F3 0x59F4 \ + 0x59F5 0x59F6 0x59F7 0x59F8 0x59FA 0x59FC 0x59FD 0x59FE \ + 0x5A00 0x5A02 0x5A0A 0x5A0B 0x5A0D 0x5A0E 0x5A0F 0x5A10 \ + 0x5A12 0x5A14 0x5A15 0x5A16 0x5A17 0x5A19 0x5A1A 0x5A1B \ + 0x5A1D 0x5A1E 0x5A21 0x5A22 0x5A24 0x5A26 0x5A27 0x5A28 \ + 0x5A2A 0x5A2B 0x5A2C 0x5A2D 0x5A2E 0x5A2F 0x5A30 0x5A33 \ + 0x5A35 0x5A37 0x5A38 0x5A39 0x5A3A 0x5A3B 0x5A3D 0x5A3E \ + 0x5A3F 0x5A41 0x5A42 0x5A43 0x5A44 0x5A45 0x5A47 0x5A48 \ + 0x5A4B 0x5A4C 0x5A4D 0x5A4E 0x5A4F 0x5A50 0x5A51 0x5A52 \ + 0x5A53 0x5A54 0x5A56 0x5A57 0x5A58 0x5A59 0x5A5B 0x5A5C \ + 0x5A5D 0x5A5E 0x5A5F 0x5A60 0x5A61 0x5A63 0x5A64 0x5A65 \ + 0x5A66 0x5A68 0x5A69 0x5A6B 0x5A6C 0x5A6D 0x5A6E 0x5A6F \ + 0x5A70 0x5A71 0x5A72 0x5A73 0x5A78 0x5A79 0x5A7B 0x5A7C \ + 0x5A7D 0x5A7E 0x5A80 0x5A81 0x5A82 0x5A83 0x5A84 0x5A85 \ + 0x5A86 0x5A87 0x5A88 0x5A89 0x5A8A 0x5A8B 0x5A8C 0x5A8D \ + 0x5A8E 0x5A8F 0x5A90 0x5A91 0x5A93 0x5A94 0x5A95 0x5A96 \ + 0x5A97 0x5A98 0x5A99 0x5A9C 0x5A9D 0x5A9E 0x5A9F 0x5AA0 \ + 0x5AA1 0x5AA2 0x5AA3 0x5AA4 0x5AA5 0x5AA6 0x5AA7 0x5AA8 \ + 0x5AA9 0x5AAB 0x5AAC 0x5AAD 0x5AAE 0x5AAF 0x5AB0 0x5AB1 \ + 0x5AB4 0x5AB6 0x5AB7 0x5AB9 0x5ABA 0x5ABB 0x5ABC 0x5ABD \ + 0x5ABF 0x5AC0 0x5AC3 0x5AC4 0x5AC5 0x5AC6 0x5AC7 0x5AC8 \ + 0x5ACA 0x5ACB 0x5ACD 0x5ACE 0x5ACF 0x5AD0 0x5AD1 0x5AD3 \ + 0x5AD5 0x5AD7 0x5AD9 0x5ADA 0x5ADB 0x5ADD 0x5ADE 0x5ADF \ + 0x5AE2 0x5AE4 0x5AE5 0x5AE7 0x5AE8 0x5AEA 0x5AEC 0x5AED \ + 0x5AEE 0x5AEF 0x5AF0 0x5AF2 0x5AF3 0x5AF4 0x5AF5 0x5AF6 \ + 0x5AF7 0x5AF8 0x5AF9 0x5AFA 0x5AFB 0x5AFC 0x5AFD 0x5AFE \ + 0x5AFF 0x5B00 0x5B01 0x5B02 0x5B03 0x5B04 0x5B05 0x5B06 \ + 0x5B07 0x5B08 0x5B0A 0x5B0B 0x5B0C 0x5B0D 0x5B0E 0x5B0F \ + 0x5B10 0x5B11 0x5B12 0x5B13 0x5B14 0x5B15 0x5B18 0x5B19 +09 0x5B1A 0x5B1B 0x5B1C 0x5B1D 0x5B1E 0x5B1F 0x5B20 0x5B21 \ + 0x5B22 0x5B23 0x5B24 0x5B25 0x5B26 0x5B27 0x5B28 0x5B29 \ + 0x5B2A 0x5B2B 0x5B2C 0x5B2D 0x5B2E 0x5B2F 0x5B30 0x5B31 \ + 0x5B33 0x5B35 0x5B36 0x5B38 0x5B39 0x5B3A 0x5B3B 0x5B3C \ + 0x5B3D 0x5B3E 0x5B3F 0x5B41 0x5B42 0x5B43 0x5B44 0x5B45 \ + 0x5B46 0x5B47 0x5B48 0x5B49 0x5B4A 0x5B4B 0x5B4C 0x5B4D \ + 0x5B4E 0x5B4F 0x5B52 0x5B56 0x5B5E 0x5B60 0x5B61 0x5B67 \ + 0x5B68 0x5B6B 0x5B6D 0x5B6E 0x5B6F 0x5B72 0x5B74 0x5B76 \ + 0x5B77 0x5B78 0x5B79 0x5B7B 0x5B7C 0x5B7E 0x5B7F 0x5B82 \ + 0x5B86 0x5B8A 0x5B8D 0x5B8E 0x5B90 0x5B91 0x5B92 0x5B94 \ + 0x5B96 0x5B9F 0x5BA7 0x5BA8 0x5BA9 0x5BAC 0x5BAD 0x5BAE \ + 0x5BAF 0x5BB1 0x5BB2 0x5BB7 0x5BBA 0x5BBB 0x5BBC 0x5BC0 \ + 0x5BC1 0x5BC3 0x5BC8 0x5BC9 0x5BCA 0x5BCB 0x5BCD 0x5BCE \ + 0x5BCF 0x5BD1 0x5BD4 0x5BD5 0x5BD6 0x5BD7 0x5BD8 0x5BD9 \ + 0x5BDA 0x5BDB 0x5BDC 0x5BE0 0x5BE2 0x5BE3 0x5BE6 0x5BE7 \ + 0x5BE9 0x5BEA 0x5BEB 0x5BEC 0x5BED 0x5BEF 0x5BF1 0x5BF2 \ + 0x5BF3 0x5BF4 0x5BF5 0x5BF6 0x5BF7 0x5BFD 0x5BFE 0x5C00 \ + 0x5C02 0x5C03 0x5C05 0x5C07 0x5C08 0x5C0B 0x5C0C 0x5C0D \ + 0x5C0E 0x5C10 0x5C12 0x5C13 0x5C17 0x5C19 0x5C1B 0x5C1E \ + 0x5C1F 0x5C20 0x5C21 0x5C23 0x5C26 0x5C28 0x5C29 0x5C2A \ + 0x5C2B 0x5C2D 0x5C2E 0x5C2F 0x5C30 0x5C32 0x5C33 0x5C35 \ + 0x5C36 0x5C37 0x5C43 0x5C44 0x5C46 0x5C47 0x5C4C 0x5C4D \ + 0x5C52 0x5C53 0x5C54 0x5C56 0x5C57 0x5C58 0x5C5A 0x5C5B \ + 0x5C5C 0x5C5D 0x5C5F 0x5C62 0x5C64 0x5C67 0x5C68 0x5C69 \ + 0x5C6A 0x5C6B 0x5C6C 0x5C6D 0x5C70 0x5C72 0x5C73 0x5C74 \ + 0x5C75 0x5C76 0x5C77 0x5C78 0x5C7B 0x5C7C 0x5C7D 0x5C7E \ + 0x5C80 0x5C83 0x5C84 0x5C85 0x5C86 0x5C87 0x5C89 0x5C8A \ + 0x5C8B 0x5C8E 0x5C8F 0x5C92 0x5C93 0x5C95 0x5C9D 0x5C9E \ + 0x5C9F 0x5CA0 0x5CA1 0x5CA4 0x5CA5 0x5CA6 0x5CA7 0x5CA8 \ + 0x5CAA 0x5CAE 0x5CAF 0x5CB0 0x5CB2 0x5CB4 0x5CB6 0x5CB9 \ + 0x5CBA 0x5CBB 0x5CBC 0x5CBE 0x5CC0 0x5CC2 0x5CC3 0x5CC5 \ + 0x5CC6 0x5CC7 0x5CC8 0x5CC9 0x5CCA 0x5CCC 0x5CCD 0x5CCE +10 0x5CCF 0x5CD0 0x5CD1 0x5CD3 0x5CD4 0x5CD5 0x5CD6 0x5CD7 \ + 0x5CD8 0x5CDA 0x5CDB 0x5CDC 0x5CDD 0x5CDE 0x5CDF 0x5CE0 \ + 0x5CE2 0x5CE3 0x5CE7 0x5CE9 0x5CEB 0x5CEC 0x5CEE 0x5CEF \ + 0x5CF1 0x5CF2 0x5CF3 0x5CF4 0x5CF5 0x5CF6 0x5CF7 0x5CF8 \ + 0x5CF9 0x5CFA 0x5CFC 0x5CFD 0x5CFE 0x5CFF 0x5D00 0x5D01 \ + 0x5D04 0x5D05 0x5D08 0x5D09 0x5D0A 0x5D0B 0x5D0C 0x5D0D \ + 0x5D0F 0x5D10 0x5D11 0x5D12 0x5D13 0x5D15 0x5D17 0x5D18 \ + 0x5D19 0x5D1A 0x5D1C 0x5D1D 0x5D1F 0x5D20 0x5D21 0x5D22 \ + 0x5D23 0x5D25 0x5D28 0x5D2A 0x5D2B 0x5D2C 0x5D2F 0x5D30 \ + 0x5D31 0x5D32 0x5D33 0x5D35 0x5D36 0x5D37 0x5D38 0x5D39 \ + 0x5D3A 0x5D3B 0x5D3C 0x5D3F 0x5D40 0x5D41 0x5D42 0x5D43 \ + 0x5D44 0x5D45 0x5D46 0x5D48 0x5D49 0x5D4D 0x5D4E 0x5D4F \ + 0x5D50 0x5D51 0x5D52 0x5D53 0x5D54 0x5D55 0x5D56 0x5D57 \ + 0x5D59 0x5D5A 0x5D5C 0x5D5E 0x5D5F 0x5D60 0x5D61 0x5D62 \ + 0x5D63 0x5D64 0x5D65 0x5D66 0x5D67 0x5D68 0x5D6A 0x5D6D \ + 0x5D6E 0x5D70 0x5D71 0x5D72 0x5D73 0x5D75 0x5D76 0x5D77 \ + 0x5D78 0x5D79 0x5D7A 0x5D7B 0x5D7C 0x5D7D 0x5D7E 0x5D7F \ + 0x5D80 0x5D81 0x5D83 0x5D84 0x5D85 0x5D86 0x5D87 0x5D88 \ + 0x5D89 0x5D8A 0x5D8B 0x5D8C 0x5D8D 0x5D8E 0x5D8F 0x5D90 \ + 0x5D91 0x5D92 0x5D93 0x5D94 0x5D95 0x5D96 0x5D97 0x5D98 \ + 0x5D9A 0x5D9B 0x5D9C 0x5D9E 0x5D9F 0x5DA0 0x5DA1 0x5DA2 \ + 0x5DA3 0x5DA4 0x5DA5 0x5DA6 0x5DA7 0x5DA8 0x5DA9 0x5DAA \ + 0x5DAB 0x5DAC 0x5DAD 0x5DAE 0x5DAF 0x5DB0 0x5DB1 0x5DB2 \ + 0x5DB3 0x5DB4 0x5DB5 0x5DB6 0x5DB8 0x5DB9 0x5DBA 0x5DBB \ + 0x5DBC 0x5DBD 0x5DBE 0x5DBF 0x5DC0 0x5DC1 0x5DC2 0x5DC3 \ + 0x5DC4 0x5DC6 0x5DC7 0x5DC8 0x5DC9 0x5DCA 0x5DCB 0x5DCC \ + 0x5DCE 0x5DCF 0x5DD0 0x5DD1 0x5DD2 0x5DD3 0x5DD4 0x5DD5 \ + 0x5DD6 0x5DD7 0x5DD8 0x5DD9 0x5DDA 0x5DDC 0x5DDF 0x5DE0 \ + 0x5DE3 0x5DE4 0x5DEA 0x5DEC 0x5DED 0x5DF0 0x5DF5 0x5DF6 \ + 0x5DF8 0x5DF9 0x5DFA 0x5DFB 0x5DFC 0x5DFF 0x5E00 0x5E04 \ + 0x5E07 0x5E09 0x5E0A 0x5E0B 0x5E0D 0x5E0E 0x5E12 0x5E13 \ + 0x5E17 0x5E1E 0x5E1F 0x5E20 0x5E21 0x5E22 0x5E23 0x5E24 +11 0x5E25 0x5E28 0x5E29 0x5E2A 0x5E2B 0x5E2C 0x5E2F 0x5E30 \ + 0x5E32 0x5E33 0x5E34 0x5E35 0x5E36 0x5E39 0x5E3A 0x5E3E \ + 0x5E3F 0x5E40 0x5E41 0x5E43 0x5E46 0x5E47 0x5E48 0x5E49 \ + 0x5E4A 0x5E4B 0x5E4D 0x5E4E 0x5E4F 0x5E50 0x5E51 0x5E52 \ + 0x5E53 0x5E56 0x5E57 0x5E58 0x5E59 0x5E5A 0x5E5C 0x5E5D \ + 0x5E5F 0x5E60 0x5E63 0x5E64 0x5E65 0x5E66 0x5E67 0x5E68 \ + 0x5E69 0x5E6A 0x5E6B 0x5E6C 0x5E6D 0x5E6E 0x5E6F 0x5E70 \ + 0x5E71 0x5E75 0x5E77 0x5E79 0x5E7E 0x5E81 0x5E82 0x5E83 \ + 0x5E85 0x5E88 0x5E89 0x5E8C 0x5E8D 0x5E8E 0x5E92 0x5E98 \ + 0x5E9B 0x5E9D 0x5EA1 0x5EA2 0x5EA3 0x5EA4 0x5EA8 0x5EA9 \ + 0x5EAA 0x5EAB 0x5EAC 0x5EAE 0x5EAF 0x5EB0 0x5EB1 0x5EB2 \ + 0x5EB4 0x5EBA 0x5EBB 0x5EBC 0x5EBD 0x5EBF 0x5EC0 0x5EC1 \ + 0x5EC2 0x5EC3 0x5EC4 0x5EC5 0x5EC6 0x5EC7 0x5EC8 0x5ECB \ + 0x5ECC 0x5ECD 0x5ECE 0x5ECF 0x5ED0 0x5ED4 0x5ED5 0x5ED7 \ + 0x5ED8 0x5ED9 0x5EDA 0x5EDC 0x5EDD 0x5EDE 0x5EDF 0x5EE0 \ + 0x5EE1 0x5EE2 0x5EE3 0x5EE4 0x5EE5 0x5EE6 0x5EE7 0x5EE9 \ + 0x5EEB 0x5EEC 0x5EED 0x5EEE 0x5EEF 0x5EF0 0x5EF1 0x5EF2 \ + 0x5EF3 0x5EF5 0x5EF8 0x5EF9 0x5EFB 0x5EFC 0x5EFD 0x5F05 \ + 0x5F06 0x5F07 0x5F09 0x5F0C 0x5F0D 0x5F0E 0x5F10 0x5F12 \ + 0x5F14 0x5F16 0x5F19 0x5F1A 0x5F1C 0x5F1D 0x5F1E 0x5F21 \ + 0x5F22 0x5F23 0x5F24 0x5F28 0x5F2B 0x5F2C 0x5F2E 0x5F30 \ + 0x5F32 0x5F33 0x5F34 0x5F35 0x5F36 0x5F37 0x5F38 0x5F3B \ + 0x5F3D 0x5F3E 0x5F3F 0x5F41 0x5F42 0x5F43 0x5F44 0x5F45 \ + 0x5F46 0x5F47 0x5F48 0x5F49 0x5F4A 0x5F4B 0x5F4C 0x5F4D \ + 0x5F4E 0x5F4F 0x5F51 0x5F54 0x5F59 0x5F5A 0x5F5B 0x5F5C \ + 0x5F5E 0x5F5F 0x5F60 0x5F63 0x5F65 0x5F67 0x5F68 0x5F6B \ + 0x5F6E 0x5F6F 0x5F72 0x5F74 0x5F75 0x5F76 0x5F78 0x5F7A \ + 0x5F7D 0x5F7E 0x5F7F 0x5F83 0x5F86 0x5F8D 0x5F8E 0x5F8F \ + 0x5F91 0x5F93 0x5F94 0x5F96 0x5F9A 0x5F9B 0x5F9D 0x5F9E \ + 0x5F9F 0x5FA0 0x5FA2 0x5FA3 0x5FA4 0x5FA5 0x5FA6 0x5FA7 \ + 0x5FA9 0x5FAB 0x5FAC 0x5FAF 0x5FB0 0x5FB1 0x5FB2 0x5FB3 \ + 0x5FB4 0x5FB6 0x5FB8 0x5FB9 0x5FBA 0x5FBB 0x5FBE 0x5FBF +12 0x5FC0 0x5FC1 0x5FC2 0x5FC7 0x5FC8 0x5FCA 0x5FCB 0x5FCE \ + 0x5FD3 0x5FD4 0x5FD5 0x5FDA 0x5FDB 0x5FDC 0x5FDE 0x5FDF \ + 0x5FE2 0x5FE3 0x5FE5 0x5FE6 0x5FE8 0x5FE9 0x5FEC 0x5FEF \ + 0x5FF0 0x5FF2 0x5FF3 0x5FF4 0x5FF6 0x5FF7 0x5FF9 0x5FFA \ + 0x5FFC 0x6007 0x6008 0x6009 0x600B 0x600C 0x6010 0x6011 \ + 0x6013 0x6017 0x6018 0x601A 0x601E 0x601F 0x6022 0x6023 \ + 0x6024 0x602C 0x602D 0x602E 0x6030 0x6031 0x6032 0x6033 \ + 0x6034 0x6036 0x6037 0x6038 0x6039 0x603A 0x603D 0x603E \ + 0x6040 0x6044 0x6045 0x6046 0x6047 0x6048 0x6049 0x604A \ + 0x604C 0x604E 0x604F 0x6051 0x6053 0x6054 0x6056 0x6057 \ + 0x6058 0x605B 0x605C 0x605E 0x605F 0x6060 0x6061 0x6065 \ + 0x6066 0x606E 0x6071 0x6072 0x6074 0x6075 0x6077 0x607E \ + 0x6080 0x6081 0x6082 0x6085 0x6086 0x6087 0x6088 0x608A \ + 0x608B 0x608E 0x608F 0x6090 0x6091 0x6093 0x6095 0x6097 \ + 0x6098 0x6099 0x609C 0x609E 0x60A1 0x60A2 0x60A4 0x60A5 \ + 0x60A7 0x60A9 0x60AA 0x60AE 0x60B0 0x60B3 0x60B5 0x60B6 \ + 0x60B7 0x60B9 0x60BA 0x60BD 0x60BE 0x60BF 0x60C0 0x60C1 \ + 0x60C2 0x60C3 0x60C4 0x60C7 0x60C8 0x60C9 0x60CC 0x60CD \ + 0x60CE 0x60CF 0x60D0 0x60D2 0x60D3 0x60D4 0x60D6 0x60D7 \ + 0x60D9 0x60DB 0x60DE 0x60E1 0x60E2 0x60E3 0x60E4 0x60E5 \ + 0x60EA 0x60F1 0x60F2 0x60F5 0x60F7 0x60F8 0x60FB 0x60FC \ + 0x60FD 0x60FE 0x60FF 0x6102 0x6103 0x6104 0x6105 0x6107 \ + 0x610A 0x610B 0x610C 0x6110 0x6111 0x6112 0x6113 0x6114 \ + 0x6116 0x6117 0x6118 0x6119 0x611B 0x611C 0x611D 0x611E \ + 0x6121 0x6122 0x6125 0x6128 0x6129 0x612A 0x612C 0x612D \ + 0x612E 0x612F 0x6130 0x6131 0x6132 0x6133 0x6134 0x6135 \ + 0x6136 0x6137 0x6138 0x6139 0x613A 0x613B 0x613C 0x613D \ + 0x613E 0x6140 0x6141 0x6142 0x6143 0x6144 0x6145 0x6146 \ + 0x6147 0x6149 0x614B 0x614D 0x614F 0x6150 0x6152 0x6153 \ + 0x6154 0x6156 0x6157 0x6158 0x6159 0x615A 0x615B 0x615C \ + 0x615E 0x615F 0x6160 0x6161 0x6163 0x6164 0x6165 0x6166 \ + 0x6169 0x616A 0x616B 0x616C 0x616D 0x616E 0x616F 0x6171 +13 0x6172 0x6173 0x6174 0x6176 0x6178 0x6179 0x617A 0x617B \ + 0x617C 0x617D 0x617E 0x617F 0x6180 0x6181 0x6182 0x6183 \ + 0x6184 0x6185 0x6186 0x6187 0x6188 0x6189 0x618A 0x618C \ + 0x618D 0x618F 0x6190 0x6191 0x6192 0x6193 0x6195 0x6196 \ + 0x6197 0x6198 0x6199 0x619A 0x619B 0x619C 0x619E 0x619F \ + 0x61A0 0x61A1 0x61A2 0x61A3 0x61A4 0x61A5 0x61A6 0x61AA \ + 0x61AB 0x61AD 0x61AE 0x61AF 0x61B0 0x61B1 0x61B2 0x61B3 \ + 0x61B4 0x61B5 0x61B6 0x61B8 0x61B9 0x61BA 0x61BB 0x61BC \ + 0x61BD 0x61BF 0x61C0 0x61C1 0x61C3 0x61C4 0x61C5 0x61C6 \ + 0x61C7 0x61C9 0x61CC 0x61CD 0x61CE 0x61CF 0x61D0 0x61D3 \ + 0x61D5 0x61D6 0x61D7 0x61D8 0x61D9 0x61DA 0x61DB 0x61DC \ + 0x61DD 0x61DE 0x61DF 0x61E0 0x61E1 0x61E2 0x61E3 0x61E4 \ + 0x61E5 0x61E7 0x61E8 0x61E9 0x61EA 0x61EB 0x61EC 0x61ED \ + 0x61EE 0x61EF 0x61F0 0x61F1 0x61F2 0x61F3 0x61F4 0x61F6 \ + 0x61F7 0x61F8 0x61F9 0x61FA 0x61FB 0x61FC 0x61FD 0x61FE \ + 0x6200 0x6201 0x6202 0x6203 0x6204 0x6205 0x6207 0x6209 \ + 0x6213 0x6214 0x6219 0x621C 0x621D 0x621E 0x6220 0x6223 \ + 0x6226 0x6227 0x6228 0x6229 0x622B 0x622D 0x622F 0x6230 \ + 0x6231 0x6232 0x6235 0x6236 0x6238 0x6239 0x623A 0x623B \ + 0x623C 0x6242 0x6244 0x6245 0x6246 0x624A 0x624F 0x6250 \ + 0x6255 0x6256 0x6257 0x6259 0x625A 0x625C 0x625D 0x625E \ + 0x625F 0x6260 0x6261 0x6262 0x6264 0x6265 0x6268 0x6271 \ + 0x6272 0x6274 0x6275 0x6277 0x6278 0x627A 0x627B 0x627D \ + 0x6281 0x6282 0x6283 0x6285 0x6286 0x6287 0x6288 0x628B \ + 0x628C 0x628D 0x628E 0x628F 0x6290 0x6294 0x6299 0x629C \ + 0x629D 0x629E 0x62A3 0x62A6 0x62A7 0x62A9 0x62AA 0x62AD \ + 0x62AE 0x62AF 0x62B0 0x62B2 0x62B3 0x62B4 0x62B6 0x62B7 \ + 0x62B8 0x62BA 0x62BE 0x62C0 0x62C1 0x62C3 0x62CB 0x62CF \ + 0x62D1 0x62D5 0x62DD 0x62DE 0x62E0 0x62E1 0x62E4 0x62EA \ + 0x62EB 0x62F0 0x62F2 0x62F5 0x62F8 0x62F9 0x62FA 0x62FB \ + 0x6300 0x6303 0x6304 0x6305 0x6306 0x630A 0x630B 0x630C \ + 0x630D 0x630F 0x6310 0x6312 0x6313 0x6314 0x6315 0x6317 +14 0x6318 0x6319 0x631C 0x6326 0x6327 0x6329 0x632C 0x632D \ + 0x632E 0x6330 0x6331 0x6333 0x6334 0x6335 0x6336 0x6337 \ + 0x6338 0x633B 0x633C 0x633E 0x633F 0x6340 0x6341 0x6344 \ + 0x6347 0x6348 0x634A 0x6351 0x6352 0x6353 0x6354 0x6356 \ + 0x6357 0x6358 0x6359 0x635A 0x635B 0x635C 0x635D 0x6360 \ + 0x6364 0x6365 0x6366 0x6368 0x636A 0x636B 0x636C 0x636F \ + 0x6370 0x6372 0x6373 0x6374 0x6375 0x6378 0x6379 0x637C \ + 0x637D 0x637E 0x637F 0x6381 0x6383 0x6384 0x6385 0x6386 \ + 0x638B 0x638D 0x6391 0x6393 0x6394 0x6395 0x6397 0x6399 \ + 0x639A 0x639B 0x639C 0x639D 0x639E 0x639F 0x63A1 0x63A4 \ + 0x63A6 0x63AB 0x63AF 0x63B1 0x63B2 0x63B5 0x63B6 0x63B9 \ + 0x63BB 0x63BD 0x63BF 0x63C0 0x63C1 0x63C2 0x63C3 0x63C5 \ + 0x63C7 0x63C8 0x63CA 0x63CB 0x63CC 0x63D1 0x63D3 0x63D4 \ + 0x63D5 0x63D7 0x63D8 0x63D9 0x63DA 0x63DB 0x63DC 0x63DD \ + 0x63DF 0x63E2 0x63E4 0x63E5 0x63E6 0x63E7 0x63E8 0x63EB \ + 0x63EC 0x63EE 0x63EF 0x63F0 0x63F1 0x63F3 0x63F5 0x63F7 \ + 0x63F9 0x63FA 0x63FB 0x63FC 0x63FE 0x6403 0x6404 0x6406 \ + 0x6407 0x6408 0x6409 0x640A 0x640D 0x640E 0x6411 0x6412 \ + 0x6415 0x6416 0x6417 0x6418 0x6419 0x641A 0x641D 0x641F \ + 0x6422 0x6423 0x6424 0x6425 0x6427 0x6428 0x6429 0x642B \ + 0x642E 0x642F 0x6430 0x6431 0x6432 0x6433 0x6435 0x6436 \ + 0x6437 0x6438 0x6439 0x643B 0x643C 0x643E 0x6440 0x6442 \ + 0x6443 0x6449 0x644B 0x644C 0x644D 0x644E 0x644F 0x6450 \ + 0x6451 0x6453 0x6455 0x6456 0x6457 0x6459 0x645A 0x645B \ + 0x645C 0x645D 0x645F 0x6460 0x6461 0x6462 0x6463 0x6464 \ + 0x6465 0x6466 0x6468 0x646A 0x646B 0x646C 0x646E 0x646F \ + 0x6470 0x6471 0x6472 0x6473 0x6474 0x6475 0x6476 0x6477 \ + 0x647B 0x647C 0x647D 0x647E 0x647F 0x6480 0x6481 0x6483 \ + 0x6486 0x6488 0x6489 0x648A 0x648B 0x648C 0x648D 0x648E \ + 0x648F 0x6490 0x6493 0x6494 0x6497 0x6498 0x649A 0x649B \ + 0x649C 0x649D 0x649F 0x64A0 0x64A1 0x64A2 0x64A3 0x64A5 \ + 0x64A6 0x64A7 0x64A8 0x64AA 0x64AB 0x64AF 0x64B1 0x64B2 +15 0x64B3 0x64B4 0x64B6 0x64B9 0x64BB 0x64BD 0x64BE 0x64BF \ + 0x64C1 0x64C3 0x64C4 0x64C6 0x64C7 0x64C8 0x64C9 0x64CA \ + 0x64CB 0x64CC 0x64CF 0x64D1 0x64D3 0x64D4 0x64D5 0x64D6 \ + 0x64D9 0x64DA 0x64DB 0x64DC 0x64DD 0x64DF 0x64E0 0x64E1 \ + 0x64E3 0x64E5 0x64E7 0x64E8 0x64E9 0x64EA 0x64EB 0x64EC \ + 0x64ED 0x64EE 0x64EF 0x64F0 0x64F1 0x64F2 0x64F3 0x64F4 \ + 0x64F5 0x64F6 0x64F7 0x64F8 0x64F9 0x64FA 0x64FB 0x64FC \ + 0x64FD 0x64FE 0x64FF 0x6501 0x6502 0x6503 0x6504 0x6505 \ + 0x6506 0x6507 0x6508 0x650A 0x650B 0x650C 0x650D 0x650E \ + 0x650F 0x6510 0x6511 0x6513 0x6514 0x6515 0x6516 0x6517 \ + 0x6519 0x651A 0x651B 0x651C 0x651D 0x651E 0x651F 0x6520 \ + 0x6521 0x6522 0x6523 0x6524 0x6526 0x6527 0x6528 0x6529 \ + 0x652A 0x652C 0x652D 0x6530 0x6531 0x6532 0x6533 0x6537 \ + 0x653A 0x653C 0x653D 0x6540 0x6541 0x6542 0x6543 0x6544 \ + 0x6546 0x6547 0x654A 0x654B 0x654D 0x654E 0x6550 0x6552 \ + 0x6553 0x6554 0x6557 0x6558 0x655A 0x655C 0x655F 0x6560 \ + 0x6561 0x6564 0x6565 0x6567 0x6568 0x6569 0x656A 0x656D \ + 0x656E 0x656F 0x6571 0x6573 0x6575 0x6576 0x6578 0x6579 \ + 0x657A 0x657B 0x657C 0x657D 0x657E 0x657F 0x6580 0x6581 \ + 0x6582 0x6583 0x6584 0x6585 0x6586 0x6588 0x6589 0x658A \ + 0x658D 0x658E 0x658F 0x6592 0x6594 0x6595 0x6596 0x6598 \ + 0x659A 0x659D 0x659E 0x65A0 0x65A2 0x65A3 0x65A6 0x65A8 \ + 0x65AA 0x65AC 0x65AE 0x65B1 0x65B2 0x65B3 0x65B4 0x65B5 \ + 0x65B6 0x65B7 0x65B8 0x65BA 0x65BB 0x65BE 0x65BF 0x65C0 \ + 0x65C2 0x65C7 0x65C8 0x65C9 0x65CA 0x65CD 0x65D0 0x65D1 \ + 0x65D3 0x65D4 0x65D5 0x65D8 0x65D9 0x65DA 0x65DB 0x65DC \ + 0x65DD 0x65DE 0x65DF 0x65E1 0x65E3 0x65E4 0x65EA 0x65EB \ + 0x65F2 0x65F3 0x65F4 0x65F5 0x65F8 0x65F9 0x65FB 0x65FC \ + 0x65FD 0x65FE 0x65FF 0x6601 0x6604 0x6605 0x6607 0x6608 \ + 0x6609 0x660B 0x660D 0x6610 0x6611 0x6612 0x6616 0x6617 \ + 0x6618 0x661A 0x661B 0x661C 0x661E 0x6621 0x6622 0x6623 \ + 0x6624 0x6626 0x6629 0x662A 0x662B 0x662C 0x662E 0x6630 +16 0x6632 0x6633 0x6637 0x6638 0x6639 0x663A 0x663B 0x663D \ + 0x663F 0x6640 0x6642 0x6644 0x6645 0x6646 0x6647 0x6648 \ + 0x6649 0x664A 0x664D 0x664E 0x6650 0x6651 0x6658 0x6659 \ + 0x665B 0x665C 0x665D 0x665E 0x6660 0x6662 0x6663 0x6665 \ + 0x6667 0x6669 0x666A 0x666B 0x666C 0x666D 0x6671 0x6672 \ + 0x6673 0x6675 0x6678 0x6679 0x667B 0x667C 0x667D 0x667F \ + 0x6680 0x6681 0x6683 0x6685 0x6686 0x6688 0x6689 0x668A \ + 0x668B 0x668D 0x668E 0x668F 0x6690 0x6692 0x6693 0x6694 \ + 0x6695 0x6698 0x6699 0x669A 0x669B 0x669C 0x669E 0x669F \ + 0x66A0 0x66A1 0x66A2 0x66A3 0x66A4 0x66A5 0x66A6 0x66A9 \ + 0x66AA 0x66AB 0x66AC 0x66AD 0x66AF 0x66B0 0x66B1 0x66B2 \ + 0x66B3 0x66B5 0x66B6 0x66B7 0x66B8 0x66BA 0x66BB 0x66BC \ + 0x66BD 0x66BF 0x66C0 0x66C1 0x66C2 0x66C3 0x66C4 0x66C5 \ + 0x66C6 0x66C7 0x66C8 0x66C9 0x66CA 0x66CB 0x66CC 0x66CD \ + 0x66CE 0x66CF 0x66D0 0x66D1 0x66D2 0x66D3 0x66D4 0x66D5 \ + 0x66D6 0x66D7 0x66D8 0x66DA 0x66DE 0x66DF 0x66E0 0x66E1 \ + 0x66E2 0x66E3 0x66E4 0x66E5 0x66E7 0x66E8 0x66EA 0x66EB \ + 0x66EC 0x66ED 0x66EE 0x66EF 0x66F1 0x66F5 0x66F6 0x66F8 \ + 0x66FA 0x66FB 0x66FD 0x6701 0x6702 0x6703 0x6704 0x6705 \ + 0x6706 0x6707 0x670C 0x670E 0x670F 0x6711 0x6712 0x6713 \ + 0x6716 0x6718 0x6719 0x671A 0x671C 0x671E 0x6720 0x6721 \ + 0x6722 0x6723 0x6724 0x6725 0x6727 0x6729 0x672E 0x6730 \ + 0x6732 0x6733 0x6736 0x6737 0x6738 0x6739 0x673B 0x673C \ + 0x673E 0x673F 0x6741 0x6744 0x6745 0x6747 0x674A 0x674B \ + 0x674D 0x6752 0x6754 0x6755 0x6757 0x6758 0x6759 0x675A \ + 0x675B 0x675D 0x6762 0x6763 0x6764 0x6766 0x6767 0x676B \ + 0x676C 0x676E 0x6771 0x6774 0x6776 0x6778 0x6779 0x677A \ + 0x677B 0x677D 0x6780 0x6782 0x6783 0x6785 0x6786 0x6788 \ + 0x678A 0x678C 0x678D 0x678E 0x678F 0x6791 0x6792 0x6793 \ + 0x6794 0x6796 0x6799 0x679B 0x679F 0x67A0 0x67A1 0x67A4 \ + 0x67A6 0x67A9 0x67AC 0x67AE 0x67B1 0x67B2 0x67B4 0x67B9 \ + 0x67BA 0x67BB 0x67BC 0x67BD 0x67BE 0x67BF 0x67C0 0x67C2 +17 0x67C5 0x67C6 0x67C7 0x67C8 0x67C9 0x67CA 0x67CB 0x67CC \ + 0x67CD 0x67CE 0x67D5 0x67D6 0x67D7 0x67DB 0x67DF 0x67E1 \ + 0x67E3 0x67E4 0x67E6 0x67E7 0x67E8 0x67EA 0x67EB 0x67ED \ + 0x67EE 0x67F2 0x67F5 0x67F6 0x67F7 0x67F8 0x67F9 0x67FA \ + 0x67FB 0x67FC 0x67FE 0x6801 0x6802 0x6803 0x6804 0x6806 \ + 0x680D 0x6810 0x6812 0x6814 0x6815 0x6818 0x6819 0x681A \ + 0x681B 0x681C 0x681E 0x681F 0x6820 0x6822 0x6823 0x6824 \ + 0x6825 0x6826 0x6827 0x6828 0x682B 0x682C 0x682D 0x682E \ + 0x682F 0x6830 0x6831 0x6834 0x6835 0x6836 0x683A 0x683B \ + 0x683F 0x6847 0x684B 0x684D 0x684F 0x6852 0x6856 0x6857 \ + 0x6858 0x6859 0x685A 0x685B 0x685C 0x685D 0x685E 0x685F \ + 0x686A 0x686C 0x686D 0x686E 0x686F 0x6870 0x6871 0x6872 \ + 0x6873 0x6875 0x6878 0x6879 0x687A 0x687B 0x687C 0x687D \ + 0x687E 0x687F 0x6880 0x6882 0x6884 0x6887 0x6888 0x6889 \ + 0x688A 0x688B 0x688C 0x688D 0x688E 0x6890 0x6891 0x6892 \ + 0x6894 0x6895 0x6896 0x6898 0x6899 0x689A 0x689B 0x689C \ + 0x689D 0x689E 0x689F 0x68A0 0x68A1 0x68A3 0x68A4 0x68A5 \ + 0x68A9 0x68AA 0x68AB 0x68AC 0x68AE 0x68B1 0x68B2 0x68B4 \ + 0x68B6 0x68B7 0x68B8 0x68B9 0x68BA 0x68BB 0x68BC 0x68BD \ + 0x68BE 0x68BF 0x68C1 0x68C3 0x68C4 0x68C5 0x68C6 0x68C7 \ + 0x68C8 0x68CA 0x68CC 0x68CE 0x68CF 0x68D0 0x68D1 0x68D3 \ + 0x68D4 0x68D6 0x68D7 0x68D9 0x68DB 0x68DC 0x68DD 0x68DE \ + 0x68DF 0x68E1 0x68E2 0x68E4 0x68E5 0x68E6 0x68E7 0x68E8 \ + 0x68E9 0x68EA 0x68EB 0x68EC 0x68ED 0x68EF 0x68F2 0x68F3 \ + 0x68F4 0x68F6 0x68F7 0x68F8 0x68FB 0x68FD 0x68FE 0x68FF \ + 0x6900 0x6902 0x6903 0x6904 0x6906 0x6907 0x6908 0x6909 \ + 0x690A 0x690C 0x690F 0x6911 0x6913 0x6914 0x6915 0x6916 \ + 0x6917 0x6918 0x6919 0x691A 0x691B 0x691C 0x691D 0x691E \ + 0x6921 0x6922 0x6923 0x6925 0x6926 0x6927 0x6928 0x6929 \ + 0x692A 0x692B 0x692C 0x692E 0x692F 0x6931 0x6932 0x6933 \ + 0x6935 0x6936 0x6937 0x6938 0x693A 0x693B 0x693C 0x693E \ + 0x6940 0x6941 0x6943 0x6944 0x6945 0x6946 0x6947 0x6948 +18 0x6949 0x694A 0x694B 0x694C 0x694D 0x694E 0x694F 0x6950 \ + 0x6951 0x6952 0x6953 0x6955 0x6956 0x6958 0x6959 0x695B \ + 0x695C 0x695F 0x6961 0x6962 0x6964 0x6965 0x6967 0x6968 \ + 0x6969 0x696A 0x696C 0x696D 0x696F 0x6970 0x6972 0x6973 \ + 0x6974 0x6975 0x6976 0x697A 0x697B 0x697D 0x697E 0x697F \ + 0x6981 0x6983 0x6985 0x698A 0x698B 0x698C 0x698E 0x698F \ + 0x6990 0x6991 0x6992 0x6993 0x6996 0x6997 0x6999 0x699A \ + 0x699D 0x699E 0x699F 0x69A0 0x69A1 0x69A2 0x69A3 0x69A4 \ + 0x69A5 0x69A6 0x69A9 0x69AA 0x69AC 0x69AE 0x69AF 0x69B0 \ + 0x69B2 0x69B3 0x69B5 0x69B6 0x69B8 0x69B9 0x69BA 0x69BC \ + 0x69BD 0x69BE 0x69BF 0x69C0 0x69C2 0x69C3 0x69C4 0x69C5 \ + 0x69C6 0x69C7 0x69C8 0x69C9 0x69CB 0x69CD 0x69CF 0x69D1 \ + 0x69D2 0x69D3 0x69D5 0x69D6 0x69D7 0x69D8 0x69D9 0x69DA \ + 0x69DC 0x69DD 0x69DE 0x69E1 0x69E2 0x69E3 0x69E4 0x69E5 \ + 0x69E6 0x69E7 0x69E8 0x69E9 0x69EA 0x69EB 0x69EC 0x69EE \ + 0x69EF 0x69F0 0x69F1 0x69F3 0x69F4 0x69F5 0x69F6 0x69F7 \ + 0x69F8 0x69F9 0x69FA 0x69FB 0x69FC 0x69FE 0x6A00 0x6A01 \ + 0x6A02 0x6A03 0x6A04 0x6A05 0x6A06 0x6A07 0x6A08 0x6A09 \ + 0x6A0B 0x6A0C 0x6A0D 0x6A0E 0x6A0F 0x6A10 0x6A11 0x6A12 \ + 0x6A13 0x6A14 0x6A15 0x6A16 0x6A19 0x6A1A 0x6A1B 0x6A1C \ + 0x6A1D 0x6A1E 0x6A20 0x6A22 0x6A23 0x6A24 0x6A25 0x6A26 \ + 0x6A27 0x6A29 0x6A2B 0x6A2C 0x6A2D 0x6A2E 0x6A30 0x6A32 \ + 0x6A33 0x6A34 0x6A36 0x6A37 0x6A38 0x6A39 0x6A3A 0x6A3B \ + 0x6A3C 0x6A3F 0x6A40 0x6A41 0x6A42 0x6A43 0x6A45 0x6A46 \ + 0x6A48 0x6A49 0x6A4A 0x6A4B 0x6A4C 0x6A4D 0x6A4E 0x6A4F \ + 0x6A51 0x6A52 0x6A53 0x6A54 0x6A55 0x6A56 0x6A57 0x6A5A \ + 0x6A5C 0x6A5D 0x6A5E 0x6A5F 0x6A60 0x6A62 0x6A63 0x6A64 \ + 0x6A66 0x6A67 0x6A68 0x6A69 0x6A6A 0x6A6B 0x6A6C 0x6A6D \ + 0x6A6E 0x6A6F 0x6A70 0x6A72 0x6A73 0x6A74 0x6A75 0x6A76 \ + 0x6A77 0x6A78 0x6A7A 0x6A7B 0x6A7D 0x6A7E 0x6A7F 0x6A81 \ + 0x6A82 0x6A83 0x6A85 0x6A86 0x6A87 0x6A88 0x6A89 0x6A8A \ + 0x6A8B 0x6A8C 0x6A8D 0x6A8F 0x6A92 0x6A93 0x6A94 0x6A95 +19 0x6A96 0x6A98 0x6A99 0x6A9A 0x6A9B 0x6A9C 0x6A9D 0x6A9E \ + 0x6A9F 0x6AA1 0x6AA2 0x6AA3 0x6AA4 0x6AA5 0x6AA6 0x6AA7 \ + 0x6AA8 0x6AAA 0x6AAD 0x6AAE 0x6AAF 0x6AB0 0x6AB1 0x6AB2 \ + 0x6AB3 0x6AB4 0x6AB5 0x6AB6 0x6AB7 0x6AB8 0x6AB9 0x6ABA \ + 0x6ABB 0x6ABC 0x6ABD 0x6ABE 0x6ABF 0x6AC0 0x6AC1 0x6AC2 \ + 0x6AC3 0x6AC4 0x6AC5 0x6AC6 0x6AC7 0x6AC8 0x6AC9 0x6ACA \ + 0x6ACB 0x6ACC 0x6ACD 0x6ACE 0x6ACF 0x6AD0 0x6AD1 0x6AD2 \ + 0x6AD3 0x6AD4 0x6AD5 0x6AD6 0x6AD7 0x6AD8 0x6AD9 0x6ADA \ + 0x6ADB 0x6ADC 0x6ADD 0x6ADE 0x6ADF 0x6AE0 0x6AE1 0x6AE2 \ + 0x6AE3 0x6AE4 0x6AE5 0x6AE6 0x6AE7 0x6AE8 0x6AE9 0x6AEA \ + 0x6AEB 0x6AEC 0x6AED 0x6AEE 0x6AEF 0x6AF0 0x6AF1 0x6AF2 \ + 0x6AF3 0x6AF4 0x6AF5 0x6AF6 0x6AF7 0x6AF8 0x6AF9 0x6AFA \ + 0x6AFB 0x6AFC 0x6AFD 0x6AFE 0x6AFF 0x6B00 0x6B01 0x6B02 \ + 0x6B03 0x6B04 0x6B05 0x6B06 0x6B07 0x6B08 0x6B09 0x6B0A \ + 0x6B0B 0x6B0C 0x6B0D 0x6B0E 0x6B0F 0x6B10 0x6B11 0x6B12 \ + 0x6B13 0x6B14 0x6B15 0x6B16 0x6B17 0x6B18 0x6B19 0x6B1A \ + 0x6B1B 0x6B1C 0x6B1D 0x6B1E 0x6B1F 0x6B25 0x6B26 0x6B28 \ + 0x6B29 0x6B2A 0x6B2B 0x6B2C 0x6B2D 0x6B2E 0x6B2F 0x6B30 \ + 0x6B31 0x6B33 0x6B34 0x6B35 0x6B36 0x6B38 0x6B3B 0x6B3C \ + 0x6B3D 0x6B3F 0x6B40 0x6B41 0x6B42 0x6B44 0x6B45 0x6B48 \ + 0x6B4A 0x6B4B 0x6B4D 0x6B4E 0x6B4F 0x6B50 0x6B51 0x6B52 \ + 0x6B53 0x6B54 0x6B55 0x6B56 0x6B57 0x6B58 0x6B5A 0x6B5B \ + 0x6B5C 0x6B5D 0x6B5E 0x6B5F 0x6B60 0x6B61 0x6B68 0x6B69 \ + 0x6B6B 0x6B6C 0x6B6D 0x6B6E 0x6B6F 0x6B70 0x6B71 0x6B72 \ + 0x6B73 0x6B74 0x6B75 0x6B76 0x6B77 0x6B78 0x6B7A 0x6B7D \ + 0x6B7E 0x6B7F 0x6B80 0x6B85 0x6B88 0x6B8C 0x6B8E 0x6B8F \ + 0x6B90 0x6B91 0x6B94 0x6B95 0x6B97 0x6B98 0x6B99 0x6B9C \ + 0x6B9D 0x6B9E 0x6B9F 0x6BA0 0x6BA2 0x6BA3 0x6BA4 0x6BA5 \ + 0x6BA6 0x6BA7 0x6BA8 0x6BA9 0x6BAB 0x6BAC 0x6BAD 0x6BAE \ + 0x6BAF 0x6BB0 0x6BB1 0x6BB2 0x6BB6 0x6BB8 0x6BB9 0x6BBA \ + 0x6BBB 0x6BBC 0x6BBD 0x6BBE 0x6BC0 0x6BC3 0x6BC4 0x6BC6 \ + 0x6BC7 0x6BC8 0x6BC9 0x6BCA 0x6BCC 0x6BCE 0x6BD0 0x6BD1 +20 0x6BD8 0x6BDA 0x6BDC 0x6BDD 0x6BDE 0x6BDF 0x6BE0 0x6BE2 \ + 0x6BE3 0x6BE4 0x6BE5 0x6BE6 0x6BE7 0x6BE8 0x6BE9 0x6BEC \ + 0x6BED 0x6BEE 0x6BF0 0x6BF1 0x6BF2 0x6BF4 0x6BF6 0x6BF7 \ + 0x6BF8 0x6BFA 0x6BFB 0x6BFC 0x6BFE 0x6BFF 0x6C00 0x6C01 \ + 0x6C02 0x6C03 0x6C04 0x6C08 0x6C09 0x6C0A 0x6C0B 0x6C0C \ + 0x6C0E 0x6C12 0x6C17 0x6C1C 0x6C1D 0x6C1E 0x6C20 0x6C23 \ + 0x6C25 0x6C2B 0x6C2C 0x6C2D 0x6C31 0x6C33 0x6C36 0x6C37 \ + 0x6C39 0x6C3A 0x6C3B 0x6C3C 0x6C3E 0x6C3F 0x6C43 0x6C44 \ + 0x6C45 0x6C48 0x6C4B 0x6C4C 0x6C4D 0x6C4E 0x6C4F 0x6C51 \ + 0x6C52 0x6C53 0x6C56 0x6C58 0x6C59 0x6C5A 0x6C62 0x6C63 \ + 0x6C65 0x6C66 0x6C67 0x6C6B 0x6C6C 0x6C6D 0x6C6E 0x6C6F \ + 0x6C71 0x6C73 0x6C75 0x6C77 0x6C78 0x6C7A 0x6C7B 0x6C7C \ + 0x6C7F 0x6C80 0x6C84 0x6C87 0x6C8A 0x6C8B 0x6C8D 0x6C8E \ + 0x6C91 0x6C92 0x6C95 0x6C96 0x6C97 0x6C98 0x6C9A 0x6C9C \ + 0x6C9D 0x6C9E 0x6CA0 0x6CA2 0x6CA8 0x6CAC 0x6CAF 0x6CB0 \ + 0x6CB4 0x6CB5 0x6CB6 0x6CB7 0x6CBA 0x6CC0 0x6CC1 0x6CC2 \ + 0x6CC3 0x6CC6 0x6CC7 0x6CC8 0x6CCB 0x6CCD 0x6CCE 0x6CCF \ + 0x6CD1 0x6CD2 0x6CD8 0x6CD9 0x6CDA 0x6CDC 0x6CDD 0x6CDF \ + 0x6CE4 0x6CE6 0x6CE7 0x6CE9 0x6CEC 0x6CED 0x6CF2 0x6CF4 \ + 0x6CF9 0x6CFF 0x6D00 0x6D02 0x6D03 0x6D05 0x6D06 0x6D08 \ + 0x6D09 0x6D0A 0x6D0D 0x6D0F 0x6D10 0x6D11 0x6D13 0x6D14 \ + 0x6D15 0x6D16 0x6D18 0x6D1C 0x6D1D 0x6D1F 0x6D20 0x6D21 \ + 0x6D22 0x6D23 0x6D24 0x6D26 0x6D28 0x6D29 0x6D2C 0x6D2D \ + 0x6D2F 0x6D30 0x6D34 0x6D36 0x6D37 0x6D38 0x6D3A 0x6D3F \ + 0x6D40 0x6D42 0x6D44 0x6D49 0x6D4C 0x6D50 0x6D55 0x6D56 \ + 0x6D57 0x6D58 0x6D5B 0x6D5D 0x6D5F 0x6D61 0x6D62 0x6D64 \ + 0x6D65 0x6D67 0x6D68 0x6D6B 0x6D6C 0x6D6D 0x6D70 0x6D71 \ + 0x6D72 0x6D73 0x6D75 0x6D76 0x6D79 0x6D7A 0x6D7B 0x6D7D \ + 0x6D7E 0x6D7F 0x6D80 0x6D81 0x6D83 0x6D84 0x6D86 0x6D87 \ + 0x6D8A 0x6D8B 0x6D8D 0x6D8F 0x6D90 0x6D92 0x6D96 0x6D97 \ + 0x6D98 0x6D99 0x6D9A 0x6D9C 0x6DA2 0x6DA5 0x6DAC 0x6DAD \ + 0x6DB0 0x6DB1 0x6DB3 0x6DB4 0x6DB6 0x6DB7 0x6DB9 0x6DBA +21 0x6DBB 0x6DBC 0x6DBD 0x6DBE 0x6DC1 0x6DC2 0x6DC3 0x6DC8 \ + 0x6DC9 0x6DCA 0x6DCD 0x6DCE 0x6DCF 0x6DD0 0x6DD2 0x6DD3 \ + 0x6DD4 0x6DD5 0x6DD7 0x6DDA 0x6DDB 0x6DDC 0x6DDF 0x6DE2 \ + 0x6DE3 0x6DE5 0x6DE7 0x6DE8 0x6DE9 0x6DEA 0x6DED 0x6DEF \ + 0x6DF0 0x6DF2 0x6DF4 0x6DF5 0x6DF6 0x6DF8 0x6DFA 0x6DFD \ + 0x6DFE 0x6DFF 0x6E00 0x6E01 0x6E02 0x6E03 0x6E04 0x6E06 \ + 0x6E07 0x6E08 0x6E09 0x6E0B 0x6E0F 0x6E12 0x6E13 0x6E15 \ + 0x6E18 0x6E19 0x6E1B 0x6E1C 0x6E1E 0x6E1F 0x6E22 0x6E26 \ + 0x6E27 0x6E28 0x6E2A 0x6E2C 0x6E2E 0x6E30 0x6E31 0x6E33 \ + 0x6E35 0x6E36 0x6E37 0x6E39 0x6E3B 0x6E3C 0x6E3D 0x6E3E \ + 0x6E3F 0x6E40 0x6E41 0x6E42 0x6E45 0x6E46 0x6E47 0x6E48 \ + 0x6E49 0x6E4A 0x6E4B 0x6E4C 0x6E4F 0x6E50 0x6E51 0x6E52 \ + 0x6E55 0x6E57 0x6E59 0x6E5A 0x6E5C 0x6E5D 0x6E5E 0x6E60 \ + 0x6E61 0x6E62 0x6E63 0x6E64 0x6E65 0x6E66 0x6E67 0x6E68 \ + 0x6E69 0x6E6A 0x6E6C 0x6E6D 0x6E6F 0x6E70 0x6E71 0x6E72 \ + 0x6E73 0x6E74 0x6E75 0x6E76 0x6E77 0x6E78 0x6E79 0x6E7A \ + 0x6E7B 0x6E7C 0x6E7D 0x6E80 0x6E81 0x6E82 0x6E84 0x6E87 \ + 0x6E88 0x6E8A 0x6E8B 0x6E8C 0x6E8D 0x6E8E 0x6E91 0x6E92 \ + 0x6E93 0x6E94 0x6E95 0x6E96 0x6E97 0x6E99 0x6E9A 0x6E9B \ + 0x6E9D 0x6E9E 0x6EA0 0x6EA1 0x6EA3 0x6EA4 0x6EA6 0x6EA8 \ + 0x6EA9 0x6EAB 0x6EAC 0x6EAD 0x6EAE 0x6EB0 0x6EB3 0x6EB5 \ + 0x6EB8 0x6EB9 0x6EBC 0x6EBE 0x6EBF 0x6EC0 0x6EC3 0x6EC4 \ + 0x6EC5 0x6EC6 0x6EC8 0x6EC9 0x6ECA 0x6ECC 0x6ECD 0x6ECE \ + 0x6ED0 0x6ED2 0x6ED6 0x6ED8 0x6ED9 0x6EDB 0x6EDC 0x6EDD \ + 0x6EE3 0x6EE7 0x6EEA 0x6EEB 0x6EEC 0x6EED 0x6EEE 0x6EEF \ + 0x6EF0 0x6EF1 0x6EF2 0x6EF3 0x6EF5 0x6EF6 0x6EF7 0x6EF8 \ + 0x6EFA 0x6EFB 0x6EFC 0x6EFD 0x6EFE 0x6EFF 0x6F00 0x6F01 \ + 0x6F03 0x6F04 0x6F05 0x6F07 0x6F08 0x6F0A 0x6F0B 0x6F0C \ + 0x6F0D 0x6F0E 0x6F10 0x6F11 0x6F12 0x6F16 0x6F17 0x6F18 \ + 0x6F19 0x6F1A 0x6F1B 0x6F1C 0x6F1D 0x6F1E 0x6F1F 0x6F21 \ + 0x6F22 0x6F23 0x6F25 0x6F26 0x6F27 0x6F28 0x6F2C 0x6F2E \ + 0x6F30 0x6F32 0x6F34 0x6F35 0x6F37 0x6F38 0x6F39 0x6F3A +22 0x6F3B 0x6F3C 0x6F3D 0x6F3F 0x6F40 0x6F41 0x6F42 0x6F43 \ + 0x6F44 0x6F45 0x6F48 0x6F49 0x6F4A 0x6F4C 0x6F4E 0x6F4F \ + 0x6F50 0x6F51 0x6F52 0x6F53 0x6F54 0x6F55 0x6F56 0x6F57 \ + 0x6F59 0x6F5A 0x6F5B 0x6F5D 0x6F5F 0x6F60 0x6F61 0x6F63 \ + 0x6F64 0x6F65 0x6F67 0x6F68 0x6F69 0x6F6A 0x6F6B 0x6F6C \ + 0x6F6F 0x6F70 0x6F71 0x6F73 0x6F75 0x6F76 0x6F77 0x6F79 \ + 0x6F7B 0x6F7D 0x6F7E 0x6F7F 0x6F80 0x6F81 0x6F82 0x6F83 \ + 0x6F85 0x6F86 0x6F87 0x6F8A 0x6F8B 0x6F8F 0x6F90 0x6F91 \ + 0x6F92 0x6F93 0x6F94 0x6F95 0x6F96 0x6F97 0x6F98 0x6F99 \ + 0x6F9A 0x6F9B 0x6F9D 0x6F9E 0x6F9F 0x6FA0 0x6FA2 0x6FA3 \ + 0x6FA4 0x6FA5 0x6FA6 0x6FA8 0x6FA9 0x6FAA 0x6FAB 0x6FAC \ + 0x6FAD 0x6FAE 0x6FAF 0x6FB0 0x6FB1 0x6FB2 0x6FB4 0x6FB5 \ + 0x6FB7 0x6FB8 0x6FBA 0x6FBB 0x6FBC 0x6FBD 0x6FBE 0x6FBF \ + 0x6FC1 0x6FC3 0x6FC4 0x6FC5 0x6FC6 0x6FC7 0x6FC8 0x6FCA \ + 0x6FCB 0x6FCC 0x6FCD 0x6FCE 0x6FCF 0x6FD0 0x6FD3 0x6FD4 \ + 0x6FD5 0x6FD6 0x6FD7 0x6FD8 0x6FD9 0x6FDA 0x6FDB 0x6FDC \ + 0x6FDD 0x6FDF 0x6FE2 0x6FE3 0x6FE4 0x6FE5 0x6FE6 0x6FE7 \ + 0x6FE8 0x6FE9 0x6FEA 0x6FEB 0x6FEC 0x6FED 0x6FF0 0x6FF1 \ + 0x6FF2 0x6FF3 0x6FF4 0x6FF5 0x6FF6 0x6FF7 0x6FF8 0x6FF9 \ + 0x6FFA 0x6FFB 0x6FFC 0x6FFD 0x6FFE 0x6FFF 0x7000 0x7001 \ + 0x7002 0x7003 0x7004 0x7005 0x7006 0x7007 0x7008 0x7009 \ + 0x700A 0x700B 0x700C 0x700D 0x700E 0x700F 0x7010 0x7012 \ + 0x7013 0x7014 0x7015 0x7016 0x7017 0x7018 0x7019 0x701C \ + 0x701D 0x701E 0x701F 0x7020 0x7021 0x7022 0x7024 0x7025 \ + 0x7026 0x7027 0x7028 0x7029 0x702A 0x702B 0x702C 0x702D \ + 0x702E 0x702F 0x7030 0x7031 0x7032 0x7033 0x7034 0x7036 \ + 0x7037 0x7038 0x703A 0x703B 0x703C 0x703D 0x703E 0x703F \ + 0x7040 0x7041 0x7042 0x7043 0x7044 0x7045 0x7046 0x7047 \ + 0x7048 0x7049 0x704A 0x704B 0x704D 0x704E 0x7050 0x7051 \ + 0x7052 0x7053 0x7054 0x7055 0x7056 0x7057 0x7058 0x7059 \ + 0x705A 0x705B 0x705C 0x705D 0x705F 0x7060 0x7061 0x7062 \ + 0x7063 0x7064 0x7065 0x7066 0x7067 0x7068 0x7069 0x706A +23 0x706E 0x7071 0x7072 0x7073 0x7074 0x7077 0x7079 0x707A \ + 0x707B 0x707D 0x7081 0x7082 0x7083 0x7084 0x7086 0x7087 \ + 0x7088 0x708B 0x708C 0x708D 0x708F 0x7090 0x7091 0x7093 \ + 0x7097 0x7098 0x709A 0x709B 0x709E 0x709F 0x70A0 0x70A1 \ + 0x70A2 0x70A3 0x70A4 0x70A5 0x70A6 0x70A7 0x70A8 0x70A9 \ + 0x70AA 0x70B0 0x70B2 0x70B4 0x70B5 0x70B6 0x70BA 0x70BE \ + 0x70BF 0x70C4 0x70C5 0x70C6 0x70C7 0x70C9 0x70CB 0x70CC \ + 0x70CD 0x70CE 0x70CF 0x70D0 0x70D1 0x70D2 0x70D3 0x70D4 \ + 0x70D5 0x70D6 0x70D7 0x70DA 0x70DC 0x70DD 0x70DE 0x70E0 \ + 0x70E1 0x70E2 0x70E3 0x70E5 0x70EA 0x70EE 0x70F0 0x70F1 \ + 0x70F2 0x70F3 0x70F4 0x70F5 0x70F6 0x70F8 0x70FA 0x70FB \ + 0x70FC 0x70FE 0x70FF 0x7100 0x7101 0x7102 0x7103 0x7104 \ + 0x7105 0x7106 0x7107 0x7108 0x710B 0x710C 0x710D 0x710E \ + 0x710F 0x7111 0x7112 0x7114 0x7117 0x711B 0x711C 0x711D \ + 0x711E 0x711F 0x7120 0x7121 0x7122 0x7123 0x7124 0x7125 \ + 0x7127 0x7128 0x7129 0x712A 0x712B 0x712C 0x712D 0x712E \ + 0x7132 0x7133 0x7134 0x7135 0x7137 0x7138 0x7139 0x713A \ + 0x713B 0x713C 0x713D 0x713E 0x713F 0x7140 0x7141 0x7142 \ + 0x7143 0x7144 0x7146 0x7147 0x7148 0x7149 0x714B 0x714D \ + 0x714F 0x7150 0x7151 0x7152 0x7153 0x7154 0x7155 0x7156 \ + 0x7157 0x7158 0x7159 0x715A 0x715B 0x715D 0x715F 0x7160 \ + 0x7161 0x7162 0x7163 0x7165 0x7169 0x716A 0x716B 0x716C \ + 0x716D 0x716F 0x7170 0x7171 0x7174 0x7175 0x7176 0x7177 \ + 0x7179 0x717B 0x717C 0x717E 0x717F 0x7180 0x7181 0x7182 \ + 0x7183 0x7185 0x7186 0x7187 0x7188 0x7189 0x718B 0x718C \ + 0x718D 0x718E 0x7190 0x7191 0x7192 0x7193 0x7195 0x7196 \ + 0x7197 0x719A 0x719B 0x719C 0x719D 0x719E 0x71A1 0x71A2 \ + 0x71A3 0x71A4 0x71A5 0x71A6 0x71A7 0x71A9 0x71AA 0x71AB \ + 0x71AD 0x71AE 0x71AF 0x71B0 0x71B1 0x71B2 0x71B4 0x71B6 \ + 0x71B7 0x71B8 0x71BA 0x71BB 0x71BC 0x71BD 0x71BE 0x71BF \ + 0x71C0 0x71C1 0x71C2 0x71C4 0x71C5 0x71C6 0x71C7 0x71C8 \ + 0x71C9 0x71CA 0x71CB 0x71CC 0x71CD 0x71CF 0x71D0 0x71D1 +24 0x71D2 0x71D3 0x71D6 0x71D7 0x71D8 0x71D9 0x71DA 0x71DB \ + 0x71DC 0x71DD 0x71DE 0x71DF 0x71E1 0x71E2 0x71E3 0x71E4 \ + 0x71E6 0x71E8 0x71E9 0x71EA 0x71EB 0x71EC 0x71ED 0x71EF \ + 0x71F0 0x71F1 0x71F2 0x71F3 0x71F4 0x71F5 0x71F6 0x71F7 \ + 0x71F8 0x71FA 0x71FB 0x71FC 0x71FD 0x71FE 0x71FF 0x7200 \ + 0x7201 0x7202 0x7203 0x7204 0x7205 0x7207 0x7208 0x7209 \ + 0x720A 0x720B 0x720C 0x720D 0x720E 0x720F 0x7210 0x7211 \ + 0x7212 0x7213 0x7214 0x7215 0x7216 0x7217 0x7218 0x7219 \ + 0x721A 0x721B 0x721C 0x721E 0x721F 0x7220 0x7221 0x7222 \ + 0x7223 0x7224 0x7225 0x7226 0x7227 0x7229 0x722B 0x722D \ + 0x722E 0x722F 0x7232 0x7233 0x7234 0x723A 0x723C 0x723E \ + 0x7240 0x7241 0x7242 0x7243 0x7244 0x7245 0x7246 0x7249 \ + 0x724A 0x724B 0x724E 0x724F 0x7250 0x7251 0x7253 0x7254 \ + 0x7255 0x7257 0x7258 0x725A 0x725C 0x725E 0x7260 0x7263 \ + 0x7264 0x7265 0x7268 0x726A 0x726B 0x726C 0x726D 0x7270 \ + 0x7271 0x7273 0x7274 0x7276 0x7277 0x7278 0x727B 0x727C \ + 0x727D 0x7282 0x7283 0x7285 0x7286 0x7287 0x7288 0x7289 \ + 0x728C 0x728E 0x7290 0x7291 0x7293 0x7294 0x7295 0x7296 \ + 0x7297 0x7298 0x7299 0x729A 0x729B 0x729C 0x729D 0x729E \ + 0x72A0 0x72A1 0x72A2 0x72A3 0x72A4 0x72A5 0x72A6 0x72A7 \ + 0x72A8 0x72A9 0x72AA 0x72AB 0x72AE 0x72B1 0x72B2 0x72B3 \ + 0x72B5 0x72BA 0x72BB 0x72BC 0x72BD 0x72BE 0x72BF 0x72C0 \ + 0x72C5 0x72C6 0x72C7 0x72C9 0x72CA 0x72CB 0x72CC 0x72CF \ + 0x72D1 0x72D3 0x72D4 0x72D5 0x72D6 0x72D8 0x72DA 0x72DB \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +25 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x3000 0x3001 0x3002 0x00B7 0x02C9 0x02C7 0x00A8 0x3003 \ + 0x3005 0x2015 0xFF5E 0x2016 0x2026 0x2018 0x2019 0x201C \ + 0x201D 0x3014 0x3015 0x3008 0x3009 0x300A 0x300B 0x300C \ + 0x300D 0x300E 0x300F 0x3016 0x3017 0x3010 0x3011 0x00B1 \ + 0x00D7 0x00F7 0x2236 0x2227 0x2228 0x2211 0x220F 0x222A \ + 0x2229 0x2208 0x2237 0x221A 0x22A5 0x2225 0x2220 0x2312 \ + 0x2299 0x222B 0x222E 0x2261 0x224C 0x2248 0x223D 0x221D \ + 0x2260 0x226E 0x226F 0x2264 0x2265 0x221E 0x2235 0x2234 \ + 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFF04 0x00A4 \ + 0xFFE0 0xFFE1 0x2030 0x00A7 0x2116 0x2606 0x2605 0x25CB \ + 0x25CF 0x25CE 0x25C7 0x25C6 0x25A1 0x25A0 0x25B3 0x25B2 \ + 0x203B 0x2192 0x2190 0x2191 0x2193 0x3013 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2170 0x2171 \ + 0x2172 0x2173 0x2174 0x2175 0x2176 0x2177 0x2178 0x2179 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2488 0x2489 \ + 0x248A 0x248B 0x248C 0x248D 0x248E 0x248F 0x2490 0x2491 \ + 0x2492 0x2493 0x2494 0x2495 0x2496 0x2497 0x2498 0x2499 +26 0x249A 0x249B 0x2474 0x2475 0x2476 0x2477 0x2478 0x2479 \ + 0x247A 0x247B 0x247C 0x247D 0x247E 0x247F 0x2480 0x2481 \ + 0x2482 0x2483 0x2484 0x2485 0x2486 0x2487 0x2460 0x2461 \ + 0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 0x2468 0x2469 \ + 0xFFFE 0xFFFE 0x3220 0x3221 0x3222 0x3223 0x3224 0x3225 \ + 0x3226 0x3227 0x3228 0x3229 0xFFFE 0xFFFE 0x2160 0x2161 \ + 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 0x2169 \ + 0x216A 0x216B 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFF01 0xFF02 0xFF03 0xFFE5 \ + 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C \ + 0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 \ + 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C \ + 0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFF3C \ + 0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 \ + 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C \ + 0xFF5D 0xFFE3 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +27 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 \ + 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E \ + 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 \ + 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E \ + 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 \ + 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E \ + 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 \ + 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E \ + 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 \ + 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E \ + 0x308F 0x3090 0x3091 0x3092 0x3093 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +28 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 \ + 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 \ + 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 \ + 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 \ + 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 \ + 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 \ + 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 \ + 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 \ + 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 \ + 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 \ + 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0391 0x0392 \ + 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A \ + 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 \ + 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x03B1 0x03B2 \ + 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA +29 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 \ + 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFE35 0xFE36 0xFE39 \ + 0xFE3A 0xFE3F 0xFE40 0xFE3D 0xFE3E 0xFE41 0xFE42 0xFE43 \ + 0xFE44 0xFFFE 0xFFFE 0xFE3B 0xFE3C 0xFE37 0xFE38 0xFE31 \ + 0xFFFE 0xFE33 0xFE34 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0410 0x0411 0x0412 0x0413 \ + 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A \ + 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 \ + 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A \ + 0x042B 0x042C 0x042D 0x042E 0x042F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0430 0x0431 0x0432 0x0433 \ + 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A \ + 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 \ + 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A \ + 0x044B 0x044C 0x044D 0x044E 0x044F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x02CA 0x02CB 0x02D9 0x2013 0x2014 0x2025 \ + 0x2035 0x2105 0x2109 0x2196 0x2197 0x2198 0x2199 0x2215 +30 0x221F 0x2223 0x2252 0x2266 0x2267 0x22BF 0x2550 0x2551 \ + 0x2552 0x2553 0x2554 0x2555 0x2556 0x2557 0x2558 0x2559 \ + 0x255A 0x255B 0x255C 0x255D 0x255E 0x255F 0x2560 0x2561 \ + 0x2562 0x2563 0x2564 0x2565 0x2566 0x2567 0x2568 0x2569 \ + 0x256A 0x256B 0x256C 0x256D 0x256E 0x256F 0x2570 0x2571 \ + 0x2572 0x2573 0x2581 0x2582 0x2583 0x2584 0x2585 0x2586 \ + 0x2587 0x2588 0x2589 0x258A 0x258B 0x258C 0x258D 0x258E \ + 0x258F 0x2593 0x2594 0x2595 0x25BC 0x25BD 0x25E2 0x25E3 \ + 0x25E4 0x25E5 0x2609 0x2295 0x3012 0x301D 0x301E 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x0101 0x00E1 0x01CE 0x00E0 0x0113 0x00E9 \ + 0x011B 0x00E8 0x012B 0x00ED 0x01D0 0x00EC 0x014D 0x00F3 \ + 0x01D2 0x00F2 0x016B 0x00FA 0x01D4 0x00F9 0x01D6 0x01D8 \ + 0x01DA 0x01DC 0x00FC 0x00EA 0x0251 0xE7C7 0x0144 0x0148 \ + 0xE7C8 0x0261 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x3105 0x3106 \ + 0x3107 0x3108 0x3109 0x310A 0x310B 0x310C 0x310D 0x310E \ + 0x310F 0x3110 0x3111 0x3112 0x3113 0x3114 0x3115 0x3116 \ + 0x3117 0x3118 0x3119 0x311A 0x311B 0x311C 0x311D 0x311E \ + 0x311F 0x3120 0x3121 0x3122 0x3123 0x3124 0x3125 0x3126 \ + 0x3127 0x3128 0x3129 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x3021 0x3022 0x3023 0x3024 0x3025 0x3026 0x3027 0x3028 \ + 0x3029 0x32A3 0x338E 0x338F 0x339C 0x339D 0x339E 0x33A1 \ + 0x33C4 0x33CE 0x33D1 0x33D2 0x33D5 0xFE30 0xFFE2 0xFFE4 \ + 0xFFFE 0x2121 0x3231 0xFFFE 0x2010 0xFFFE 0xFFFE 0xFFFE \ + 0x30FC 0x309B 0x309C 0x30FD 0x30FE 0x3006 0x309D 0x309E \ + 0xFE49 0xFE4A 0xFE4B 0xFE4C 0xFE4D 0xFE4E 0xFE4F 0xFE50 \ + 0xFE51 0xFE52 0xFE54 0xFE55 0xFE56 0xFE57 0xFE59 0xFE5A \ + 0xFE5B 0xFE5C 0xFE5D 0xFE5E 0xFE5F 0xFE60 0xFE61 0xFE62 \ + 0xFE63 0xFE64 0xFE65 0xFE66 0xFE68 0xFE69 0xFE6A 0xFE6B \ + 0xE7E7 0xE7E8 0xE7E9 0xE7EA 0xE7EB 0xE7EC 0xE7ED 0xE7EE +31 0xE7EF 0xE7F0 0xE7F1 0xE7F2 0xE7F3 0x3007 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x2500 0x2501 0x2502 0x2503 0x2504 \ + 0x2505 0x2506 0x2507 0x2508 0x2509 0x250A 0x250B 0x250C \ + 0x250D 0x250E 0x250F 0x2510 0x2511 0x2512 0x2513 0x2514 \ + 0x2515 0x2516 0x2517 0x2518 0x2519 0x251A 0x251B 0x251C \ + 0x251D 0x251E 0x251F 0x2520 0x2521 0x2522 0x2523 0x2524 \ + 0x2525 0x2526 0x2527 0x2528 0x2529 0x252A 0x252B 0x252C \ + 0x252D 0x252E 0x252F 0x2530 0x2531 0x2532 0x2533 0x2534 \ + 0x2535 0x2536 0x2537 0x2538 0x2539 0x253A 0x253B 0x253C \ + 0x253D 0x253E 0x253F 0x2540 0x2541 0x2542 0x2543 0x2544 \ + 0x2545 0x2546 0x2547 0x2548 0x2549 0x254A 0x254B 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x72DC 0x72DD \ + 0x72DF 0x72E2 0x72E3 0x72E4 0x72E5 0x72E6 0x72E7 0x72EA \ + 0x72EB 0x72F5 0x72F6 0x72F9 0x72FD 0x72FE 0x72FF 0x7300 \ + 0x7302 0x7304 0x7305 0x7306 0x7307 0x7308 0x7309 0x730B \ + 0x730C 0x730D 0x730F 0x7310 0x7311 0x7312 0x7314 0x7318 \ + 0x7319 0x731A 0x731F 0x7320 0x7323 0x7324 0x7326 0x7327 \ + 0x7328 0x732D 0x732F 0x7330 0x7332 0x7333 0x7335 0x7336 \ + 0x733A 0x733B 0x733C 0x733D 0x7340 0x7341 0x7342 0x7343 \ + 0x7344 0x7345 0x7346 0x7347 0x7348 0x7349 0x734A 0x734B \ + 0x734C 0x734E 0x734F 0x7351 0x7353 0x7354 0x7355 0x7356 \ + 0x7358 0x7359 0x735A 0x735B 0x735C 0x735D 0x735E 0x735F \ + 0x7361 0x7362 0x7363 0x7364 0x7365 0x7366 0x7367 0x7368 \ + 0x7369 0x736A 0x736B 0x736E 0x7370 0x7371 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +32 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x7372 0x7373 0x7374 0x7375 \ + 0x7376 0x7377 0x7378 0x7379 0x737A 0x737B 0x737C 0x737D \ + 0x737F 0x7380 0x7381 0x7382 0x7383 0x7385 0x7386 0x7388 \ + 0x738A 0x738C 0x738D 0x738F 0x7390 0x7392 0x7393 0x7394 \ + 0x7395 0x7397 0x7398 0x7399 0x739A 0x739C 0x739D 0x739E \ + 0x73A0 0x73A1 0x73A3 0x73A4 0x73A5 0x73A6 0x73A7 0x73A8 \ + 0x73AA 0x73AC 0x73AD 0x73B1 0x73B4 0x73B5 0x73B6 0x73B8 \ + 0x73B9 0x73BC 0x73BD 0x73BE 0x73BF 0x73C1 0x73C3 0x73C4 \ + 0x73C5 0x73C6 0x73C7 0x73CB 0x73CC 0x73CE 0x73D2 0x73D3 \ + 0x73D4 0x73D5 0x73D6 0x73D7 0x73D8 0x73DA 0x73DB 0x73DC \ + 0x73DD 0x73DF 0x73E1 0x73E2 0x73E3 0x73E4 0x73E6 0x73E8 \ + 0x73EA 0x73EB 0x73EC 0x73EE 0x73EF 0x73F0 0x73F1 0x73F3 \ + 0x73F4 0x73F5 0x73F6 0x73F7 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x73F8 0x73F9 0x73FA 0x73FB 0x73FC 0x73FD \ + 0x73FE 0x73FF 0x7400 0x7401 0x7402 0x7404 0x7407 0x7408 \ + 0x740B 0x740C 0x740D 0x740E 0x7411 0x7412 0x7413 0x7414 +33 0x7415 0x7416 0x7417 0x7418 0x7419 0x741C 0x741D 0x741E \ + 0x741F 0x7420 0x7421 0x7423 0x7424 0x7427 0x7429 0x742B \ + 0x742D 0x742F 0x7431 0x7432 0x7437 0x7438 0x7439 0x743A \ + 0x743B 0x743D 0x743E 0x743F 0x7440 0x7442 0x7443 0x7444 \ + 0x7445 0x7446 0x7447 0x7448 0x7449 0x744A 0x744B 0x744C \ + 0x744D 0x744E 0x744F 0x7450 0x7451 0x7452 0x7453 0x7454 \ + 0x7456 0x7458 0x745D 0x7460 0x7461 0x7462 0x7463 0x7464 \ + 0x7465 0x7466 0x7467 0x7468 0x7469 0x746A 0x746B 0x746C \ + 0x746E 0x746F 0x7471 0x7472 0x7473 0x7474 0x7475 0x7478 \ + 0x7479 0x747A 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x747B 0x747C 0x747D 0x747F 0x7482 0x7484 0x7485 0x7486 \ + 0x7488 0x7489 0x748A 0x748C 0x748D 0x748F 0x7491 0x7492 \ + 0x7493 0x7494 0x7495 0x7496 0x7497 0x7498 0x7499 0x749A \ + 0x749B 0x749D 0x749F 0x74A0 0x74A1 0x74A2 0x74A3 0x74A4 \ + 0x74A5 0x74A6 0x74AA 0x74AB 0x74AC 0x74AD 0x74AE 0x74AF \ + 0x74B0 0x74B1 0x74B2 0x74B3 0x74B4 0x74B5 0x74B6 0x74B7 \ + 0x74B8 0x74B9 0x74BB 0x74BC 0x74BD 0x74BE 0x74BF 0x74C0 \ + 0x74C1 0x74C2 0x74C3 0x74C4 0x74C5 0x74C6 0x74C7 0x74C8 \ + 0x74C9 0x74CA 0x74CB 0x74CC 0x74CD 0x74CE 0x74CF 0x74D0 \ + 0x74D1 0x74D3 0x74D4 0x74D5 0x74D6 0x74D7 0x74D8 0x74D9 \ + 0x74DA 0x74DB 0x74DD 0x74DF 0x74E1 0x74E5 0x74E7 0x74E8 +34 0x74E9 0x74EA 0x74EB 0x74EC 0x74ED 0x74F0 0x74F1 0x74F2 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x74F3 0x74F5 \ + 0x74F8 0x74F9 0x74FA 0x74FB 0x74FC 0x74FD 0x74FE 0x7500 \ + 0x7501 0x7502 0x7503 0x7505 0x7506 0x7507 0x7508 0x7509 \ + 0x750A 0x750B 0x750C 0x750E 0x7510 0x7512 0x7514 0x7515 \ + 0x7516 0x7517 0x751B 0x751D 0x751E 0x7520 0x7521 0x7522 \ + 0x7523 0x7524 0x7526 0x7527 0x752A 0x752E 0x7534 0x7536 \ + 0x7539 0x753C 0x753D 0x753F 0x7541 0x7542 0x7543 0x7544 \ + 0x7546 0x7547 0x7549 0x754A 0x754D 0x7550 0x7551 0x7552 \ + 0x7553 0x7555 0x7556 0x7557 0x7558 0x755D 0x755E 0x755F \ + 0x7560 0x7561 0x7562 0x7563 0x7564 0x7567 0x7568 0x7569 \ + 0x756B 0x756C 0x756D 0x756E 0x756F 0x7570 0x7571 0x7573 \ + 0x7575 0x7576 0x7577 0x757A 0x757B 0x757C 0x757D 0x757E \ + 0x7580 0x7581 0x7582 0x7584 0x7585 0x7587 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +35 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x7588 0x7589 0x758A 0x758C \ + 0x758D 0x758E 0x7590 0x7593 0x7595 0x7598 0x759B 0x759C \ + 0x759E 0x75A2 0x75A6 0x75A7 0x75A8 0x75A9 0x75AA 0x75AD \ + 0x75B6 0x75B7 0x75BA 0x75BB 0x75BF 0x75C0 0x75C1 0x75C6 \ + 0x75CB 0x75CC 0x75CE 0x75CF 0x75D0 0x75D1 0x75D3 0x75D7 \ + 0x75D9 0x75DA 0x75DC 0x75DD 0x75DF 0x75E0 0x75E1 0x75E5 \ + 0x75E9 0x75EC 0x75ED 0x75EE 0x75EF 0x75F2 0x75F3 0x75F5 \ + 0x75F6 0x75F7 0x75F8 0x75FA 0x75FB 0x75FD 0x75FE 0x7602 \ + 0x7604 0x7606 0x7607 0x7608 0x7609 0x760B 0x760D 0x760E \ + 0x760F 0x7611 0x7612 0x7613 0x7614 0x7616 0x761A 0x761C \ + 0x761D 0x761E 0x7621 0x7623 0x7627 0x7628 0x762C 0x762E \ + 0x762F 0x7631 0x7632 0x7636 0x7637 0x7639 0x763A 0x763B \ + 0x763D 0x7641 0x7642 0x7644 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x7645 0x7646 0x7647 0x7648 0x7649 0x764A \ + 0x764B 0x764E 0x764F 0x7650 0x7651 0x7652 0x7653 0x7655 \ + 0x7657 0x7658 0x7659 0x765A 0x765B 0x765D 0x765F 0x7660 \ + 0x7661 0x7662 0x7664 0x7665 0x7666 0x7667 0x7668 0x7669 +36 0x766A 0x766C 0x766D 0x766E 0x7670 0x7671 0x7672 0x7673 \ + 0x7674 0x7675 0x7676 0x7677 0x7679 0x767A 0x767C 0x767F \ + 0x7680 0x7681 0x7683 0x7685 0x7689 0x768A 0x768C 0x768D \ + 0x768F 0x7690 0x7692 0x7694 0x7695 0x7697 0x7698 0x769A \ + 0x769B 0x769C 0x769D 0x769E 0x769F 0x76A0 0x76A1 0x76A2 \ + 0x76A3 0x76A5 0x76A6 0x76A7 0x76A8 0x76A9 0x76AA 0x76AB \ + 0x76AC 0x76AD 0x76AF 0x76B0 0x76B3 0x76B5 0x76B6 0x76B7 \ + 0x76B8 0x76B9 0x76BA 0x76BB 0x76BC 0x76BD 0x76BE 0x76C0 \ + 0x76C1 0x76C3 0x554A 0x963F 0x57C3 0x6328 0x54CE 0x5509 \ + 0x54C0 0x7691 0x764C 0x853C 0x77EE 0x827E 0x788D 0x7231 \ + 0x9698 0x978D 0x6C28 0x5B89 0x4FFA 0x6309 0x6697 0x5CB8 \ + 0x80FA 0x6848 0x80AE 0x6602 0x76CE 0x51F9 0x6556 0x71AC \ + 0x7FF1 0x8884 0x50B2 0x5965 0x61CA 0x6FB3 0x82AD 0x634C \ + 0x6252 0x53ED 0x5427 0x7B06 0x516B 0x75A4 0x5DF4 0x62D4 \ + 0x8DCB 0x9776 0x628A 0x8019 0x575D 0x9738 0x7F62 0x7238 \ + 0x767D 0x67CF 0x767E 0x6446 0x4F70 0x8D25 0x62DC 0x7A17 \ + 0x6591 0x73ED 0x642C 0x6273 0x822C 0x9881 0x677F 0x7248 \ + 0x626E 0x62CC 0x4F34 0x74E3 0x534A 0x529E 0x7ECA 0x90A6 \ + 0x5E2E 0x6886 0x699C 0x8180 0x7ED1 0x68D2 0x78C5 0x868C \ + 0x9551 0x508D 0x8C24 0x82DE 0x80DE 0x5305 0x8912 0x5265 \ + 0x76C4 0x76C7 0x76C9 0x76CB 0x76CC 0x76D3 0x76D5 0x76D9 \ + 0x76DA 0x76DC 0x76DD 0x76DE 0x76E0 0x76E1 0x76E2 0x76E3 \ + 0x76E4 0x76E6 0x76E7 0x76E8 0x76E9 0x76EA 0x76EB 0x76EC \ + 0x76ED 0x76F0 0x76F3 0x76F5 0x76F6 0x76F7 0x76FA 0x76FB \ + 0x76FD 0x76FF 0x7700 0x7702 0x7703 0x7705 0x7706 0x770A \ + 0x770C 0x770E 0x770F 0x7710 0x7711 0x7712 0x7713 0x7714 \ + 0x7715 0x7716 0x7717 0x7718 0x771B 0x771C 0x771D 0x771E \ + 0x7721 0x7723 0x7724 0x7725 0x7727 0x772A 0x772B 0x772C \ + 0x772E 0x7730 0x7731 0x7732 0x7733 0x7734 0x7739 0x773B \ + 0x773D 0x773E 0x773F 0x7742 0x7744 0x7745 0x7746 0x7748 \ + 0x7749 0x774A 0x774B 0x774C 0x774D 0x774E 0x774F 0x7752 \ + 0x7753 0x7754 0x7755 0x7756 0x7757 0x7758 0x7759 0x775C +37 0x8584 0x96F9 0x4FDD 0x5821 0x9971 0x5B9D 0x62B1 0x62A5 \ + 0x66B4 0x8C79 0x9C8D 0x7206 0x676F 0x7891 0x60B2 0x5351 \ + 0x5317 0x8F88 0x80CC 0x8D1D 0x94A1 0x500D 0x72C8 0x5907 \ + 0x60EB 0x7119 0x88AB 0x5954 0x82EF 0x672C 0x7B28 0x5D29 \ + 0x7EF7 0x752D 0x6CF5 0x8E66 0x8FF8 0x903C 0x9F3B 0x6BD4 \ + 0x9119 0x7B14 0x5F7C 0x78A7 0x84D6 0x853D 0x6BD5 0x6BD9 \ + 0x6BD6 0x5E01 0x5E87 0x75F9 0x95ED 0x655D 0x5F0A 0x5FC5 \ + 0x8F9F 0x58C1 0x81C2 0x907F 0x965B 0x97AD 0x8FB9 0x7F16 \ + 0x8D2C 0x6241 0x4FBF 0x53D8 0x535E 0x8FA8 0x8FA9 0x8FAB \ + 0x904D 0x6807 0x5F6A 0x8198 0x8868 0x9CD6 0x618B 0x522B \ + 0x762A 0x5F6C 0x658C 0x6FD2 0x6EE8 0x5BBE 0x6448 0x5175 \ + 0x51B0 0x67C4 0x4E19 0x79C9 0x997C 0x70B3 0x775D 0x775E \ + 0x775F 0x7760 0x7764 0x7767 0x7769 0x776A 0x776D 0x776E \ + 0x776F 0x7770 0x7771 0x7772 0x7773 0x7774 0x7775 0x7776 \ + 0x7777 0x7778 0x777A 0x777B 0x777C 0x7781 0x7782 0x7783 \ + 0x7786 0x7787 0x7788 0x7789 0x778A 0x778B 0x778F 0x7790 \ + 0x7793 0x7794 0x7795 0x7796 0x7797 0x7798 0x7799 0x779A \ + 0x779B 0x779C 0x779D 0x779E 0x77A1 0x77A3 0x77A4 0x77A6 \ + 0x77A8 0x77AB 0x77AD 0x77AE 0x77AF 0x77B1 0x77B2 0x77B4 \ + 0x77B6 0x77B7 0x77B8 0x77B9 0x77BA 0x77BC 0x77BE 0x77C0 \ + 0x77C1 0x77C2 0x77C3 0x77C4 0x77C5 0x77C6 0x77C7 0x77C8 \ + 0x77C9 0x77CA 0x77CB 0x77CC 0x77CE 0x77CF 0x77D0 0x77D1 \ + 0x77D2 0x77D3 0x77D4 0x77D5 0x77D6 0x77D8 0x77D9 0x77DA \ + 0x77DD 0x77DE 0x77DF 0x77E0 0x77E1 0x77E4 0x75C5 0x5E76 \ + 0x73BB 0x83E0 0x64AD 0x62E8 0x94B5 0x6CE2 0x535A 0x52C3 \ + 0x640F 0x94C2 0x7B94 0x4F2F 0x5E1B 0x8236 0x8116 0x818A \ + 0x6E24 0x6CCA 0x9A73 0x6355 0x535C 0x54FA 0x8865 0x57E0 \ + 0x4E0D 0x5E03 0x6B65 0x7C3F 0x90E8 0x6016 0x64E6 0x731C \ + 0x88C1 0x6750 0x624D 0x8D22 0x776C 0x8E29 0x91C7 0x5F69 \ + 0x83DC 0x8521 0x9910 0x53C2 0x8695 0x6B8B 0x60ED 0x60E8 \ + 0x707F 0x82CD 0x8231 0x4ED3 0x6CA7 0x85CF 0x64CD 0x7CD9 \ + 0x69FD 0x66F9 0x8349 0x5395 0x7B56 0x4FA7 0x518C 0x6D4B +38 0x5C42 0x8E6D 0x63D2 0x53C9 0x832C 0x8336 0x67E5 0x78B4 \ + 0x643D 0x5BDF 0x5C94 0x5DEE 0x8BE7 0x62C6 0x67F4 0x8C7A \ + 0x6400 0x63BA 0x8749 0x998B 0x8C17 0x7F20 0x94F2 0x4EA7 \ + 0x9610 0x98A4 0x660C 0x7316 0x77E6 0x77E8 0x77EA 0x77EF \ + 0x77F0 0x77F1 0x77F2 0x77F4 0x77F5 0x77F7 0x77F9 0x77FA \ + 0x77FB 0x77FC 0x7803 0x7804 0x7805 0x7806 0x7807 0x7808 \ + 0x780A 0x780B 0x780E 0x780F 0x7810 0x7813 0x7815 0x7819 \ + 0x781B 0x781E 0x7820 0x7821 0x7822 0x7824 0x7828 0x782A \ + 0x782B 0x782E 0x782F 0x7831 0x7832 0x7833 0x7835 0x7836 \ + 0x783D 0x783F 0x7841 0x7842 0x7843 0x7844 0x7846 0x7848 \ + 0x7849 0x784A 0x784B 0x784D 0x784F 0x7851 0x7853 0x7854 \ + 0x7858 0x7859 0x785A 0x785B 0x785C 0x785E 0x785F 0x7860 \ + 0x7861 0x7862 0x7863 0x7864 0x7865 0x7866 0x7867 0x7868 \ + 0x7869 0x786F 0x7870 0x7871 0x7872 0x7873 0x7874 0x7875 \ + 0x7876 0x7878 0x7879 0x787A 0x787B 0x787D 0x787E 0x787F \ + 0x7880 0x7881 0x7882 0x7883 0x573A 0x5C1D 0x5E38 0x957F \ + 0x507F 0x80A0 0x5382 0x655E 0x7545 0x5531 0x5021 0x8D85 \ + 0x6284 0x949E 0x671D 0x5632 0x6F6E 0x5DE2 0x5435 0x7092 \ + 0x8F66 0x626F 0x64A4 0x63A3 0x5F7B 0x6F88 0x90F4 0x81E3 \ + 0x8FB0 0x5C18 0x6668 0x5FF1 0x6C89 0x9648 0x8D81 0x886C \ + 0x6491 0x79F0 0x57CE 0x6A59 0x6210 0x5448 0x4E58 0x7A0B \ + 0x60E9 0x6F84 0x8BDA 0x627F 0x901E 0x9A8B 0x79E4 0x5403 \ + 0x75F4 0x6301 0x5319 0x6C60 0x8FDF 0x5F1B 0x9A70 0x803B \ + 0x9F7F 0x4F88 0x5C3A 0x8D64 0x7FC5 0x65A5 0x70BD 0x5145 \ + 0x51B2 0x866B 0x5D07 0x5BA0 0x62BD 0x916C 0x7574 0x8E0C \ + 0x7A20 0x6101 0x7B79 0x4EC7 0x7EF8 0x7785 0x4E11 0x81ED \ + 0x521D 0x51FA 0x6A71 0x53A8 0x8E87 0x9504 0x96CF 0x6EC1 \ + 0x9664 0x695A 0x7884 0x7885 0x7886 0x7888 0x788A 0x788B \ + 0x788F 0x7890 0x7892 0x7894 0x7895 0x7896 0x7899 0x789D \ + 0x789E 0x78A0 0x78A2 0x78A4 0x78A6 0x78A8 0x78A9 0x78AA \ + 0x78AB 0x78AC 0x78AD 0x78AE 0x78AF 0x78B5 0x78B6 0x78B7 \ + 0x78B8 0x78BA 0x78BB 0x78BC 0x78BD 0x78BF 0x78C0 0x78C2 +39 0x78C3 0x78C4 0x78C6 0x78C7 0x78C8 0x78CC 0x78CD 0x78CE \ + 0x78CF 0x78D1 0x78D2 0x78D3 0x78D6 0x78D7 0x78D8 0x78DA \ + 0x78DB 0x78DC 0x78DD 0x78DE 0x78DF 0x78E0 0x78E1 0x78E2 \ + 0x78E3 0x78E4 0x78E5 0x78E6 0x78E7 0x78E9 0x78EA 0x78EB \ + 0x78ED 0x78EE 0x78EF 0x78F0 0x78F1 0x78F3 0x78F5 0x78F6 \ + 0x78F8 0x78F9 0x78FB 0x78FC 0x78FD 0x78FE 0x78FF 0x7900 \ + 0x7902 0x7903 0x7904 0x7906 0x7907 0x7908 0x7909 0x790A \ + 0x790B 0x790C 0x7840 0x50A8 0x77D7 0x6410 0x89E6 0x5904 \ + 0x63E3 0x5DDD 0x7A7F 0x693D 0x4F20 0x8239 0x5598 0x4E32 \ + 0x75AE 0x7A97 0x5E62 0x5E8A 0x95EF 0x521B 0x5439 0x708A \ + 0x6376 0x9524 0x5782 0x6625 0x693F 0x9187 0x5507 0x6DF3 \ + 0x7EAF 0x8822 0x6233 0x7EF0 0x75B5 0x8328 0x78C1 0x96CC \ + 0x8F9E 0x6148 0x74F7 0x8BCD 0x6B64 0x523A 0x8D50 0x6B21 \ + 0x806A 0x8471 0x56F1 0x5306 0x4ECE 0x4E1B 0x51D1 0x7C97 \ + 0x918B 0x7C07 0x4FC3 0x8E7F 0x7BE1 0x7A9C 0x6467 0x5D14 \ + 0x50AC 0x8106 0x7601 0x7CB9 0x6DEC 0x7FE0 0x6751 0x5B58 \ + 0x5BF8 0x78CB 0x64AE 0x6413 0x63AA 0x632B 0x9519 0x642D \ + 0x8FBE 0x7B54 0x7629 0x6253 0x5927 0x5446 0x6B79 0x50A3 \ + 0x6234 0x5E26 0x6B86 0x4EE3 0x8D37 0x888B 0x5F85 0x902E \ + 0x790D 0x790E 0x790F 0x7910 0x7911 0x7912 0x7914 0x7915 \ + 0x7916 0x7917 0x7918 0x7919 0x791A 0x791B 0x791C 0x791D \ + 0x791F 0x7920 0x7921 0x7922 0x7923 0x7925 0x7926 0x7927 \ + 0x7928 0x7929 0x792A 0x792B 0x792C 0x792D 0x792E 0x792F \ + 0x7930 0x7931 0x7932 0x7933 0x7935 0x7936 0x7937 0x7938 \ + 0x7939 0x793D 0x793F 0x7942 0x7943 0x7944 0x7945 0x7947 \ + 0x794A 0x794B 0x794C 0x794D 0x794E 0x794F 0x7950 0x7951 \ + 0x7952 0x7954 0x7955 0x7958 0x7959 0x7961 0x7963 0x7964 \ + 0x7966 0x7969 0x796A 0x796B 0x796C 0x796E 0x7970 0x7971 \ + 0x7972 0x7973 0x7974 0x7975 0x7976 0x7979 0x797B 0x797C \ + 0x797D 0x797E 0x797F 0x7982 0x7983 0x7986 0x7987 0x7988 \ + 0x7989 0x798B 0x798C 0x798D 0x798E 0x7990 0x7991 0x7992 \ + 0x6020 0x803D 0x62C5 0x4E39 0x5355 0x90F8 0x63B8 0x80C6 +40 0x65E6 0x6C2E 0x4F46 0x60EE 0x6DE1 0x8BDE 0x5F39 0x86CB \ + 0x5F53 0x6321 0x515A 0x8361 0x6863 0x5200 0x6363 0x8E48 \ + 0x5012 0x5C9B 0x7977 0x5BFC 0x5230 0x7A3B 0x60BC 0x9053 \ + 0x76D7 0x5FB7 0x5F97 0x7684 0x8E6C 0x706F 0x767B 0x7B49 \ + 0x77AA 0x51F3 0x9093 0x5824 0x4F4E 0x6EF4 0x8FEA 0x654C \ + 0x7B1B 0x72C4 0x6DA4 0x7FDF 0x5AE1 0x62B5 0x5E95 0x5730 \ + 0x8482 0x7B2C 0x5E1D 0x5F1F 0x9012 0x7F14 0x98A0 0x6382 \ + 0x6EC7 0x7898 0x70B9 0x5178 0x975B 0x57AB 0x7535 0x4F43 \ + 0x7538 0x5E97 0x60E6 0x5960 0x6DC0 0x6BBF 0x7889 0x53FC \ + 0x96D5 0x51CB 0x5201 0x6389 0x540A 0x9493 0x8C03 0x8DCC \ + 0x7239 0x789F 0x8776 0x8FED 0x8C0D 0x53E0 0x7993 0x7994 \ + 0x7995 0x7996 0x7997 0x7998 0x7999 0x799B 0x799C 0x799D \ + 0x799E 0x799F 0x79A0 0x79A1 0x79A2 0x79A3 0x79A4 0x79A5 \ + 0x79A6 0x79A8 0x79A9 0x79AA 0x79AB 0x79AC 0x79AD 0x79AE \ + 0x79AF 0x79B0 0x79B1 0x79B2 0x79B4 0x79B5 0x79B6 0x79B7 \ + 0x79B8 0x79BC 0x79BF 0x79C2 0x79C4 0x79C5 0x79C7 0x79C8 \ + 0x79CA 0x79CC 0x79CE 0x79CF 0x79D0 0x79D3 0x79D4 0x79D6 \ + 0x79D7 0x79D9 0x79DA 0x79DB 0x79DC 0x79DD 0x79DE 0x79E0 \ + 0x79E1 0x79E2 0x79E5 0x79E8 0x79EA 0x79EC 0x79EE 0x79F1 \ + 0x79F2 0x79F3 0x79F4 0x79F5 0x79F6 0x79F7 0x79F9 0x79FA \ + 0x79FC 0x79FE 0x79FF 0x7A01 0x7A04 0x7A05 0x7A07 0x7A08 \ + 0x7A09 0x7A0A 0x7A0C 0x7A0F 0x7A10 0x7A11 0x7A12 0x7A13 \ + 0x7A15 0x7A16 0x7A18 0x7A19 0x7A1B 0x7A1C 0x4E01 0x76EF \ + 0x53EE 0x9489 0x9876 0x9F0E 0x952D 0x5B9A 0x8BA2 0x4E22 \ + 0x4E1C 0x51AC 0x8463 0x61C2 0x52A8 0x680B 0x4F97 0x606B \ + 0x51BB 0x6D1E 0x515C 0x6296 0x6597 0x9661 0x8C46 0x9017 \ + 0x75D8 0x90FD 0x7763 0x6BD2 0x728A 0x72EC 0x8BFB 0x5835 \ + 0x7779 0x8D4C 0x675C 0x9540 0x809A 0x5EA6 0x6E21 0x5992 \ + 0x7AEF 0x77ED 0x953B 0x6BB5 0x65AD 0x7F0E 0x5806 0x5151 \ + 0x961F 0x5BF9 0x58A9 0x5428 0x8E72 0x6566 0x987F 0x56E4 \ + 0x949D 0x76FE 0x9041 0x6387 0x54C6 0x591A 0x593A 0x579B \ + 0x8EB2 0x6735 0x8DFA 0x8235 0x5241 0x60F0 0x5815 0x86FE +41 0x5CE8 0x9E45 0x4FC4 0x989D 0x8BB9 0x5A25 0x6076 0x5384 \ + 0x627C 0x904F 0x9102 0x997F 0x6069 0x800C 0x513F 0x8033 \ + 0x5C14 0x9975 0x6D31 0x4E8C 0x7A1D 0x7A1F 0x7A21 0x7A22 \ + 0x7A24 0x7A25 0x7A26 0x7A27 0x7A28 0x7A29 0x7A2A 0x7A2B \ + 0x7A2C 0x7A2D 0x7A2E 0x7A2F 0x7A30 0x7A31 0x7A32 0x7A34 \ + 0x7A35 0x7A36 0x7A38 0x7A3A 0x7A3E 0x7A40 0x7A41 0x7A42 \ + 0x7A43 0x7A44 0x7A45 0x7A47 0x7A48 0x7A49 0x7A4A 0x7A4B \ + 0x7A4C 0x7A4D 0x7A4E 0x7A4F 0x7A50 0x7A52 0x7A53 0x7A54 \ + 0x7A55 0x7A56 0x7A58 0x7A59 0x7A5A 0x7A5B 0x7A5C 0x7A5D \ + 0x7A5E 0x7A5F 0x7A60 0x7A61 0x7A62 0x7A63 0x7A64 0x7A65 \ + 0x7A66 0x7A67 0x7A68 0x7A69 0x7A6A 0x7A6B 0x7A6C 0x7A6D \ + 0x7A6E 0x7A6F 0x7A71 0x7A72 0x7A73 0x7A75 0x7A7B 0x7A7C \ + 0x7A7D 0x7A7E 0x7A82 0x7A85 0x7A87 0x7A89 0x7A8A 0x7A8B \ + 0x7A8C 0x7A8E 0x7A8F 0x7A90 0x7A93 0x7A94 0x7A99 0x7A9A \ + 0x7A9B 0x7A9E 0x7AA1 0x7AA2 0x8D30 0x53D1 0x7F5A 0x7B4F \ + 0x4F10 0x4E4F 0x9600 0x6CD5 0x73D0 0x85E9 0x5E06 0x756A \ + 0x7FFB 0x6A0A 0x77FE 0x9492 0x7E41 0x51E1 0x70E6 0x53CD \ + 0x8FD4 0x8303 0x8D29 0x72AF 0x996D 0x6CDB 0x574A 0x82B3 \ + 0x65B9 0x80AA 0x623F 0x9632 0x59A8 0x4EFF 0x8BBF 0x7EBA \ + 0x653E 0x83F2 0x975E 0x5561 0x98DE 0x80A5 0x532A 0x8BFD \ + 0x5420 0x80BA 0x5E9F 0x6CB8 0x8D39 0x82AC 0x915A 0x5429 \ + 0x6C1B 0x5206 0x7EB7 0x575F 0x711A 0x6C7E 0x7C89 0x594B \ + 0x4EFD 0x5FFF 0x6124 0x7CAA 0x4E30 0x5C01 0x67AB 0x8702 \ + 0x5CF0 0x950B 0x98CE 0x75AF 0x70FD 0x9022 0x51AF 0x7F1D \ + 0x8BBD 0x5949 0x51E4 0x4F5B 0x5426 0x592B 0x6577 0x80A4 \ + 0x5B75 0x6276 0x62C2 0x8F90 0x5E45 0x6C1F 0x7B26 0x4F0F \ + 0x4FD8 0x670D 0x7AA3 0x7AA4 0x7AA7 0x7AA9 0x7AAA 0x7AAB \ + 0x7AAE 0x7AAF 0x7AB0 0x7AB1 0x7AB2 0x7AB4 0x7AB5 0x7AB6 \ + 0x7AB7 0x7AB8 0x7AB9 0x7ABA 0x7ABB 0x7ABC 0x7ABD 0x7ABE \ + 0x7AC0 0x7AC1 0x7AC2 0x7AC3 0x7AC4 0x7AC5 0x7AC6 0x7AC7 \ + 0x7AC8 0x7AC9 0x7ACA 0x7ACC 0x7ACD 0x7ACE 0x7ACF 0x7AD0 \ + 0x7AD1 0x7AD2 0x7AD3 0x7AD4 0x7AD5 0x7AD7 0x7AD8 0x7ADA +42 0x7ADB 0x7ADC 0x7ADD 0x7AE1 0x7AE2 0x7AE4 0x7AE7 0x7AE8 \ + 0x7AE9 0x7AEA 0x7AEB 0x7AEC 0x7AEE 0x7AF0 0x7AF1 0x7AF2 \ + 0x7AF3 0x7AF4 0x7AF5 0x7AF6 0x7AF7 0x7AF8 0x7AFB 0x7AFC \ + 0x7AFE 0x7B00 0x7B01 0x7B02 0x7B05 0x7B07 0x7B09 0x7B0C \ + 0x7B0D 0x7B0E 0x7B10 0x7B12 0x7B13 0x7B16 0x7B17 0x7B18 \ + 0x7B1A 0x7B1C 0x7B1D 0x7B1F 0x7B21 0x7B22 0x7B23 0x7B27 \ + 0x7B29 0x7B2D 0x6D6E 0x6DAA 0x798F 0x88B1 0x5F17 0x752B \ + 0x629A 0x8F85 0x4FEF 0x91DC 0x65A7 0x812F 0x8151 0x5E9C \ + 0x8150 0x8D74 0x526F 0x8986 0x8D4B 0x590D 0x5085 0x4ED8 \ + 0x961C 0x7236 0x8179 0x8D1F 0x5BCC 0x8BA3 0x9644 0x5987 \ + 0x7F1A 0x5490 0x5676 0x560E 0x8BE5 0x6539 0x6982 0x9499 \ + 0x76D6 0x6E89 0x5E72 0x7518 0x6746 0x67D1 0x7AFF 0x809D \ + 0x8D76 0x611F 0x79C6 0x6562 0x8D63 0x5188 0x521A 0x94A2 \ + 0x7F38 0x809B 0x7EB2 0x5C97 0x6E2F 0x6760 0x7BD9 0x768B \ + 0x9AD8 0x818F 0x7F94 0x7CD5 0x641E 0x9550 0x7A3F 0x544A \ + 0x54E5 0x6B4C 0x6401 0x6208 0x9E3D 0x80F3 0x7599 0x5272 \ + 0x9769 0x845B 0x683C 0x86E4 0x9601 0x9694 0x94EC 0x4E2A \ + 0x5404 0x7ED9 0x6839 0x8DDF 0x8015 0x66F4 0x5E9A 0x7FB9 \ + 0x7B2F 0x7B30 0x7B32 0x7B34 0x7B35 0x7B36 0x7B37 0x7B39 \ + 0x7B3B 0x7B3D 0x7B3F 0x7B40 0x7B41 0x7B42 0x7B43 0x7B44 \ + 0x7B46 0x7B48 0x7B4A 0x7B4D 0x7B4E 0x7B53 0x7B55 0x7B57 \ + 0x7B59 0x7B5C 0x7B5E 0x7B5F 0x7B61 0x7B63 0x7B64 0x7B65 \ + 0x7B66 0x7B67 0x7B68 0x7B69 0x7B6A 0x7B6B 0x7B6C 0x7B6D \ + 0x7B6F 0x7B70 0x7B73 0x7B74 0x7B76 0x7B78 0x7B7A 0x7B7C \ + 0x7B7D 0x7B7F 0x7B81 0x7B82 0x7B83 0x7B84 0x7B86 0x7B87 \ + 0x7B88 0x7B89 0x7B8A 0x7B8B 0x7B8C 0x7B8E 0x7B8F 0x7B91 \ + 0x7B92 0x7B93 0x7B96 0x7B98 0x7B99 0x7B9A 0x7B9B 0x7B9E \ + 0x7B9F 0x7BA0 0x7BA3 0x7BA4 0x7BA5 0x7BAE 0x7BAF 0x7BB0 \ + 0x7BB2 0x7BB3 0x7BB5 0x7BB6 0x7BB7 0x7BB9 0x7BBA 0x7BBB \ + 0x7BBC 0x7BBD 0x7BBE 0x7BBF 0x7BC0 0x7BC2 0x7BC3 0x7BC4 \ + 0x57C2 0x803F 0x6897 0x5DE5 0x653B 0x529F 0x606D 0x9F9A \ + 0x4F9B 0x8EAC 0x516C 0x5BAB 0x5F13 0x5DE9 0x6C5E 0x62F1 +43 0x8D21 0x5171 0x94A9 0x52FE 0x6C9F 0x82DF 0x72D7 0x57A2 \ + 0x6784 0x8D2D 0x591F 0x8F9C 0x83C7 0x5495 0x7B8D 0x4F30 \ + 0x6CBD 0x5B64 0x59D1 0x9F13 0x53E4 0x86CA 0x9AA8 0x8C37 \ + 0x80A1 0x6545 0x987E 0x56FA 0x96C7 0x522E 0x74DC 0x5250 \ + 0x5BE1 0x6302 0x8902 0x4E56 0x62D0 0x602A 0x68FA 0x5173 \ + 0x5B98 0x51A0 0x89C2 0x7BA1 0x9986 0x7F50 0x60EF 0x704C \ + 0x8D2F 0x5149 0x5E7F 0x901B 0x7470 0x89C4 0x572D 0x7845 \ + 0x5F52 0x9F9F 0x95FA 0x8F68 0x9B3C 0x8BE1 0x7678 0x6842 \ + 0x67DC 0x8DEA 0x8D35 0x523D 0x8F8A 0x6EDA 0x68CD 0x9505 \ + 0x90ED 0x56FD 0x679C 0x88F9 0x8FC7 0x54C8 0x7BC5 0x7BC8 \ + 0x7BC9 0x7BCA 0x7BCB 0x7BCD 0x7BCE 0x7BCF 0x7BD0 0x7BD2 \ + 0x7BD4 0x7BD5 0x7BD6 0x7BD7 0x7BD8 0x7BDB 0x7BDC 0x7BDE \ + 0x7BDF 0x7BE0 0x7BE2 0x7BE3 0x7BE4 0x7BE7 0x7BE8 0x7BE9 \ + 0x7BEB 0x7BEC 0x7BED 0x7BEF 0x7BF0 0x7BF2 0x7BF3 0x7BF4 \ + 0x7BF5 0x7BF6 0x7BF8 0x7BF9 0x7BFA 0x7BFB 0x7BFD 0x7BFF \ + 0x7C00 0x7C01 0x7C02 0x7C03 0x7C04 0x7C05 0x7C06 0x7C08 \ + 0x7C09 0x7C0A 0x7C0D 0x7C0E 0x7C10 0x7C11 0x7C12 0x7C13 \ + 0x7C14 0x7C15 0x7C17 0x7C18 0x7C19 0x7C1A 0x7C1B 0x7C1C \ + 0x7C1D 0x7C1E 0x7C20 0x7C21 0x7C22 0x7C23 0x7C24 0x7C25 \ + 0x7C28 0x7C29 0x7C2B 0x7C2C 0x7C2D 0x7C2E 0x7C2F 0x7C30 \ + 0x7C31 0x7C32 0x7C33 0x7C34 0x7C35 0x7C36 0x7C37 0x7C39 \ + 0x7C3A 0x7C3B 0x7C3C 0x7C3D 0x7C3E 0x7C42 0x9AB8 0x5B69 \ + 0x6D77 0x6C26 0x4EA5 0x5BB3 0x9A87 0x9163 0x61A8 0x90AF \ + 0x97E9 0x542B 0x6DB5 0x5BD2 0x51FD 0x558A 0x7F55 0x7FF0 \ + 0x64BC 0x634D 0x65F1 0x61BE 0x608D 0x710A 0x6C57 0x6C49 \ + 0x592F 0x676D 0x822A 0x58D5 0x568E 0x8C6A 0x6BEB 0x90DD \ + 0x597D 0x8017 0x53F7 0x6D69 0x5475 0x559D 0x8377 0x83CF \ + 0x6838 0x79BE 0x548C 0x4F55 0x5408 0x76D2 0x8C89 0x9602 \ + 0x6CB3 0x6DB8 0x8D6B 0x8910 0x9E64 0x8D3A 0x563F 0x9ED1 \ + 0x75D5 0x5F88 0x72E0 0x6068 0x54FC 0x4EA8 0x6A2A 0x8861 \ + 0x6052 0x8F70 0x54C4 0x70D8 0x8679 0x9E3F 0x6D2A 0x5B8F \ + 0x5F18 0x7EA2 0x5589 0x4FAF 0x7334 0x543C 0x539A 0x5019 +44 0x540E 0x547C 0x4E4E 0x5FFD 0x745A 0x58F6 0x846B 0x80E1 \ + 0x8774 0x72D0 0x7CCA 0x6E56 0x7C43 0x7C44 0x7C45 0x7C46 \ + 0x7C47 0x7C48 0x7C49 0x7C4A 0x7C4B 0x7C4C 0x7C4E 0x7C4F \ + 0x7C50 0x7C51 0x7C52 0x7C53 0x7C54 0x7C55 0x7C56 0x7C57 \ + 0x7C58 0x7C59 0x7C5A 0x7C5B 0x7C5C 0x7C5D 0x7C5E 0x7C5F \ + 0x7C60 0x7C61 0x7C62 0x7C63 0x7C64 0x7C65 0x7C66 0x7C67 \ + 0x7C68 0x7C69 0x7C6A 0x7C6B 0x7C6C 0x7C6D 0x7C6E 0x7C6F \ + 0x7C70 0x7C71 0x7C72 0x7C75 0x7C76 0x7C77 0x7C78 0x7C79 \ + 0x7C7A 0x7C7E 0x7C7F 0x7C80 0x7C81 0x7C82 0x7C83 0x7C84 \ + 0x7C85 0x7C86 0x7C87 0x7C88 0x7C8A 0x7C8B 0x7C8C 0x7C8D \ + 0x7C8E 0x7C8F 0x7C90 0x7C93 0x7C94 0x7C96 0x7C99 0x7C9A \ + 0x7C9B 0x7CA0 0x7CA1 0x7CA3 0x7CA6 0x7CA7 0x7CA8 0x7CA9 \ + 0x7CAB 0x7CAC 0x7CAD 0x7CAF 0x7CB0 0x7CB4 0x7CB5 0x7CB6 \ + 0x7CB7 0x7CB8 0x7CBA 0x7CBB 0x5F27 0x864E 0x552C 0x62A4 \ + 0x4E92 0x6CAA 0x6237 0x82B1 0x54D7 0x534E 0x733E 0x6ED1 \ + 0x753B 0x5212 0x5316 0x8BDD 0x69D0 0x5F8A 0x6000 0x6DEE \ + 0x574F 0x6B22 0x73AF 0x6853 0x8FD8 0x7F13 0x6362 0x60A3 \ + 0x5524 0x75EA 0x8C62 0x7115 0x6DA3 0x5BA6 0x5E7B 0x8352 \ + 0x614C 0x9EC4 0x78FA 0x8757 0x7C27 0x7687 0x51F0 0x60F6 \ + 0x714C 0x6643 0x5E4C 0x604D 0x8C0E 0x7070 0x6325 0x8F89 \ + 0x5FBD 0x6062 0x86D4 0x56DE 0x6BC1 0x6094 0x6167 0x5349 \ + 0x60E0 0x6666 0x8D3F 0x79FD 0x4F1A 0x70E9 0x6C47 0x8BB3 \ + 0x8BF2 0x7ED8 0x8364 0x660F 0x5A5A 0x9B42 0x6D51 0x6DF7 \ + 0x8C41 0x6D3B 0x4F19 0x706B 0x83B7 0x6216 0x60D1 0x970D \ + 0x8D27 0x7978 0x51FB 0x573E 0x57FA 0x673A 0x7578 0x7A3D \ + 0x79EF 0x7B95 0x7CBF 0x7CC0 0x7CC2 0x7CC3 0x7CC4 0x7CC6 \ + 0x7CC9 0x7CCB 0x7CCE 0x7CCF 0x7CD0 0x7CD1 0x7CD2 0x7CD3 \ + 0x7CD4 0x7CD8 0x7CDA 0x7CDB 0x7CDD 0x7CDE 0x7CE1 0x7CE2 \ + 0x7CE3 0x7CE4 0x7CE5 0x7CE6 0x7CE7 0x7CE9 0x7CEA 0x7CEB \ + 0x7CEC 0x7CED 0x7CEE 0x7CF0 0x7CF1 0x7CF2 0x7CF3 0x7CF4 \ + 0x7CF5 0x7CF6 0x7CF7 0x7CF9 0x7CFA 0x7CFC 0x7CFD 0x7CFE \ + 0x7CFF 0x7D00 0x7D01 0x7D02 0x7D03 0x7D04 0x7D05 0x7D06 +45 0x7D07 0x7D08 0x7D09 0x7D0B 0x7D0C 0x7D0D 0x7D0E 0x7D0F \ + 0x7D10 0x7D11 0x7D12 0x7D13 0x7D14 0x7D15 0x7D16 0x7D17 \ + 0x7D18 0x7D19 0x7D1A 0x7D1B 0x7D1C 0x7D1D 0x7D1E 0x7D1F \ + 0x7D21 0x7D23 0x7D24 0x7D25 0x7D26 0x7D28 0x7D29 0x7D2A \ + 0x7D2C 0x7D2D 0x7D2E 0x7D30 0x7D31 0x7D32 0x7D33 0x7D34 \ + 0x7D35 0x7D36 0x808C 0x9965 0x8FF9 0x6FC0 0x8BA5 0x9E21 \ + 0x59EC 0x7EE9 0x7F09 0x5409 0x6781 0x68D8 0x8F91 0x7C4D \ + 0x96C6 0x53CA 0x6025 0x75BE 0x6C72 0x5373 0x5AC9 0x7EA7 \ + 0x6324 0x51E0 0x810A 0x5DF1 0x84DF 0x6280 0x5180 0x5B63 \ + 0x4F0E 0x796D 0x5242 0x60B8 0x6D4E 0x5BC4 0x5BC2 0x8BA1 \ + 0x8BB0 0x65E2 0x5FCC 0x9645 0x5993 0x7EE7 0x7EAA 0x5609 \ + 0x67B7 0x5939 0x4F73 0x5BB6 0x52A0 0x835A 0x988A 0x8D3E \ + 0x7532 0x94BE 0x5047 0x7A3C 0x4EF7 0x67B6 0x9A7E 0x5AC1 \ + 0x6B7C 0x76D1 0x575A 0x5C16 0x7B3A 0x95F4 0x714E 0x517C \ + 0x80A9 0x8270 0x5978 0x7F04 0x8327 0x68C0 0x67EC 0x78B1 \ + 0x7877 0x62E3 0x6361 0x7B80 0x4FED 0x526A 0x51CF 0x8350 \ + 0x69DB 0x9274 0x8DF5 0x8D31 0x89C1 0x952E 0x7BAD 0x4EF6 \ + 0x7D37 0x7D38 0x7D39 0x7D3A 0x7D3B 0x7D3C 0x7D3D 0x7D3E \ + 0x7D3F 0x7D40 0x7D41 0x7D42 0x7D43 0x7D44 0x7D45 0x7D46 \ + 0x7D47 0x7D48 0x7D49 0x7D4A 0x7D4B 0x7D4C 0x7D4D 0x7D4E \ + 0x7D4F 0x7D50 0x7D51 0x7D52 0x7D53 0x7D54 0x7D55 0x7D56 \ + 0x7D57 0x7D58 0x7D59 0x7D5A 0x7D5B 0x7D5C 0x7D5D 0x7D5E \ + 0x7D5F 0x7D60 0x7D61 0x7D62 0x7D63 0x7D64 0x7D65 0x7D66 \ + 0x7D67 0x7D68 0x7D69 0x7D6A 0x7D6B 0x7D6C 0x7D6D 0x7D6F \ + 0x7D70 0x7D71 0x7D72 0x7D73 0x7D74 0x7D75 0x7D76 0x7D78 \ + 0x7D79 0x7D7A 0x7D7B 0x7D7C 0x7D7D 0x7D7E 0x7D7F 0x7D80 \ + 0x7D81 0x7D82 0x7D83 0x7D84 0x7D85 0x7D86 0x7D87 0x7D88 \ + 0x7D89 0x7D8A 0x7D8B 0x7D8C 0x7D8D 0x7D8E 0x7D8F 0x7D90 \ + 0x7D91 0x7D92 0x7D93 0x7D94 0x7D95 0x7D96 0x7D97 0x7D98 \ + 0x5065 0x8230 0x5251 0x996F 0x6E10 0x6E85 0x6DA7 0x5EFA \ + 0x50F5 0x59DC 0x5C06 0x6D46 0x6C5F 0x7586 0x848B 0x6868 \ + 0x5956 0x8BB2 0x5320 0x9171 0x964D 0x8549 0x6912 0x7901 +46 0x7126 0x80F6 0x4EA4 0x90CA 0x6D47 0x9A84 0x5A07 0x56BC \ + 0x6405 0x94F0 0x77EB 0x4FA5 0x811A 0x72E1 0x89D2 0x997A \ + 0x7F34 0x7EDE 0x527F 0x6559 0x9175 0x8F7F 0x8F83 0x53EB \ + 0x7A96 0x63ED 0x63A5 0x7686 0x79F8 0x8857 0x9636 0x622A \ + 0x52AB 0x8282 0x6854 0x6770 0x6377 0x776B 0x7AED 0x6D01 \ + 0x7ED3 0x89E3 0x59D0 0x6212 0x85C9 0x82A5 0x754C 0x501F \ + 0x4ECB 0x75A5 0x8BEB 0x5C4A 0x5DFE 0x7B4B 0x65A4 0x91D1 \ + 0x4ECA 0x6D25 0x895F 0x7D27 0x9526 0x4EC5 0x8C28 0x8FDB \ + 0x9773 0x664B 0x7981 0x8FD1 0x70EC 0x6D78 0x7D99 0x7D9A \ + 0x7D9B 0x7D9C 0x7D9D 0x7D9E 0x7D9F 0x7DA0 0x7DA1 0x7DA2 \ + 0x7DA3 0x7DA4 0x7DA5 0x7DA7 0x7DA8 0x7DA9 0x7DAA 0x7DAB \ + 0x7DAC 0x7DAD 0x7DAF 0x7DB0 0x7DB1 0x7DB2 0x7DB3 0x7DB4 \ + 0x7DB5 0x7DB6 0x7DB7 0x7DB8 0x7DB9 0x7DBA 0x7DBB 0x7DBC \ + 0x7DBD 0x7DBE 0x7DBF 0x7DC0 0x7DC1 0x7DC2 0x7DC3 0x7DC4 \ + 0x7DC5 0x7DC6 0x7DC7 0x7DC8 0x7DC9 0x7DCA 0x7DCB 0x7DCC \ + 0x7DCD 0x7DCE 0x7DCF 0x7DD0 0x7DD1 0x7DD2 0x7DD3 0x7DD4 \ + 0x7DD5 0x7DD6 0x7DD7 0x7DD8 0x7DD9 0x7DDA 0x7DDB 0x7DDC \ + 0x7DDD 0x7DDE 0x7DDF 0x7DE0 0x7DE1 0x7DE2 0x7DE3 0x7DE4 \ + 0x7DE5 0x7DE6 0x7DE7 0x7DE8 0x7DE9 0x7DEA 0x7DEB 0x7DEC \ + 0x7DED 0x7DEE 0x7DEF 0x7DF0 0x7DF1 0x7DF2 0x7DF3 0x7DF4 \ + 0x7DF5 0x7DF6 0x7DF7 0x7DF8 0x7DF9 0x7DFA 0x5C3D 0x52B2 \ + 0x8346 0x5162 0x830E 0x775B 0x6676 0x9CB8 0x4EAC 0x60CA \ + 0x7CBE 0x7CB3 0x7ECF 0x4E95 0x8B66 0x666F 0x9888 0x9759 \ + 0x5883 0x656C 0x955C 0x5F84 0x75C9 0x9756 0x7ADF 0x7ADE \ + 0x51C0 0x70AF 0x7A98 0x63EA 0x7A76 0x7EA0 0x7396 0x97ED \ + 0x4E45 0x7078 0x4E5D 0x9152 0x53A9 0x6551 0x65E7 0x81FC \ + 0x8205 0x548E 0x5C31 0x759A 0x97A0 0x62D8 0x72D9 0x75BD \ + 0x5C45 0x9A79 0x83CA 0x5C40 0x5480 0x77E9 0x4E3E 0x6CAE \ + 0x805A 0x62D2 0x636E 0x5DE8 0x5177 0x8DDD 0x8E1E 0x952F \ + 0x4FF1 0x53E5 0x60E7 0x70AC 0x5267 0x6350 0x9E43 0x5A1F \ + 0x5026 0x7737 0x5377 0x7EE2 0x6485 0x652B 0x6289 0x6398 \ + 0x5014 0x7235 0x89C9 0x51B3 0x8BC0 0x7EDD 0x5747 0x83CC +47 0x94A7 0x519B 0x541B 0x5CFB 0x7DFB 0x7DFC 0x7DFD 0x7DFE \ + 0x7DFF 0x7E00 0x7E01 0x7E02 0x7E03 0x7E04 0x7E05 0x7E06 \ + 0x7E07 0x7E08 0x7E09 0x7E0A 0x7E0B 0x7E0C 0x7E0D 0x7E0E \ + 0x7E0F 0x7E10 0x7E11 0x7E12 0x7E13 0x7E14 0x7E15 0x7E16 \ + 0x7E17 0x7E18 0x7E19 0x7E1A 0x7E1B 0x7E1C 0x7E1D 0x7E1E \ + 0x7E1F 0x7E20 0x7E21 0x7E22 0x7E23 0x7E24 0x7E25 0x7E26 \ + 0x7E27 0x7E28 0x7E29 0x7E2A 0x7E2B 0x7E2C 0x7E2D 0x7E2E \ + 0x7E2F 0x7E30 0x7E31 0x7E32 0x7E33 0x7E34 0x7E35 0x7E36 \ + 0x7E37 0x7E38 0x7E39 0x7E3A 0x7E3C 0x7E3D 0x7E3E 0x7E3F \ + 0x7E40 0x7E42 0x7E43 0x7E44 0x7E45 0x7E46 0x7E48 0x7E49 \ + 0x7E4A 0x7E4B 0x7E4C 0x7E4D 0x7E4E 0x7E4F 0x7E50 0x7E51 \ + 0x7E52 0x7E53 0x7E54 0x7E55 0x7E56 0x7E57 0x7E58 0x7E59 \ + 0x7E5A 0x7E5B 0x7E5C 0x7E5D 0x4FCA 0x7AE3 0x6D5A 0x90E1 \ + 0x9A8F 0x5580 0x5496 0x5361 0x54AF 0x5F00 0x63E9 0x6977 \ + 0x51EF 0x6168 0x520A 0x582A 0x52D8 0x574E 0x780D 0x770B \ + 0x5EB7 0x6177 0x7CE0 0x625B 0x6297 0x4EA2 0x7095 0x8003 \ + 0x62F7 0x70E4 0x9760 0x5777 0x82DB 0x67EF 0x68F5 0x78D5 \ + 0x9897 0x79D1 0x58F3 0x54B3 0x53EF 0x6E34 0x514B 0x523B \ + 0x5BA2 0x8BFE 0x80AF 0x5543 0x57A6 0x6073 0x5751 0x542D \ + 0x7A7A 0x6050 0x5B54 0x63A7 0x62A0 0x53E3 0x6263 0x5BC7 \ + 0x67AF 0x54ED 0x7A9F 0x82E6 0x9177 0x5E93 0x88E4 0x5938 \ + 0x57AE 0x630E 0x8DE8 0x80EF 0x5757 0x7B77 0x4FA9 0x5FEB \ + 0x5BBD 0x6B3E 0x5321 0x7B50 0x72C2 0x6846 0x77FF 0x7736 \ + 0x65F7 0x51B5 0x4E8F 0x76D4 0x5CBF 0x7AA5 0x8475 0x594E \ + 0x9B41 0x5080 0x7E5E 0x7E5F 0x7E60 0x7E61 0x7E62 0x7E63 \ + 0x7E64 0x7E65 0x7E66 0x7E67 0x7E68 0x7E69 0x7E6A 0x7E6B \ + 0x7E6C 0x7E6D 0x7E6E 0x7E6F 0x7E70 0x7E71 0x7E72 0x7E73 \ + 0x7E74 0x7E75 0x7E76 0x7E77 0x7E78 0x7E79 0x7E7A 0x7E7B \ + 0x7E7C 0x7E7D 0x7E7E 0x7E7F 0x7E80 0x7E81 0x7E83 0x7E84 \ + 0x7E85 0x7E86 0x7E87 0x7E88 0x7E89 0x7E8A 0x7E8B 0x7E8C \ + 0x7E8D 0x7E8E 0x7E8F 0x7E90 0x7E91 0x7E92 0x7E93 0x7E94 \ + 0x7E95 0x7E96 0x7E97 0x7E98 0x7E99 0x7E9A 0x7E9C 0x7E9D +48 0x7E9E 0x7EAE 0x7EB4 0x7EBB 0x7EBC 0x7ED6 0x7EE4 0x7EEC \ + 0x7EF9 0x7F0A 0x7F10 0x7F1E 0x7F37 0x7F39 0x7F3B 0x7F3C \ + 0x7F3D 0x7F3E 0x7F3F 0x7F40 0x7F41 0x7F43 0x7F46 0x7F47 \ + 0x7F48 0x7F49 0x7F4A 0x7F4B 0x7F4C 0x7F4D 0x7F4E 0x7F4F \ + 0x7F52 0x7F53 0x9988 0x6127 0x6E83 0x5764 0x6606 0x6346 \ + 0x56F0 0x62EC 0x6269 0x5ED3 0x9614 0x5783 0x62C9 0x5587 \ + 0x8721 0x814A 0x8FA3 0x5566 0x83B1 0x6765 0x8D56 0x84DD \ + 0x5A6A 0x680F 0x62E6 0x7BEE 0x9611 0x5170 0x6F9C 0x8C30 \ + 0x63FD 0x89C8 0x61D2 0x7F06 0x70C2 0x6EE5 0x7405 0x6994 \ + 0x72FC 0x5ECA 0x90CE 0x6717 0x6D6A 0x635E 0x52B3 0x7262 \ + 0x8001 0x4F6C 0x59E5 0x916A 0x70D9 0x6D9D 0x52D2 0x4E50 \ + 0x96F7 0x956D 0x857E 0x78CA 0x7D2F 0x5121 0x5792 0x64C2 \ + 0x808B 0x7C7B 0x6CEA 0x68F1 0x695E 0x51B7 0x5398 0x68A8 \ + 0x7281 0x9ECE 0x7BF1 0x72F8 0x79BB 0x6F13 0x7406 0x674E \ + 0x91CC 0x9CA4 0x793C 0x8389 0x8354 0x540F 0x6817 0x4E3D \ + 0x5389 0x52B1 0x783E 0x5386 0x5229 0x5088 0x4F8B 0x4FD0 \ + 0x7F56 0x7F59 0x7F5B 0x7F5C 0x7F5D 0x7F5E 0x7F60 0x7F63 \ + 0x7F64 0x7F65 0x7F66 0x7F67 0x7F6B 0x7F6C 0x7F6D 0x7F6F \ + 0x7F70 0x7F73 0x7F75 0x7F76 0x7F77 0x7F78 0x7F7A 0x7F7B \ + 0x7F7C 0x7F7D 0x7F7F 0x7F80 0x7F82 0x7F83 0x7F84 0x7F85 \ + 0x7F86 0x7F87 0x7F88 0x7F89 0x7F8B 0x7F8D 0x7F8F 0x7F90 \ + 0x7F91 0x7F92 0x7F93 0x7F95 0x7F96 0x7F97 0x7F98 0x7F99 \ + 0x7F9B 0x7F9C 0x7FA0 0x7FA2 0x7FA3 0x7FA5 0x7FA6 0x7FA8 \ + 0x7FA9 0x7FAA 0x7FAB 0x7FAC 0x7FAD 0x7FAE 0x7FB1 0x7FB3 \ + 0x7FB4 0x7FB5 0x7FB6 0x7FB7 0x7FBA 0x7FBB 0x7FBE 0x7FC0 \ + 0x7FC2 0x7FC3 0x7FC4 0x7FC6 0x7FC7 0x7FC8 0x7FC9 0x7FCB \ + 0x7FCD 0x7FCF 0x7FD0 0x7FD1 0x7FD2 0x7FD3 0x7FD6 0x7FD7 \ + 0x7FD9 0x7FDA 0x7FDB 0x7FDC 0x7FDD 0x7FDE 0x7FE2 0x7FE3 \ + 0x75E2 0x7ACB 0x7C92 0x6CA5 0x96B6 0x529B 0x7483 0x54E9 \ + 0x4FE9 0x8054 0x83B2 0x8FDE 0x9570 0x5EC9 0x601C 0x6D9F \ + 0x5E18 0x655B 0x8138 0x94FE 0x604B 0x70BC 0x7EC3 0x7CAE \ + 0x51C9 0x6881 0x7CB1 0x826F 0x4E24 0x8F86 0x91CF 0x667E +49 0x4EAE 0x8C05 0x64A9 0x804A 0x50DA 0x7597 0x71CE 0x5BE5 \ + 0x8FBD 0x6F66 0x4E86 0x6482 0x9563 0x5ED6 0x6599 0x5217 \ + 0x88C2 0x70C8 0x52A3 0x730E 0x7433 0x6797 0x78F7 0x9716 \ + 0x4E34 0x90BB 0x9CDE 0x6DCB 0x51DB 0x8D41 0x541D 0x62CE \ + 0x73B2 0x83F1 0x96F6 0x9F84 0x94C3 0x4F36 0x7F9A 0x51CC \ + 0x7075 0x9675 0x5CAD 0x9886 0x53E6 0x4EE4 0x6E9C 0x7409 \ + 0x69B4 0x786B 0x998F 0x7559 0x5218 0x7624 0x6D41 0x67F3 \ + 0x516D 0x9F99 0x804B 0x5499 0x7B3C 0x7ABF 0x7FE4 0x7FE7 \ + 0x7FE8 0x7FEA 0x7FEB 0x7FEC 0x7FED 0x7FEF 0x7FF2 0x7FF4 \ + 0x7FF5 0x7FF6 0x7FF7 0x7FF8 0x7FF9 0x7FFA 0x7FFD 0x7FFE \ + 0x7FFF 0x8002 0x8007 0x8008 0x8009 0x800A 0x800E 0x800F \ + 0x8011 0x8013 0x801A 0x801B 0x801D 0x801E 0x801F 0x8021 \ + 0x8023 0x8024 0x802B 0x802C 0x802D 0x802E 0x802F 0x8030 \ + 0x8032 0x8034 0x8039 0x803A 0x803C 0x803E 0x8040 0x8041 \ + 0x8044 0x8045 0x8047 0x8048 0x8049 0x804E 0x804F 0x8050 \ + 0x8051 0x8053 0x8055 0x8056 0x8057 0x8059 0x805B 0x805C \ + 0x805D 0x805E 0x805F 0x8060 0x8061 0x8062 0x8063 0x8064 \ + 0x8065 0x8066 0x8067 0x8068 0x806B 0x806C 0x806D 0x806E \ + 0x806F 0x8070 0x8072 0x8073 0x8074 0x8075 0x8076 0x8077 \ + 0x8078 0x8079 0x807A 0x807B 0x807C 0x807D 0x9686 0x5784 \ + 0x62E2 0x9647 0x697C 0x5A04 0x6402 0x7BD3 0x6F0F 0x964B \ + 0x82A6 0x5362 0x9885 0x5E90 0x7089 0x63B3 0x5364 0x864F \ + 0x9C81 0x9E93 0x788C 0x9732 0x8DEF 0x8D42 0x9E7F 0x6F5E \ + 0x7984 0x5F55 0x9646 0x622E 0x9A74 0x5415 0x94DD 0x4FA3 \ + 0x65C5 0x5C65 0x5C61 0x7F15 0x8651 0x6C2F 0x5F8B 0x7387 \ + 0x6EE4 0x7EFF 0x5CE6 0x631B 0x5B6A 0x6EE6 0x5375 0x4E71 \ + 0x63A0 0x7565 0x62A1 0x8F6E 0x4F26 0x4ED1 0x6CA6 0x7EB6 \ + 0x8BBA 0x841D 0x87BA 0x7F57 0x903B 0x9523 0x7BA9 0x9AA1 \ + 0x88F8 0x843D 0x6D1B 0x9A86 0x7EDC 0x5988 0x9EBB 0x739B \ + 0x7801 0x8682 0x9A6C 0x9A82 0x561B 0x5417 0x57CB 0x4E70 \ + 0x9EA6 0x5356 0x8FC8 0x8109 0x7792 0x9992 0x86EE 0x6EE1 \ + 0x8513 0x66FC 0x6162 0x6F2B 0x807E 0x8081 0x8082 0x8085 +50 0x8088 0x808A 0x808D 0x808E 0x808F 0x8090 0x8091 0x8092 \ + 0x8094 0x8095 0x8097 0x8099 0x809E 0x80A3 0x80A6 0x80A7 \ + 0x80A8 0x80AC 0x80B0 0x80B3 0x80B5 0x80B6 0x80B8 0x80B9 \ + 0x80BB 0x80C5 0x80C7 0x80C8 0x80C9 0x80CA 0x80CB 0x80CF \ + 0x80D0 0x80D1 0x80D2 0x80D3 0x80D4 0x80D5 0x80D8 0x80DF \ + 0x80E0 0x80E2 0x80E3 0x80E6 0x80EE 0x80F5 0x80F7 0x80F9 \ + 0x80FB 0x80FE 0x80FF 0x8100 0x8101 0x8103 0x8104 0x8105 \ + 0x8107 0x8108 0x810B 0x810C 0x8115 0x8117 0x8119 0x811B \ + 0x811C 0x811D 0x811F 0x8120 0x8121 0x8122 0x8123 0x8124 \ + 0x8125 0x8126 0x8127 0x8128 0x8129 0x812A 0x812B 0x812D \ + 0x812E 0x8130 0x8133 0x8134 0x8135 0x8137 0x8139 0x813A \ + 0x813B 0x813C 0x813D 0x813F 0x8C29 0x8292 0x832B 0x76F2 \ + 0x6C13 0x5FD9 0x83BD 0x732B 0x8305 0x951A 0x6BDB 0x77DB \ + 0x94C6 0x536F 0x8302 0x5192 0x5E3D 0x8C8C 0x8D38 0x4E48 \ + 0x73AB 0x679A 0x6885 0x9176 0x9709 0x7164 0x6CA1 0x7709 \ + 0x5A92 0x9541 0x6BCF 0x7F8E 0x6627 0x5BD0 0x59B9 0x5A9A \ + 0x95E8 0x95F7 0x4EEC 0x840C 0x8499 0x6AAC 0x76DF 0x9530 \ + 0x731B 0x68A6 0x5B5F 0x772F 0x919A 0x9761 0x7CDC 0x8FF7 \ + 0x8C1C 0x5F25 0x7C73 0x79D8 0x89C5 0x6CCC 0x871C 0x5BC6 \ + 0x5E42 0x68C9 0x7720 0x7EF5 0x5195 0x514D 0x52C9 0x5A29 \ + 0x7F05 0x9762 0x82D7 0x63CF 0x7784 0x85D0 0x79D2 0x6E3A \ + 0x5E99 0x5999 0x8511 0x706D 0x6C11 0x62BF 0x76BF 0x654F \ + 0x60AF 0x95FD 0x660E 0x879F 0x9E23 0x94ED 0x540D 0x547D \ + 0x8C2C 0x6478 0x8140 0x8141 0x8142 0x8143 0x8144 0x8145 \ + 0x8147 0x8149 0x814D 0x814E 0x814F 0x8152 0x8156 0x8157 \ + 0x8158 0x815B 0x815C 0x815D 0x815E 0x815F 0x8161 0x8162 \ + 0x8163 0x8164 0x8166 0x8168 0x816A 0x816B 0x816C 0x816F \ + 0x8172 0x8173 0x8175 0x8176 0x8177 0x8178 0x8181 0x8183 \ + 0x8184 0x8185 0x8186 0x8187 0x8189 0x818B 0x818C 0x818D \ + 0x818E 0x8190 0x8192 0x8193 0x8194 0x8195 0x8196 0x8197 \ + 0x8199 0x819A 0x819E 0x819F 0x81A0 0x81A1 0x81A2 0x81A4 \ + 0x81A5 0x81A7 0x81A9 0x81AB 0x81AC 0x81AD 0x81AE 0x81AF +51 0x81B0 0x81B1 0x81B2 0x81B4 0x81B5 0x81B6 0x81B7 0x81B8 \ + 0x81B9 0x81BC 0x81BD 0x81BE 0x81BF 0x81C4 0x81C5 0x81C7 \ + 0x81C8 0x81C9 0x81CB 0x81CD 0x81CE 0x81CF 0x81D0 0x81D1 \ + 0x81D2 0x81D3 0x6479 0x8611 0x6A21 0x819C 0x78E8 0x6469 \ + 0x9B54 0x62B9 0x672B 0x83AB 0x58A8 0x9ED8 0x6CAB 0x6F20 \ + 0x5BDE 0x964C 0x8C0B 0x725F 0x67D0 0x62C7 0x7261 0x4EA9 \ + 0x59C6 0x6BCD 0x5893 0x66AE 0x5E55 0x52DF 0x6155 0x6728 \ + 0x76EE 0x7766 0x7267 0x7A46 0x62FF 0x54EA 0x5450 0x94A0 \ + 0x90A3 0x5A1C 0x7EB3 0x6C16 0x4E43 0x5976 0x8010 0x5948 \ + 0x5357 0x7537 0x96BE 0x56CA 0x6320 0x8111 0x607C 0x95F9 \ + 0x6DD6 0x5462 0x9981 0x5185 0x5AE9 0x80FD 0x59AE 0x9713 \ + 0x502A 0x6CE5 0x5C3C 0x62DF 0x4F60 0x533F 0x817B 0x9006 \ + 0x6EBA 0x852B 0x62C8 0x5E74 0x78BE 0x64B5 0x637B 0x5FF5 \ + 0x5A18 0x917F 0x9E1F 0x5C3F 0x634F 0x8042 0x5B7D 0x556E \ + 0x954A 0x954D 0x6D85 0x60A8 0x67E0 0x72DE 0x51DD 0x5B81 \ + 0x81D4 0x81D5 0x81D6 0x81D7 0x81D8 0x81D9 0x81DA 0x81DB \ + 0x81DC 0x81DD 0x81DE 0x81DF 0x81E0 0x81E1 0x81E2 0x81E4 \ + 0x81E5 0x81E6 0x81E8 0x81E9 0x81EB 0x81EE 0x81EF 0x81F0 \ + 0x81F1 0x81F2 0x81F5 0x81F6 0x81F7 0x81F8 0x81F9 0x81FA \ + 0x81FD 0x81FF 0x8203 0x8207 0x8208 0x8209 0x820A 0x820B \ + 0x820E 0x820F 0x8211 0x8213 0x8215 0x8216 0x8217 0x8218 \ + 0x8219 0x821A 0x821D 0x8220 0x8224 0x8225 0x8226 0x8227 \ + 0x8229 0x822E 0x8232 0x823A 0x823C 0x823D 0x823F 0x8240 \ + 0x8241 0x8242 0x8243 0x8245 0x8246 0x8248 0x824A 0x824C \ + 0x824D 0x824E 0x8250 0x8251 0x8252 0x8253 0x8254 0x8255 \ + 0x8256 0x8257 0x8259 0x825B 0x825C 0x825D 0x825E 0x8260 \ + 0x8261 0x8262 0x8263 0x8264 0x8265 0x8266 0x8267 0x8269 \ + 0x62E7 0x6CDE 0x725B 0x626D 0x94AE 0x7EBD 0x8113 0x6D53 \ + 0x519C 0x5F04 0x5974 0x52AA 0x6012 0x5973 0x6696 0x8650 \ + 0x759F 0x632A 0x61E6 0x7CEF 0x8BFA 0x54E6 0x6B27 0x9E25 \ + 0x6BB4 0x85D5 0x5455 0x5076 0x6CA4 0x556A 0x8DB4 0x722C \ + 0x5E15 0x6015 0x7436 0x62CD 0x6392 0x724C 0x5F98 0x6E43 +52 0x6D3E 0x6500 0x6F58 0x76D8 0x78D0 0x76FC 0x7554 0x5224 \ + 0x53DB 0x4E53 0x5E9E 0x65C1 0x802A 0x80D6 0x629B 0x5486 \ + 0x5228 0x70AE 0x888D 0x8DD1 0x6CE1 0x5478 0x80DA 0x57F9 \ + 0x88F4 0x8D54 0x966A 0x914D 0x4F69 0x6C9B 0x55B7 0x76C6 \ + 0x7830 0x62A8 0x70F9 0x6F8E 0x5F6D 0x84EC 0x68DA 0x787C \ + 0x7BF7 0x81A8 0x670B 0x9E4F 0x6367 0x78B0 0x576F 0x7812 \ + 0x9739 0x6279 0x62AB 0x5288 0x7435 0x6BD7 0x826A 0x826B \ + 0x826C 0x826D 0x8271 0x8275 0x8276 0x8277 0x8278 0x827B \ + 0x827C 0x8280 0x8281 0x8283 0x8285 0x8286 0x8287 0x8289 \ + 0x828C 0x8290 0x8293 0x8294 0x8295 0x8296 0x829A 0x829B \ + 0x829E 0x82A0 0x82A2 0x82A3 0x82A7 0x82B2 0x82B5 0x82B6 \ + 0x82BA 0x82BB 0x82BC 0x82BF 0x82C0 0x82C2 0x82C3 0x82C5 \ + 0x82C6 0x82C9 0x82D0 0x82D6 0x82D9 0x82DA 0x82DD 0x82E2 \ + 0x82E7 0x82E8 0x82E9 0x82EA 0x82EC 0x82ED 0x82EE 0x82F0 \ + 0x82F2 0x82F3 0x82F5 0x82F6 0x82F8 0x82FA 0x82FC 0x82FD \ + 0x82FE 0x82FF 0x8300 0x830A 0x830B 0x830D 0x8310 0x8312 \ + 0x8313 0x8316 0x8318 0x8319 0x831D 0x831E 0x831F 0x8320 \ + 0x8321 0x8322 0x8323 0x8324 0x8325 0x8326 0x8329 0x832A \ + 0x832E 0x8330 0x8332 0x8337 0x833B 0x833D 0x5564 0x813E \ + 0x75B2 0x76AE 0x5339 0x75DE 0x50FB 0x5C41 0x8B6C 0x7BC7 \ + 0x504F 0x7247 0x9A97 0x98D8 0x6F02 0x74E2 0x7968 0x6487 \ + 0x77A5 0x62FC 0x9891 0x8D2B 0x54C1 0x8058 0x4E52 0x576A \ + 0x82F9 0x840D 0x5E73 0x51ED 0x74F6 0x8BC4 0x5C4F 0x5761 \ + 0x6CFC 0x9887 0x5A46 0x7834 0x9B44 0x8FEB 0x7C95 0x5256 \ + 0x6251 0x94FA 0x4EC6 0x8386 0x8461 0x83E9 0x84B2 0x57D4 \ + 0x6734 0x5703 0x666E 0x6D66 0x8C31 0x66DD 0x7011 0x671F \ + 0x6B3A 0x6816 0x621A 0x59BB 0x4E03 0x51C4 0x6F06 0x67D2 \ + 0x6C8F 0x5176 0x68CB 0x5947 0x6B67 0x7566 0x5D0E 0x8110 \ + 0x9F50 0x65D7 0x7948 0x7941 0x9A91 0x8D77 0x5C82 0x4E5E \ + 0x4F01 0x542F 0x5951 0x780C 0x5668 0x6C14 0x8FC4 0x5F03 \ + 0x6C7D 0x6CE3 0x8BAB 0x6390 0x833E 0x833F 0x8341 0x8342 \ + 0x8344 0x8345 0x8348 0x834A 0x834B 0x834C 0x834D 0x834E +53 0x8353 0x8355 0x8356 0x8357 0x8358 0x8359 0x835D 0x8362 \ + 0x8370 0x8371 0x8372 0x8373 0x8374 0x8375 0x8376 0x8379 \ + 0x837A 0x837E 0x837F 0x8380 0x8381 0x8382 0x8383 0x8384 \ + 0x8387 0x8388 0x838A 0x838B 0x838C 0x838D 0x838F 0x8390 \ + 0x8391 0x8394 0x8395 0x8396 0x8397 0x8399 0x839A 0x839D \ + 0x839F 0x83A1 0x83A2 0x83A3 0x83A4 0x83A5 0x83A6 0x83A7 \ + 0x83AC 0x83AD 0x83AE 0x83AF 0x83B5 0x83BB 0x83BE 0x83BF \ + 0x83C2 0x83C3 0x83C4 0x83C6 0x83C8 0x83C9 0x83CB 0x83CD \ + 0x83CE 0x83D0 0x83D1 0x83D2 0x83D3 0x83D5 0x83D7 0x83D9 \ + 0x83DA 0x83DB 0x83DE 0x83E2 0x83E3 0x83E4 0x83E6 0x83E7 \ + 0x83E8 0x83EB 0x83EC 0x83ED 0x6070 0x6D3D 0x7275 0x6266 \ + 0x948E 0x94C5 0x5343 0x8FC1 0x7B7E 0x4EDF 0x8C26 0x4E7E \ + 0x9ED4 0x94B1 0x94B3 0x524D 0x6F5C 0x9063 0x6D45 0x8C34 \ + 0x5811 0x5D4C 0x6B20 0x6B49 0x67AA 0x545B 0x8154 0x7F8C \ + 0x5899 0x8537 0x5F3A 0x62A2 0x6A47 0x9539 0x6572 0x6084 \ + 0x6865 0x77A7 0x4E54 0x4FA8 0x5DE7 0x9798 0x64AC 0x7FD8 \ + 0x5CED 0x4FCF 0x7A8D 0x5207 0x8304 0x4E14 0x602F 0x7A83 \ + 0x94A6 0x4FB5 0x4EB2 0x79E6 0x7434 0x52E4 0x82B9 0x64D2 \ + 0x79BD 0x5BDD 0x6C81 0x9752 0x8F7B 0x6C22 0x503E 0x537F \ + 0x6E05 0x64CE 0x6674 0x6C30 0x60C5 0x9877 0x8BF7 0x5E86 \ + 0x743C 0x7A77 0x79CB 0x4E18 0x90B1 0x7403 0x6C42 0x56DA \ + 0x914B 0x6CC5 0x8D8B 0x533A 0x86C6 0x66F2 0x8EAF 0x5C48 \ + 0x9A71 0x6E20 0x83EE 0x83EF 0x83F3 0x83F4 0x83F5 0x83F6 \ + 0x83F7 0x83FA 0x83FB 0x83FC 0x83FE 0x83FF 0x8400 0x8402 \ + 0x8405 0x8407 0x8408 0x8409 0x840A 0x8410 0x8412 0x8413 \ + 0x8414 0x8415 0x8416 0x8417 0x8419 0x841A 0x841B 0x841E \ + 0x841F 0x8420 0x8421 0x8422 0x8423 0x8429 0x842A 0x842B \ + 0x842C 0x842D 0x842E 0x842F 0x8430 0x8432 0x8433 0x8434 \ + 0x8435 0x8436 0x8437 0x8439 0x843A 0x843B 0x843E 0x843F \ + 0x8440 0x8441 0x8442 0x8443 0x8444 0x8445 0x8447 0x8448 \ + 0x8449 0x844A 0x844B 0x844C 0x844D 0x844E 0x844F 0x8450 \ + 0x8452 0x8453 0x8454 0x8455 0x8456 0x8458 0x845D 0x845E +54 0x845F 0x8460 0x8462 0x8464 0x8465 0x8466 0x8467 0x8468 \ + 0x846A 0x846E 0x846F 0x8470 0x8472 0x8474 0x8477 0x8479 \ + 0x847B 0x847C 0x53D6 0x5A36 0x9F8B 0x8DA3 0x53BB 0x5708 \ + 0x98A7 0x6743 0x919B 0x6CC9 0x5168 0x75CA 0x62F3 0x72AC \ + 0x5238 0x529D 0x7F3A 0x7094 0x7638 0x5374 0x9E4A 0x69B7 \ + 0x786E 0x96C0 0x88D9 0x7FA4 0x7136 0x71C3 0x5189 0x67D3 \ + 0x74E4 0x58E4 0x6518 0x56B7 0x8BA9 0x9976 0x6270 0x7ED5 \ + 0x60F9 0x70ED 0x58EC 0x4EC1 0x4EBA 0x5FCD 0x97E7 0x4EFB \ + 0x8BA4 0x5203 0x598A 0x7EAB 0x6254 0x4ECD 0x65E5 0x620E \ + 0x8338 0x84C9 0x8363 0x878D 0x7194 0x6EB6 0x5BB9 0x7ED2 \ + 0x5197 0x63C9 0x67D4 0x8089 0x8339 0x8815 0x5112 0x5B7A \ + 0x5982 0x8FB1 0x4E73 0x6C5D 0x5165 0x8925 0x8F6F 0x962E \ + 0x854A 0x745E 0x9510 0x95F0 0x6DA6 0x82E5 0x5F31 0x6492 \ + 0x6D12 0x8428 0x816E 0x9CC3 0x585E 0x8D5B 0x4E09 0x53C1 \ + 0x847D 0x847E 0x847F 0x8480 0x8481 0x8483 0x8484 0x8485 \ + 0x8486 0x848A 0x848D 0x848F 0x8490 0x8491 0x8492 0x8493 \ + 0x8494 0x8495 0x8496 0x8498 0x849A 0x849B 0x849D 0x849E \ + 0x849F 0x84A0 0x84A2 0x84A3 0x84A4 0x84A5 0x84A6 0x84A7 \ + 0x84A8 0x84A9 0x84AA 0x84AB 0x84AC 0x84AD 0x84AE 0x84B0 \ + 0x84B1 0x84B3 0x84B5 0x84B6 0x84B7 0x84BB 0x84BC 0x84BE \ + 0x84C0 0x84C2 0x84C3 0x84C5 0x84C6 0x84C7 0x84C8 0x84CB \ + 0x84CC 0x84CE 0x84CF 0x84D2 0x84D4 0x84D5 0x84D7 0x84D8 \ + 0x84D9 0x84DA 0x84DB 0x84DC 0x84DE 0x84E1 0x84E2 0x84E4 \ + 0x84E7 0x84E8 0x84E9 0x84EA 0x84EB 0x84ED 0x84EE 0x84EF \ + 0x84F1 0x84F2 0x84F3 0x84F4 0x84F5 0x84F6 0x84F7 0x84F8 \ + 0x84F9 0x84FA 0x84FB 0x84FD 0x84FE 0x8500 0x8501 0x8502 \ + 0x4F1E 0x6563 0x6851 0x55D3 0x4E27 0x6414 0x9A9A 0x626B \ + 0x5AC2 0x745F 0x8272 0x6DA9 0x68EE 0x50E7 0x838E 0x7802 \ + 0x6740 0x5239 0x6C99 0x7EB1 0x50BB 0x5565 0x715E 0x7B5B \ + 0x6652 0x73CA 0x82EB 0x6749 0x5C71 0x5220 0x717D 0x886B \ + 0x95EA 0x9655 0x64C5 0x8D61 0x81B3 0x5584 0x6C55 0x6247 \ + 0x7F2E 0x5892 0x4F24 0x5546 0x8D4F 0x664C 0x4E0A 0x5C1A +55 0x88F3 0x68A2 0x634E 0x7A0D 0x70E7 0x828D 0x52FA 0x97F6 \ + 0x5C11 0x54E8 0x90B5 0x7ECD 0x5962 0x8D4A 0x86C7 0x820C \ + 0x820D 0x8D66 0x6444 0x5C04 0x6151 0x6D89 0x793E 0x8BBE \ + 0x7837 0x7533 0x547B 0x4F38 0x8EAB 0x6DF1 0x5A20 0x7EC5 \ + 0x795E 0x6C88 0x5BA1 0x5A76 0x751A 0x80BE 0x614E 0x6E17 \ + 0x58F0 0x751F 0x7525 0x7272 0x5347 0x7EF3 0x8503 0x8504 \ + 0x8505 0x8506 0x8507 0x8508 0x8509 0x850A 0x850B 0x850D \ + 0x850E 0x850F 0x8510 0x8512 0x8514 0x8515 0x8516 0x8518 \ + 0x8519 0x851B 0x851C 0x851D 0x851E 0x8520 0x8522 0x8523 \ + 0x8524 0x8525 0x8526 0x8527 0x8528 0x8529 0x852A 0x852D \ + 0x852E 0x852F 0x8530 0x8531 0x8532 0x8533 0x8534 0x8535 \ + 0x8536 0x853E 0x853F 0x8540 0x8541 0x8542 0x8544 0x8545 \ + 0x8546 0x8547 0x854B 0x854C 0x854D 0x854E 0x854F 0x8550 \ + 0x8551 0x8552 0x8553 0x8554 0x8555 0x8557 0x8558 0x855A \ + 0x855B 0x855C 0x855D 0x855F 0x8560 0x8561 0x8562 0x8563 \ + 0x8565 0x8566 0x8567 0x8569 0x856A 0x856B 0x856C 0x856D \ + 0x856E 0x856F 0x8570 0x8571 0x8573 0x8575 0x8576 0x8577 \ + 0x8578 0x857C 0x857D 0x857F 0x8580 0x8581 0x7701 0x76DB \ + 0x5269 0x80DC 0x5723 0x5E08 0x5931 0x72EE 0x65BD 0x6E7F \ + 0x8BD7 0x5C38 0x8671 0x5341 0x77F3 0x62FE 0x65F6 0x4EC0 \ + 0x98DF 0x8680 0x5B9E 0x8BC6 0x53F2 0x77E2 0x4F7F 0x5C4E \ + 0x9A76 0x59CB 0x5F0F 0x793A 0x58EB 0x4E16 0x67FF 0x4E8B \ + 0x62ED 0x8A93 0x901D 0x52BF 0x662F 0x55DC 0x566C 0x9002 \ + 0x4ED5 0x4F8D 0x91CA 0x9970 0x6C0F 0x5E02 0x6043 0x5BA4 \ + 0x89C6 0x8BD5 0x6536 0x624B 0x9996 0x5B88 0x5BFF 0x6388 \ + 0x552E 0x53D7 0x7626 0x517D 0x852C 0x67A2 0x68B3 0x6B8A \ + 0x6292 0x8F93 0x53D4 0x8212 0x6DD1 0x758F 0x4E66 0x8D4E \ + 0x5B70 0x719F 0x85AF 0x6691 0x66D9 0x7F72 0x8700 0x9ECD \ + 0x9F20 0x5C5E 0x672F 0x8FF0 0x6811 0x675F 0x620D 0x7AD6 \ + 0x5885 0x5EB6 0x6570 0x6F31 0x8582 0x8583 0x8586 0x8588 \ + 0x8589 0x858A 0x858B 0x858C 0x858D 0x858E 0x8590 0x8591 \ + 0x8592 0x8593 0x8594 0x8595 0x8596 0x8597 0x8598 0x8599 +56 0x859A 0x859D 0x859E 0x859F 0x85A0 0x85A1 0x85A2 0x85A3 \ + 0x85A5 0x85A6 0x85A7 0x85A9 0x85AB 0x85AC 0x85AD 0x85B1 \ + 0x85B2 0x85B3 0x85B4 0x85B5 0x85B6 0x85B8 0x85BA 0x85BB \ + 0x85BC 0x85BD 0x85BE 0x85BF 0x85C0 0x85C2 0x85C3 0x85C4 \ + 0x85C5 0x85C6 0x85C7 0x85C8 0x85CA 0x85CB 0x85CC 0x85CD \ + 0x85CE 0x85D1 0x85D2 0x85D4 0x85D6 0x85D7 0x85D8 0x85D9 \ + 0x85DA 0x85DB 0x85DD 0x85DE 0x85DF 0x85E0 0x85E1 0x85E2 \ + 0x85E3 0x85E5 0x85E6 0x85E7 0x85E8 0x85EA 0x85EB 0x85EC \ + 0x85ED 0x85EE 0x85EF 0x85F0 0x85F1 0x85F2 0x85F3 0x85F4 \ + 0x85F5 0x85F6 0x85F7 0x85F8 0x6055 0x5237 0x800D 0x6454 \ + 0x8870 0x7529 0x5E05 0x6813 0x62F4 0x971C 0x53CC 0x723D \ + 0x8C01 0x6C34 0x7761 0x7A0E 0x542E 0x77AC 0x987A 0x821C \ + 0x8BF4 0x7855 0x6714 0x70C1 0x65AF 0x6495 0x5636 0x601D \ + 0x79C1 0x53F8 0x4E1D 0x6B7B 0x8086 0x5BFA 0x55E3 0x56DB \ + 0x4F3A 0x4F3C 0x9972 0x5DF3 0x677E 0x8038 0x6002 0x9882 \ + 0x9001 0x5B8B 0x8BBC 0x8BF5 0x641C 0x8258 0x64DE 0x55FD \ + 0x82CF 0x9165 0x4FD7 0x7D20 0x901F 0x7C9F 0x50F3 0x5851 \ + 0x6EAF 0x5BBF 0x8BC9 0x8083 0x9178 0x849C 0x7B97 0x867D \ + 0x968B 0x968F 0x7EE5 0x9AD3 0x788E 0x5C81 0x7A57 0x9042 \ + 0x96A7 0x795F 0x5B59 0x635F 0x7B0B 0x84D1 0x68AD 0x5506 \ + 0x7F29 0x7410 0x7D22 0x9501 0x6240 0x584C 0x4ED6 0x5B83 \ + 0x5979 0x5854 0x85F9 0x85FA 0x85FC 0x85FD 0x85FE 0x8600 \ + 0x8601 0x8602 0x8603 0x8604 0x8606 0x8607 0x8608 0x8609 \ + 0x860A 0x860B 0x860C 0x860D 0x860E 0x860F 0x8610 0x8612 \ + 0x8613 0x8614 0x8615 0x8617 0x8618 0x8619 0x861A 0x861B \ + 0x861C 0x861D 0x861E 0x861F 0x8620 0x8621 0x8622 0x8623 \ + 0x8624 0x8625 0x8626 0x8628 0x862A 0x862B 0x862C 0x862D \ + 0x862E 0x862F 0x8630 0x8631 0x8632 0x8633 0x8634 0x8635 \ + 0x8636 0x8637 0x8639 0x863A 0x863B 0x863D 0x863E 0x863F \ + 0x8640 0x8641 0x8642 0x8643 0x8644 0x8645 0x8646 0x8647 \ + 0x8648 0x8649 0x864A 0x864B 0x864C 0x8652 0x8653 0x8655 \ + 0x8656 0x8657 0x8658 0x8659 0x865B 0x865C 0x865D 0x865F +57 0x8660 0x8661 0x8663 0x8664 0x8665 0x8666 0x8667 0x8668 \ + 0x8669 0x866A 0x736D 0x631E 0x8E4B 0x8E0F 0x80CE 0x82D4 \ + 0x62AC 0x53F0 0x6CF0 0x915E 0x592A 0x6001 0x6C70 0x574D \ + 0x644A 0x8D2A 0x762B 0x6EE9 0x575B 0x6A80 0x75F0 0x6F6D \ + 0x8C2D 0x8C08 0x5766 0x6BEF 0x8892 0x78B3 0x63A2 0x53F9 \ + 0x70AD 0x6C64 0x5858 0x642A 0x5802 0x68E0 0x819B 0x5510 \ + 0x7CD6 0x5018 0x8EBA 0x6DCC 0x8D9F 0x70EB 0x638F 0x6D9B \ + 0x6ED4 0x7EE6 0x8404 0x6843 0x9003 0x6DD8 0x9676 0x8BA8 \ + 0x5957 0x7279 0x85E4 0x817E 0x75BC 0x8A8A 0x68AF 0x5254 \ + 0x8E22 0x9511 0x63D0 0x9898 0x8E44 0x557C 0x4F53 0x66FF \ + 0x568F 0x60D5 0x6D95 0x5243 0x5C49 0x5929 0x6DFB 0x586B \ + 0x7530 0x751C 0x606C 0x8214 0x8146 0x6311 0x6761 0x8FE2 \ + 0x773A 0x8DF3 0x8D34 0x94C1 0x5E16 0x5385 0x542C 0x70C3 \ + 0x866D 0x866F 0x8670 0x8672 0x8673 0x8674 0x8675 0x8676 \ + 0x8677 0x8678 0x8683 0x8684 0x8685 0x8686 0x8687 0x8688 \ + 0x8689 0x868E 0x868F 0x8690 0x8691 0x8692 0x8694 0x8696 \ + 0x8697 0x8698 0x8699 0x869A 0x869B 0x869E 0x869F 0x86A0 \ + 0x86A1 0x86A2 0x86A5 0x86A6 0x86AB 0x86AD 0x86AE 0x86B2 \ + 0x86B3 0x86B7 0x86B8 0x86B9 0x86BB 0x86BC 0x86BD 0x86BE \ + 0x86BF 0x86C1 0x86C2 0x86C3 0x86C5 0x86C8 0x86CC 0x86CD \ + 0x86D2 0x86D3 0x86D5 0x86D6 0x86D7 0x86DA 0x86DC 0x86DD \ + 0x86E0 0x86E1 0x86E2 0x86E3 0x86E5 0x86E6 0x86E7 0x86E8 \ + 0x86EA 0x86EB 0x86EC 0x86EF 0x86F5 0x86F6 0x86F7 0x86FA \ + 0x86FB 0x86FC 0x86FD 0x86FF 0x8701 0x8704 0x8705 0x8706 \ + 0x870B 0x870C 0x870E 0x870F 0x8710 0x8711 0x8714 0x8716 \ + 0x6C40 0x5EF7 0x505C 0x4EAD 0x5EAD 0x633A 0x8247 0x901A \ + 0x6850 0x916E 0x77B3 0x540C 0x94DC 0x5F64 0x7AE5 0x6876 \ + 0x6345 0x7B52 0x7EDF 0x75DB 0x5077 0x6295 0x5934 0x900F \ + 0x51F8 0x79C3 0x7A81 0x56FE 0x5F92 0x9014 0x6D82 0x5C60 \ + 0x571F 0x5410 0x5154 0x6E4D 0x56E2 0x63A8 0x9893 0x817F \ + 0x8715 0x892A 0x9000 0x541E 0x5C6F 0x81C0 0x62D6 0x6258 \ + 0x8131 0x9E35 0x9640 0x9A6E 0x9A7C 0x692D 0x59A5 0x62D3 +58 0x553E 0x6316 0x54C7 0x86D9 0x6D3C 0x5A03 0x74E6 0x889C \ + 0x6B6A 0x5916 0x8C4C 0x5F2F 0x6E7E 0x73A9 0x987D 0x4E38 \ + 0x70F7 0x5B8C 0x7897 0x633D 0x665A 0x7696 0x60CB 0x5B9B \ + 0x5A49 0x4E07 0x8155 0x6C6A 0x738B 0x4EA1 0x6789 0x7F51 \ + 0x5F80 0x65FA 0x671B 0x5FD8 0x5984 0x5A01 0x8719 0x871B \ + 0x871D 0x871F 0x8720 0x8724 0x8726 0x8727 0x8728 0x872A \ + 0x872B 0x872C 0x872D 0x872F 0x8730 0x8732 0x8733 0x8735 \ + 0x8736 0x8738 0x8739 0x873A 0x873C 0x873D 0x8740 0x8741 \ + 0x8742 0x8743 0x8744 0x8745 0x8746 0x874A 0x874B 0x874D \ + 0x874F 0x8750 0x8751 0x8752 0x8754 0x8755 0x8756 0x8758 \ + 0x875A 0x875B 0x875C 0x875D 0x875E 0x875F 0x8761 0x8762 \ + 0x8766 0x8767 0x8768 0x8769 0x876A 0x876B 0x876C 0x876D \ + 0x876F 0x8771 0x8772 0x8773 0x8775 0x8777 0x8778 0x8779 \ + 0x877A 0x877F 0x8780 0x8781 0x8784 0x8786 0x8787 0x8789 \ + 0x878A 0x878C 0x878E 0x878F 0x8790 0x8791 0x8792 0x8794 \ + 0x8795 0x8796 0x8798 0x8799 0x879A 0x879B 0x879C 0x879D \ + 0x879E 0x87A0 0x87A1 0x87A2 0x87A3 0x87A4 0x5DCD 0x5FAE \ + 0x5371 0x97E6 0x8FDD 0x6845 0x56F4 0x552F 0x60DF 0x4E3A \ + 0x6F4D 0x7EF4 0x82C7 0x840E 0x59D4 0x4F1F 0x4F2A 0x5C3E \ + 0x7EAC 0x672A 0x851A 0x5473 0x754F 0x80C3 0x5582 0x9B4F \ + 0x4F4D 0x6E2D 0x8C13 0x5C09 0x6170 0x536B 0x761F 0x6E29 \ + 0x868A 0x6587 0x95FB 0x7EB9 0x543B 0x7A33 0x7D0A 0x95EE \ + 0x55E1 0x7FC1 0x74EE 0x631D 0x8717 0x6DA1 0x7A9D 0x6211 \ + 0x65A1 0x5367 0x63E1 0x6C83 0x5DEB 0x545C 0x94A8 0x4E4C \ + 0x6C61 0x8BEC 0x5C4B 0x65E0 0x829C 0x68A7 0x543E 0x5434 \ + 0x6BCB 0x6B66 0x4E94 0x6342 0x5348 0x821E 0x4F0D 0x4FAE \ + 0x575E 0x620A 0x96FE 0x6664 0x7269 0x52FF 0x52A1 0x609F \ + 0x8BEF 0x6614 0x7199 0x6790 0x897F 0x7852 0x77FD 0x6670 \ + 0x563B 0x5438 0x9521 0x727A 0x87A5 0x87A6 0x87A7 0x87A9 \ + 0x87AA 0x87AE 0x87B0 0x87B1 0x87B2 0x87B4 0x87B6 0x87B7 \ + 0x87B8 0x87B9 0x87BB 0x87BC 0x87BE 0x87BF 0x87C1 0x87C2 \ + 0x87C3 0x87C4 0x87C5 0x87C7 0x87C8 0x87C9 0x87CC 0x87CD +59 0x87CE 0x87CF 0x87D0 0x87D4 0x87D5 0x87D6 0x87D7 0x87D8 \ + 0x87D9 0x87DA 0x87DC 0x87DD 0x87DE 0x87DF 0x87E1 0x87E2 \ + 0x87E3 0x87E4 0x87E6 0x87E7 0x87E8 0x87E9 0x87EB 0x87EC \ + 0x87ED 0x87EF 0x87F0 0x87F1 0x87F2 0x87F3 0x87F4 0x87F5 \ + 0x87F6 0x87F7 0x87F8 0x87FA 0x87FB 0x87FC 0x87FD 0x87FF \ + 0x8800 0x8801 0x8802 0x8804 0x8805 0x8806 0x8807 0x8808 \ + 0x8809 0x880B 0x880C 0x880D 0x880E 0x880F 0x8810 0x8811 \ + 0x8812 0x8814 0x8817 0x8818 0x8819 0x881A 0x881C 0x881D \ + 0x881E 0x881F 0x8820 0x8823 0x7A00 0x606F 0x5E0C 0x6089 \ + 0x819D 0x5915 0x60DC 0x7184 0x70EF 0x6EAA 0x6C50 0x7280 \ + 0x6A84 0x88AD 0x5E2D 0x4E60 0x5AB3 0x559C 0x94E3 0x6D17 \ + 0x7CFB 0x9699 0x620F 0x7EC6 0x778E 0x867E 0x5323 0x971E \ + 0x8F96 0x6687 0x5CE1 0x4FA0 0x72ED 0x4E0B 0x53A6 0x590F \ + 0x5413 0x6380 0x9528 0x5148 0x4ED9 0x9C9C 0x7EA4 0x54B8 \ + 0x8D24 0x8854 0x8237 0x95F2 0x6D8E 0x5F26 0x5ACC 0x663E \ + 0x9669 0x73B0 0x732E 0x53BF 0x817A 0x9985 0x7FA1 0x5BAA \ + 0x9677 0x9650 0x7EBF 0x76F8 0x53A2 0x9576 0x9999 0x7BB1 \ + 0x8944 0x6E58 0x4E61 0x7FD4 0x7965 0x8BE6 0x60F3 0x54CD \ + 0x4EAB 0x9879 0x5DF7 0x6A61 0x50CF 0x5411 0x8C61 0x8427 \ + 0x785D 0x9704 0x524A 0x54EE 0x56A3 0x9500 0x6D88 0x5BB5 \ + 0x6DC6 0x6653 0x8824 0x8825 0x8826 0x8827 0x8828 0x8829 \ + 0x882A 0x882B 0x882C 0x882D 0x882E 0x882F 0x8830 0x8831 \ + 0x8833 0x8834 0x8835 0x8836 0x8837 0x8838 0x883A 0x883B \ + 0x883D 0x883E 0x883F 0x8841 0x8842 0x8843 0x8846 0x8847 \ + 0x8848 0x8849 0x884A 0x884B 0x884E 0x884F 0x8850 0x8851 \ + 0x8852 0x8853 0x8855 0x8856 0x8858 0x885A 0x885B 0x885C \ + 0x885D 0x885E 0x885F 0x8860 0x8866 0x8867 0x886A 0x886D \ + 0x886F 0x8871 0x8873 0x8874 0x8875 0x8876 0x8878 0x8879 \ + 0x887A 0x887B 0x887C 0x8880 0x8883 0x8886 0x8887 0x8889 \ + 0x888A 0x888C 0x888E 0x888F 0x8890 0x8891 0x8893 0x8894 \ + 0x8895 0x8897 0x8898 0x8899 0x889A 0x889B 0x889D 0x889E \ + 0x889F 0x88A0 0x88A1 0x88A3 0x88A5 0x88A6 0x88A7 0x88A8 +60 0x88A9 0x88AA 0x5C0F 0x5B5D 0x6821 0x8096 0x5578 0x7B11 \ + 0x6548 0x6954 0x4E9B 0x6B47 0x874E 0x978B 0x534F 0x631F \ + 0x643A 0x90AA 0x659C 0x80C1 0x8C10 0x5199 0x68B0 0x5378 \ + 0x87F9 0x61C8 0x6CC4 0x6CFB 0x8C22 0x5C51 0x85AA 0x82AF \ + 0x950C 0x6B23 0x8F9B 0x65B0 0x5FFB 0x5FC3 0x4FE1 0x8845 \ + 0x661F 0x8165 0x7329 0x60FA 0x5174 0x5211 0x578B 0x5F62 \ + 0x90A2 0x884C 0x9192 0x5E78 0x674F 0x6027 0x59D3 0x5144 \ + 0x51F6 0x80F8 0x5308 0x6C79 0x96C4 0x718A 0x4F11 0x4FEE \ + 0x7F9E 0x673D 0x55C5 0x9508 0x79C0 0x8896 0x7EE3 0x589F \ + 0x620C 0x9700 0x865A 0x5618 0x987B 0x5F90 0x8BB8 0x84C4 \ + 0x9157 0x53D9 0x65ED 0x5E8F 0x755C 0x6064 0x7D6E 0x5A7F \ + 0x7EEA 0x7EED 0x8F69 0x55A7 0x5BA3 0x60AC 0x65CB 0x7384 \ + 0x88AC 0x88AE 0x88AF 0x88B0 0x88B2 0x88B3 0x88B4 0x88B5 \ + 0x88B6 0x88B8 0x88B9 0x88BA 0x88BB 0x88BD 0x88BE 0x88BF \ + 0x88C0 0x88C3 0x88C4 0x88C7 0x88C8 0x88CA 0x88CB 0x88CC \ + 0x88CD 0x88CF 0x88D0 0x88D1 0x88D3 0x88D6 0x88D7 0x88DA \ + 0x88DB 0x88DC 0x88DD 0x88DE 0x88E0 0x88E1 0x88E6 0x88E7 \ + 0x88E9 0x88EA 0x88EB 0x88EC 0x88ED 0x88EE 0x88EF 0x88F2 \ + 0x88F5 0x88F6 0x88F7 0x88FA 0x88FB 0x88FD 0x88FF 0x8900 \ + 0x8901 0x8903 0x8904 0x8905 0x8906 0x8907 0x8908 0x8909 \ + 0x890B 0x890C 0x890D 0x890E 0x890F 0x8911 0x8914 0x8915 \ + 0x8916 0x8917 0x8918 0x891C 0x891D 0x891E 0x891F 0x8920 \ + 0x8922 0x8923 0x8924 0x8926 0x8927 0x8928 0x8929 0x892C \ + 0x892D 0x892E 0x892F 0x8931 0x8932 0x8933 0x8935 0x8937 \ + 0x9009 0x7663 0x7729 0x7EDA 0x9774 0x859B 0x5B66 0x7A74 \ + 0x96EA 0x8840 0x52CB 0x718F 0x5FAA 0x65EC 0x8BE2 0x5BFB \ + 0x9A6F 0x5DE1 0x6B89 0x6C5B 0x8BAD 0x8BAF 0x900A 0x8FC5 \ + 0x538B 0x62BC 0x9E26 0x9E2D 0x5440 0x4E2B 0x82BD 0x7259 \ + 0x869C 0x5D16 0x8859 0x6DAF 0x96C5 0x54D1 0x4E9A 0x8BB6 \ + 0x7109 0x54BD 0x9609 0x70DF 0x6DF9 0x76D0 0x4E25 0x7814 \ + 0x8712 0x5CA9 0x5EF6 0x8A00 0x989C 0x960E 0x708E 0x6CBF \ + 0x5944 0x63A9 0x773C 0x884D 0x6F14 0x8273 0x5830 0x71D5 +61 0x538C 0x781A 0x96C1 0x5501 0x5F66 0x7130 0x5BB4 0x8C1A \ + 0x9A8C 0x6B83 0x592E 0x9E2F 0x79E7 0x6768 0x626C 0x4F6F \ + 0x75A1 0x7F8A 0x6D0B 0x9633 0x6C27 0x4EF0 0x75D2 0x517B \ + 0x6837 0x6F3E 0x9080 0x8170 0x5996 0x7476 0x8938 0x8939 \ + 0x893A 0x893B 0x893C 0x893D 0x893E 0x893F 0x8940 0x8942 \ + 0x8943 0x8945 0x8946 0x8947 0x8948 0x8949 0x894A 0x894B \ + 0x894C 0x894D 0x894E 0x894F 0x8950 0x8951 0x8952 0x8953 \ + 0x8954 0x8955 0x8956 0x8957 0x8958 0x8959 0x895A 0x895B \ + 0x895C 0x895D 0x8960 0x8961 0x8962 0x8963 0x8964 0x8965 \ + 0x8967 0x8968 0x8969 0x896A 0x896B 0x896C 0x896D 0x896E \ + 0x896F 0x8970 0x8971 0x8972 0x8973 0x8974 0x8975 0x8976 \ + 0x8977 0x8978 0x8979 0x897A 0x897C 0x897D 0x897E 0x8980 \ + 0x8982 0x8984 0x8985 0x8987 0x8988 0x8989 0x898A 0x898B \ + 0x898C 0x898D 0x898E 0x898F 0x8990 0x8991 0x8992 0x8993 \ + 0x8994 0x8995 0x8996 0x8997 0x8998 0x8999 0x899A 0x899B \ + 0x899C 0x899D 0x899E 0x899F 0x89A0 0x89A1 0x6447 0x5C27 \ + 0x9065 0x7A91 0x8C23 0x59DA 0x54AC 0x8200 0x836F 0x8981 \ + 0x8000 0x6930 0x564E 0x8036 0x7237 0x91CE 0x51B6 0x4E5F \ + 0x9875 0x6396 0x4E1A 0x53F6 0x66F3 0x814B 0x591C 0x6DB2 \ + 0x4E00 0x58F9 0x533B 0x63D6 0x94F1 0x4F9D 0x4F0A 0x8863 \ + 0x9890 0x5937 0x9057 0x79FB 0x4EEA 0x80F0 0x7591 0x6C82 \ + 0x5B9C 0x59E8 0x5F5D 0x6905 0x8681 0x501A 0x5DF2 0x4E59 \ + 0x77E3 0x4EE5 0x827A 0x6291 0x6613 0x9091 0x5C79 0x4EBF \ + 0x5F79 0x81C6 0x9038 0x8084 0x75AB 0x4EA6 0x88D4 0x610F \ + 0x6BC5 0x5FC6 0x4E49 0x76CA 0x6EA2 0x8BE3 0x8BAE 0x8C0A \ + 0x8BD1 0x5F02 0x7FFC 0x7FCC 0x7ECE 0x8335 0x836B 0x56E0 \ + 0x6BB7 0x97F3 0x9634 0x59FB 0x541F 0x94F6 0x6DEB 0x5BC5 \ + 0x996E 0x5C39 0x5F15 0x9690 0x89A2 0x89A3 0x89A4 0x89A5 \ + 0x89A6 0x89A7 0x89A8 0x89A9 0x89AA 0x89AB 0x89AC 0x89AD \ + 0x89AE 0x89AF 0x89B0 0x89B1 0x89B2 0x89B3 0x89B4 0x89B5 \ + 0x89B6 0x89B7 0x89B8 0x89B9 0x89BA 0x89BB 0x89BC 0x89BD \ + 0x89BE 0x89BF 0x89C0 0x89C3 0x89CD 0x89D3 0x89D4 0x89D5 +62 0x89D7 0x89D8 0x89D9 0x89DB 0x89DD 0x89DF 0x89E0 0x89E1 \ + 0x89E2 0x89E4 0x89E7 0x89E8 0x89E9 0x89EA 0x89EC 0x89ED \ + 0x89EE 0x89F0 0x89F1 0x89F2 0x89F4 0x89F5 0x89F6 0x89F7 \ + 0x89F8 0x89F9 0x89FA 0x89FB 0x89FC 0x89FD 0x89FE 0x89FF \ + 0x8A01 0x8A02 0x8A03 0x8A04 0x8A05 0x8A06 0x8A08 0x8A09 \ + 0x8A0A 0x8A0B 0x8A0C 0x8A0D 0x8A0E 0x8A0F 0x8A10 0x8A11 \ + 0x8A12 0x8A13 0x8A14 0x8A15 0x8A16 0x8A17 0x8A18 0x8A19 \ + 0x8A1A 0x8A1B 0x8A1C 0x8A1D 0x5370 0x82F1 0x6A31 0x5A74 \ + 0x9E70 0x5E94 0x7F28 0x83B9 0x8424 0x8425 0x8367 0x8747 \ + 0x8FCE 0x8D62 0x76C8 0x5F71 0x9896 0x786C 0x6620 0x54DF \ + 0x62E5 0x4F63 0x81C3 0x75C8 0x5EB8 0x96CD 0x8E0A 0x86F9 \ + 0x548F 0x6CF3 0x6D8C 0x6C38 0x607F 0x52C7 0x7528 0x5E7D \ + 0x4F18 0x60A0 0x5FE7 0x5C24 0x7531 0x90AE 0x94C0 0x72B9 \ + 0x6CB9 0x6E38 0x9149 0x6709 0x53CB 0x53F3 0x4F51 0x91C9 \ + 0x8BF1 0x53C8 0x5E7C 0x8FC2 0x6DE4 0x4E8E 0x76C2 0x6986 \ + 0x865E 0x611A 0x8206 0x4F59 0x4FDE 0x903E 0x9C7C 0x6109 \ + 0x6E1D 0x6E14 0x9685 0x4E88 0x5A31 0x96E8 0x4E0E 0x5C7F \ + 0x79B9 0x5B87 0x8BED 0x7FBD 0x7389 0x57DF 0x828B 0x90C1 \ + 0x5401 0x9047 0x55BB 0x5CEA 0x5FA1 0x6108 0x6B32 0x72F1 \ + 0x80B2 0x8A89 0x8A1E 0x8A1F 0x8A20 0x8A21 0x8A22 0x8A23 \ + 0x8A24 0x8A25 0x8A26 0x8A27 0x8A28 0x8A29 0x8A2A 0x8A2B \ + 0x8A2C 0x8A2D 0x8A2E 0x8A2F 0x8A30 0x8A31 0x8A32 0x8A33 \ + 0x8A34 0x8A35 0x8A36 0x8A37 0x8A38 0x8A39 0x8A3A 0x8A3B \ + 0x8A3C 0x8A3D 0x8A3F 0x8A40 0x8A41 0x8A42 0x8A43 0x8A44 \ + 0x8A45 0x8A46 0x8A47 0x8A49 0x8A4A 0x8A4B 0x8A4C 0x8A4D \ + 0x8A4E 0x8A4F 0x8A50 0x8A51 0x8A52 0x8A53 0x8A54 0x8A55 \ + 0x8A56 0x8A57 0x8A58 0x8A59 0x8A5A 0x8A5B 0x8A5C 0x8A5D \ + 0x8A5E 0x8A5F 0x8A60 0x8A61 0x8A62 0x8A63 0x8A64 0x8A65 \ + 0x8A66 0x8A67 0x8A68 0x8A69 0x8A6A 0x8A6B 0x8A6C 0x8A6D \ + 0x8A6E 0x8A6F 0x8A70 0x8A71 0x8A72 0x8A73 0x8A74 0x8A75 \ + 0x8A76 0x8A77 0x8A78 0x8A7A 0x8A7B 0x8A7C 0x8A7D 0x8A7E \ + 0x8A7F 0x8A80 0x6D74 0x5BD3 0x88D5 0x9884 0x8C6B 0x9A6D +63 0x9E33 0x6E0A 0x51A4 0x5143 0x57A3 0x8881 0x539F 0x63F4 \ + 0x8F95 0x56ED 0x5458 0x5706 0x733F 0x6E90 0x7F18 0x8FDC \ + 0x82D1 0x613F 0x6028 0x9662 0x66F0 0x7EA6 0x8D8A 0x8DC3 \ + 0x94A5 0x5CB3 0x7CA4 0x6708 0x60A6 0x9605 0x8018 0x4E91 \ + 0x90E7 0x5300 0x9668 0x5141 0x8FD0 0x8574 0x915D 0x6655 \ + 0x97F5 0x5B55 0x531D 0x7838 0x6742 0x683D 0x54C9 0x707E \ + 0x5BB0 0x8F7D 0x518D 0x5728 0x54B1 0x6512 0x6682 0x8D5E \ + 0x8D43 0x810F 0x846C 0x906D 0x7CDF 0x51FF 0x85FB 0x67A3 \ + 0x65E9 0x6FA1 0x86A4 0x8E81 0x566A 0x9020 0x7682 0x7076 \ + 0x71E5 0x8D23 0x62E9 0x5219 0x6CFD 0x8D3C 0x600E 0x589E \ + 0x618E 0x66FE 0x8D60 0x624E 0x55B3 0x6E23 0x672D 0x8F67 \ + 0x8A81 0x8A82 0x8A83 0x8A84 0x8A85 0x8A86 0x8A87 0x8A88 \ + 0x8A8B 0x8A8C 0x8A8D 0x8A8E 0x8A8F 0x8A90 0x8A91 0x8A92 \ + 0x8A94 0x8A95 0x8A96 0x8A97 0x8A98 0x8A99 0x8A9A 0x8A9B \ + 0x8A9C 0x8A9D 0x8A9E 0x8A9F 0x8AA0 0x8AA1 0x8AA2 0x8AA3 \ + 0x8AA4 0x8AA5 0x8AA6 0x8AA7 0x8AA8 0x8AA9 0x8AAA 0x8AAB \ + 0x8AAC 0x8AAD 0x8AAE 0x8AAF 0x8AB0 0x8AB1 0x8AB2 0x8AB3 \ + 0x8AB4 0x8AB5 0x8AB6 0x8AB7 0x8AB8 0x8AB9 0x8ABA 0x8ABB \ + 0x8ABC 0x8ABD 0x8ABE 0x8ABF 0x8AC0 0x8AC1 0x8AC2 0x8AC3 \ + 0x8AC4 0x8AC5 0x8AC6 0x8AC7 0x8AC8 0x8AC9 0x8ACA 0x8ACB \ + 0x8ACC 0x8ACD 0x8ACE 0x8ACF 0x8AD0 0x8AD1 0x8AD2 0x8AD3 \ + 0x8AD4 0x8AD5 0x8AD6 0x8AD7 0x8AD8 0x8AD9 0x8ADA 0x8ADB \ + 0x8ADC 0x8ADD 0x8ADE 0x8ADF 0x8AE0 0x8AE1 0x8AE2 0x8AE3 \ + 0x94E1 0x95F8 0x7728 0x6805 0x69A8 0x548B 0x4E4D 0x70B8 \ + 0x8BC8 0x6458 0x658B 0x5B85 0x7A84 0x503A 0x5BE8 0x77BB \ + 0x6BE1 0x8A79 0x7C98 0x6CBE 0x76CF 0x65A9 0x8F97 0x5D2D \ + 0x5C55 0x8638 0x6808 0x5360 0x6218 0x7AD9 0x6E5B 0x7EFD \ + 0x6A1F 0x7AE0 0x5F70 0x6F33 0x5F20 0x638C 0x6DA8 0x6756 \ + 0x4E08 0x5E10 0x8D26 0x4ED7 0x80C0 0x7634 0x969C 0x62DB \ + 0x662D 0x627E 0x6CBC 0x8D75 0x7167 0x7F69 0x5146 0x8087 \ + 0x53EC 0x906E 0x6298 0x54F2 0x86F0 0x8F99 0x8005 0x9517 \ + 0x8517 0x8FD9 0x6D59 0x73CD 0x659F 0x771F 0x7504 0x7827 +64 0x81FB 0x8D1E 0x9488 0x4FA6 0x6795 0x75B9 0x8BCA 0x9707 \ + 0x632F 0x9547 0x9635 0x84B8 0x6323 0x7741 0x5F81 0x72F0 \ + 0x4E89 0x6014 0x6574 0x62EF 0x6B63 0x653F 0x8AE4 0x8AE5 \ + 0x8AE6 0x8AE7 0x8AE8 0x8AE9 0x8AEA 0x8AEB 0x8AEC 0x8AED \ + 0x8AEE 0x8AEF 0x8AF0 0x8AF1 0x8AF2 0x8AF3 0x8AF4 0x8AF5 \ + 0x8AF6 0x8AF7 0x8AF8 0x8AF9 0x8AFA 0x8AFB 0x8AFC 0x8AFD \ + 0x8AFE 0x8AFF 0x8B00 0x8B01 0x8B02 0x8B03 0x8B04 0x8B05 \ + 0x8B06 0x8B08 0x8B09 0x8B0A 0x8B0B 0x8B0C 0x8B0D 0x8B0E \ + 0x8B0F 0x8B10 0x8B11 0x8B12 0x8B13 0x8B14 0x8B15 0x8B16 \ + 0x8B17 0x8B18 0x8B19 0x8B1A 0x8B1B 0x8B1C 0x8B1D 0x8B1E \ + 0x8B1F 0x8B20 0x8B21 0x8B22 0x8B23 0x8B24 0x8B25 0x8B27 \ + 0x8B28 0x8B29 0x8B2A 0x8B2B 0x8B2C 0x8B2D 0x8B2E 0x8B2F \ + 0x8B30 0x8B31 0x8B32 0x8B33 0x8B34 0x8B35 0x8B36 0x8B37 \ + 0x8B38 0x8B39 0x8B3A 0x8B3B 0x8B3C 0x8B3D 0x8B3E 0x8B3F \ + 0x8B40 0x8B41 0x8B42 0x8B43 0x8B44 0x8B45 0x5E27 0x75C7 \ + 0x90D1 0x8BC1 0x829D 0x679D 0x652F 0x5431 0x8718 0x77E5 \ + 0x80A2 0x8102 0x6C41 0x4E4B 0x7EC7 0x804C 0x76F4 0x690D \ + 0x6B96 0x6267 0x503C 0x4F84 0x5740 0x6307 0x6B62 0x8DBE \ + 0x53EA 0x65E8 0x7EB8 0x5FD7 0x631A 0x63B7 0x81F3 0x81F4 \ + 0x7F6E 0x5E1C 0x5CD9 0x5236 0x667A 0x79E9 0x7A1A 0x8D28 \ + 0x7099 0x75D4 0x6EDE 0x6CBB 0x7A92 0x4E2D 0x76C5 0x5FE0 \ + 0x949F 0x8877 0x7EC8 0x79CD 0x80BF 0x91CD 0x4EF2 0x4F17 \ + 0x821F 0x5468 0x5DDE 0x6D32 0x8BCC 0x7CA5 0x8F74 0x8098 \ + 0x5E1A 0x5492 0x76B1 0x5B99 0x663C 0x9AA4 0x73E0 0x682A \ + 0x86DB 0x6731 0x732A 0x8BF8 0x8BDB 0x9010 0x7AF9 0x70DB \ + 0x716E 0x62C4 0x77A9 0x5631 0x4E3B 0x8457 0x67F1 0x52A9 \ + 0x86C0 0x8D2E 0x94F8 0x7B51 0x8B46 0x8B47 0x8B48 0x8B49 \ + 0x8B4A 0x8B4B 0x8B4C 0x8B4D 0x8B4E 0x8B4F 0x8B50 0x8B51 \ + 0x8B52 0x8B53 0x8B54 0x8B55 0x8B56 0x8B57 0x8B58 0x8B59 \ + 0x8B5A 0x8B5B 0x8B5C 0x8B5D 0x8B5E 0x8B5F 0x8B60 0x8B61 \ + 0x8B62 0x8B63 0x8B64 0x8B65 0x8B67 0x8B68 0x8B69 0x8B6A \ + 0x8B6B 0x8B6D 0x8B6E 0x8B6F 0x8B70 0x8B71 0x8B72 0x8B73 +65 0x8B74 0x8B75 0x8B76 0x8B77 0x8B78 0x8B79 0x8B7A 0x8B7B \ + 0x8B7C 0x8B7D 0x8B7E 0x8B7F 0x8B80 0x8B81 0x8B82 0x8B83 \ + 0x8B84 0x8B85 0x8B86 0x8B87 0x8B88 0x8B89 0x8B8A 0x8B8B \ + 0x8B8C 0x8B8D 0x8B8E 0x8B8F 0x8B90 0x8B91 0x8B92 0x8B93 \ + 0x8B94 0x8B95 0x8B96 0x8B97 0x8B98 0x8B99 0x8B9A 0x8B9B \ + 0x8B9C 0x8B9D 0x8B9E 0x8B9F 0x8BAC 0x8BB1 0x8BBB 0x8BC7 \ + 0x8BD0 0x8BEA 0x8C09 0x8C1E 0x4F4F 0x6CE8 0x795D 0x9A7B \ + 0x6293 0x722A 0x62FD 0x4E13 0x7816 0x8F6C 0x64B0 0x8D5A \ + 0x7BC6 0x6869 0x5E84 0x88C5 0x5986 0x649E 0x58EE 0x72B6 \ + 0x690E 0x9525 0x8FFD 0x8D58 0x5760 0x7F00 0x8C06 0x51C6 \ + 0x6349 0x62D9 0x5353 0x684C 0x7422 0x8301 0x914C 0x5544 \ + 0x7740 0x707C 0x6D4A 0x5179 0x54A8 0x8D44 0x59FF 0x6ECB \ + 0x6DC4 0x5B5C 0x7D2B 0x4ED4 0x7C7D 0x6ED3 0x5B50 0x81EA \ + 0x6E0D 0x5B57 0x9B03 0x68D5 0x8E2A 0x5B97 0x7EFC 0x603B \ + 0x7EB5 0x90B9 0x8D70 0x594F 0x63CD 0x79DF 0x8DB3 0x5352 \ + 0x65CF 0x7956 0x8BC5 0x963B 0x7EC4 0x94BB 0x7E82 0x5634 \ + 0x9189 0x6700 0x7F6A 0x5C0A 0x9075 0x6628 0x5DE6 0x4F50 \ + 0x67DE 0x505A 0x4F5C 0x5750 0x5EA7 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x8C38 0x8C39 0x8C3A 0x8C3B 0x8C3C 0x8C3D \ + 0x8C3E 0x8C3F 0x8C40 0x8C42 0x8C43 0x8C44 0x8C45 0x8C48 \ + 0x8C4A 0x8C4B 0x8C4D 0x8C4E 0x8C4F 0x8C50 0x8C51 0x8C52 \ + 0x8C53 0x8C54 0x8C56 0x8C57 0x8C58 0x8C59 0x8C5B 0x8C5C \ + 0x8C5D 0x8C5E 0x8C5F 0x8C60 0x8C63 0x8C64 0x8C65 0x8C66 \ + 0x8C67 0x8C68 0x8C69 0x8C6C 0x8C6D 0x8C6E 0x8C6F 0x8C70 \ + 0x8C71 0x8C72 0x8C74 0x8C75 0x8C76 0x8C77 0x8C7B 0x8C7C \ + 0x8C7D 0x8C7E 0x8C7F 0x8C80 0x8C81 0x8C83 0x8C84 0x8C86 \ + 0x8C87 0x8C88 0x8C8B 0x8C8D 0x8C8E 0x8C8F 0x8C90 0x8C91 \ + 0x8C92 0x8C93 0x8C95 0x8C96 0x8C97 0x8C99 0x8C9A 0x8C9B \ + 0x8C9C 0x8C9D 0x8C9E 0x8C9F 0x8CA0 0x8CA1 0x8CA2 0x8CA3 \ + 0x8CA4 0x8CA5 0x8CA6 0x8CA7 0x8CA8 0x8CA9 0x8CAA 0x8CAB \ + 0x8CAC 0x8CAD 0x4E8D 0x4E0C 0x5140 0x4E10 0x5EFF 0x5345 \ + 0x4E15 0x4E98 0x4E1E 0x9B32 0x5B6C 0x5669 0x4E28 0x79BA +66 0x4E3F 0x5315 0x4E47 0x592D 0x723B 0x536E 0x6C10 0x56DF \ + 0x80E4 0x9997 0x6BD3 0x777E 0x9F17 0x4E36 0x4E9F 0x9F10 \ + 0x4E5C 0x4E69 0x4E93 0x8288 0x5B5B 0x556C 0x560F 0x4EC4 \ + 0x538D 0x539D 0x53A3 0x53A5 0x53AE 0x9765 0x8D5D 0x531A \ + 0x53F5 0x5326 0x532E 0x533E 0x8D5C 0x5366 0x5363 0x5202 \ + 0x5208 0x520E 0x522D 0x5233 0x523F 0x5240 0x524C 0x525E \ + 0x5261 0x525C 0x84AF 0x527D 0x5282 0x5281 0x5290 0x5293 \ + 0x5182 0x7F54 0x4EBB 0x4EC3 0x4EC9 0x4EC2 0x4EE8 0x4EE1 \ + 0x4EEB 0x4EDE 0x4F1B 0x4EF3 0x4F22 0x4F64 0x4EF5 0x4F25 \ + 0x4F27 0x4F09 0x4F2B 0x4F5E 0x4F67 0x6538 0x4F5A 0x4F5D \ + 0x8CAE 0x8CAF 0x8CB0 0x8CB1 0x8CB2 0x8CB3 0x8CB4 0x8CB5 \ + 0x8CB6 0x8CB7 0x8CB8 0x8CB9 0x8CBA 0x8CBB 0x8CBC 0x8CBD \ + 0x8CBE 0x8CBF 0x8CC0 0x8CC1 0x8CC2 0x8CC3 0x8CC4 0x8CC5 \ + 0x8CC6 0x8CC7 0x8CC8 0x8CC9 0x8CCA 0x8CCB 0x8CCC 0x8CCD \ + 0x8CCE 0x8CCF 0x8CD0 0x8CD1 0x8CD2 0x8CD3 0x8CD4 0x8CD5 \ + 0x8CD6 0x8CD7 0x8CD8 0x8CD9 0x8CDA 0x8CDB 0x8CDC 0x8CDD \ + 0x8CDE 0x8CDF 0x8CE0 0x8CE1 0x8CE2 0x8CE3 0x8CE4 0x8CE5 \ + 0x8CE6 0x8CE7 0x8CE8 0x8CE9 0x8CEA 0x8CEB 0x8CEC 0x8CED \ + 0x8CEE 0x8CEF 0x8CF0 0x8CF1 0x8CF2 0x8CF3 0x8CF4 0x8CF5 \ + 0x8CF6 0x8CF7 0x8CF8 0x8CF9 0x8CFA 0x8CFB 0x8CFC 0x8CFD \ + 0x8CFE 0x8CFF 0x8D00 0x8D01 0x8D02 0x8D03 0x8D04 0x8D05 \ + 0x8D06 0x8D07 0x8D08 0x8D09 0x8D0A 0x8D0B 0x8D0C 0x8D0D \ + 0x4F5F 0x4F57 0x4F32 0x4F3D 0x4F76 0x4F74 0x4F91 0x4F89 \ + 0x4F83 0x4F8F 0x4F7E 0x4F7B 0x4FAA 0x4F7C 0x4FAC 0x4F94 \ + 0x4FE6 0x4FE8 0x4FEA 0x4FC5 0x4FDA 0x4FE3 0x4FDC 0x4FD1 \ + 0x4FDF 0x4FF8 0x5029 0x504C 0x4FF3 0x502C 0x500F 0x502E \ + 0x502D 0x4FFE 0x501C 0x500C 0x5025 0x5028 0x507E 0x5043 \ + 0x5055 0x5048 0x504E 0x506C 0x507B 0x50A5 0x50A7 0x50A9 \ + 0x50BA 0x50D6 0x5106 0x50ED 0x50EC 0x50E6 0x50EE 0x5107 \ + 0x510B 0x4EDD 0x6C3D 0x4F58 0x4F65 0x4FCE 0x9FA0 0x6C46 \ + 0x7C74 0x516E 0x5DFD 0x9EC9 0x9998 0x5181 0x5914 0x52F9 \ + 0x530D 0x8A07 0x5310 0x51EB 0x5919 0x5155 0x4EA0 0x5156 +67 0x4EB3 0x886E 0x88A4 0x4EB5 0x8114 0x88D2 0x7980 0x5B34 \ + 0x8803 0x7FB8 0x51AB 0x51B1 0x51BD 0x51BC 0x8D0E 0x8D0F \ + 0x8D10 0x8D11 0x8D12 0x8D13 0x8D14 0x8D15 0x8D16 0x8D17 \ + 0x8D18 0x8D19 0x8D1A 0x8D1B 0x8D1C 0x8D20 0x8D51 0x8D52 \ + 0x8D57 0x8D5F 0x8D65 0x8D68 0x8D69 0x8D6A 0x8D6C 0x8D6E \ + 0x8D6F 0x8D71 0x8D72 0x8D78 0x8D79 0x8D7A 0x8D7B 0x8D7C \ + 0x8D7D 0x8D7E 0x8D7F 0x8D80 0x8D82 0x8D83 0x8D86 0x8D87 \ + 0x8D88 0x8D89 0x8D8C 0x8D8D 0x8D8E 0x8D8F 0x8D90 0x8D92 \ + 0x8D93 0x8D95 0x8D96 0x8D97 0x8D98 0x8D99 0x8D9A 0x8D9B \ + 0x8D9C 0x8D9D 0x8D9E 0x8DA0 0x8DA1 0x8DA2 0x8DA4 0x8DA5 \ + 0x8DA6 0x8DA7 0x8DA8 0x8DA9 0x8DAA 0x8DAB 0x8DAC 0x8DAD \ + 0x8DAE 0x8DAF 0x8DB0 0x8DB2 0x8DB6 0x8DB7 0x8DB9 0x8DBB \ + 0x8DBD 0x8DC0 0x8DC1 0x8DC2 0x8DC5 0x8DC7 0x8DC8 0x8DC9 \ + 0x8DCA 0x8DCD 0x8DD0 0x8DD2 0x8DD3 0x8DD4 0x51C7 0x5196 \ + 0x51A2 0x51A5 0x8BA0 0x8BA6 0x8BA7 0x8BAA 0x8BB4 0x8BB5 \ + 0x8BB7 0x8BC2 0x8BC3 0x8BCB 0x8BCF 0x8BCE 0x8BD2 0x8BD3 \ + 0x8BD4 0x8BD6 0x8BD8 0x8BD9 0x8BDC 0x8BDF 0x8BE0 0x8BE4 \ + 0x8BE8 0x8BE9 0x8BEE 0x8BF0 0x8BF3 0x8BF6 0x8BF9 0x8BFC \ + 0x8BFF 0x8C00 0x8C02 0x8C04 0x8C07 0x8C0C 0x8C0F 0x8C11 \ + 0x8C12 0x8C14 0x8C15 0x8C16 0x8C19 0x8C1B 0x8C18 0x8C1D \ + 0x8C1F 0x8C20 0x8C21 0x8C25 0x8C27 0x8C2A 0x8C2B 0x8C2E \ + 0x8C2F 0x8C32 0x8C33 0x8C35 0x8C36 0x5369 0x537A 0x961D \ + 0x9622 0x9621 0x9631 0x962A 0x963D 0x963C 0x9642 0x9649 \ + 0x9654 0x965F 0x9667 0x966C 0x9672 0x9674 0x9688 0x968D \ + 0x9697 0x96B0 0x9097 0x909B 0x909D 0x9099 0x90AC 0x90A1 \ + 0x90B4 0x90B3 0x90B6 0x90BA 0x8DD5 0x8DD8 0x8DD9 0x8DDC \ + 0x8DE0 0x8DE1 0x8DE2 0x8DE5 0x8DE6 0x8DE7 0x8DE9 0x8DED \ + 0x8DEE 0x8DF0 0x8DF1 0x8DF2 0x8DF4 0x8DF6 0x8DFC 0x8DFE \ + 0x8DFF 0x8E00 0x8E01 0x8E02 0x8E03 0x8E04 0x8E06 0x8E07 \ + 0x8E08 0x8E0B 0x8E0D 0x8E0E 0x8E10 0x8E11 0x8E12 0x8E13 \ + 0x8E15 0x8E16 0x8E17 0x8E18 0x8E19 0x8E1A 0x8E1B 0x8E1C \ + 0x8E20 0x8E21 0x8E24 0x8E25 0x8E26 0x8E27 0x8E28 0x8E2B +68 0x8E2D 0x8E30 0x8E32 0x8E33 0x8E34 0x8E36 0x8E37 0x8E38 \ + 0x8E3B 0x8E3C 0x8E3E 0x8E3F 0x8E43 0x8E45 0x8E46 0x8E4C \ + 0x8E4D 0x8E4E 0x8E4F 0x8E50 0x8E53 0x8E54 0x8E55 0x8E56 \ + 0x8E57 0x8E58 0x8E5A 0x8E5B 0x8E5C 0x8E5D 0x8E5E 0x8E5F \ + 0x8E60 0x8E61 0x8E62 0x8E63 0x8E64 0x8E65 0x8E67 0x8E68 \ + 0x8E6A 0x8E6B 0x8E6E 0x8E71 0x90B8 0x90B0 0x90CF 0x90C5 \ + 0x90BE 0x90D0 0x90C4 0x90C7 0x90D3 0x90E6 0x90E2 0x90DC \ + 0x90D7 0x90DB 0x90EB 0x90EF 0x90FE 0x9104 0x9122 0x911E \ + 0x9123 0x9131 0x912F 0x9139 0x9143 0x9146 0x520D 0x5942 \ + 0x52A2 0x52AC 0x52AD 0x52BE 0x54FF 0x52D0 0x52D6 0x52F0 \ + 0x53DF 0x71EE 0x77CD 0x5EF4 0x51F5 0x51FC 0x9B2F 0x53B6 \ + 0x5F01 0x755A 0x5DEF 0x574C 0x57A9 0x57A1 0x587E 0x58BC \ + 0x58C5 0x58D1 0x5729 0x572C 0x572A 0x5733 0x5739 0x572E \ + 0x572F 0x575C 0x573B 0x5742 0x5769 0x5785 0x576B 0x5786 \ + 0x577C 0x577B 0x5768 0x576D 0x5776 0x5773 0x57AD 0x57A4 \ + 0x578C 0x57B2 0x57CF 0x57A7 0x57B4 0x5793 0x57A0 0x57D5 \ + 0x57D8 0x57DA 0x57D9 0x57D2 0x57B8 0x57F4 0x57EF 0x57F8 \ + 0x57E4 0x57DD 0x8E73 0x8E75 0x8E77 0x8E78 0x8E79 0x8E7A \ + 0x8E7B 0x8E7D 0x8E7E 0x8E80 0x8E82 0x8E83 0x8E84 0x8E86 \ + 0x8E88 0x8E89 0x8E8A 0x8E8B 0x8E8C 0x8E8D 0x8E8E 0x8E91 \ + 0x8E92 0x8E93 0x8E95 0x8E96 0x8E97 0x8E98 0x8E99 0x8E9A \ + 0x8E9B 0x8E9D 0x8E9F 0x8EA0 0x8EA1 0x8EA2 0x8EA3 0x8EA4 \ + 0x8EA5 0x8EA6 0x8EA7 0x8EA8 0x8EA9 0x8EAA 0x8EAD 0x8EAE \ + 0x8EB0 0x8EB1 0x8EB3 0x8EB4 0x8EB5 0x8EB6 0x8EB7 0x8EB8 \ + 0x8EB9 0x8EBB 0x8EBC 0x8EBD 0x8EBE 0x8EBF 0x8EC0 0x8EC1 \ + 0x8EC2 0x8EC3 0x8EC4 0x8EC5 0x8EC6 0x8EC7 0x8EC8 0x8EC9 \ + 0x8ECA 0x8ECB 0x8ECC 0x8ECD 0x8ECF 0x8ED0 0x8ED1 0x8ED2 \ + 0x8ED3 0x8ED4 0x8ED5 0x8ED6 0x8ED7 0x8ED8 0x8ED9 0x8EDA \ + 0x8EDB 0x8EDC 0x8EDD 0x8EDE 0x8EDF 0x8EE0 0x8EE1 0x8EE2 \ + 0x8EE3 0x8EE4 0x580B 0x580D 0x57FD 0x57ED 0x5800 0x581E \ + 0x5819 0x5844 0x5820 0x5865 0x586C 0x5881 0x5889 0x589A \ + 0x5880 0x99A8 0x9F19 0x61FF 0x8279 0x827D 0x827F 0x828F +69 0x828A 0x82A8 0x8284 0x828E 0x8291 0x8297 0x8299 0x82AB \ + 0x82B8 0x82BE 0x82B0 0x82C8 0x82CA 0x82E3 0x8298 0x82B7 \ + 0x82AE 0x82CB 0x82CC 0x82C1 0x82A9 0x82B4 0x82A1 0x82AA \ + 0x829F 0x82C4 0x82CE 0x82A4 0x82E1 0x8309 0x82F7 0x82E4 \ + 0x830F 0x8307 0x82DC 0x82F4 0x82D2 0x82D8 0x830C 0x82FB \ + 0x82D3 0x8311 0x831A 0x8306 0x8314 0x8315 0x82E0 0x82D5 \ + 0x831C 0x8351 0x835B 0x835C 0x8308 0x8392 0x833C 0x8334 \ + 0x8331 0x839B 0x835E 0x832F 0x834F 0x8347 0x8343 0x835F \ + 0x8340 0x8317 0x8360 0x832D 0x833A 0x8333 0x8366 0x8365 \ + 0x8EE5 0x8EE6 0x8EE7 0x8EE8 0x8EE9 0x8EEA 0x8EEB 0x8EEC \ + 0x8EED 0x8EEE 0x8EEF 0x8EF0 0x8EF1 0x8EF2 0x8EF3 0x8EF4 \ + 0x8EF5 0x8EF6 0x8EF7 0x8EF8 0x8EF9 0x8EFA 0x8EFB 0x8EFC \ + 0x8EFD 0x8EFE 0x8EFF 0x8F00 0x8F01 0x8F02 0x8F03 0x8F04 \ + 0x8F05 0x8F06 0x8F07 0x8F08 0x8F09 0x8F0A 0x8F0B 0x8F0C \ + 0x8F0D 0x8F0E 0x8F0F 0x8F10 0x8F11 0x8F12 0x8F13 0x8F14 \ + 0x8F15 0x8F16 0x8F17 0x8F18 0x8F19 0x8F1A 0x8F1B 0x8F1C \ + 0x8F1D 0x8F1E 0x8F1F 0x8F20 0x8F21 0x8F22 0x8F23 0x8F24 \ + 0x8F25 0x8F26 0x8F27 0x8F28 0x8F29 0x8F2A 0x8F2B 0x8F2C \ + 0x8F2D 0x8F2E 0x8F2F 0x8F30 0x8F31 0x8F32 0x8F33 0x8F34 \ + 0x8F35 0x8F36 0x8F37 0x8F38 0x8F39 0x8F3A 0x8F3B 0x8F3C \ + 0x8F3D 0x8F3E 0x8F3F 0x8F40 0x8F41 0x8F42 0x8F43 0x8F44 \ + 0x8368 0x831B 0x8369 0x836C 0x836A 0x836D 0x836E 0x83B0 \ + 0x8378 0x83B3 0x83B4 0x83A0 0x83AA 0x8393 0x839C 0x8385 \ + 0x837C 0x83B6 0x83A9 0x837D 0x83B8 0x837B 0x8398 0x839E \ + 0x83A8 0x83BA 0x83BC 0x83C1 0x8401 0x83E5 0x83D8 0x5807 \ + 0x8418 0x840B 0x83DD 0x83FD 0x83D6 0x841C 0x8438 0x8411 \ + 0x8406 0x83D4 0x83DF 0x840F 0x8403 0x83F8 0x83F9 0x83EA \ + 0x83C5 0x83C0 0x8426 0x83F0 0x83E1 0x845C 0x8451 0x845A \ + 0x8459 0x8473 0x8487 0x8488 0x847A 0x8489 0x8478 0x843C \ + 0x8446 0x8469 0x8476 0x848C 0x848E 0x8431 0x846D 0x84C1 \ + 0x84CD 0x84D0 0x84E6 0x84BD 0x84D3 0x84CA 0x84BF 0x84BA \ + 0x84E0 0x84A1 0x84B9 0x84B4 0x8497 0x84E5 0x84E3 0x850C +70 0x750D 0x8538 0x84F0 0x8539 0x851F 0x853A 0x8F45 0x8F46 \ + 0x8F47 0x8F48 0x8F49 0x8F4A 0x8F4B 0x8F4C 0x8F4D 0x8F4E \ + 0x8F4F 0x8F50 0x8F51 0x8F52 0x8F53 0x8F54 0x8F55 0x8F56 \ + 0x8F57 0x8F58 0x8F59 0x8F5A 0x8F5B 0x8F5C 0x8F5D 0x8F5E \ + 0x8F5F 0x8F60 0x8F61 0x8F62 0x8F63 0x8F64 0x8F65 0x8F6A \ + 0x8F80 0x8F8C 0x8F92 0x8F9D 0x8FA0 0x8FA1 0x8FA2 0x8FA4 \ + 0x8FA5 0x8FA6 0x8FA7 0x8FAA 0x8FAC 0x8FAD 0x8FAE 0x8FAF \ + 0x8FB2 0x8FB3 0x8FB4 0x8FB5 0x8FB7 0x8FB8 0x8FBA 0x8FBB \ + 0x8FBC 0x8FBF 0x8FC0 0x8FC3 0x8FC6 0x8FC9 0x8FCA 0x8FCB \ + 0x8FCC 0x8FCD 0x8FCF 0x8FD2 0x8FD6 0x8FD7 0x8FDA 0x8FE0 \ + 0x8FE1 0x8FE3 0x8FE7 0x8FEC 0x8FEF 0x8FF1 0x8FF2 0x8FF4 \ + 0x8FF5 0x8FF6 0x8FFA 0x8FFB 0x8FFC 0x8FFE 0x8FFF 0x9007 \ + 0x9008 0x900C 0x900E 0x9013 0x9015 0x9018 0x8556 0x853B \ + 0x84FF 0x84FC 0x8559 0x8548 0x8568 0x8564 0x855E 0x857A \ + 0x77A2 0x8543 0x8572 0x857B 0x85A4 0x85A8 0x8587 0x858F \ + 0x8579 0x85AE 0x859C 0x8585 0x85B9 0x85B7 0x85B0 0x85D3 \ + 0x85C1 0x85DC 0x85FF 0x8627 0x8605 0x8629 0x8616 0x863C \ + 0x5EFE 0x5F08 0x593C 0x5941 0x8037 0x5955 0x595A 0x5958 \ + 0x530F 0x5C22 0x5C25 0x5C2C 0x5C34 0x624C 0x626A 0x629F \ + 0x62BB 0x62CA 0x62DA 0x62D7 0x62EE 0x6322 0x62F6 0x6339 \ + 0x634B 0x6343 0x63AD 0x63F6 0x6371 0x637A 0x638E 0x63B4 \ + 0x636D 0x63AC 0x638A 0x6369 0x63AE 0x63BC 0x63F2 0x63F8 \ + 0x63E0 0x63FF 0x63C4 0x63DE 0x63CE 0x6452 0x63C6 0x63BE \ + 0x6445 0x6441 0x640B 0x641B 0x6420 0x640C 0x6426 0x6421 \ + 0x645E 0x6484 0x646D 0x6496 0x9019 0x901C 0x9023 0x9024 \ + 0x9025 0x9027 0x9028 0x9029 0x902A 0x902B 0x902C 0x9030 \ + 0x9031 0x9032 0x9033 0x9034 0x9037 0x9039 0x903A 0x903D \ + 0x903F 0x9040 0x9043 0x9045 0x9046 0x9048 0x9049 0x904A \ + 0x904B 0x904C 0x904E 0x9054 0x9055 0x9056 0x9059 0x905A \ + 0x905C 0x905D 0x905E 0x905F 0x9060 0x9061 0x9064 0x9066 \ + 0x9067 0x9069 0x906A 0x906B 0x906C 0x906F 0x9070 0x9071 \ + 0x9072 0x9073 0x9076 0x9077 0x9078 0x9079 0x907A 0x907B +71 0x907C 0x907E 0x9081 0x9084 0x9085 0x9086 0x9087 0x9089 \ + 0x908A 0x908C 0x908D 0x908E 0x908F 0x9090 0x9092 0x9094 \ + 0x9096 0x9098 0x909A 0x909C 0x909E 0x909F 0x90A0 0x90A4 \ + 0x90A5 0x90A7 0x90A8 0x90A9 0x90AB 0x90AD 0x90B2 0x90B7 \ + 0x90BC 0x90BD 0x90BF 0x90C0 0x647A 0x64B7 0x64B8 0x6499 \ + 0x64BA 0x64C0 0x64D0 0x64D7 0x64E4 0x64E2 0x6509 0x6525 \ + 0x652E 0x5F0B 0x5FD2 0x7519 0x5F11 0x535F 0x53F1 0x53FD \ + 0x53E9 0x53E8 0x53FB 0x5412 0x5416 0x5406 0x544B 0x5452 \ + 0x5453 0x5454 0x5456 0x5443 0x5421 0x5457 0x5459 0x5423 \ + 0x5432 0x5482 0x5494 0x5477 0x5471 0x5464 0x549A 0x549B \ + 0x5484 0x5476 0x5466 0x549D 0x54D0 0x54AD 0x54C2 0x54B4 \ + 0x54D2 0x54A7 0x54A6 0x54D3 0x54D4 0x5472 0x54A3 0x54D5 \ + 0x54BB 0x54BF 0x54CC 0x54D9 0x54DA 0x54DC 0x54A9 0x54AA \ + 0x54A4 0x54DD 0x54CF 0x54DE 0x551B 0x54E7 0x5520 0x54FD \ + 0x5514 0x54F3 0x5522 0x5523 0x550F 0x5511 0x5527 0x552A \ + 0x5567 0x558F 0x55B5 0x5549 0x556D 0x5541 0x5555 0x553F \ + 0x5550 0x553C 0x90C2 0x90C3 0x90C6 0x90C8 0x90C9 0x90CB \ + 0x90CC 0x90CD 0x90D2 0x90D4 0x90D5 0x90D6 0x90D8 0x90D9 \ + 0x90DA 0x90DE 0x90DF 0x90E0 0x90E3 0x90E4 0x90E5 0x90E9 \ + 0x90EA 0x90EC 0x90EE 0x90F0 0x90F1 0x90F2 0x90F3 0x90F5 \ + 0x90F6 0x90F7 0x90F9 0x90FA 0x90FB 0x90FC 0x90FF 0x9100 \ + 0x9101 0x9103 0x9105 0x9106 0x9107 0x9108 0x9109 0x910A \ + 0x910B 0x910C 0x910D 0x910E 0x910F 0x9110 0x9111 0x9112 \ + 0x9113 0x9114 0x9115 0x9116 0x9117 0x9118 0x911A 0x911B \ + 0x911C 0x911D 0x911F 0x9120 0x9121 0x9124 0x9125 0x9126 \ + 0x9127 0x9128 0x9129 0x912A 0x912B 0x912C 0x912D 0x912E \ + 0x9130 0x9132 0x9133 0x9134 0x9135 0x9136 0x9137 0x9138 \ + 0x913A 0x913B 0x913C 0x913D 0x913E 0x913F 0x9140 0x9141 \ + 0x9142 0x9144 0x5537 0x5556 0x5575 0x5576 0x5577 0x5533 \ + 0x5530 0x555C 0x558B 0x55D2 0x5583 0x55B1 0x55B9 0x5588 \ + 0x5581 0x559F 0x557E 0x55D6 0x5591 0x557B 0x55DF 0x55BD \ + 0x55BE 0x5594 0x5599 0x55EA 0x55F7 0x55C9 0x561F 0x55D1 +72 0x55EB 0x55EC 0x55D4 0x55E6 0x55DD 0x55C4 0x55EF 0x55E5 \ + 0x55F2 0x55F3 0x55CC 0x55CD 0x55E8 0x55F5 0x55E4 0x8F94 \ + 0x561E 0x5608 0x560C 0x5601 0x5624 0x5623 0x55FE 0x5600 \ + 0x5627 0x562D 0x5658 0x5639 0x5657 0x562C 0x564D 0x5662 \ + 0x5659 0x565C 0x564C 0x5654 0x5686 0x5664 0x5671 0x566B \ + 0x567B 0x567C 0x5685 0x5693 0x56AF 0x56D4 0x56D7 0x56DD \ + 0x56E1 0x56F5 0x56EB 0x56F9 0x56FF 0x5704 0x570A 0x5709 \ + 0x571C 0x5E0F 0x5E19 0x5E14 0x5E11 0x5E31 0x5E3B 0x5E3C \ + 0x9145 0x9147 0x9148 0x9151 0x9153 0x9154 0x9155 0x9156 \ + 0x9158 0x9159 0x915B 0x915C 0x915F 0x9160 0x9166 0x9167 \ + 0x9168 0x916B 0x916D 0x9173 0x917A 0x917B 0x917C 0x9180 \ + 0x9181 0x9182 0x9183 0x9184 0x9186 0x9188 0x918A 0x918E \ + 0x918F 0x9193 0x9194 0x9195 0x9196 0x9197 0x9198 0x9199 \ + 0x919C 0x919D 0x919E 0x919F 0x91A0 0x91A1 0x91A4 0x91A5 \ + 0x91A6 0x91A7 0x91A8 0x91A9 0x91AB 0x91AC 0x91B0 0x91B1 \ + 0x91B2 0x91B3 0x91B6 0x91B7 0x91B8 0x91B9 0x91BB 0x91BC \ + 0x91BD 0x91BE 0x91BF 0x91C0 0x91C1 0x91C2 0x91C3 0x91C4 \ + 0x91C5 0x91C6 0x91C8 0x91CB 0x91D0 0x91D2 0x91D3 0x91D4 \ + 0x91D5 0x91D6 0x91D7 0x91D8 0x91D9 0x91DA 0x91DB 0x91DD \ + 0x91DE 0x91DF 0x91E0 0x91E1 0x91E2 0x91E3 0x91E4 0x91E5 \ + 0x5E37 0x5E44 0x5E54 0x5E5B 0x5E5E 0x5E61 0x5C8C 0x5C7A \ + 0x5C8D 0x5C90 0x5C96 0x5C88 0x5C98 0x5C99 0x5C91 0x5C9A \ + 0x5C9C 0x5CB5 0x5CA2 0x5CBD 0x5CAC 0x5CAB 0x5CB1 0x5CA3 \ + 0x5CC1 0x5CB7 0x5CC4 0x5CD2 0x5CE4 0x5CCB 0x5CE5 0x5D02 \ + 0x5D03 0x5D27 0x5D26 0x5D2E 0x5D24 0x5D1E 0x5D06 0x5D1B \ + 0x5D58 0x5D3E 0x5D34 0x5D3D 0x5D6C 0x5D5B 0x5D6F 0x5D5D \ + 0x5D6B 0x5D4B 0x5D4A 0x5D69 0x5D74 0x5D82 0x5D99 0x5D9D \ + 0x8C73 0x5DB7 0x5DC5 0x5F73 0x5F77 0x5F82 0x5F87 0x5F89 \ + 0x5F8C 0x5F95 0x5F99 0x5F9C 0x5FA8 0x5FAD 0x5FB5 0x5FBC \ + 0x8862 0x5F61 0x72AD 0x72B0 0x72B4 0x72B7 0x72B8 0x72C3 \ + 0x72C1 0x72CE 0x72CD 0x72D2 0x72E8 0x72EF 0x72E9 0x72F2 \ + 0x72F4 0x72F7 0x7301 0x72F3 0x7303 0x72FA 0x91E6 0x91E7 +73 0x91E8 0x91E9 0x91EA 0x91EB 0x91EC 0x91ED 0x91EE 0x91EF \ + 0x91F0 0x91F1 0x91F2 0x91F3 0x91F4 0x91F5 0x91F6 0x91F7 \ + 0x91F8 0x91F9 0x91FA 0x91FB 0x91FC 0x91FD 0x91FE 0x91FF \ + 0x9200 0x9201 0x9202 0x9203 0x9204 0x9205 0x9206 0x9207 \ + 0x9208 0x9209 0x920A 0x920B 0x920C 0x920D 0x920E 0x920F \ + 0x9210 0x9211 0x9212 0x9213 0x9214 0x9215 0x9216 0x9217 \ + 0x9218 0x9219 0x921A 0x921B 0x921C 0x921D 0x921E 0x921F \ + 0x9220 0x9221 0x9222 0x9223 0x9224 0x9225 0x9226 0x9227 \ + 0x9228 0x9229 0x922A 0x922B 0x922C 0x922D 0x922E 0x922F \ + 0x9230 0x9231 0x9232 0x9233 0x9234 0x9235 0x9236 0x9237 \ + 0x9238 0x9239 0x923A 0x923B 0x923C 0x923D 0x923E 0x923F \ + 0x9240 0x9241 0x9242 0x9243 0x9244 0x9245 0x72FB 0x7317 \ + 0x7313 0x7321 0x730A 0x731E 0x731D 0x7315 0x7322 0x7339 \ + 0x7325 0x732C 0x7338 0x7331 0x7350 0x734D 0x7357 0x7360 \ + 0x736C 0x736F 0x737E 0x821B 0x5925 0x98E7 0x5924 0x5902 \ + 0x9963 0x9967 0x9968 0x9969 0x996A 0x996B 0x996C 0x9974 \ + 0x9977 0x997D 0x9980 0x9984 0x9987 0x998A 0x998D 0x9990 \ + 0x9991 0x9993 0x9994 0x9995 0x5E80 0x5E91 0x5E8B 0x5E96 \ + 0x5EA5 0x5EA0 0x5EB9 0x5EB5 0x5EBE 0x5EB3 0x8D53 0x5ED2 \ + 0x5ED1 0x5EDB 0x5EE8 0x5EEA 0x81BA 0x5FC4 0x5FC9 0x5FD6 \ + 0x5FCF 0x6003 0x5FEE 0x6004 0x5FE1 0x5FE4 0x5FFE 0x6005 \ + 0x6006 0x5FEA 0x5FED 0x5FF8 0x6019 0x6035 0x6026 0x601B \ + 0x600F 0x600D 0x6029 0x602B 0x600A 0x603F 0x6021 0x6078 \ + 0x6079 0x607B 0x607A 0x6042 0x9246 0x9247 0x9248 0x9249 \ + 0x924A 0x924B 0x924C 0x924D 0x924E 0x924F 0x9250 0x9251 \ + 0x9252 0x9253 0x9254 0x9255 0x9256 0x9257 0x9258 0x9259 \ + 0x925A 0x925B 0x925C 0x925D 0x925E 0x925F 0x9260 0x9261 \ + 0x9262 0x9263 0x9264 0x9265 0x9266 0x9267 0x9268 0x9269 \ + 0x926A 0x926B 0x926C 0x926D 0x926E 0x926F 0x9270 0x9271 \ + 0x9272 0x9273 0x9275 0x9276 0x9277 0x9278 0x9279 0x927A \ + 0x927B 0x927C 0x927D 0x927E 0x927F 0x9280 0x9281 0x9282 \ + 0x9283 0x9284 0x9285 0x9286 0x9287 0x9288 0x9289 0x928A +74 0x928B 0x928C 0x928D 0x928F 0x9290 0x9291 0x9292 0x9293 \ + 0x9294 0x9295 0x9296 0x9297 0x9298 0x9299 0x929A 0x929B \ + 0x929C 0x929D 0x929E 0x929F 0x92A0 0x92A1 0x92A2 0x92A3 \ + 0x92A4 0x92A5 0x92A6 0x92A7 0x606A 0x607D 0x6096 0x609A \ + 0x60AD 0x609D 0x6083 0x6092 0x608C 0x609B 0x60EC 0x60BB \ + 0x60B1 0x60DD 0x60D8 0x60C6 0x60DA 0x60B4 0x6120 0x6126 \ + 0x6115 0x6123 0x60F4 0x6100 0x610E 0x612B 0x614A 0x6175 \ + 0x61AC 0x6194 0x61A7 0x61B7 0x61D4 0x61F5 0x5FDD 0x96B3 \ + 0x95E9 0x95EB 0x95F1 0x95F3 0x95F5 0x95F6 0x95FC 0x95FE \ + 0x9603 0x9604 0x9606 0x9608 0x960A 0x960B 0x960C 0x960D \ + 0x960F 0x9612 0x9615 0x9616 0x9617 0x9619 0x961A 0x4E2C \ + 0x723F 0x6215 0x6C35 0x6C54 0x6C5C 0x6C4A 0x6CA3 0x6C85 \ + 0x6C90 0x6C94 0x6C8C 0x6C68 0x6C69 0x6C74 0x6C76 0x6C86 \ + 0x6CA9 0x6CD0 0x6CD4 0x6CAD 0x6CF7 0x6CF8 0x6CF1 0x6CD7 \ + 0x6CB2 0x6CE0 0x6CD6 0x6CFA 0x6CEB 0x6CEE 0x6CB1 0x6CD3 \ + 0x6CEF 0x6CFE 0x92A8 0x92A9 0x92AA 0x92AB 0x92AC 0x92AD \ + 0x92AF 0x92B0 0x92B1 0x92B2 0x92B3 0x92B4 0x92B5 0x92B6 \ + 0x92B7 0x92B8 0x92B9 0x92BA 0x92BB 0x92BC 0x92BD 0x92BE \ + 0x92BF 0x92C0 0x92C1 0x92C2 0x92C3 0x92C4 0x92C5 0x92C6 \ + 0x92C7 0x92C9 0x92CA 0x92CB 0x92CC 0x92CD 0x92CE 0x92CF \ + 0x92D0 0x92D1 0x92D2 0x92D3 0x92D4 0x92D5 0x92D6 0x92D7 \ + 0x92D8 0x92D9 0x92DA 0x92DB 0x92DC 0x92DD 0x92DE 0x92DF \ + 0x92E0 0x92E1 0x92E2 0x92E3 0x92E4 0x92E5 0x92E6 0x92E7 \ + 0x92E8 0x92E9 0x92EA 0x92EB 0x92EC 0x92ED 0x92EE 0x92EF \ + 0x92F0 0x92F1 0x92F2 0x92F3 0x92F4 0x92F5 0x92F6 0x92F7 \ + 0x92F8 0x92F9 0x92FA 0x92FB 0x92FC 0x92FD 0x92FE 0x92FF \ + 0x9300 0x9301 0x9302 0x9303 0x9304 0x9305 0x9306 0x9307 \ + 0x9308 0x9309 0x6D39 0x6D27 0x6D0C 0x6D43 0x6D48 0x6D07 \ + 0x6D04 0x6D19 0x6D0E 0x6D2B 0x6D4D 0x6D2E 0x6D35 0x6D1A \ + 0x6D4F 0x6D52 0x6D54 0x6D33 0x6D91 0x6D6F 0x6D9E 0x6DA0 \ + 0x6D5E 0x6D93 0x6D94 0x6D5C 0x6D60 0x6D7C 0x6D63 0x6E1A \ + 0x6DC7 0x6DC5 0x6DDE 0x6E0E 0x6DBF 0x6DE0 0x6E11 0x6DE6 +75 0x6DDD 0x6DD9 0x6E16 0x6DAB 0x6E0C 0x6DAE 0x6E2B 0x6E6E \ + 0x6E4E 0x6E6B 0x6EB2 0x6E5F 0x6E86 0x6E53 0x6E54 0x6E32 \ + 0x6E25 0x6E44 0x6EDF 0x6EB1 0x6E98 0x6EE0 0x6F2D 0x6EE2 \ + 0x6EA5 0x6EA7 0x6EBD 0x6EBB 0x6EB7 0x6ED7 0x6EB4 0x6ECF \ + 0x6E8F 0x6EC2 0x6E9F 0x6F62 0x6F46 0x6F47 0x6F24 0x6F15 \ + 0x6EF9 0x6F2F 0x6F36 0x6F4B 0x6F74 0x6F2A 0x6F09 0x6F29 \ + 0x6F89 0x6F8D 0x6F8C 0x6F78 0x6F72 0x6F7C 0x6F7A 0x6FD1 \ + 0x930A 0x930B 0x930C 0x930D 0x930E 0x930F 0x9310 0x9311 \ + 0x9312 0x9313 0x9314 0x9315 0x9316 0x9317 0x9318 0x9319 \ + 0x931A 0x931B 0x931C 0x931D 0x931E 0x931F 0x9320 0x9321 \ + 0x9322 0x9323 0x9324 0x9325 0x9326 0x9327 0x9328 0x9329 \ + 0x932A 0x932B 0x932C 0x932D 0x932E 0x932F 0x9330 0x9331 \ + 0x9332 0x9333 0x9334 0x9335 0x9336 0x9337 0x9338 0x9339 \ + 0x933A 0x933B 0x933C 0x933D 0x933F 0x9340 0x9341 0x9342 \ + 0x9343 0x9344 0x9345 0x9346 0x9347 0x9348 0x9349 0x934A \ + 0x934B 0x934C 0x934D 0x934E 0x934F 0x9350 0x9351 0x9352 \ + 0x9353 0x9354 0x9355 0x9356 0x9357 0x9358 0x9359 0x935A \ + 0x935B 0x935C 0x935D 0x935E 0x935F 0x9360 0x9361 0x9362 \ + 0x9363 0x9364 0x9365 0x9366 0x9367 0x9368 0x9369 0x936B \ + 0x6FC9 0x6FA7 0x6FB9 0x6FB6 0x6FC2 0x6FE1 0x6FEE 0x6FDE \ + 0x6FE0 0x6FEF 0x701A 0x7023 0x701B 0x7039 0x7035 0x704F \ + 0x705E 0x5B80 0x5B84 0x5B95 0x5B93 0x5BA5 0x5BB8 0x752F \ + 0x9A9E 0x6434 0x5BE4 0x5BEE 0x8930 0x5BF0 0x8E47 0x8B07 \ + 0x8FB6 0x8FD3 0x8FD5 0x8FE5 0x8FEE 0x8FE4 0x8FE9 0x8FE6 \ + 0x8FF3 0x8FE8 0x9005 0x9004 0x900B 0x9026 0x9011 0x900D \ + 0x9016 0x9021 0x9035 0x9036 0x902D 0x902F 0x9044 0x9051 \ + 0x9052 0x9050 0x9068 0x9058 0x9062 0x905B 0x66B9 0x9074 \ + 0x907D 0x9082 0x9088 0x9083 0x908B 0x5F50 0x5F57 0x5F56 \ + 0x5F58 0x5C3B 0x54AB 0x5C50 0x5C59 0x5B71 0x5C63 0x5C66 \ + 0x7FBC 0x5F2A 0x5F29 0x5F2D 0x8274 0x5F3C 0x9B3B 0x5C6E \ + 0x5981 0x5983 0x598D 0x59A9 0x59AA 0x59A3 0x936C 0x936D \ + 0x936E 0x936F 0x9370 0x9371 0x9372 0x9373 0x9374 0x9375 +76 0x9376 0x9377 0x9378 0x9379 0x937A 0x937B 0x937C 0x937D \ + 0x937E 0x937F 0x9380 0x9381 0x9382 0x9383 0x9384 0x9385 \ + 0x9386 0x9387 0x9388 0x9389 0x938A 0x938B 0x938C 0x938D \ + 0x938E 0x9390 0x9391 0x9392 0x9393 0x9394 0x9395 0x9396 \ + 0x9397 0x9398 0x9399 0x939A 0x939B 0x939C 0x939D 0x939E \ + 0x939F 0x93A0 0x93A1 0x93A2 0x93A3 0x93A4 0x93A5 0x93A6 \ + 0x93A7 0x93A8 0x93A9 0x93AA 0x93AB 0x93AC 0x93AD 0x93AE \ + 0x93AF 0x93B0 0x93B1 0x93B2 0x93B3 0x93B4 0x93B5 0x93B6 \ + 0x93B7 0x93B8 0x93B9 0x93BA 0x93BB 0x93BC 0x93BD 0x93BE \ + 0x93BF 0x93C0 0x93C1 0x93C2 0x93C3 0x93C4 0x93C5 0x93C6 \ + 0x93C7 0x93C8 0x93C9 0x93CB 0x93CC 0x93CD 0x5997 0x59CA \ + 0x59AB 0x599E 0x59A4 0x59D2 0x59B2 0x59AF 0x59D7 0x59BE \ + 0x5A05 0x5A06 0x59DD 0x5A08 0x59E3 0x59D8 0x59F9 0x5A0C \ + 0x5A09 0x5A32 0x5A34 0x5A11 0x5A23 0x5A13 0x5A40 0x5A67 \ + 0x5A4A 0x5A55 0x5A3C 0x5A62 0x5A75 0x80EC 0x5AAA 0x5A9B \ + 0x5A77 0x5A7A 0x5ABE 0x5AEB 0x5AB2 0x5AD2 0x5AD4 0x5AB8 \ + 0x5AE0 0x5AE3 0x5AF1 0x5AD6 0x5AE6 0x5AD8 0x5ADC 0x5B09 \ + 0x5B17 0x5B16 0x5B32 0x5B37 0x5B40 0x5C15 0x5C1C 0x5B5A \ + 0x5B65 0x5B73 0x5B51 0x5B53 0x5B62 0x9A75 0x9A77 0x9A78 \ + 0x9A7A 0x9A7F 0x9A7D 0x9A80 0x9A81 0x9A85 0x9A88 0x9A8A \ + 0x9A90 0x9A92 0x9A93 0x9A96 0x9A98 0x9A9B 0x9A9C 0x9A9D \ + 0x9A9F 0x9AA0 0x9AA2 0x9AA3 0x9AA5 0x9AA7 0x7E9F 0x7EA1 \ + 0x7EA3 0x7EA5 0x7EA8 0x7EA9 0x93CE 0x93CF 0x93D0 0x93D1 \ + 0x93D2 0x93D3 0x93D4 0x93D5 0x93D7 0x93D8 0x93D9 0x93DA \ + 0x93DB 0x93DC 0x93DD 0x93DE 0x93DF 0x93E0 0x93E1 0x93E2 \ + 0x93E3 0x93E4 0x93E5 0x93E6 0x93E7 0x93E8 0x93E9 0x93EA \ + 0x93EB 0x93EC 0x93ED 0x93EE 0x93EF 0x93F0 0x93F1 0x93F2 \ + 0x93F3 0x93F4 0x93F5 0x93F6 0x93F7 0x93F8 0x93F9 0x93FA \ + 0x93FB 0x93FC 0x93FD 0x93FE 0x93FF 0x9400 0x9401 0x9402 \ + 0x9403 0x9404 0x9405 0x9406 0x9407 0x9408 0x9409 0x940A \ + 0x940B 0x940C 0x940D 0x940E 0x940F 0x9410 0x9411 0x9412 \ + 0x9413 0x9414 0x9415 0x9416 0x9417 0x9418 0x9419 0x941A +77 0x941B 0x941C 0x941D 0x941E 0x941F 0x9420 0x9421 0x9422 \ + 0x9423 0x9424 0x9425 0x9426 0x9427 0x9428 0x9429 0x942A \ + 0x942B 0x942C 0x942D 0x942E 0x7EAD 0x7EB0 0x7EBE 0x7EC0 \ + 0x7EC1 0x7EC2 0x7EC9 0x7ECB 0x7ECC 0x7ED0 0x7ED4 0x7ED7 \ + 0x7EDB 0x7EE0 0x7EE1 0x7EE8 0x7EEB 0x7EEE 0x7EEF 0x7EF1 \ + 0x7EF2 0x7F0D 0x7EF6 0x7EFA 0x7EFB 0x7EFE 0x7F01 0x7F02 \ + 0x7F03 0x7F07 0x7F08 0x7F0B 0x7F0C 0x7F0F 0x7F11 0x7F12 \ + 0x7F17 0x7F19 0x7F1C 0x7F1B 0x7F1F 0x7F21 0x7F22 0x7F23 \ + 0x7F24 0x7F25 0x7F26 0x7F27 0x7F2A 0x7F2B 0x7F2C 0x7F2D \ + 0x7F2F 0x7F30 0x7F31 0x7F32 0x7F33 0x7F35 0x5E7A 0x757F \ + 0x5DDB 0x753E 0x9095 0x738E 0x7391 0x73AE 0x73A2 0x739F \ + 0x73CF 0x73C2 0x73D1 0x73B7 0x73B3 0x73C0 0x73C9 0x73C8 \ + 0x73E5 0x73D9 0x987C 0x740A 0x73E9 0x73E7 0x73DE 0x73BA \ + 0x73F2 0x740F 0x742A 0x745B 0x7426 0x7425 0x7428 0x7430 \ + 0x742E 0x742C 0x942F 0x9430 0x9431 0x9432 0x9433 0x9434 \ + 0x9435 0x9436 0x9437 0x9438 0x9439 0x943A 0x943B 0x943C \ + 0x943D 0x943F 0x9440 0x9441 0x9442 0x9443 0x9444 0x9445 \ + 0x9446 0x9447 0x9448 0x9449 0x944A 0x944B 0x944C 0x944D \ + 0x944E 0x944F 0x9450 0x9451 0x9452 0x9453 0x9454 0x9455 \ + 0x9456 0x9457 0x9458 0x9459 0x945A 0x945B 0x945C 0x945D \ + 0x945E 0x945F 0x9460 0x9461 0x9462 0x9463 0x9464 0x9465 \ + 0x9466 0x9467 0x9468 0x9469 0x946A 0x946C 0x946D 0x946E \ + 0x946F 0x9470 0x9471 0x9472 0x9473 0x9474 0x9475 0x9476 \ + 0x9477 0x9478 0x9479 0x947A 0x947B 0x947C 0x947D 0x947E \ + 0x947F 0x9480 0x9481 0x9482 0x9483 0x9484 0x9491 0x9496 \ + 0x9498 0x94C7 0x94CF 0x94D3 0x94D4 0x94DA 0x94E6 0x94FB \ + 0x951C 0x9520 0x741B 0x741A 0x7441 0x745C 0x7457 0x7455 \ + 0x7459 0x7477 0x746D 0x747E 0x749C 0x748E 0x7480 0x7481 \ + 0x7487 0x748B 0x749E 0x74A8 0x74A9 0x7490 0x74A7 0x74D2 \ + 0x74BA 0x97EA 0x97EB 0x97EC 0x674C 0x6753 0x675E 0x6748 \ + 0x6769 0x67A5 0x6787 0x676A 0x6773 0x6798 0x67A7 0x6775 \ + 0x67A8 0x679E 0x67AD 0x678B 0x6777 0x677C 0x67F0 0x6809 +78 0x67D8 0x680A 0x67E9 0x67B0 0x680C 0x67D9 0x67B5 0x67DA \ + 0x67B3 0x67DD 0x6800 0x67C3 0x67B8 0x67E2 0x680E 0x67C1 \ + 0x67FD 0x6832 0x6833 0x6860 0x6861 0x684E 0x6862 0x6844 \ + 0x6864 0x6883 0x681D 0x6855 0x6866 0x6841 0x6867 0x6840 \ + 0x683E 0x684A 0x6849 0x6829 0x68B5 0x688F 0x6874 0x6877 \ + 0x6893 0x686B 0x68C2 0x696E 0x68FC 0x691F 0x6920 0x68F9 \ + 0x9527 0x9533 0x953D 0x9543 0x9548 0x954B 0x9555 0x955A \ + 0x9560 0x956E 0x9574 0x9575 0x9577 0x9578 0x9579 0x957A \ + 0x957B 0x957C 0x957D 0x957E 0x9580 0x9581 0x9582 0x9583 \ + 0x9584 0x9585 0x9586 0x9587 0x9588 0x9589 0x958A 0x958B \ + 0x958C 0x958D 0x958E 0x958F 0x9590 0x9591 0x9592 0x9593 \ + 0x9594 0x9595 0x9596 0x9597 0x9598 0x9599 0x959A 0x959B \ + 0x959C 0x959D 0x959E 0x959F 0x95A0 0x95A1 0x95A2 0x95A3 \ + 0x95A4 0x95A5 0x95A6 0x95A7 0x95A8 0x95A9 0x95AA 0x95AB \ + 0x95AC 0x95AD 0x95AE 0x95AF 0x95B0 0x95B1 0x95B2 0x95B3 \ + 0x95B4 0x95B5 0x95B6 0x95B7 0x95B8 0x95B9 0x95BA 0x95BB \ + 0x95BC 0x95BD 0x95BE 0x95BF 0x95C0 0x95C1 0x95C2 0x95C3 \ + 0x95C4 0x95C5 0x95C6 0x95C7 0x95C8 0x95C9 0x95CA 0x95CB \ + 0x6924 0x68F0 0x690B 0x6901 0x6957 0x68E3 0x6910 0x6971 \ + 0x6939 0x6960 0x6942 0x695D 0x6984 0x696B 0x6980 0x6998 \ + 0x6978 0x6934 0x69CC 0x6987 0x6988 0x69CE 0x6989 0x6966 \ + 0x6963 0x6979 0x699B 0x69A7 0x69BB 0x69AB 0x69AD 0x69D4 \ + 0x69B1 0x69C1 0x69CA 0x69DF 0x6995 0x69E0 0x698D 0x69FF \ + 0x6A2F 0x69ED 0x6A17 0x6A18 0x6A65 0x69F2 0x6A44 0x6A3E \ + 0x6AA0 0x6A50 0x6A5B 0x6A35 0x6A8E 0x6A79 0x6A3D 0x6A28 \ + 0x6A58 0x6A7C 0x6A91 0x6A90 0x6AA9 0x6A97 0x6AAB 0x7337 \ + 0x7352 0x6B81 0x6B82 0x6B87 0x6B84 0x6B92 0x6B93 0x6B8D \ + 0x6B9A 0x6B9B 0x6BA1 0x6BAA 0x8F6B 0x8F6D 0x8F71 0x8F72 \ + 0x8F73 0x8F75 0x8F76 0x8F78 0x8F77 0x8F79 0x8F7A 0x8F7C \ + 0x8F7E 0x8F81 0x8F82 0x8F84 0x8F87 0x8F8B 0x95CC 0x95CD \ + 0x95CE 0x95CF 0x95D0 0x95D1 0x95D2 0x95D3 0x95D4 0x95D5 \ + 0x95D6 0x95D7 0x95D8 0x95D9 0x95DA 0x95DB 0x95DC 0x95DD +79 0x95DE 0x95DF 0x95E0 0x95E1 0x95E2 0x95E3 0x95E4 0x95E5 \ + 0x95E6 0x95E7 0x95EC 0x95FF 0x9607 0x9613 0x9618 0x961B \ + 0x961E 0x9620 0x9623 0x9624 0x9625 0x9626 0x9627 0x9628 \ + 0x9629 0x962B 0x962C 0x962D 0x962F 0x9630 0x9637 0x9638 \ + 0x9639 0x963A 0x963E 0x9641 0x9643 0x964A 0x964E 0x964F \ + 0x9651 0x9652 0x9653 0x9656 0x9657 0x9658 0x9659 0x965A \ + 0x965C 0x965D 0x965E 0x9660 0x9663 0x9665 0x9666 0x966B \ + 0x966D 0x966E 0x966F 0x9670 0x9671 0x9673 0x9678 0x9679 \ + 0x967A 0x967B 0x967C 0x967D 0x967E 0x967F 0x9680 0x9681 \ + 0x9682 0x9683 0x9684 0x9687 0x9689 0x968A 0x8F8D 0x8F8E \ + 0x8F8F 0x8F98 0x8F9A 0x8ECE 0x620B 0x6217 0x621B 0x621F \ + 0x6222 0x6221 0x6225 0x6224 0x622C 0x81E7 0x74EF 0x74F4 \ + 0x74FF 0x750F 0x7511 0x7513 0x6534 0x65EE 0x65EF 0x65F0 \ + 0x660A 0x6619 0x6772 0x6603 0x6615 0x6600 0x7085 0x66F7 \ + 0x661D 0x6634 0x6631 0x6636 0x6635 0x8006 0x665F 0x6654 \ + 0x6641 0x664F 0x6656 0x6661 0x6657 0x6677 0x6684 0x668C \ + 0x66A7 0x669D 0x66BE 0x66DB 0x66DC 0x66E6 0x66E9 0x8D32 \ + 0x8D33 0x8D36 0x8D3B 0x8D3D 0x8D40 0x8D45 0x8D46 0x8D48 \ + 0x8D49 0x8D47 0x8D4D 0x8D55 0x8D59 0x89C7 0x89CA 0x89CB \ + 0x89CC 0x89CE 0x89CF 0x89D0 0x89D1 0x726E 0x729F 0x725D \ + 0x7266 0x726F 0x727E 0x727F 0x7284 0x728B 0x728D 0x728F \ + 0x7292 0x6308 0x6332 0x63B0 0x968C 0x968E 0x9691 0x9692 \ + 0x9693 0x9695 0x9696 0x969A 0x969B 0x969D 0x969E 0x969F \ + 0x96A0 0x96A1 0x96A2 0x96A3 0x96A4 0x96A5 0x96A6 0x96A8 \ + 0x96A9 0x96AA 0x96AB 0x96AC 0x96AD 0x96AE 0x96AF 0x96B1 \ + 0x96B2 0x96B4 0x96B5 0x96B7 0x96B8 0x96BA 0x96BB 0x96BF \ + 0x96C2 0x96C3 0x96C8 0x96CA 0x96CB 0x96D0 0x96D1 0x96D3 \ + 0x96D4 0x96D6 0x96D7 0x96D8 0x96D9 0x96DA 0x96DB 0x96DC \ + 0x96DD 0x96DE 0x96DF 0x96E1 0x96E2 0x96E3 0x96E4 0x96E5 \ + 0x96E6 0x96E7 0x96EB 0x96EC 0x96ED 0x96EE 0x96F0 0x96F1 \ + 0x96F2 0x96F4 0x96F5 0x96F8 0x96FA 0x96FB 0x96FC 0x96FD \ + 0x96FF 0x9702 0x9703 0x9705 0x970A 0x970B 0x970C 0x9710 +80 0x9711 0x9712 0x9714 0x9715 0x9717 0x9718 0x9719 0x971A \ + 0x971B 0x971D 0x971F 0x9720 0x643F 0x64D8 0x8004 0x6BEA \ + 0x6BF3 0x6BFD 0x6BF5 0x6BF9 0x6C05 0x6C07 0x6C06 0x6C0D \ + 0x6C15 0x6C18 0x6C19 0x6C1A 0x6C21 0x6C29 0x6C24 0x6C2A \ + 0x6C32 0x6535 0x6555 0x656B 0x724D 0x7252 0x7256 0x7230 \ + 0x8662 0x5216 0x809F 0x809C 0x8093 0x80BC 0x670A 0x80BD \ + 0x80B1 0x80AB 0x80AD 0x80B4 0x80B7 0x80E7 0x80E8 0x80E9 \ + 0x80EA 0x80DB 0x80C2 0x80C4 0x80D9 0x80CD 0x80D7 0x6710 \ + 0x80DD 0x80EB 0x80F1 0x80F4 0x80ED 0x810D 0x810E 0x80F2 \ + 0x80FC 0x6715 0x8112 0x8C5A 0x8136 0x811E 0x812C 0x8118 \ + 0x8132 0x8148 0x814C 0x8153 0x8174 0x8159 0x815A 0x8171 \ + 0x8160 0x8169 0x817C 0x817D 0x816D 0x8167 0x584D 0x5AB5 \ + 0x8188 0x8182 0x8191 0x6ED5 0x81A3 0x81AA 0x81CC 0x6726 \ + 0x81CA 0x81BB 0x9721 0x9722 0x9723 0x9724 0x9725 0x9726 \ + 0x9727 0x9728 0x9729 0x972B 0x972C 0x972E 0x972F 0x9731 \ + 0x9733 0x9734 0x9735 0x9736 0x9737 0x973A 0x973B 0x973C \ + 0x973D 0x973F 0x9740 0x9741 0x9742 0x9743 0x9744 0x9745 \ + 0x9746 0x9747 0x9748 0x9749 0x974A 0x974B 0x974C 0x974D \ + 0x974E 0x974F 0x9750 0x9751 0x9754 0x9755 0x9757 0x9758 \ + 0x975A 0x975C 0x975D 0x975F 0x9763 0x9764 0x9766 0x9767 \ + 0x9768 0x976A 0x976B 0x976C 0x976D 0x976E 0x976F 0x9770 \ + 0x9771 0x9772 0x9775 0x9777 0x9778 0x9779 0x977A 0x977B \ + 0x977D 0x977E 0x977F 0x9780 0x9781 0x9782 0x9783 0x9784 \ + 0x9786 0x9787 0x9788 0x9789 0x978A 0x978C 0x978E 0x978F \ + 0x9790 0x9793 0x9795 0x9796 0x9797 0x9799 0x979A 0x979B \ + 0x979C 0x979D 0x81C1 0x81A6 0x6B24 0x6B37 0x6B39 0x6B43 \ + 0x6B46 0x6B59 0x98D1 0x98D2 0x98D3 0x98D5 0x98D9 0x98DA \ + 0x6BB3 0x5F40 0x6BC2 0x89F3 0x6590 0x9F51 0x6593 0x65BC \ + 0x65C6 0x65C4 0x65C3 0x65CC 0x65CE 0x65D2 0x65D6 0x7080 \ + 0x709C 0x7096 0x709D 0x70BB 0x70C0 0x70B7 0x70AB 0x70B1 \ + 0x70E8 0x70CA 0x7110 0x7113 0x7116 0x712F 0x7131 0x7173 \ + 0x715C 0x7168 0x7145 0x7172 0x714A 0x7178 0x717A 0x7198 +81 0x71B3 0x71B5 0x71A8 0x71A0 0x71E0 0x71D4 0x71E7 0x71F9 \ + 0x721D 0x7228 0x706C 0x7118 0x7166 0x71B9 0x623E 0x623D \ + 0x6243 0x6248 0x6249 0x793B 0x7940 0x7946 0x7949 0x795B \ + 0x795C 0x7953 0x795A 0x7962 0x7957 0x7960 0x796F 0x7967 \ + 0x797A 0x7985 0x798A 0x799A 0x79A7 0x79B3 0x5FD1 0x5FD0 \ + 0x979E 0x979F 0x97A1 0x97A2 0x97A4 0x97A5 0x97A6 0x97A7 \ + 0x97A8 0x97A9 0x97AA 0x97AC 0x97AE 0x97B0 0x97B1 0x97B3 \ + 0x97B5 0x97B6 0x97B7 0x97B8 0x97B9 0x97BA 0x97BB 0x97BC \ + 0x97BD 0x97BE 0x97BF 0x97C0 0x97C1 0x97C2 0x97C3 0x97C4 \ + 0x97C5 0x97C6 0x97C7 0x97C8 0x97C9 0x97CA 0x97CB 0x97CC \ + 0x97CD 0x97CE 0x97CF 0x97D0 0x97D1 0x97D2 0x97D3 0x97D4 \ + 0x97D5 0x97D6 0x97D7 0x97D8 0x97D9 0x97DA 0x97DB 0x97DC \ + 0x97DD 0x97DE 0x97DF 0x97E0 0x97E1 0x97E2 0x97E3 0x97E4 \ + 0x97E5 0x97E8 0x97EE 0x97EF 0x97F0 0x97F1 0x97F2 0x97F4 \ + 0x97F7 0x97F8 0x97F9 0x97FA 0x97FB 0x97FC 0x97FD 0x97FE \ + 0x97FF 0x9800 0x9801 0x9802 0x9803 0x9804 0x9805 0x9806 \ + 0x9807 0x9808 0x9809 0x980A 0x980B 0x980C 0x980D 0x980E \ + 0x603C 0x605D 0x605A 0x6067 0x6041 0x6059 0x6063 0x60AB \ + 0x6106 0x610D 0x615D 0x61A9 0x619D 0x61CB 0x61D1 0x6206 \ + 0x8080 0x807F 0x6C93 0x6CF6 0x6DFC 0x77F6 0x77F8 0x7800 \ + 0x7809 0x7817 0x7818 0x7811 0x65AB 0x782D 0x781C 0x781D \ + 0x7839 0x783A 0x783B 0x781F 0x783C 0x7825 0x782C 0x7823 \ + 0x7829 0x784E 0x786D 0x7856 0x7857 0x7826 0x7850 0x7847 \ + 0x784C 0x786A 0x789B 0x7893 0x789A 0x7887 0x789C 0x78A1 \ + 0x78A3 0x78B2 0x78B9 0x78A5 0x78D4 0x78D9 0x78C9 0x78EC \ + 0x78F2 0x7905 0x78F4 0x7913 0x7924 0x791E 0x7934 0x9F9B \ + 0x9EF9 0x9EFB 0x9EFC 0x76F1 0x7704 0x770D 0x76F9 0x7707 \ + 0x7708 0x771A 0x7722 0x7719 0x772D 0x7726 0x7735 0x7738 \ + 0x7750 0x7751 0x7747 0x7743 0x775A 0x7768 0x980F 0x9810 \ + 0x9811 0x9812 0x9813 0x9814 0x9815 0x9816 0x9817 0x9818 \ + 0x9819 0x981A 0x981B 0x981C 0x981D 0x981E 0x981F 0x9820 \ + 0x9821 0x9822 0x9823 0x9824 0x9825 0x9826 0x9827 0x9828 +82 0x9829 0x982A 0x982B 0x982C 0x982D 0x982E 0x982F 0x9830 \ + 0x9831 0x9832 0x9833 0x9834 0x9835 0x9836 0x9837 0x9838 \ + 0x9839 0x983A 0x983B 0x983C 0x983D 0x983E 0x983F 0x9840 \ + 0x9841 0x9842 0x9843 0x9844 0x9845 0x9846 0x9847 0x9848 \ + 0x9849 0x984A 0x984B 0x984C 0x984D 0x984E 0x984F 0x9850 \ + 0x9851 0x9852 0x9853 0x9854 0x9855 0x9856 0x9857 0x9858 \ + 0x9859 0x985A 0x985B 0x985C 0x985D 0x985E 0x985F 0x9860 \ + 0x9861 0x9862 0x9863 0x9864 0x9865 0x9866 0x9867 0x9868 \ + 0x9869 0x986A 0x986B 0x986C 0x986D 0x986E 0x7762 0x7765 \ + 0x777F 0x778D 0x777D 0x7780 0x778C 0x7791 0x779F 0x77A0 \ + 0x77B0 0x77B5 0x77BD 0x753A 0x7540 0x754E 0x754B 0x7548 \ + 0x755B 0x7572 0x7579 0x7583 0x7F58 0x7F61 0x7F5F 0x8A48 \ + 0x7F68 0x7F74 0x7F71 0x7F79 0x7F81 0x7F7E 0x76CD 0x76E5 \ + 0x8832 0x9485 0x9486 0x9487 0x948B 0x948A 0x948C 0x948D \ + 0x948F 0x9490 0x9494 0x9497 0x9495 0x949A 0x949B 0x949C \ + 0x94A3 0x94A4 0x94AB 0x94AA 0x94AD 0x94AC 0x94AF 0x94B0 \ + 0x94B2 0x94B4 0x94B6 0x94B7 0x94B8 0x94B9 0x94BA 0x94BC \ + 0x94BD 0x94BF 0x94C4 0x94C8 0x94C9 0x94CA 0x94CB 0x94CC \ + 0x94CD 0x94CE 0x94D0 0x94D1 0x94D2 0x94D5 0x94D6 0x94D7 \ + 0x94D9 0x94D8 0x94DB 0x94DE 0x94DF 0x94E0 0x94E2 0x94E4 \ + 0x94E5 0x94E7 0x94E8 0x94EA 0x986F 0x9870 0x9871 0x9872 \ + 0x9873 0x9874 0x988B 0x988E 0x9892 0x9895 0x9899 0x98A3 \ + 0x98A8 0x98A9 0x98AA 0x98AB 0x98AC 0x98AD 0x98AE 0x98AF \ + 0x98B0 0x98B1 0x98B2 0x98B3 0x98B4 0x98B5 0x98B6 0x98B7 \ + 0x98B8 0x98B9 0x98BA 0x98BB 0x98BC 0x98BD 0x98BE 0x98BF \ + 0x98C0 0x98C1 0x98C2 0x98C3 0x98C4 0x98C5 0x98C6 0x98C7 \ + 0x98C8 0x98C9 0x98CA 0x98CB 0x98CC 0x98CD 0x98CF 0x98D0 \ + 0x98D4 0x98D6 0x98D7 0x98DB 0x98DC 0x98DD 0x98E0 0x98E1 \ + 0x98E2 0x98E3 0x98E4 0x98E5 0x98E6 0x98E9 0x98EA 0x98EB \ + 0x98EC 0x98ED 0x98EE 0x98EF 0x98F0 0x98F1 0x98F2 0x98F3 \ + 0x98F4 0x98F5 0x98F6 0x98F7 0x98F8 0x98F9 0x98FA 0x98FB \ + 0x98FC 0x98FD 0x98FE 0x98FF 0x9900 0x9901 0x9902 0x9903 +83 0x9904 0x9905 0x9906 0x9907 0x94E9 0x94EB 0x94EE 0x94EF \ + 0x94F3 0x94F4 0x94F5 0x94F7 0x94F9 0x94FC 0x94FD 0x94FF \ + 0x9503 0x9502 0x9506 0x9507 0x9509 0x950A 0x950D 0x950E \ + 0x950F 0x9512 0x9513 0x9514 0x9515 0x9516 0x9518 0x951B \ + 0x951D 0x951E 0x951F 0x9522 0x952A 0x952B 0x9529 0x952C \ + 0x9531 0x9532 0x9534 0x9536 0x9537 0x9538 0x953C 0x953E \ + 0x953F 0x9542 0x9535 0x9544 0x9545 0x9546 0x9549 0x954C \ + 0x954E 0x954F 0x9552 0x9553 0x9554 0x9556 0x9557 0x9558 \ + 0x9559 0x955B 0x955E 0x955F 0x955D 0x9561 0x9562 0x9564 \ + 0x9565 0x9566 0x9567 0x9568 0x9569 0x956A 0x956B 0x956C \ + 0x956F 0x9571 0x9572 0x9573 0x953A 0x77E7 0x77EC 0x96C9 \ + 0x79D5 0x79ED 0x79E3 0x79EB 0x7A06 0x5D47 0x7A03 0x7A02 \ + 0x7A1E 0x7A14 0x9908 0x9909 0x990A 0x990B 0x990C 0x990E \ + 0x990F 0x9911 0x9912 0x9913 0x9914 0x9915 0x9916 0x9917 \ + 0x9918 0x9919 0x991A 0x991B 0x991C 0x991D 0x991E 0x991F \ + 0x9920 0x9921 0x9922 0x9923 0x9924 0x9925 0x9926 0x9927 \ + 0x9928 0x9929 0x992A 0x992B 0x992C 0x992D 0x992F 0x9930 \ + 0x9931 0x9932 0x9933 0x9934 0x9935 0x9936 0x9937 0x9938 \ + 0x9939 0x993A 0x993B 0x993C 0x993D 0x993E 0x993F 0x9940 \ + 0x9941 0x9942 0x9943 0x9944 0x9945 0x9946 0x9947 0x9948 \ + 0x9949 0x994A 0x994B 0x994C 0x994D 0x994E 0x994F 0x9950 \ + 0x9951 0x9952 0x9953 0x9956 0x9957 0x9958 0x9959 0x995A \ + 0x995B 0x995C 0x995D 0x995E 0x995F 0x9960 0x9961 0x9962 \ + 0x9964 0x9966 0x9973 0x9978 0x9979 0x997B 0x997E 0x9982 \ + 0x9983 0x9989 0x7A39 0x7A37 0x7A51 0x9ECF 0x99A5 0x7A70 \ + 0x7688 0x768E 0x7693 0x7699 0x76A4 0x74DE 0x74E0 0x752C \ + 0x9E20 0x9E22 0x9E28 0x9E29 0x9E2A 0x9E2B 0x9E2C 0x9E32 \ + 0x9E31 0x9E36 0x9E38 0x9E37 0x9E39 0x9E3A 0x9E3E 0x9E41 \ + 0x9E42 0x9E44 0x9E46 0x9E47 0x9E48 0x9E49 0x9E4B 0x9E4C \ + 0x9E4E 0x9E51 0x9E55 0x9E57 0x9E5A 0x9E5B 0x9E5C 0x9E5E \ + 0x9E63 0x9E66 0x9E67 0x9E68 0x9E69 0x9E6A 0x9E6B 0x9E6C \ + 0x9E71 0x9E6D 0x9E73 0x7592 0x7594 0x7596 0x75A0 0x759D +84 0x75AC 0x75A3 0x75B3 0x75B4 0x75B8 0x75C4 0x75B1 0x75B0 \ + 0x75C3 0x75C2 0x75D6 0x75CD 0x75E3 0x75E8 0x75E6 0x75E4 \ + 0x75EB 0x75E7 0x7603 0x75F1 0x75FC 0x75FF 0x7610 0x7600 \ + 0x7605 0x760C 0x7617 0x760A 0x7625 0x7618 0x7615 0x7619 \ + 0x998C 0x998E 0x999A 0x999B 0x999C 0x999D 0x999E 0x999F \ + 0x99A0 0x99A1 0x99A2 0x99A3 0x99A4 0x99A6 0x99A7 0x99A9 \ + 0x99AA 0x99AB 0x99AC 0x99AD 0x99AE 0x99AF 0x99B0 0x99B1 \ + 0x99B2 0x99B3 0x99B4 0x99B5 0x99B6 0x99B7 0x99B8 0x99B9 \ + 0x99BA 0x99BB 0x99BC 0x99BD 0x99BE 0x99BF 0x99C0 0x99C1 \ + 0x99C2 0x99C3 0x99C4 0x99C5 0x99C6 0x99C7 0x99C8 0x99C9 \ + 0x99CA 0x99CB 0x99CC 0x99CD 0x99CE 0x99CF 0x99D0 0x99D1 \ + 0x99D2 0x99D3 0x99D4 0x99D5 0x99D6 0x99D7 0x99D8 0x99D9 \ + 0x99DA 0x99DB 0x99DC 0x99DD 0x99DE 0x99DF 0x99E0 0x99E1 \ + 0x99E2 0x99E3 0x99E4 0x99E5 0x99E6 0x99E7 0x99E8 0x99E9 \ + 0x99EA 0x99EB 0x99EC 0x99ED 0x99EE 0x99EF 0x99F0 0x99F1 \ + 0x99F2 0x99F3 0x99F4 0x99F5 0x99F6 0x99F7 0x99F8 0x99F9 \ + 0x761B 0x763C 0x7622 0x7620 0x7640 0x762D 0x7630 0x763F \ + 0x7635 0x7643 0x763E 0x7633 0x764D 0x765E 0x7654 0x765C \ + 0x7656 0x766B 0x766F 0x7FCA 0x7AE6 0x7A78 0x7A79 0x7A80 \ + 0x7A86 0x7A88 0x7A95 0x7AA6 0x7AA0 0x7AAC 0x7AA8 0x7AAD \ + 0x7AB3 0x8864 0x8869 0x8872 0x887D 0x887F 0x8882 0x88A2 \ + 0x88C6 0x88B7 0x88BC 0x88C9 0x88E2 0x88CE 0x88E3 0x88E5 \ + 0x88F1 0x891A 0x88FC 0x88E8 0x88FE 0x88F0 0x8921 0x8919 \ + 0x8913 0x891B 0x890A 0x8934 0x892B 0x8936 0x8941 0x8966 \ + 0x897B 0x758B 0x80E5 0x76B2 0x76B4 0x77DC 0x8012 0x8014 \ + 0x8016 0x801C 0x8020 0x8022 0x8025 0x8026 0x8027 0x8029 \ + 0x8028 0x8031 0x800B 0x8035 0x8043 0x8046 0x804D 0x8052 \ + 0x8069 0x8071 0x8983 0x9878 0x9880 0x9883 0x99FA 0x99FB \ + 0x99FC 0x99FD 0x99FE 0x99FF 0x9A00 0x9A01 0x9A02 0x9A03 \ + 0x9A04 0x9A05 0x9A06 0x9A07 0x9A08 0x9A09 0x9A0A 0x9A0B \ + 0x9A0C 0x9A0D 0x9A0E 0x9A0F 0x9A10 0x9A11 0x9A12 0x9A13 \ + 0x9A14 0x9A15 0x9A16 0x9A17 0x9A18 0x9A19 0x9A1A 0x9A1B +85 0x9A1C 0x9A1D 0x9A1E 0x9A1F 0x9A20 0x9A21 0x9A22 0x9A23 \ + 0x9A24 0x9A25 0x9A26 0x9A27 0x9A28 0x9A29 0x9A2A 0x9A2B \ + 0x9A2C 0x9A2D 0x9A2E 0x9A2F 0x9A30 0x9A31 0x9A32 0x9A33 \ + 0x9A34 0x9A35 0x9A36 0x9A37 0x9A38 0x9A39 0x9A3A 0x9A3B \ + 0x9A3C 0x9A3D 0x9A3E 0x9A3F 0x9A40 0x9A41 0x9A42 0x9A43 \ + 0x9A44 0x9A45 0x9A46 0x9A47 0x9A48 0x9A49 0x9A4A 0x9A4B \ + 0x9A4C 0x9A4D 0x9A4E 0x9A4F 0x9A50 0x9A51 0x9A52 0x9A53 \ + 0x9A54 0x9A55 0x9A56 0x9A57 0x9A58 0x9A59 0x9889 0x988C \ + 0x988D 0x988F 0x9894 0x989A 0x989B 0x989E 0x989F 0x98A1 \ + 0x98A2 0x98A5 0x98A6 0x864D 0x8654 0x866C 0x866E 0x867F \ + 0x867A 0x867C 0x867B 0x86A8 0x868D 0x868B 0x86AC 0x869D \ + 0x86A7 0x86A3 0x86AA 0x8693 0x86A9 0x86B6 0x86C4 0x86B5 \ + 0x86CE 0x86B0 0x86BA 0x86B1 0x86AF 0x86C9 0x86CF 0x86B4 \ + 0x86E9 0x86F1 0x86F2 0x86ED 0x86F3 0x86D0 0x8713 0x86DE \ + 0x86F4 0x86DF 0x86D8 0x86D1 0x8703 0x8707 0x86F8 0x8708 \ + 0x870A 0x870D 0x8709 0x8723 0x873B 0x871E 0x8725 0x872E \ + 0x871A 0x873E 0x8748 0x8734 0x8731 0x8729 0x8737 0x873F \ + 0x8782 0x8722 0x877D 0x877E 0x877B 0x8760 0x8770 0x874C \ + 0x876E 0x878B 0x8753 0x8763 0x877C 0x8764 0x8759 0x8765 \ + 0x8793 0x87AF 0x87A8 0x87D2 0x9A5A 0x9A5B 0x9A5C 0x9A5D \ + 0x9A5E 0x9A5F 0x9A60 0x9A61 0x9A62 0x9A63 0x9A64 0x9A65 \ + 0x9A66 0x9A67 0x9A68 0x9A69 0x9A6A 0x9A6B 0x9A72 0x9A83 \ + 0x9A89 0x9A8D 0x9A8E 0x9A94 0x9A95 0x9A99 0x9AA6 0x9AA9 \ + 0x9AAA 0x9AAB 0x9AAC 0x9AAD 0x9AAE 0x9AAF 0x9AB2 0x9AB3 \ + 0x9AB4 0x9AB5 0x9AB9 0x9ABB 0x9ABD 0x9ABE 0x9ABF 0x9AC3 \ + 0x9AC4 0x9AC6 0x9AC7 0x9AC8 0x9AC9 0x9ACA 0x9ACD 0x9ACE \ + 0x9ACF 0x9AD0 0x9AD2 0x9AD4 0x9AD5 0x9AD6 0x9AD7 0x9AD9 \ + 0x9ADA 0x9ADB 0x9ADC 0x9ADD 0x9ADE 0x9AE0 0x9AE2 0x9AE3 \ + 0x9AE4 0x9AE5 0x9AE7 0x9AE8 0x9AE9 0x9AEA 0x9AEC 0x9AEE \ + 0x9AF0 0x9AF1 0x9AF2 0x9AF3 0x9AF4 0x9AF5 0x9AF6 0x9AF7 \ + 0x9AF8 0x9AFA 0x9AFC 0x9AFD 0x9AFE 0x9AFF 0x9B00 0x9B01 \ + 0x9B02 0x9B04 0x9B05 0x9B06 0x87C6 0x8788 0x8785 0x87AD +86 0x8797 0x8783 0x87AB 0x87E5 0x87AC 0x87B5 0x87B3 0x87CB \ + 0x87D3 0x87BD 0x87D1 0x87C0 0x87CA 0x87DB 0x87EA 0x87E0 \ + 0x87EE 0x8816 0x8813 0x87FE 0x880A 0x881B 0x8821 0x8839 \ + 0x883C 0x7F36 0x7F42 0x7F44 0x7F45 0x8210 0x7AFA 0x7AFD \ + 0x7B08 0x7B03 0x7B04 0x7B15 0x7B0A 0x7B2B 0x7B0F 0x7B47 \ + 0x7B38 0x7B2A 0x7B19 0x7B2E 0x7B31 0x7B20 0x7B25 0x7B24 \ + 0x7B33 0x7B3E 0x7B1E 0x7B58 0x7B5A 0x7B45 0x7B75 0x7B4C \ + 0x7B5D 0x7B60 0x7B6E 0x7B7B 0x7B62 0x7B72 0x7B71 0x7B90 \ + 0x7BA6 0x7BA7 0x7BB8 0x7BAC 0x7B9D 0x7BA8 0x7B85 0x7BAA \ + 0x7B9C 0x7BA2 0x7BAB 0x7BB4 0x7BD1 0x7BC1 0x7BCC 0x7BDD \ + 0x7BDA 0x7BE5 0x7BE6 0x7BEA 0x7C0C 0x7BFE 0x7BFC 0x7C0F \ + 0x7C16 0x7C0B 0x9B07 0x9B09 0x9B0A 0x9B0B 0x9B0C 0x9B0D \ + 0x9B0E 0x9B10 0x9B11 0x9B12 0x9B14 0x9B15 0x9B16 0x9B17 \ + 0x9B18 0x9B19 0x9B1A 0x9B1B 0x9B1C 0x9B1D 0x9B1E 0x9B20 \ + 0x9B21 0x9B22 0x9B24 0x9B25 0x9B26 0x9B27 0x9B28 0x9B29 \ + 0x9B2A 0x9B2B 0x9B2C 0x9B2D 0x9B2E 0x9B30 0x9B31 0x9B33 \ + 0x9B34 0x9B35 0x9B36 0x9B37 0x9B38 0x9B39 0x9B3A 0x9B3D \ + 0x9B3E 0x9B3F 0x9B40 0x9B46 0x9B4A 0x9B4B 0x9B4C 0x9B4E \ + 0x9B50 0x9B52 0x9B53 0x9B55 0x9B56 0x9B57 0x9B58 0x9B59 \ + 0x9B5A 0x9B5B 0x9B5C 0x9B5D 0x9B5E 0x9B5F 0x9B60 0x9B61 \ + 0x9B62 0x9B63 0x9B64 0x9B65 0x9B66 0x9B67 0x9B68 0x9B69 \ + 0x9B6A 0x9B6B 0x9B6C 0x9B6D 0x9B6E 0x9B6F 0x9B70 0x9B71 \ + 0x9B72 0x9B73 0x9B74 0x9B75 0x9B76 0x9B77 0x9B78 0x9B79 \ + 0x9B7A 0x9B7B 0x7C1F 0x7C2A 0x7C26 0x7C38 0x7C41 0x7C40 \ + 0x81FE 0x8201 0x8202 0x8204 0x81EC 0x8844 0x8221 0x8222 \ + 0x8223 0x822D 0x822F 0x8228 0x822B 0x8238 0x823B 0x8233 \ + 0x8234 0x823E 0x8244 0x8249 0x824B 0x824F 0x825A 0x825F \ + 0x8268 0x887E 0x8885 0x8888 0x88D8 0x88DF 0x895E 0x7F9D \ + 0x7F9F 0x7FA7 0x7FAF 0x7FB0 0x7FB2 0x7C7C 0x6549 0x7C91 \ + 0x7C9D 0x7C9C 0x7C9E 0x7CA2 0x7CB2 0x7CBC 0x7CBD 0x7CC1 \ + 0x7CC7 0x7CCC 0x7CCD 0x7CC8 0x7CC5 0x7CD7 0x7CE8 0x826E \ + 0x66A8 0x7FBF 0x7FCE 0x7FD5 0x7FE5 0x7FE1 0x7FE6 0x7FE9 +87 0x7FEE 0x7FF3 0x7CF8 0x7D77 0x7DA6 0x7DAE 0x7E47 0x7E9B \ + 0x9EB8 0x9EB4 0x8D73 0x8D84 0x8D94 0x8D91 0x8DB1 0x8D67 \ + 0x8D6D 0x8C47 0x8C49 0x914A 0x9150 0x914E 0x914F 0x9164 \ + 0x9B7C 0x9B7D 0x9B7E 0x9B7F 0x9B80 0x9B81 0x9B82 0x9B83 \ + 0x9B84 0x9B85 0x9B86 0x9B87 0x9B88 0x9B89 0x9B8A 0x9B8B \ + 0x9B8C 0x9B8D 0x9B8E 0x9B8F 0x9B90 0x9B91 0x9B92 0x9B93 \ + 0x9B94 0x9B95 0x9B96 0x9B97 0x9B98 0x9B99 0x9B9A 0x9B9B \ + 0x9B9C 0x9B9D 0x9B9E 0x9B9F 0x9BA0 0x9BA1 0x9BA2 0x9BA3 \ + 0x9BA4 0x9BA5 0x9BA6 0x9BA7 0x9BA8 0x9BA9 0x9BAA 0x9BAB \ + 0x9BAC 0x9BAD 0x9BAE 0x9BAF 0x9BB0 0x9BB1 0x9BB2 0x9BB3 \ + 0x9BB4 0x9BB5 0x9BB6 0x9BB7 0x9BB8 0x9BB9 0x9BBA 0x9BBB \ + 0x9BBC 0x9BBD 0x9BBE 0x9BBF 0x9BC0 0x9BC1 0x9BC2 0x9BC3 \ + 0x9BC4 0x9BC5 0x9BC6 0x9BC7 0x9BC8 0x9BC9 0x9BCA 0x9BCB \ + 0x9BCC 0x9BCD 0x9BCE 0x9BCF 0x9BD0 0x9BD1 0x9BD2 0x9BD3 \ + 0x9BD4 0x9BD5 0x9BD6 0x9BD7 0x9BD8 0x9BD9 0x9BDA 0x9BDB \ + 0x9162 0x9161 0x9170 0x9169 0x916F 0x917D 0x917E 0x9172 \ + 0x9174 0x9179 0x918C 0x9185 0x9190 0x918D 0x9191 0x91A2 \ + 0x91A3 0x91AA 0x91AD 0x91AE 0x91AF 0x91B5 0x91B4 0x91BA \ + 0x8C55 0x9E7E 0x8DB8 0x8DEB 0x8E05 0x8E59 0x8E69 0x8DB5 \ + 0x8DBF 0x8DBC 0x8DBA 0x8DC4 0x8DD6 0x8DD7 0x8DDA 0x8DDE \ + 0x8DCE 0x8DCF 0x8DDB 0x8DC6 0x8DEC 0x8DF7 0x8DF8 0x8DE3 \ + 0x8DF9 0x8DFB 0x8DE4 0x8E09 0x8DFD 0x8E14 0x8E1D 0x8E1F \ + 0x8E2C 0x8E2E 0x8E23 0x8E2F 0x8E3A 0x8E40 0x8E39 0x8E35 \ + 0x8E3D 0x8E31 0x8E49 0x8E41 0x8E42 0x8E51 0x8E52 0x8E4A \ + 0x8E70 0x8E76 0x8E7C 0x8E6F 0x8E74 0x8E85 0x8E8F 0x8E94 \ + 0x8E90 0x8E9C 0x8E9E 0x8C78 0x8C82 0x8C8A 0x8C85 0x8C98 \ + 0x8C94 0x659B 0x89D6 0x89DE 0x89DA 0x89DC 0x9BDC 0x9BDD \ + 0x9BDE 0x9BDF 0x9BE0 0x9BE1 0x9BE2 0x9BE3 0x9BE4 0x9BE5 \ + 0x9BE6 0x9BE7 0x9BE8 0x9BE9 0x9BEA 0x9BEB 0x9BEC 0x9BED \ + 0x9BEE 0x9BEF 0x9BF0 0x9BF1 0x9BF2 0x9BF3 0x9BF4 0x9BF5 \ + 0x9BF6 0x9BF7 0x9BF8 0x9BF9 0x9BFA 0x9BFB 0x9BFC 0x9BFD \ + 0x9BFE 0x9BFF 0x9C00 0x9C01 0x9C02 0x9C03 0x9C04 0x9C05 +88 0x9C06 0x9C07 0x9C08 0x9C09 0x9C0A 0x9C0B 0x9C0C 0x9C0D \ + 0x9C0E 0x9C0F 0x9C10 0x9C11 0x9C12 0x9C13 0x9C14 0x9C15 \ + 0x9C16 0x9C17 0x9C18 0x9C19 0x9C1A 0x9C1B 0x9C1C 0x9C1D \ + 0x9C1E 0x9C1F 0x9C20 0x9C21 0x9C22 0x9C23 0x9C24 0x9C25 \ + 0x9C26 0x9C27 0x9C28 0x9C29 0x9C2A 0x9C2B 0x9C2C 0x9C2D \ + 0x9C2E 0x9C2F 0x9C30 0x9C31 0x9C32 0x9C33 0x9C34 0x9C35 \ + 0x9C36 0x9C37 0x9C38 0x9C39 0x9C3A 0x9C3B 0x89E5 0x89EB \ + 0x89EF 0x8A3E 0x8B26 0x9753 0x96E9 0x96F3 0x96EF 0x9706 \ + 0x9701 0x9708 0x970F 0x970E 0x972A 0x972D 0x9730 0x973E \ + 0x9F80 0x9F83 0x9F85 0x9F86 0x9F87 0x9F88 0x9F89 0x9F8A \ + 0x9F8C 0x9EFE 0x9F0B 0x9F0D 0x96B9 0x96BC 0x96BD 0x96CE \ + 0x96D2 0x77BF 0x96E0 0x928E 0x92AE 0x92C8 0x933E 0x936A \ + 0x93CA 0x938F 0x943E 0x946B 0x9C7F 0x9C82 0x9C85 0x9C86 \ + 0x9C87 0x9C88 0x7A23 0x9C8B 0x9C8E 0x9C90 0x9C91 0x9C92 \ + 0x9C94 0x9C95 0x9C9A 0x9C9B 0x9C9E 0x9C9F 0x9CA0 0x9CA1 \ + 0x9CA2 0x9CA3 0x9CA5 0x9CA6 0x9CA7 0x9CA8 0x9CA9 0x9CAB \ + 0x9CAD 0x9CAE 0x9CB0 0x9CB1 0x9CB2 0x9CB3 0x9CB4 0x9CB5 \ + 0x9CB6 0x9CB7 0x9CBA 0x9CBB 0x9CBC 0x9CBD 0x9CC4 0x9CC5 \ + 0x9CC6 0x9CC7 0x9CCA 0x9CCB 0x9C3C 0x9C3D 0x9C3E 0x9C3F \ + 0x9C40 0x9C41 0x9C42 0x9C43 0x9C44 0x9C45 0x9C46 0x9C47 \ + 0x9C48 0x9C49 0x9C4A 0x9C4B 0x9C4C 0x9C4D 0x9C4E 0x9C4F \ + 0x9C50 0x9C51 0x9C52 0x9C53 0x9C54 0x9C55 0x9C56 0x9C57 \ + 0x9C58 0x9C59 0x9C5A 0x9C5B 0x9C5C 0x9C5D 0x9C5E 0x9C5F \ + 0x9C60 0x9C61 0x9C62 0x9C63 0x9C64 0x9C65 0x9C66 0x9C67 \ + 0x9C68 0x9C69 0x9C6A 0x9C6B 0x9C6C 0x9C6D 0x9C6E 0x9C6F \ + 0x9C70 0x9C71 0x9C72 0x9C73 0x9C74 0x9C75 0x9C76 0x9C77 \ + 0x9C78 0x9C79 0x9C7A 0x9C7B 0x9C7D 0x9C7E 0x9C80 0x9C83 \ + 0x9C84 0x9C89 0x9C8A 0x9C8C 0x9C8F 0x9C93 0x9C96 0x9C97 \ + 0x9C98 0x9C99 0x9C9D 0x9CAA 0x9CAC 0x9CAF 0x9CB9 0x9CBE \ + 0x9CBF 0x9CC0 0x9CC1 0x9CC2 0x9CC8 0x9CC9 0x9CD1 0x9CD2 \ + 0x9CDA 0x9CDB 0x9CE0 0x9CE1 0x9CCC 0x9CCD 0x9CCE 0x9CCF \ + 0x9CD0 0x9CD3 0x9CD4 0x9CD5 0x9CD7 0x9CD8 0x9CD9 0x9CDC +89 0x9CDD 0x9CDF 0x9CE2 0x977C 0x9785 0x9791 0x9792 0x9794 \ + 0x97AF 0x97AB 0x97A3 0x97B2 0x97B4 0x9AB1 0x9AB0 0x9AB7 \ + 0x9E58 0x9AB6 0x9ABA 0x9ABC 0x9AC1 0x9AC0 0x9AC5 0x9AC2 \ + 0x9ACB 0x9ACC 0x9AD1 0x9B45 0x9B43 0x9B47 0x9B49 0x9B48 \ + 0x9B4D 0x9B51 0x98E8 0x990D 0x992E 0x9955 0x9954 0x9ADF \ + 0x9AE1 0x9AE6 0x9AEF 0x9AEB 0x9AFB 0x9AED 0x9AF9 0x9B08 \ + 0x9B0F 0x9B13 0x9B1F 0x9B23 0x9EBD 0x9EBE 0x7E3B 0x9E82 \ + 0x9E87 0x9E88 0x9E8B 0x9E92 0x93D6 0x9E9D 0x9E9F 0x9EDB \ + 0x9EDC 0x9EDD 0x9EE0 0x9EDF 0x9EE2 0x9EE9 0x9EE7 0x9EE5 \ + 0x9EEA 0x9EEF 0x9F22 0x9F2C 0x9F2F 0x9F39 0x9F37 0x9F3D \ + 0x9F3E 0x9F44 0x9CE3 0x9CE4 0x9CE5 0x9CE6 0x9CE7 0x9CE8 \ + 0x9CE9 0x9CEA 0x9CEB 0x9CEC 0x9CED 0x9CEE 0x9CEF 0x9CF0 \ + 0x9CF1 0x9CF2 0x9CF3 0x9CF4 0x9CF5 0x9CF6 0x9CF7 0x9CF8 \ + 0x9CF9 0x9CFA 0x9CFB 0x9CFC 0x9CFD 0x9CFE 0x9CFF 0x9D00 \ + 0x9D01 0x9D02 0x9D03 0x9D04 0x9D05 0x9D06 0x9D07 0x9D08 \ + 0x9D09 0x9D0A 0x9D0B 0x9D0C 0x9D0D 0x9D0E 0x9D0F 0x9D10 \ + 0x9D11 0x9D12 0x9D13 0x9D14 0x9D15 0x9D16 0x9D17 0x9D18 \ + 0x9D19 0x9D1A 0x9D1B 0x9D1C 0x9D1D 0x9D1E 0x9D1F 0x9D20 \ + 0x9D21 0x9D22 0x9D23 0x9D24 0x9D25 0x9D26 0x9D27 0x9D28 \ + 0x9D29 0x9D2A 0x9D2B 0x9D2C 0x9D2D 0x9D2E 0x9D2F 0x9D30 \ + 0x9D31 0x9D32 0x9D33 0x9D34 0x9D35 0x9D36 0x9D37 0x9D38 \ + 0x9D39 0x9D3A 0x9D3B 0x9D3C 0x9D3D 0x9D3E 0x9D3F 0x9D40 \ + 0x9D41 0x9D42 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +90 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x9D43 0x9D44 0x9D45 0x9D46 0x9D47 0x9D48 0x9D49 0x9D4A \ + 0x9D4B 0x9D4C 0x9D4D 0x9D4E 0x9D4F 0x9D50 0x9D51 0x9D52 \ + 0x9D53 0x9D54 0x9D55 0x9D56 0x9D57 0x9D58 0x9D59 0x9D5A \ + 0x9D5B 0x9D5C 0x9D5D 0x9D5E 0x9D5F 0x9D60 0x9D61 0x9D62 \ + 0x9D63 0x9D64 0x9D65 0x9D66 0x9D67 0x9D68 0x9D69 0x9D6A \ + 0x9D6B 0x9D6C 0x9D6D 0x9D6E 0x9D6F 0x9D70 0x9D71 0x9D72 \ + 0x9D73 0x9D74 0x9D75 0x9D76 0x9D77 0x9D78 0x9D79 0x9D7A \ + 0x9D7B 0x9D7C 0x9D7D 0x9D7E 0x9D7F 0x9D80 0x9D81 0x9D82 \ + 0x9D83 0x9D84 0x9D85 0x9D86 0x9D87 0x9D88 0x9D89 0x9D8A \ + 0x9D8B 0x9D8C 0x9D8D 0x9D8E 0x9D8F 0x9D90 0x9D91 0x9D92 \ + 0x9D93 0x9D94 0x9D95 0x9D96 0x9D97 0x9D98 0x9D99 0x9D9A \ + 0x9D9B 0x9D9C 0x9D9D 0x9D9E 0x9D9F 0x9DA0 0x9DA1 0x9DA2 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x9DA3 0x9DA4 \ + 0x9DA5 0x9DA6 0x9DA7 0x9DA8 0x9DA9 0x9DAA 0x9DAB 0x9DAC \ + 0x9DAD 0x9DAE 0x9DAF 0x9DB0 0x9DB1 0x9DB2 0x9DB3 0x9DB4 \ + 0x9DB5 0x9DB6 0x9DB7 0x9DB8 0x9DB9 0x9DBA 0x9DBB 0x9DBC \ + 0x9DBD 0x9DBE 0x9DBF 0x9DC0 0x9DC1 0x9DC2 0x9DC3 0x9DC4 \ + 0x9DC5 0x9DC6 0x9DC7 0x9DC8 0x9DC9 0x9DCA 0x9DCB 0x9DCC \ + 0x9DCD 0x9DCE 0x9DCF 0x9DD0 0x9DD1 0x9DD2 0x9DD3 0x9DD4 +91 0x9DD5 0x9DD6 0x9DD7 0x9DD8 0x9DD9 0x9DDA 0x9DDB 0x9DDC \ + 0x9DDD 0x9DDE 0x9DDF 0x9DE0 0x9DE1 0x9DE2 0x9DE3 0x9DE4 \ + 0x9DE5 0x9DE6 0x9DE7 0x9DE8 0x9DE9 0x9DEA 0x9DEB 0x9DEC \ + 0x9DED 0x9DEE 0x9DEF 0x9DF0 0x9DF1 0x9DF2 0x9DF3 0x9DF4 \ + 0x9DF5 0x9DF6 0x9DF7 0x9DF8 0x9DF9 0x9DFA 0x9DFB 0x9DFC \ + 0x9DFD 0x9DFE 0x9DFF 0x9E00 0x9E01 0x9E02 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x9E03 0x9E04 0x9E05 0x9E06 \ + 0x9E07 0x9E08 0x9E09 0x9E0A 0x9E0B 0x9E0C 0x9E0D 0x9E0E \ + 0x9E0F 0x9E10 0x9E11 0x9E12 0x9E13 0x9E14 0x9E15 0x9E16 \ + 0x9E17 0x9E18 0x9E19 0x9E1A 0x9E1B 0x9E1C 0x9E1D 0x9E1E \ + 0x9E24 0x9E27 0x9E2E 0x9E30 0x9E34 0x9E3B 0x9E3C 0x9E40 \ + 0x9E4D 0x9E50 0x9E52 0x9E53 0x9E54 0x9E56 0x9E59 0x9E5D \ + 0x9E5F 0x9E60 0x9E61 0x9E62 0x9E65 0x9E6E 0x9E6F 0x9E72 \ + 0x9E74 0x9E75 0x9E76 0x9E77 0x9E78 0x9E79 0x9E7A 0x9E7B \ + 0x9E7C 0x9E7D 0x9E80 0x9E81 0x9E83 0x9E84 0x9E85 0x9E86 \ + 0x9E89 0x9E8A 0x9E8C 0x9E8D 0x9E8E 0x9E8F 0x9E90 0x9E91 \ + 0x9E94 0x9E95 0x9E96 0x9E97 0x9E98 0x9E99 0x9E9A 0x9E9B \ + 0x9E9C 0x9E9E 0x9EA0 0x9EA1 0x9EA2 0x9EA3 0x9EA4 0x9EA5 \ + 0x9EA7 0x9EA8 0x9EA9 0x9EAA 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +92 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x9EAB 0x9EAC 0x9EAD 0x9EAE 0x9EAF 0x9EB0 \ + 0x9EB1 0x9EB2 0x9EB3 0x9EB5 0x9EB6 0x9EB7 0x9EB9 0x9EBA \ + 0x9EBC 0x9EBF 0x9EC0 0x9EC1 0x9EC2 0x9EC3 0x9EC5 0x9EC6 \ + 0x9EC7 0x9EC8 0x9ECA 0x9ECB 0x9ECC 0x9ED0 0x9ED2 0x9ED3 \ + 0x9ED5 0x9ED6 0x9ED7 0x9ED9 0x9EDA 0x9EDE 0x9EE1 0x9EE3 \ + 0x9EE4 0x9EE6 0x9EE8 0x9EEB 0x9EEC 0x9EED 0x9EEE 0x9EF0 \ + 0x9EF1 0x9EF2 0x9EF3 0x9EF4 0x9EF5 0x9EF6 0x9EF7 0x9EF8 \ + 0x9EFA 0x9EFD 0x9EFF 0x9F00 0x9F01 0x9F02 0x9F03 0x9F04 \ + 0x9F05 0x9F06 0x9F07 0x9F08 0x9F09 0x9F0A 0x9F0C 0x9F0F \ + 0x9F11 0x9F12 0x9F14 0x9F15 0x9F16 0x9F18 0x9F1A 0x9F1B \ + 0x9F1C 0x9F1D 0x9F1E 0x9F1F 0x9F21 0x9F23 0x9F24 0x9F25 \ + 0x9F26 0x9F27 0x9F28 0x9F29 0x9F2A 0x9F2B 0x9F2D 0x9F2E \ + 0x9F30 0x9F31 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +93 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x9F32 0x9F33 0x9F34 0x9F35 0x9F36 0x9F38 0x9F3A 0x9F3C \ + 0x9F3F 0x9F40 0x9F41 0x9F42 0x9F43 0x9F45 0x9F46 0x9F47 \ + 0x9F48 0x9F49 0x9F4A 0x9F4B 0x9F4C 0x9F4D 0x9F4E 0x9F4F \ + 0x9F52 0x9F53 0x9F54 0x9F55 0x9F56 0x9F57 0x9F58 0x9F59 \ + 0x9F5A 0x9F5B 0x9F5C 0x9F5D 0x9F5E 0x9F5F 0x9F60 0x9F61 \ + 0x9F62 0x9F63 0x9F64 0x9F65 0x9F66 0x9F67 0x9F68 0x9F69 \ + 0x9F6A 0x9F6B 0x9F6C 0x9F6D 0x9F6E 0x9F6F 0x9F70 0x9F71 \ + 0x9F72 0x9F73 0x9F74 0x9F75 0x9F76 0x9F77 0x9F78 0x9F79 \ + 0x9F7A 0x9F7B 0x9F7C 0x9F7D 0x9F7E 0x9F81 0x9F82 0x9F8D \ + 0x9F8E 0x9F8F 0x9F90 0x9F91 0x9F92 0x9F93 0x9F94 0x9F95 \ + 0x9F96 0x9F97 0x9F98 0x9F9C 0x9F9D 0x9F9E 0x9FA1 0x9FA2 \ + 0x9FA3 0x9FA4 0x9FA5 0xF92C 0xF979 0xF995 0xF9E7 0xF9F1 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFA0C 0xFA0D \ + 0xFA0E 0xFA0F 0xFA11 0xFA13 0xFA14 0xFA18 0xFA1F 0xFA20 \ + 0xFA21 0xFA23 0xFA24 0xFA27 0xFA28 0xFA29 0xE815 0xE816 \ + 0xE817 0xE818 0xE819 0xE81A 0xE81B 0xE81C 0xE81D 0xE81E \ + 0xE81F 0xE820 0xE821 0xE822 0xE823 0xE824 0xE825 0xE826 \ + 0xE827 0xE828 0xE829 0xE82A 0xE82B 0xE82C 0xE82D 0xE82E \ + 0xE82F 0xE830 0xE831 0xE832 0xE833 0xE834 0xE835 0xE836 \ + 0xE837 0xE838 0xE839 0xE83A 0xE83B 0xE83C 0xE83D 0xE83E +94 0xE83F 0xE840 0xE841 0xE842 0xE843 0xE844 0xE845 0xE846 \ + 0xE847 0xE848 0xE849 0xE84A 0xE84B 0xE84C 0xE84D 0xE84E \ + 0xE84F 0xE850 0xE851 0xE852 0xE853 0xE854 0xE855 0xE856 \ + 0xE857 0xE858 0xE859 0xE85A 0xE85B 0xE85C 0xE85D 0xE85E \ + 0xE85F 0xE860 0xE861 0xE862 0xE863 0xE864 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UJIS.sfd b/contrib/ttf2pk/data/UJIS.sfd new file mode 100644 index 0000000..073c49d --- /dev/null +++ b/contrib/ttf2pk/data/UJIS.sfd @@ -0,0 +1,1114 @@ +# UJIS.sfd +# +# subfont numbers for JIS X 0208 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x3000 0x3001 0x3002 0xFF0C 0xFF0E 0x30FB 0xFF1A 0xFF1B \ + 0xFF1F 0xFF01 0x309B 0x309C 0x00B4 0xFF40 0x00A8 0xFF3E \ + 0xFFE3 0xFF3F 0x30FD 0x30FE 0x309D 0x309E 0x3003 0x4EDD \ + 0x3005 0x3006 0x3007 0x30FC 0x2015 0x2010 0xFF0F 0x005C \ + 0x301C 0x2016 0xFF5C 0x2026 0x2025 0x2018 0x2019 0x201C \ + 0x201D 0xFF08 0xFF09 0x3014 0x3015 0xFF3B 0xFF3D 0xFF5B \ + 0xFF5D 0x3008 0x3009 0x300A 0x300B 0x300C 0x300D 0x300E \ + 0x300F 0x3010 0x3011 0xFF0B 0x2212 0x00B1 0x00D7 0x00F7 \ + 0xFF1D 0x2260 0xFF1C 0xFF1E 0x2266 0x2267 0x221E 0x2234 \ + 0x2642 0x2640 0x00B0 0x2032 0x2033 0x2103 0xFFE5 0xFF04 \ + 0x00A2 0x00A3 0xFF05 0xFF03 0xFF06 0xFF0A 0xFF20 0x00A7 \ + 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 0x25C6 0x25A1 \ + 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x203B 0x3012 0x2192 \ + 0x2190 0x2191 0x2193 0x3013 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2208 \ + 0x220B 0x2286 0x2287 0x2282 0x2283 0x222A 0x2229 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2227 \ + 0x2228 0x00AC 0x21D2 0x21D4 0x2200 0x2203 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0x2220 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 \ + 0x226A 0x226B 0x221A 0x223D 0x221D 0x2235 0x222B 0x222C \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x212B \ + 0x2030 0x266F 0x266D 0x266A 0x2020 0x2021 0x00B6 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0x25EF 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 \ + 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFF41 0xFF42 0xFF43 0xFF44 +02 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x3041 0x3042 0x3043 0x3044 0x3045 0x3046 \ + 0x3047 0x3048 0x3049 0x304A 0x304B 0x304C 0x304D 0x304E \ + 0x304F 0x3050 0x3051 0x3052 0x3053 0x3054 0x3055 0x3056 \ + 0x3057 0x3058 0x3059 0x305A 0x305B 0x305C 0x305D 0x305E \ + 0x305F 0x3060 0x3061 0x3062 0x3063 0x3064 0x3065 0x3066 \ + 0x3067 0x3068 0x3069 0x306A 0x306B 0x306C 0x306D 0x306E \ + 0x306F 0x3070 0x3071 0x3072 0x3073 0x3074 0x3075 0x3076 \ + 0x3077 0x3078 0x3079 0x307A 0x307B 0x307C 0x307D 0x307E \ + 0x307F 0x3080 0x3081 0x3082 0x3083 0x3084 0x3085 0x3086 \ + 0x3087 0x3088 0x3089 0x308A 0x308B 0x308C 0x308D 0x308E \ + 0x308F 0x3090 0x3091 0x3092 0x3093 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x30A1 0x30A2 0x30A3 0x30A4 0x30A5 0x30A6 0x30A7 0x30A8 \ + 0x30A9 0x30AA 0x30AB 0x30AC 0x30AD 0x30AE 0x30AF 0x30B0 \ + 0x30B1 0x30B2 0x30B3 0x30B4 0x30B5 0x30B6 0x30B7 0x30B8 \ + 0x30B9 0x30BA 0x30BB 0x30BC 0x30BD 0x30BE 0x30BF 0x30C0 \ + 0x30C1 0x30C2 0x30C3 0x30C4 0x30C5 0x30C6 0x30C7 0x30C8 \ + 0x30C9 0x30CA 0x30CB 0x30CC 0x30CD 0x30CE 0x30CF 0x30D0 \ + 0x30D1 0x30D2 0x30D3 0x30D4 0x30D5 0x30D6 0x30D7 0x30D8 \ + 0x30D9 0x30DA 0x30DB 0x30DC 0x30DD 0x30DE 0x30DF 0x30E0 \ + 0x30E1 0x30E2 0x30E3 0x30E4 0x30E5 0x30E6 0x30E7 0x30E8 \ + 0x30E9 0x30EA 0x30EB 0x30EC 0x30ED 0x30EE 0x30EF 0x30F0 \ + 0x30F1 0x30F2 0x30F3 0x30F4 0x30F5 0x30F6 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0391 0x0392 \ + 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 0x0399 0x039A \ + 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 0x03A1 0x03A3 \ + 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x03B1 0x03B2 \ + 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 0x03B9 0x03BA +03 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 0x03C1 0x03C3 \ + 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0410 0x0411 0x0412 0x0413 \ + 0x0414 0x0415 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A \ + 0x041B 0x041C 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 \ + 0x0423 0x0424 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A \ + 0x042B 0x042C 0x042D 0x042E 0x042F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x0430 0x0431 0x0432 0x0433 \ + 0x0434 0x0435 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A \ + 0x043B 0x043C 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 \ + 0x0443 0x0444 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A \ + 0x044B 0x044C 0x044D 0x044E 0x044F 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x2500 0x2502 0x250C 0x2510 0x2518 0x2514 \ + 0x251C 0x252C 0x2524 0x2534 0x253C 0x2501 0x2503 0x250F \ + 0x2513 0x251B 0x2517 0x2523 0x2533 0x252B 0x253B 0x254B \ + 0x2520 0x252F 0x2528 0x2537 0x253F 0x251D 0x2530 0x2525 \ + 0x2538 0x2542 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +04 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +05 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +06 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x4E9C 0x5516 0x5A03 0x963F 0x54C0 0x611B \ + 0x6328 0x59F6 0x9022 0x8475 0x831C 0x7A50 0x60AA 0x63E1 \ + 0x6E25 0x65ED 0x8466 0x82A6 0x9BF5 0x6893 0x5727 0x65A1 \ + 0x6271 0x5B9B 0x59D0 0x867B 0x98F4 0x7D62 0x7DBE 0x9B8E \ + 0x6216 0x7C9F 0x88B7 0x5B89 0x5EB5 0x6309 0x6697 0x6848 \ + 0x95C7 0x978D 0x674F 0x4EE5 0x4F0A 0x4F4D 0x4F9D 0x5049 \ + 0x56F2 0x5937 0x59D4 0x5A01 0x5C09 0x60DF 0x610F 0x6170 \ + 0x6613 0x6905 0x70BA 0x754F 0x7570 0x79FB 0x7DAD 0x7DEF \ + 0x80C3 0x840E 0x8863 0x8B02 0x9055 0x907A 0x533B 0x4E95 \ + 0x4EA5 0x57DF 0x80B2 0x90C1 0x78EF 0x4E00 0x58F1 0x6EA2 \ + 0x9038 0x7A32 0x8328 0x828B 0x9C2F 0x5141 0x5370 0x54BD \ + 0x54E1 0x56E0 0x59FB 0x5F15 0x98F2 0x6DEB 0x80E4 0x852D \ + 0x9662 0x9670 0x96A0 0x97FB 0x540B 0x53F3 0x5B87 0x70CF \ + 0x7FBD 0x8FC2 0x96E8 0x536F 0x9D5C 0x7ABA 0x4E11 0x7893 \ + 0x81FC 0x6E26 0x5618 0x5504 0x6B1D 0x851A 0x9C3B 0x59E5 \ + 0x53A9 0x6D66 0x74DC 0x958F 0x5642 0x4E91 0x904B 0x96F2 +07 0x834F 0x990C 0x53E1 0x55B6 0x5B30 0x5F71 0x6620 0x66F3 \ + 0x6804 0x6C38 0x6CF3 0x6D29 0x745B 0x76C8 0x7A4E 0x9834 \ + 0x82F1 0x885B 0x8A60 0x92ED 0x6DB2 0x75AB 0x76CA 0x99C5 \ + 0x60A6 0x8B01 0x8D8A 0x95B2 0x698E 0x53AD 0x5186 0x5712 \ + 0x5830 0x5944 0x5BB4 0x5EF6 0x6028 0x63A9 0x63F4 0x6CBF \ + 0x6F14 0x708E 0x7114 0x7159 0x71D5 0x733F 0x7E01 0x8276 \ + 0x82D1 0x8597 0x9060 0x925B 0x9D1B 0x5869 0x65BC 0x6C5A \ + 0x7525 0x51F9 0x592E 0x5965 0x5F80 0x5FDC 0x62BC 0x65FA \ + 0x6A2A 0x6B27 0x6BB4 0x738B 0x7FC1 0x8956 0x9D2C 0x9D0E \ + 0x9EC4 0x5CA1 0x6C96 0x837B 0x5104 0x5C4B 0x61B6 0x81C6 \ + 0x6876 0x7261 0x4E59 0x4FFA 0x5378 0x6069 0x6E29 0x7A4F \ + 0x97F3 0x4E0B 0x5316 0x4EEE 0x4F55 0x4F3D 0x4FA1 0x4F73 \ + 0x52A0 0x53EF 0x5609 0x590F 0x5AC1 0x5BB6 0x5BE1 0x79D1 \ + 0x6687 0x679C 0x67B6 0x6B4C 0x6CB3 0x706B 0x73C2 0x798D \ + 0x79BE 0x7A3C 0x7B87 0x82B1 0x82DB 0x8304 0x8377 0x83EF \ + 0x83D3 0x8766 0x8AB2 0x5629 0x8CA8 0x8FE6 0x904E 0x971E \ + 0x868A 0x4FC4 0x5CE8 0x6211 0x7259 0x753B 0x81E5 0x82BD \ + 0x86FE 0x8CC0 0x96C5 0x9913 0x99D5 0x4ECB 0x4F1A 0x89E3 \ + 0x56DE 0x584A 0x58CA 0x5EFB 0x5FEB 0x602A 0x6094 0x6062 \ + 0x61D0 0x6212 0x62D0 0x6539 0x9B41 0x6666 0x68B0 0x6D77 \ + 0x7070 0x754C 0x7686 0x7D75 0x82A5 0x87F9 0x958B 0x968E \ + 0x8C9D 0x51F1 0x52BE 0x5916 0x54B3 0x5BB3 0x5D16 0x6168 \ + 0x6982 0x6DAF 0x788D 0x84CB 0x8857 0x8A72 0x93A7 0x9AB8 \ + 0x6D6C 0x99A8 0x86D9 0x57A3 0x67FF 0x86CE 0x920E 0x5283 \ + 0x5687 0x5404 0x5ED3 0x62E1 0x64B9 0x683C 0x6838 0x6BBB \ + 0x7372 0x78BA 0x7A6B 0x899A 0x89D2 0x8D6B 0x8F03 0x90ED \ + 0x95A3 0x9694 0x9769 0x5B66 0x5CB3 0x697D 0x984D 0x984E \ + 0x639B 0x7B20 0x6A2B 0x6A7F 0x68B6 0x9C0D 0x6F5F 0x5272 \ + 0x559D 0x6070 0x62EC 0x6D3B 0x6E07 0x6ED1 0x845B 0x8910 \ + 0x8F44 0x4E14 0x9C39 0x53F6 0x691B 0x6A3A 0x9784 0x682A \ + 0x515C 0x7AC3 0x84B2 0x91DC 0x938C 0x565B 0x9D28 0x6822 \ + 0x8305 0x8431 0x7CA5 0x5208 0x82C5 0x74E6 0x4E7E 0x4F83 +08 0x51A0 0x5BD2 0x520A 0x52D8 0x52E7 0x5DFB 0x559A 0x582A \ + 0x59E6 0x5B8C 0x5B98 0x5BDB 0x5E72 0x5E79 0x60A3 0x611F \ + 0x6163 0x61BE 0x63DB 0x6562 0x67D1 0x6853 0x68FA 0x6B3E \ + 0x6B53 0x6C57 0x6F22 0x6F97 0x6F45 0x74B0 0x7518 0x76E3 \ + 0x770B 0x7AFF 0x7BA1 0x7C21 0x7DE9 0x7F36 0x7FF0 0x809D \ + 0x8266 0x839E 0x89B3 0x8ACC 0x8CAB 0x9084 0x9451 0x9593 \ + 0x9591 0x95A2 0x9665 0x97D3 0x9928 0x8218 0x4E38 0x542B \ + 0x5CB8 0x5DCC 0x73A9 0x764C 0x773C 0x5CA9 0x7FEB 0x8D0B \ + 0x96C1 0x9811 0x9854 0x9858 0x4F01 0x4F0E 0x5371 0x559C \ + 0x5668 0x57FA 0x5947 0x5B09 0x5BC4 0x5C90 0x5E0C 0x5E7E \ + 0x5FCC 0x63EE 0x673A 0x65D7 0x65E2 0x671F 0x68CB 0x68C4 \ + 0x6A5F 0x5E30 0x6BC5 0x6C17 0x6C7D 0x757F 0x7948 0x5B63 \ + 0x7A00 0x7D00 0x5FBD 0x898F 0x8A18 0x8CB4 0x8D77 0x8ECC \ + 0x8F1D 0x98E2 0x9A0E 0x9B3C 0x4E80 0x507D 0x5100 0x5993 \ + 0x5B9C 0x622F 0x6280 0x64EC 0x6B3A 0x72A0 0x7591 0x7947 \ + 0x7FA9 0x87FB 0x8ABC 0x8B70 0x63AC 0x83CA 0x97A0 0x5409 \ + 0x5403 0x55AB 0x6854 0x6A58 0x8A70 0x7827 0x6775 0x9ECD \ + 0x5374 0x5BA2 0x811A 0x8650 0x9006 0x4E18 0x4E45 0x4EC7 \ + 0x4F11 0x53CA 0x5438 0x5BAE 0x5F13 0x6025 0x6551 0x673D \ + 0x6C42 0x6C72 0x6CE3 0x7078 0x7403 0x7A76 0x7AAE 0x7B08 \ + 0x7D1A 0x7CFE 0x7D66 0x65E7 0x725B 0x53BB 0x5C45 0x5DE8 \ + 0x62D2 0x62E0 0x6319 0x6E20 0x865A 0x8A31 0x8DDD 0x92F8 \ + 0x6F01 0x79A6 0x9B5A 0x4EA8 0x4EAB 0x4EAC 0x4F9B 0x4FA0 \ + 0x50D1 0x5147 0x7AF6 0x5171 0x51F6 0x5354 0x5321 0x537F \ + 0x53EB 0x55AC 0x5883 0x5CE1 0x5F37 0x5F4A 0x602F 0x6050 \ + 0x606D 0x631F 0x6559 0x6A4B 0x6CC1 0x72C2 0x72ED 0x77EF \ + 0x80F8 0x8105 0x8208 0x854E 0x90F7 0x93E1 0x97FF 0x9957 \ + 0x9A5A 0x4EF0 0x51DD 0x5C2D 0x6681 0x696D 0x5C40 0x66F2 \ + 0x6975 0x7389 0x6850 0x7C81 0x50C5 0x52E4 0x5747 0x5DFE \ + 0x9326 0x65A4 0x6B23 0x6B3D 0x7434 0x7981 0x79BD 0x7B4B \ + 0x7DCA 0x82B9 0x83CC 0x887F 0x895F 0x8B39 0x8FD1 0x91D1 \ + 0x541F 0x9280 0x4E5D 0x5036 0x53E5 0x533A 0x72D7 0x7396 +09 0x77E9 0x82E6 0x8EAF 0x99C6 0x99C8 0x99D2 0x5177 0x611A \ + 0x865E 0x55B0 0x7A7A 0x5076 0x5BD3 0x9047 0x9685 0x4E32 \ + 0x6ADB 0x91E7 0x5C51 0x5C48 0x6398 0x7A9F 0x6C93 0x9774 \ + 0x8F61 0x7AAA 0x718A 0x9688 0x7C82 0x6817 0x7E70 0x6851 \ + 0x936C 0x52F2 0x541B 0x85AB 0x8A13 0x7FA4 0x8ECD 0x90E1 \ + 0x5366 0x8888 0x7941 0x4FC2 0x50BE 0x5211 0x5144 0x5553 \ + 0x572D 0x73EA 0x578B 0x5951 0x5F62 0x5F84 0x6075 0x6176 \ + 0x6167 0x61A9 0x63B2 0x643A 0x656C 0x666F 0x6842 0x6E13 \ + 0x7566 0x7A3D 0x7CFB 0x7D4C 0x7D99 0x7E4B 0x7F6B 0x830E \ + 0x834A 0x86CD 0x8A08 0x8A63 0x8B66 0x8EFD 0x981A 0x9D8F \ + 0x82B8 0x8FCE 0x9BE8 0x5287 0x621F 0x6483 0x6FC0 0x9699 \ + 0x6841 0x5091 0x6B20 0x6C7A 0x6F54 0x7A74 0x7D50 0x8840 \ + 0x8A23 0x6708 0x4EF6 0x5039 0x5026 0x5065 0x517C 0x5238 \ + 0x5263 0x55A7 0x570F 0x5805 0x5ACC 0x5EFA 0x61B2 0x61F8 \ + 0x62F3 0x6372 0x691C 0x6A29 0x727D 0x72AC 0x732E 0x7814 \ + 0x786F 0x7D79 0x770C 0x80A9 0x898B 0x8B19 0x8CE2 0x8ED2 \ + 0x9063 0x9375 0x967A 0x9855 0x9A13 0x9E78 0x5143 0x539F \ + 0x53B3 0x5E7B 0x5F26 0x6E1B 0x6E90 0x7384 0x73FE 0x7D43 \ + 0x8237 0x8A00 0x8AFA 0x9650 0x4E4E 0x500B 0x53E4 0x547C \ + 0x56FA 0x59D1 0x5B64 0x5DF1 0x5EAB 0x5F27 0x6238 0x6545 \ + 0x67AF 0x6E56 0x72D0 0x7CCA 0x88B4 0x80A1 0x80E1 0x83F0 \ + 0x864E 0x8A87 0x8DE8 0x9237 0x96C7 0x9867 0x9F13 0x4E94 \ + 0x4E92 0x4F0D 0x5348 0x5449 0x543E 0x5A2F 0x5F8C 0x5FA1 \ + 0x609F 0x68A7 0x6A8E 0x745A 0x7881 0x8A9E 0x8AA4 0x8B77 \ + 0x9190 0x4E5E 0x9BC9 0x4EA4 0x4F7C 0x4FAF 0x5019 0x5016 \ + 0x5149 0x516C 0x529F 0x52B9 0x52FE 0x539A 0x53E3 0x5411 \ + 0x540E 0x5589 0x5751 0x57A2 0x597D 0x5B54 0x5B5D 0x5B8F \ + 0x5DE5 0x5DE7 0x5DF7 0x5E78 0x5E83 0x5E9A 0x5EB7 0x5F18 \ + 0x6052 0x614C 0x6297 0x62D8 0x63A7 0x653B 0x6602 0x6643 \ + 0x66F4 0x676D 0x6821 0x6897 0x69CB 0x6C5F 0x6D2A 0x6D69 \ + 0x6E2F 0x6E9D 0x7532 0x7687 0x786C 0x7A3F 0x7CE0 0x7D05 \ + 0x7D18 0x7D5E 0x7DB1 0x8015 0x8003 0x80AF 0x80B1 0x8154 +10 0x818F 0x822A 0x8352 0x884C 0x8861 0x8B1B 0x8CA2 0x8CFC \ + 0x90CA 0x9175 0x9271 0x783F 0x92FC 0x95A4 0x964D 0x9805 \ + 0x9999 0x9AD8 0x9D3B 0x525B 0x52AB 0x53F7 0x5408 0x58D5 \ + 0x62F7 0x6FE0 0x8C6A 0x8F5F 0x9EB9 0x514B 0x523B 0x544A \ + 0x56FD 0x7A40 0x9177 0x9D60 0x9ED2 0x7344 0x6F09 0x8170 \ + 0x7511 0x5FFD 0x60DA 0x9AA8 0x72DB 0x8FBC 0x6B64 0x9803 \ + 0x4ECA 0x56F0 0x5764 0x58BE 0x5A5A 0x6068 0x61C7 0x660F \ + 0x6606 0x6839 0x68B1 0x6DF7 0x75D5 0x7D3A 0x826E 0x9B42 \ + 0x4E9B 0x4F50 0x53C9 0x5506 0x5D6F 0x5DE6 0x5DEE 0x67FB \ + 0x6C99 0x7473 0x7802 0x8A50 0x9396 0x88DF 0x5750 0x5EA7 \ + 0x632B 0x50B5 0x50AC 0x518D 0x6700 0x54C9 0x585E 0x59BB \ + 0x5BB0 0x5F69 0x624D 0x63A1 0x683D 0x6B73 0x6E08 0x707D \ + 0x91C7 0x7280 0x7815 0x7826 0x796D 0x658E 0x7D30 0x83DC \ + 0x88C1 0x8F09 0x969B 0x5264 0x5728 0x6750 0x7F6A 0x8CA1 \ + 0x51B4 0x5742 0x962A 0x583A 0x698A 0x80B4 0x54B2 0x5D0E \ + 0x57FC 0x7895 0x9DFA 0x4F5C 0x524A 0x548B 0x643E 0x6628 \ + 0x6714 0x67F5 0x7A84 0x7B56 0x7D22 0x932F 0x685C 0x9BAD \ + 0x7B39 0x5319 0x518A 0x5237 0x5BDF 0x62F6 0x64AE 0x64E6 \ + 0x672D 0x6BBA 0x85A9 0x96D1 0x7690 0x9BD6 0x634C 0x9306 \ + 0x9BAB 0x76BF 0x6652 0x4E09 0x5098 0x53C2 0x5C71 0x60E8 \ + 0x6492 0x6563 0x685F 0x71E6 0x73CA 0x7523 0x7B97 0x7E82 \ + 0x8695 0x8B83 0x8CDB 0x9178 0x9910 0x65AC 0x66AB 0x6B8B \ + 0x4ED5 0x4ED4 0x4F3A 0x4F7F 0x523A 0x53F8 0x53F2 0x55E3 \ + 0x56DB 0x58EB 0x59CB 0x59C9 0x59FF 0x5B50 0x5C4D 0x5E02 \ + 0x5E2B 0x5FD7 0x601D 0x6307 0x652F 0x5B5C 0x65AF 0x65BD \ + 0x65E8 0x679D 0x6B62 0x6B7B 0x6C0F 0x7345 0x7949 0x79C1 \ + 0x7CF8 0x7D19 0x7D2B 0x80A2 0x8102 0x81F3 0x8996 0x8A5E \ + 0x8A69 0x8A66 0x8A8C 0x8AEE 0x8CC7 0x8CDC 0x96CC 0x98FC \ + 0x6B6F 0x4E8B 0x4F3C 0x4F8D 0x5150 0x5B57 0x5BFA 0x6148 \ + 0x6301 0x6642 0x6B21 0x6ECB 0x6CBB 0x723E 0x74BD 0x75D4 \ + 0x78C1 0x793A 0x800C 0x8033 0x81EA 0x8494 0x8F9E 0x6C50 \ + 0x9E7F 0x5F0F 0x8B58 0x9D2B 0x7AFA 0x8EF8 0x5B8D 0x96EB +11 0x4E03 0x53F1 0x57F7 0x5931 0x5AC9 0x5BA4 0x6089 0x6E7F \ + 0x6F06 0x75BE 0x8CEA 0x5B9F 0x8500 0x7BE0 0x5072 0x67F4 \ + 0x829D 0x5C61 0x854A 0x7E1E 0x820E 0x5199 0x5C04 0x6368 \ + 0x8D66 0x659C 0x716E 0x793E 0x7D17 0x8005 0x8B1D 0x8ECA \ + 0x906E 0x86C7 0x90AA 0x501F 0x52FA 0x5C3A 0x6753 0x707C \ + 0x7235 0x914C 0x91C8 0x932B 0x82E5 0x5BC2 0x5F31 0x60F9 \ + 0x4E3B 0x53D6 0x5B88 0x624B 0x6731 0x6B8A 0x72E9 0x73E0 \ + 0x7A2E 0x816B 0x8DA3 0x9152 0x9996 0x5112 0x53D7 0x546A \ + 0x5BFF 0x6388 0x6A39 0x7DAC 0x9700 0x56DA 0x53CE 0x5468 \ + 0x5B97 0x5C31 0x5DDE 0x4FEE 0x6101 0x62FE 0x6D32 0x79C0 \ + 0x79CB 0x7D42 0x7E4D 0x7FD2 0x81ED 0x821F 0x8490 0x8846 \ + 0x8972 0x8B90 0x8E74 0x8F2F 0x9031 0x914B 0x916C 0x96C6 \ + 0x919C 0x4EC0 0x4F4F 0x5145 0x5341 0x5F93 0x620E 0x67D4 \ + 0x6C41 0x6E0B 0x7363 0x7E26 0x91CD 0x9283 0x53D4 0x5919 \ + 0x5BBF 0x6DD1 0x795D 0x7E2E 0x7C9B 0x587E 0x719F 0x51FA \ + 0x8853 0x8FF0 0x4FCA 0x5CFB 0x6625 0x77AC 0x7AE3 0x821C \ + 0x99FF 0x51C6 0x5FAA 0x65EC 0x696F 0x6B89 0x6DF3 0x6E96 \ + 0x6F64 0x76FE 0x7D14 0x5DE1 0x9075 0x9187 0x9806 0x51E6 \ + 0x521D 0x6240 0x6691 0x66D9 0x6E1A 0x5EB6 0x7DD2 0x7F72 \ + 0x66F8 0x85AF 0x85F7 0x8AF8 0x52A9 0x53D9 0x5973 0x5E8F \ + 0x5F90 0x6055 0x92E4 0x9664 0x50B7 0x511F 0x52DD 0x5320 \ + 0x5347 0x53EC 0x54E8 0x5546 0x5531 0x5617 0x5968 0x59BE \ + 0x5A3C 0x5BB5 0x5C06 0x5C0F 0x5C11 0x5C1A 0x5E84 0x5E8A \ + 0x5EE0 0x5F70 0x627F 0x6284 0x62DB 0x638C 0x6377 0x6607 \ + 0x660C 0x662D 0x6676 0x677E 0x68A2 0x6A1F 0x6A35 0x6CBC \ + 0x6D88 0x6E09 0x6E58 0x713C 0x7126 0x7167 0x75C7 0x7701 \ + 0x785D 0x7901 0x7965 0x79F0 0x7AE0 0x7B11 0x7CA7 0x7D39 \ + 0x8096 0x83D6 0x848B 0x8549 0x885D 0x88F3 0x8A1F 0x8A3C \ + 0x8A54 0x8A73 0x8C61 0x8CDE 0x91A4 0x9266 0x937E 0x9418 \ + 0x969C 0x9798 0x4E0A 0x4E08 0x4E1E 0x4E57 0x5197 0x5270 \ + 0x57CE 0x5834 0x58CC 0x5B22 0x5E38 0x60C5 0x64FE 0x6761 \ + 0x6756 0x6D44 0x72B6 0x7573 0x7A63 0x84B8 0x8B72 0x91B8 +12 0x9320 0x5631 0x57F4 0x98FE 0x62ED 0x690D 0x6B96 0x71ED \ + 0x7E54 0x8077 0x8272 0x89E6 0x98DF 0x8755 0x8FB1 0x5C3B \ + 0x4F38 0x4FE1 0x4FB5 0x5507 0x5A20 0x5BDD 0x5BE9 0x5FC3 \ + 0x614E 0x632F 0x65B0 0x664B 0x68EE 0x699B 0x6D78 0x6DF1 \ + 0x7533 0x75B9 0x771F 0x795E 0x79E6 0x7D33 0x81E3 0x82AF \ + 0x85AA 0x89AA 0x8A3A 0x8EAB 0x8F9B 0x9032 0x91DD 0x9707 \ + 0x4EBA 0x4EC1 0x5203 0x5875 0x58EC 0x5C0B 0x751A 0x5C3D \ + 0x814E 0x8A0A 0x8FC5 0x9663 0x976D 0x7B25 0x8ACF 0x9808 \ + 0x9162 0x56F3 0x53A8 0x9017 0x5439 0x5782 0x5E25 0x63A8 \ + 0x6C34 0x708A 0x7761 0x7C8B 0x7FE0 0x8870 0x9042 0x9154 \ + 0x9310 0x9318 0x968F 0x745E 0x9AC4 0x5D07 0x5D69 0x6570 \ + 0x67A2 0x8DA8 0x96DB 0x636E 0x6749 0x6919 0x83C5 0x9817 \ + 0x96C0 0x88FE 0x6F84 0x647A 0x5BF8 0x4E16 0x702C 0x755D \ + 0x662F 0x51C4 0x5236 0x52E2 0x59D3 0x5F81 0x6027 0x6210 \ + 0x653F 0x6574 0x661F 0x6674 0x68F2 0x6816 0x6B63 0x6E05 \ + 0x7272 0x751F 0x76DB 0x7CBE 0x8056 0x58F0 0x88FD 0x897F \ + 0x8AA0 0x8A93 0x8ACB 0x901D 0x9192 0x9752 0x9759 0x6589 \ + 0x7A0E 0x8106 0x96BB 0x5E2D 0x60DC 0x621A 0x65A5 0x6614 \ + 0x6790 0x77F3 0x7A4D 0x7C4D 0x7E3E 0x810A 0x8CAC 0x8D64 \ + 0x8DE1 0x8E5F 0x78A9 0x5207 0x62D9 0x63A5 0x6442 0x6298 \ + 0x8A2D 0x7A83 0x7BC0 0x8AAC 0x96EA 0x7D76 0x820C 0x8749 \ + 0x4ED9 0x5148 0x5343 0x5360 0x5BA3 0x5C02 0x5C16 0x5DDD \ + 0x6226 0x6247 0x64B0 0x6813 0x6834 0x6CC9 0x6D45 0x6D17 \ + 0x67D3 0x6F5C 0x714E 0x717D 0x65CB 0x7A7F 0x7BAD 0x7DDA \ + 0x7E4A 0x7FA8 0x817A 0x821B 0x8239 0x85A6 0x8A6E 0x8CCE \ + 0x8DF5 0x9078 0x9077 0x92AD 0x9291 0x9583 0x9BAE 0x524D \ + 0x5584 0x6F38 0x7136 0x5168 0x7985 0x7E55 0x81B3 0x7CCE \ + 0x564C 0x5851 0x5CA8 0x63AA 0x66FE 0x66FD 0x695A 0x72D9 \ + 0x758F 0x758E 0x790E 0x7956 0x79DF 0x7C97 0x7D20 0x7D44 \ + 0x8607 0x8A34 0x963B 0x9061 0x9F20 0x50E7 0x5275 0x53CC \ + 0x53E2 0x5009 0x55AA 0x58EE 0x594F 0x723D 0x5B8B 0x5C64 \ + 0x531D 0x60E3 0x60F3 0x635C 0x6383 0x633F 0x63BB 0x64CD +13 0x65E9 0x66F9 0x5DE3 0x69CD 0x69FD 0x6F15 0x71E5 0x4E89 \ + 0x75E9 0x76F8 0x7A93 0x7CDF 0x7DCF 0x7D9C 0x8061 0x8349 \ + 0x8358 0x846C 0x84BC 0x85FB 0x88C5 0x8D70 0x9001 0x906D \ + 0x9397 0x971C 0x9A12 0x50CF 0x5897 0x618E 0x81D3 0x8535 \ + 0x8D08 0x9020 0x4FC3 0x5074 0x5247 0x5373 0x606F 0x6349 \ + 0x675F 0x6E2C 0x8DB3 0x901F 0x4FD7 0x5C5E 0x8CCA 0x65CF \ + 0x7D9A 0x5352 0x8896 0x5176 0x63C3 0x5B58 0x5B6B 0x5C0A \ + 0x640D 0x6751 0x905C 0x4ED6 0x591A 0x592A 0x6C70 0x8A51 \ + 0x553E 0x5815 0x59A5 0x60F0 0x6253 0x67C1 0x8235 0x6955 \ + 0x9640 0x99C4 0x9A28 0x4F53 0x5806 0x5BFE 0x8010 0x5CB1 \ + 0x5E2F 0x5F85 0x6020 0x614B 0x6234 0x66FF 0x6CF0 0x6EDE \ + 0x80CE 0x817F 0x82D4 0x888B 0x8CB8 0x9000 0x902E 0x968A \ + 0x9EDB 0x9BDB 0x4EE3 0x53F0 0x5927 0x7B2C 0x918D 0x984C \ + 0x9DF9 0x6EDD 0x7027 0x5353 0x5544 0x5B85 0x6258 0x629E \ + 0x62D3 0x6CA2 0x6FEF 0x7422 0x8A17 0x9438 0x6FC1 0x8AFE \ + 0x8338 0x51E7 0x86F8 0x53EA 0x53E9 0x4F46 0x9054 0x8FB0 \ + 0x596A 0x8131 0x5DFD 0x7AEA 0x8FBF 0x68DA 0x8C37 0x72F8 \ + 0x9C48 0x6A3D 0x8AB0 0x4E39 0x5358 0x5606 0x5766 0x62C5 \ + 0x63A2 0x65E6 0x6B4E 0x6DE1 0x6E5B 0x70AD 0x77ED 0x7AEF \ + 0x7BAA 0x7DBB 0x803D 0x80C6 0x86CB 0x8A95 0x935B 0x56E3 \ + 0x58C7 0x5F3E 0x65AD 0x6696 0x6A80 0x6BB5 0x7537 0x8AC7 \ + 0x5024 0x77E5 0x5730 0x5F1B 0x6065 0x667A 0x6C60 0x75F4 \ + 0x7A1A 0x7F6E 0x81F4 0x8718 0x9045 0x99B3 0x7BC9 0x755C \ + 0x7AF9 0x7B51 0x84C4 0x9010 0x79E9 0x7A92 0x8336 0x5AE1 \ + 0x7740 0x4E2D 0x4EF2 0x5B99 0x5FE0 0x62BD 0x663C 0x67F1 \ + 0x6CE8 0x866B 0x8877 0x8A3B 0x914E 0x92F3 0x99D0 0x6A17 \ + 0x7026 0x732A 0x82E7 0x8457 0x8CAF 0x4E01 0x5146 0x51CB \ + 0x558B 0x5BF5 0x5E16 0x5E33 0x5E81 0x5F14 0x5F35 0x5F6B \ + 0x5FB4 0x61F2 0x6311 0x66A2 0x671D 0x6F6E 0x7252 0x753A \ + 0x773A 0x8074 0x8139 0x8178 0x8776 0x8ABF 0x8ADC 0x8D85 \ + 0x8DF3 0x929A 0x9577 0x9802 0x9CE5 0x52C5 0x6357 0x76F4 \ + 0x6715 0x6C88 0x73CD 0x8CC3 0x93AE 0x9673 0x6D25 0x589C +14 0x690E 0x69CC 0x8FFD 0x939A 0x75DB 0x901A 0x585A 0x6802 \ + 0x63B4 0x69FB 0x4F43 0x6F2C 0x67D8 0x8FBB 0x8526 0x7DB4 \ + 0x9354 0x693F 0x6F70 0x576A 0x58F7 0x5B2C 0x7D2C 0x722A \ + 0x540A 0x91E3 0x9DB4 0x4EAD 0x4F4E 0x505C 0x5075 0x5243 \ + 0x8C9E 0x5448 0x5824 0x5B9A 0x5E1D 0x5E95 0x5EAD 0x5EF7 \ + 0x5F1F 0x608C 0x62B5 0x633A 0x63D0 0x68AF 0x6C40 0x7887 \ + 0x798E 0x7A0B 0x7DE0 0x8247 0x8A02 0x8AE6 0x8E44 0x9013 \ + 0x90B8 0x912D 0x91D8 0x9F0E 0x6CE5 0x6458 0x64E2 0x6575 \ + 0x6EF4 0x7684 0x7B1B 0x9069 0x93D1 0x6EBA 0x54F2 0x5FB9 \ + 0x64A4 0x8F4D 0x8FED 0x9244 0x5178 0x586B 0x5929 0x5C55 \ + 0x5E97 0x6DFB 0x7E8F 0x751C 0x8CBC 0x8EE2 0x985B 0x70B9 \ + 0x4F1D 0x6BBF 0x6FB1 0x7530 0x96FB 0x514E 0x5410 0x5835 \ + 0x5857 0x59AC 0x5C60 0x5F92 0x6597 0x675C 0x6E21 0x767B \ + 0x83DF 0x8CED 0x9014 0x90FD 0x934D 0x7825 0x783A 0x52AA \ + 0x5EA6 0x571F 0x5974 0x6012 0x5012 0x515A 0x51AC 0x51CD \ + 0x5200 0x5510 0x5854 0x5858 0x5957 0x5B95 0x5CF6 0x5D8B \ + 0x60BC 0x6295 0x642D 0x6771 0x6843 0x68BC 0x68DF 0x76D7 \ + 0x6DD8 0x6E6F 0x6D9B 0x706F 0x71C8 0x5F53 0x75D8 0x7977 \ + 0x7B49 0x7B54 0x7B52 0x7CD6 0x7D71 0x5230 0x8463 0x8569 \ + 0x85E4 0x8A0E 0x8B04 0x8C46 0x8E0F 0x9003 0x900F 0x9419 \ + 0x9676 0x982D 0x9A30 0x95D8 0x50CD 0x52D5 0x540C 0x5802 \ + 0x5C0E 0x61A7 0x649E 0x6D1E 0x77B3 0x7AE5 0x80F4 0x8404 \ + 0x9053 0x9285 0x5CE0 0x9D07 0x533F 0x5F97 0x5FB3 0x6D9C \ + 0x7279 0x7763 0x79BF 0x7BE4 0x6BD2 0x72EC 0x8AAD 0x6803 \ + 0x6A61 0x51F8 0x7A81 0x6934 0x5C4A 0x9CF6 0x82EB 0x5BC5 \ + 0x9149 0x701E 0x5678 0x5C6F 0x60C7 0x6566 0x6C8C 0x8C5A \ + 0x9041 0x9813 0x5451 0x66C7 0x920D 0x5948 0x90A3 0x5185 \ + 0x4E4D 0x51EA 0x8599 0x8B0E 0x7058 0x637A 0x934B 0x6962 \ + 0x99B4 0x7E04 0x7577 0x5357 0x6960 0x8EDF 0x96E3 0x6C5D \ + 0x4E8C 0x5C3C 0x5F10 0x8FE9 0x5302 0x8CD1 0x8089 0x8679 \ + 0x5EFF 0x65E5 0x4E73 0x5165 0x5982 0x5C3F 0x97EE 0x4EFB \ + 0x598A 0x5FCD 0x8A8D 0x6FE1 0x79B0 0x7962 0x5BE7 0x8471 +15 0x732B 0x71B1 0x5E74 0x5FF5 0x637B 0x649A 0x71C3 0x7C98 \ + 0x4E43 0x5EFC 0x4E4B 0x57DC 0x56A2 0x60A9 0x6FC3 0x7D0D \ + 0x80FD 0x8133 0x81BF 0x8FB2 0x8997 0x86A4 0x5DF4 0x628A \ + 0x64AD 0x8987 0x6777 0x6CE2 0x6D3E 0x7436 0x7834 0x5A46 \ + 0x7F75 0x82AD 0x99AC 0x4FF3 0x5EC3 0x62DD 0x6392 0x6557 \ + 0x676F 0x76C3 0x724C 0x80CC 0x80BA 0x8F29 0x914D 0x500D \ + 0x57F9 0x5A92 0x6885 0x6973 0x7164 0x72FD 0x8CB7 0x58F2 \ + 0x8CE0 0x966A 0x9019 0x877F 0x79E4 0x77E7 0x8429 0x4F2F \ + 0x5265 0x535A 0x62CD 0x67CF 0x6CCA 0x767D 0x7B94 0x7C95 \ + 0x8236 0x8584 0x8FEB 0x66DD 0x6F20 0x7206 0x7E1B 0x83AB \ + 0x99C1 0x9EA6 0x51FD 0x7BB1 0x7872 0x7BB8 0x8087 0x7B48 \ + 0x6AE8 0x5E61 0x808C 0x7551 0x7560 0x516B 0x9262 0x6E8C \ + 0x767A 0x9197 0x9AEA 0x4F10 0x7F70 0x629C 0x7B4F 0x95A5 \ + 0x9CE9 0x567A 0x5859 0x86E4 0x96BC 0x4F34 0x5224 0x534A \ + 0x53CD 0x53DB 0x5E06 0x642C 0x6591 0x677F 0x6C3E 0x6C4E \ + 0x7248 0x72AF 0x73ED 0x7554 0x7E41 0x822C 0x85E9 0x8CA9 \ + 0x7BC4 0x91C6 0x7169 0x9812 0x98EF 0x633D 0x6669 0x756A \ + 0x76E4 0x78D0 0x8543 0x86EE 0x532A 0x5351 0x5426 0x5983 \ + 0x5E87 0x5F7C 0x60B2 0x6249 0x6279 0x62AB 0x6590 0x6BD4 \ + 0x6CCC 0x75B2 0x76AE 0x7891 0x79D8 0x7DCB 0x7F77 0x80A5 \ + 0x88AB 0x8AB9 0x8CBB 0x907F 0x975E 0x98DB 0x6A0B 0x7C38 \ + 0x5099 0x5C3E 0x5FAE 0x6787 0x6BD8 0x7435 0x7709 0x7F8E \ + 0x9F3B 0x67CA 0x7A17 0x5339 0x758B 0x9AED 0x5F66 0x819D \ + 0x83F1 0x8098 0x5F3C 0x5FC5 0x7562 0x7B46 0x903C 0x6867 \ + 0x59EB 0x5A9B 0x7D10 0x767E 0x8B2C 0x4FF5 0x5F6A 0x6A19 \ + 0x6C37 0x6F02 0x74E2 0x7968 0x8868 0x8A55 0x8C79 0x5EDF \ + 0x63CF 0x75C5 0x79D2 0x82D7 0x9328 0x92F2 0x849C 0x86ED \ + 0x9C2D 0x54C1 0x5F6C 0x658C 0x6D5C 0x7015 0x8CA7 0x8CD3 \ + 0x983B 0x654F 0x74F6 0x4E0D 0x4ED8 0x57E0 0x592B 0x5A66 \ + 0x5BCC 0x51A8 0x5E03 0x5E9C 0x6016 0x6276 0x6577 0x65A7 \ + 0x666E 0x6D6E 0x7236 0x7B26 0x8150 0x819A 0x8299 0x8B5C \ + 0x8CA0 0x8CE6 0x8D74 0x961C 0x9644 0x4FAE 0x64AB 0x6B66 +16 0x821E 0x8461 0x856A 0x90E8 0x5C01 0x6953 0x98A8 0x847A \ + 0x8557 0x4F0F 0x526F 0x5FA9 0x5E45 0x670D 0x798F 0x8179 \ + 0x8907 0x8986 0x6DF5 0x5F17 0x6255 0x6CB8 0x4ECF 0x7269 \ + 0x9B92 0x5206 0x543B 0x5674 0x58B3 0x61A4 0x626E 0x711A \ + 0x596E 0x7C89 0x7CDE 0x7D1B 0x96F0 0x6587 0x805E 0x4E19 \ + 0x4F75 0x5175 0x5840 0x5E63 0x5E73 0x5F0A 0x67C4 0x4E26 \ + 0x853D 0x9589 0x965B 0x7C73 0x9801 0x50FB 0x58C1 0x7656 \ + 0x78A7 0x5225 0x77A5 0x8511 0x7B86 0x504F 0x5909 0x7247 \ + 0x7BC7 0x7DE8 0x8FBA 0x8FD4 0x904D 0x4FBF 0x52C9 0x5A29 \ + 0x5F01 0x97AD 0x4FDD 0x8217 0x92EA 0x5703 0x6355 0x6B69 \ + 0x752B 0x88DC 0x8F14 0x7A42 0x52DF 0x5893 0x6155 0x620A \ + 0x66AE 0x6BCD 0x7C3F 0x83E9 0x5023 0x4FF8 0x5305 0x5446 \ + 0x5831 0x5949 0x5B9D 0x5CF0 0x5CEF 0x5D29 0x5E96 0x62B1 \ + 0x6367 0x653E 0x65B9 0x670B 0x6CD5 0x6CE1 0x70F9 0x7832 \ + 0x7E2B 0x80DE 0x82B3 0x840C 0x84EC 0x8702 0x8912 0x8A2A \ + 0x8C4A 0x90A6 0x92D2 0x98FD 0x9CF3 0x9D6C 0x4E4F 0x4EA1 \ + 0x508D 0x5256 0x574A 0x59A8 0x5E3D 0x5FD8 0x5FD9 0x623F \ + 0x66B4 0x671B 0x67D0 0x68D2 0x5192 0x7D21 0x80AA 0x81A8 \ + 0x8B00 0x8C8C 0x8CBF 0x927E 0x9632 0x5420 0x982C 0x5317 \ + 0x50D5 0x535C 0x58A8 0x64B2 0x6734 0x7267 0x7766 0x7A46 \ + 0x91E6 0x52C3 0x6CA1 0x6B86 0x5800 0x5E4C 0x5954 0x672C \ + 0x7FFB 0x51E1 0x76C6 0x6469 0x78E8 0x9B54 0x9EBB 0x57CB \ + 0x59B9 0x6627 0x679A 0x6BCE 0x54E9 0x69D9 0x5E55 0x819C \ + 0x6795 0x9BAA 0x67FE 0x9C52 0x685D 0x4EA6 0x4FE3 0x53C8 \ + 0x62B9 0x672B 0x6CAB 0x8FC4 0x4FAD 0x7E6D 0x9EBF 0x4E07 \ + 0x6162 0x6E80 0x6F2B 0x8513 0x5473 0x672A 0x9B45 0x5DF3 \ + 0x7B95 0x5CAC 0x5BC6 0x871C 0x6E4A 0x84D1 0x7A14 0x8108 \ + 0x5999 0x7C8D 0x6C11 0x7720 0x52D9 0x5922 0x7121 0x725F \ + 0x77DB 0x9727 0x9D61 0x690B 0x5A7F 0x5A18 0x51A5 0x540D \ + 0x547D 0x660E 0x76DF 0x8FF7 0x9298 0x9CF4 0x59EA 0x725D \ + 0x6EC5 0x514D 0x68C9 0x7DBF 0x7DEC 0x9762 0x9EBA 0x6478 \ + 0x6A21 0x8302 0x5984 0x5B5F 0x6BDB 0x731B 0x76F2 0x7DB2 +17 0x8017 0x8499 0x5132 0x6728 0x9ED9 0x76EE 0x6762 0x52FF \ + 0x9905 0x5C24 0x623B 0x7C7E 0x8CB0 0x554F 0x60B6 0x7D0B \ + 0x9580 0x5301 0x4E5F 0x51B6 0x591C 0x723A 0x8036 0x91CE \ + 0x5F25 0x77E2 0x5384 0x5F79 0x7D04 0x85AC 0x8A33 0x8E8D \ + 0x9756 0x67F3 0x85AE 0x9453 0x6109 0x6108 0x6CB9 0x7652 \ + 0x8AED 0x8F38 0x552F 0x4F51 0x512A 0x52C7 0x53CB 0x5BA5 \ + 0x5E7D 0x60A0 0x6182 0x63D6 0x6709 0x67DA 0x6E67 0x6D8C \ + 0x7336 0x7337 0x7531 0x7950 0x88D5 0x8A98 0x904A 0x9091 \ + 0x90F5 0x96C4 0x878D 0x5915 0x4E88 0x4F59 0x4E0E 0x8A89 \ + 0x8F3F 0x9810 0x50AD 0x5E7C 0x5996 0x5BB9 0x5EB8 0x63DA \ + 0x63FA 0x64C1 0x66DC 0x694A 0x69D8 0x6D0B 0x6EB6 0x7194 \ + 0x7528 0x7AAF 0x7F8A 0x8000 0x8449 0x84C9 0x8981 0x8B21 \ + 0x8E0A 0x9065 0x967D 0x990A 0x617E 0x6291 0x6B32 0x6C83 \ + 0x6D74 0x7FCC 0x7FFC 0x6DC0 0x7F85 0x87BA 0x88F8 0x6765 \ + 0x83B1 0x983C 0x96F7 0x6D1B 0x7D61 0x843D 0x916A 0x4E71 \ + 0x5375 0x5D50 0x6B04 0x6FEB 0x85CD 0x862D 0x89A7 0x5229 \ + 0x540F 0x5C65 0x674E 0x68A8 0x7406 0x7483 0x75E2 0x88CF \ + 0x88E1 0x91CC 0x96E2 0x9678 0x5F8B 0x7387 0x7ACB 0x844E \ + 0x63A0 0x7565 0x5289 0x6D41 0x6E9C 0x7409 0x7559 0x786B \ + 0x7C92 0x9686 0x7ADC 0x9F8D 0x4FB6 0x616E 0x65C5 0x865C \ + 0x4E86 0x4EAE 0x50DA 0x4E21 0x51CC 0x5BEE 0x6599 0x6881 \ + 0x6DBC 0x731F 0x7642 0x77AD 0x7A1C 0x7CE7 0x826F 0x8AD2 \ + 0x907C 0x91CF 0x9675 0x9818 0x529B 0x7DD1 0x502B 0x5398 \ + 0x6797 0x6DCB 0x71D0 0x7433 0x81E8 0x8F2A 0x96A3 0x9C57 \ + 0x9E9F 0x7460 0x5841 0x6D99 0x7D2F 0x985E 0x4EE4 0x4F36 \ + 0x4F8B 0x51B7 0x52B1 0x5DBA 0x601C 0x73B2 0x793C 0x82D3 \ + 0x9234 0x96B7 0x96F6 0x970A 0x9E97 0x9F62 0x66A6 0x6B74 \ + 0x5217 0x52A3 0x70C8 0x88C2 0x5EC9 0x604B 0x6190 0x6F23 \ + 0x7149 0x7C3E 0x7DF4 0x806F 0x84EE 0x9023 0x932C 0x5442 \ + 0x9B6F 0x6AD3 0x7089 0x8CC2 0x8DEF 0x9732 0x52B4 0x5A41 \ + 0x5ECA 0x5F04 0x6717 0x697C 0x6994 0x6D6A 0x6F0F 0x7262 \ + 0x72FC 0x7BED 0x8001 0x807E 0x874B 0x90CE 0x516D 0x9E93 +18 0x7984 0x808B 0x9332 0x8AD6 0x502D 0x548C 0x8A71 0x6B6A \ + 0x8CC4 0x8107 0x60D1 0x67A0 0x9DF2 0x4E99 0x4E98 0x9C10 \ + 0x8A6B 0x85C1 0x8568 0x6900 0x6E7E 0x7897 0x8155 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x5F0C 0x4E10 0x4E15 0x4E2A 0x4E31 0x4E36 \ + 0x4E3C 0x4E3F 0x4E42 0x4E56 0x4E58 0x4E82 0x4E85 0x8C6B \ + 0x4E8A 0x8212 0x5F0D 0x4E8E 0x4E9E 0x4E9F 0x4EA0 0x4EA2 \ + 0x4EB0 0x4EB3 0x4EB6 0x4ECE 0x4ECD 0x4EC4 0x4EC6 0x4EC2 \ + 0x4ED7 0x4EDE 0x4EED 0x4EDF 0x4EF7 0x4F09 0x4F5A 0x4F30 \ + 0x4F5B 0x4F5D 0x4F57 0x4F47 0x4F76 0x4F88 0x4F8F 0x4F98 \ + 0x4F7B 0x4F69 0x4F70 0x4F91 0x4F6F 0x4F86 0x4F96 0x5118 \ + 0x4FD4 0x4FDF 0x4FCE 0x4FD8 0x4FDB 0x4FD1 0x4FDA 0x4FD0 \ + 0x4FE4 0x4FE5 0x501A 0x5028 0x5014 0x502A 0x5025 0x5005 \ + 0x4F1C 0x4FF6 0x5021 0x5029 0x502C 0x4FFE 0x4FEF 0x5011 \ + 0x5006 0x5043 0x5047 0x6703 0x5055 0x5050 0x5048 0x505A \ + 0x5056 0x506C 0x5078 0x5080 0x509A 0x5085 0x50B4 0x50B2 \ + 0x50C9 0x50CA 0x50B3 0x50C2 0x50D6 0x50DE 0x50E5 0x50ED \ + 0x50E3 0x50EE 0x50F9 0x50F5 0x5109 0x5101 0x5102 0x5116 \ + 0x5115 0x5114 0x511A 0x5121 0x513A 0x5137 0x513C 0x513B \ + 0x513F 0x5140 0x5152 0x514C 0x5154 0x5162 0x7AF8 0x5169 \ + 0x516A 0x516E 0x5180 0x5182 0x56D8 0x518C 0x5189 0x518F \ + 0x5191 0x5193 0x5195 0x5196 0x51A4 0x51A6 0x51A2 0x51A9 \ + 0x51AA 0x51AB 0x51B3 0x51B1 0x51B2 0x51B0 0x51B5 0x51BD \ + 0x51C5 0x51C9 0x51DB 0x51E0 0x8655 0x51E9 0x51ED 0x51F0 \ + 0x51F5 0x51FE 0x5204 0x520B 0x5214 0x520E 0x5227 0x522A \ + 0x522E 0x5233 0x5239 0x524F 0x5244 0x524B 0x524C 0x525E \ + 0x5254 0x526A 0x5274 0x5269 0x5273 0x527F 0x527D 0x528D \ + 0x5294 0x5292 0x5271 0x5288 0x5291 0x8FA8 0x8FA7 0x52AC +19 0x52AD 0x52BC 0x52B5 0x52C1 0x52CD 0x52D7 0x52DE 0x52E3 \ + 0x52E6 0x98ED 0x52E0 0x52F3 0x52F5 0x52F8 0x52F9 0x5306 \ + 0x5308 0x7538 0x530D 0x5310 0x530F 0x5315 0x531A 0x5323 \ + 0x532F 0x5331 0x5333 0x5338 0x5340 0x5346 0x5345 0x4E17 \ + 0x5349 0x534D 0x51D6 0x535E 0x5369 0x536E 0x5918 0x537B \ + 0x5377 0x5382 0x5396 0x53A0 0x53A6 0x53A5 0x53AE 0x53B0 \ + 0x53B6 0x53C3 0x7C12 0x96D9 0x53DF 0x66FC 0x71EE 0x53EE \ + 0x53E8 0x53ED 0x53FA 0x5401 0x543D 0x5440 0x542C 0x542D \ + 0x543C 0x542E 0x5436 0x5429 0x541D 0x544E 0x548F 0x5475 \ + 0x548E 0x545F 0x5471 0x5477 0x5470 0x5492 0x547B 0x5480 \ + 0x5476 0x5484 0x5490 0x5486 0x54C7 0x54A2 0x54B8 0x54A5 \ + 0x54AC 0x54C4 0x54C8 0x54A8 0x54AB 0x54C2 0x54A4 0x54BE \ + 0x54BC 0x54D8 0x54E5 0x54E6 0x550F 0x5514 0x54FD 0x54EE \ + 0x54ED 0x54FA 0x54E2 0x5539 0x5540 0x5563 0x554C 0x552E \ + 0x555C 0x5545 0x5556 0x5557 0x5538 0x5533 0x555D 0x5599 \ + 0x5580 0x54AF 0x558A 0x559F 0x557B 0x557E 0x5598 0x559E \ + 0x55AE 0x557C 0x5583 0x55A9 0x5587 0x55A8 0x55DA 0x55C5 \ + 0x55DF 0x55C4 0x55DC 0x55E4 0x55D4 0x5614 0x55F7 0x5616 \ + 0x55FE 0x55FD 0x561B 0x55F9 0x564E 0x5650 0x71DF 0x5634 \ + 0x5636 0x5632 0x5638 0x566B 0x5664 0x562F 0x566C 0x566A \ + 0x5686 0x5680 0x568A 0x56A0 0x5694 0x568F 0x56A5 0x56AE \ + 0x56B6 0x56B4 0x56C2 0x56BC 0x56C1 0x56C3 0x56C0 0x56C8 \ + 0x56CE 0x56D1 0x56D3 0x56D7 0x56EE 0x56F9 0x5700 0x56FF \ + 0x5704 0x5709 0x5708 0x570B 0x570D 0x5713 0x5718 0x5716 \ + 0x55C7 0x571C 0x5726 0x5737 0x5738 0x574E 0x573B 0x5740 \ + 0x574F 0x5769 0x57C0 0x5788 0x5761 0x577F 0x5789 0x5793 \ + 0x57A0 0x57B3 0x57A4 0x57AA 0x57B0 0x57C3 0x57C6 0x57D4 \ + 0x57D2 0x57D3 0x580A 0x57D6 0x57E3 0x580B 0x5819 0x581D \ + 0x5872 0x5821 0x5862 0x584B 0x5870 0x6BC0 0x5852 0x583D \ + 0x5879 0x5885 0x58B9 0x589F 0x58AB 0x58BA 0x58DE 0x58BB \ + 0x58B8 0x58AE 0x58C5 0x58D3 0x58D1 0x58D7 0x58D9 0x58D8 \ + 0x58E5 0x58DC 0x58E4 0x58DF 0x58EF 0x58FA 0x58F9 0x58FB +20 0x58FC 0x58FD 0x5902 0x590A 0x5910 0x591B 0x68A6 0x5925 \ + 0x592C 0x592D 0x5932 0x5938 0x593E 0x7AD2 0x5955 0x5950 \ + 0x594E 0x595A 0x5958 0x5962 0x5960 0x5967 0x596C 0x5969 \ + 0x5978 0x5981 0x599D 0x4F5E 0x4FAB 0x59A3 0x59B2 0x59C6 \ + 0x59E8 0x59DC 0x598D 0x59D9 0x59DA 0x5A25 0x5A1F 0x5A11 \ + 0x5A1C 0x5A09 0x5A1A 0x5A40 0x5A6C 0x5A49 0x5A35 0x5A36 \ + 0x5A62 0x5A6A 0x5A9A 0x5ABC 0x5ABE 0x5ACB 0x5AC2 0x5ABD \ + 0x5AE3 0x5AD7 0x5AE6 0x5AE9 0x5AD6 0x5AFA 0x5AFB 0x5B0C \ + 0x5B0B 0x5B16 0x5B32 0x5AD0 0x5B2A 0x5B36 0x5B3E 0x5B43 \ + 0x5B45 0x5B40 0x5B51 0x5B55 0x5B5A 0x5B5B 0x5B65 0x5B69 \ + 0x5B70 0x5B73 0x5B75 0x5B78 0x6588 0x5B7A 0x5B80 0x5B83 \ + 0x5BA6 0x5BB8 0x5BC3 0x5BC7 0x5BC9 0x5BD4 0x5BD0 0x5BE4 \ + 0x5BE6 0x5BE2 0x5BDE 0x5BE5 0x5BEB 0x5BF0 0x5BF6 0x5BF3 \ + 0x5C05 0x5C07 0x5C08 0x5C0D 0x5C13 0x5C20 0x5C22 0x5C28 \ + 0x5C38 0x5C39 0x5C41 0x5C46 0x5C4E 0x5C53 0x5C50 0x5C4F \ + 0x5B71 0x5C6C 0x5C6E 0x4E62 0x5C76 0x5C79 0x5C8C 0x5C91 \ + 0x5C94 0x599B 0x5CAB 0x5CBB 0x5CB6 0x5CBC 0x5CB7 0x5CC5 \ + 0x5CBE 0x5CC7 0x5CD9 0x5CE9 0x5CFD 0x5CFA 0x5CED 0x5D8C \ + 0x5CEA 0x5D0B 0x5D15 0x5D17 0x5D5C 0x5D1F 0x5D1B 0x5D11 \ + 0x5D14 0x5D22 0x5D1A 0x5D19 0x5D18 0x5D4C 0x5D52 0x5D4E \ + 0x5D4B 0x5D6C 0x5D73 0x5D76 0x5D87 0x5D84 0x5D82 0x5DA2 \ + 0x5D9D 0x5DAC 0x5DAE 0x5DBD 0x5D90 0x5DB7 0x5DBC 0x5DC9 \ + 0x5DCD 0x5DD3 0x5DD2 0x5DD6 0x5DDB 0x5DEB 0x5DF2 0x5DF5 \ + 0x5E0B 0x5E1A 0x5E19 0x5E11 0x5E1B 0x5E36 0x5E37 0x5E44 \ + 0x5E43 0x5E40 0x5E4E 0x5E57 0x5E54 0x5E5F 0x5E62 0x5E64 \ + 0x5E47 0x5E75 0x5E76 0x5E7A 0x9EBC 0x5E7F 0x5EA0 0x5EC1 \ + 0x5EC2 0x5EC8 0x5ED0 0x5ECF 0x5ED6 0x5EE3 0x5EDD 0x5EDA \ + 0x5EDB 0x5EE2 0x5EE1 0x5EE8 0x5EE9 0x5EEC 0x5EF1 0x5EF3 \ + 0x5EF0 0x5EF4 0x5EF8 0x5EFE 0x5F03 0x5F09 0x5F5D 0x5F5C \ + 0x5F0B 0x5F11 0x5F16 0x5F29 0x5F2D 0x5F38 0x5F41 0x5F48 \ + 0x5F4C 0x5F4E 0x5F2F 0x5F51 0x5F56 0x5F57 0x5F59 0x5F61 \ + 0x5F6D 0x5F73 0x5F77 0x5F83 0x5F82 0x5F7F 0x5F8A 0x5F88 +21 0x5F91 0x5F87 0x5F9E 0x5F99 0x5F98 0x5FA0 0x5FA8 0x5FAD \ + 0x5FBC 0x5FD6 0x5FFB 0x5FE4 0x5FF8 0x5FF1 0x5FDD 0x60B3 \ + 0x5FFF 0x6021 0x6060 0x6019 0x6010 0x6029 0x600E 0x6031 \ + 0x601B 0x6015 0x602B 0x6026 0x600F 0x603A 0x605A 0x6041 \ + 0x606A 0x6077 0x605F 0x604A 0x6046 0x604D 0x6063 0x6043 \ + 0x6064 0x6042 0x606C 0x606B 0x6059 0x6081 0x608D 0x60E7 \ + 0x6083 0x609A 0x6084 0x609B 0x6096 0x6097 0x6092 0x60A7 \ + 0x608B 0x60E1 0x60B8 0x60E0 0x60D3 0x60B4 0x5FF0 0x60BD \ + 0x60C6 0x60B5 0x60D8 0x614D 0x6115 0x6106 0x60F6 0x60F7 \ + 0x6100 0x60F4 0x60FA 0x6103 0x6121 0x60FB 0x60F1 0x610D \ + 0x610E 0x6147 0x613E 0x6128 0x6127 0x614A 0x613F 0x613C \ + 0x612C 0x6134 0x613D 0x6142 0x6144 0x6173 0x6177 0x6158 \ + 0x6159 0x615A 0x616B 0x6174 0x616F 0x6165 0x6171 0x615F \ + 0x615D 0x6153 0x6175 0x6199 0x6196 0x6187 0x61AC 0x6194 \ + 0x619A 0x618A 0x6191 0x61AB 0x61AE 0x61CC 0x61CA 0x61C9 \ + 0x61F7 0x61C8 0x61C3 0x61C6 0x61BA 0x61CB 0x7F79 0x61CD \ + 0x61E6 0x61E3 0x61F6 0x61FA 0x61F4 0x61FF 0x61FD 0x61FC \ + 0x61FE 0x6200 0x6208 0x6209 0x620D 0x620C 0x6214 0x621B \ + 0x621E 0x6221 0x622A 0x622E 0x6230 0x6232 0x6233 0x6241 \ + 0x624E 0x625E 0x6263 0x625B 0x6260 0x6268 0x627C 0x6282 \ + 0x6289 0x627E 0x6292 0x6293 0x6296 0x62D4 0x6283 0x6294 \ + 0x62D7 0x62D1 0x62BB 0x62CF 0x62FF 0x62C6 0x64D4 0x62C8 \ + 0x62DC 0x62CC 0x62CA 0x62C2 0x62C7 0x629B 0x62C9 0x630C \ + 0x62EE 0x62F1 0x6327 0x6302 0x6308 0x62EF 0x62F5 0x6350 \ + 0x633E 0x634D 0x641C 0x634F 0x6396 0x638E 0x6380 0x63AB \ + 0x6376 0x63A3 0x638F 0x6389 0x639F 0x63B5 0x636B 0x6369 \ + 0x63BE 0x63E9 0x63C0 0x63C6 0x63E3 0x63C9 0x63D2 0x63F6 \ + 0x63C4 0x6416 0x6434 0x6406 0x6413 0x6426 0x6436 0x651D \ + 0x6417 0x6428 0x640F 0x6467 0x646F 0x6476 0x644E 0x652A \ + 0x6495 0x6493 0x64A5 0x64A9 0x6488 0x64BC 0x64DA 0x64D2 \ + 0x64C5 0x64C7 0x64BB 0x64D8 0x64C2 0x64F1 0x64E7 0x8209 \ + 0x64E0 0x64E1 0x62AC 0x64E3 0x64EF 0x652C 0x64F6 0x64F4 +22 0x64F2 0x64FA 0x6500 0x64FD 0x6518 0x651C 0x6505 0x6524 \ + 0x6523 0x652B 0x6534 0x6535 0x6537 0x6536 0x6538 0x754B \ + 0x6548 0x6556 0x6555 0x654D 0x6558 0x655E 0x655D 0x6572 \ + 0x6578 0x6582 0x6583 0x8B8A 0x659B 0x659F 0x65AB 0x65B7 \ + 0x65C3 0x65C6 0x65C1 0x65C4 0x65CC 0x65D2 0x65DB 0x65D9 \ + 0x65E0 0x65E1 0x65F1 0x6772 0x660A 0x6603 0x65FB 0x6773 \ + 0x6635 0x6636 0x6634 0x661C 0x664F 0x6644 0x6649 0x6641 \ + 0x665E 0x665D 0x6664 0x6667 0x6668 0x665F 0x6662 0x6670 \ + 0x6683 0x6688 0x668E 0x6689 0x6684 0x6698 0x669D 0x66C1 \ + 0x66B9 0x66C9 0x66BE 0x66BC 0x66C4 0x66B8 0x66D6 0x66DA \ + 0x66E0 0x663F 0x66E6 0x66E9 0x66F0 0x66F5 0x66F7 0x670F \ + 0x6716 0x671E 0x6726 0x6727 0x9738 0x672E 0x673F 0x6736 \ + 0x6741 0x6738 0x6737 0x6746 0x675E 0x6760 0x6759 0x6763 \ + 0x6764 0x6789 0x6770 0x67A9 0x677C 0x676A 0x678C 0x678B \ + 0x67A6 0x67A1 0x6785 0x67B7 0x67EF 0x67B4 0x67EC 0x67B3 \ + 0x67E9 0x67B8 0x67E4 0x67DE 0x67DD 0x67E2 0x67EE 0x67B9 \ + 0x67CE 0x67C6 0x67E7 0x6A9C 0x681E 0x6846 0x6829 0x6840 \ + 0x684D 0x6832 0x684E 0x68B3 0x682B 0x6859 0x6863 0x6877 \ + 0x687F 0x689F 0x688F 0x68AD 0x6894 0x689D 0x689B 0x6883 \ + 0x6AAE 0x68B9 0x6874 0x68B5 0x68A0 0x68BA 0x690F 0x688D \ + 0x687E 0x6901 0x68CA 0x6908 0x68D8 0x6922 0x6926 0x68E1 \ + 0x690C 0x68CD 0x68D4 0x68E7 0x68D5 0x6936 0x6912 0x6904 \ + 0x68D7 0x68E3 0x6925 0x68F9 0x68E0 0x68EF 0x6928 0x692A \ + 0x691A 0x6923 0x6921 0x68C6 0x6979 0x6977 0x695C 0x6978 \ + 0x696B 0x6954 0x697E 0x696E 0x6939 0x6974 0x693D 0x6959 \ + 0x6930 0x6961 0x695E 0x695D 0x6981 0x696A 0x69B2 0x69AE \ + 0x69D0 0x69BF 0x69C1 0x69D3 0x69BE 0x69CE 0x5BE8 0x69CA \ + 0x69DD 0x69BB 0x69C3 0x69A7 0x6A2E 0x6991 0x69A0 0x699C \ + 0x6995 0x69B4 0x69DE 0x69E8 0x6A02 0x6A1B 0x69FF 0x6B0A \ + 0x69F9 0x69F2 0x69E7 0x6A05 0x69B1 0x6A1E 0x69ED 0x6A14 \ + 0x69EB 0x6A0A 0x6A12 0x6AC1 0x6A23 0x6A13 0x6A44 0x6A0C \ + 0x6A72 0x6A36 0x6A78 0x6A47 0x6A62 0x6A59 0x6A66 0x6A48 +23 0x6A38 0x6A22 0x6A90 0x6A8D 0x6AA0 0x6A84 0x6AA2 0x6AA3 \ + 0x6A97 0x8617 0x6ABB 0x6AC3 0x6AC2 0x6AB8 0x6AB3 0x6AAC \ + 0x6ADE 0x6AD1 0x6ADF 0x6AAA 0x6ADA 0x6AEA 0x6AFB 0x6B05 \ + 0x8616 0x6AFA 0x6B12 0x6B16 0x9B31 0x6B1F 0x6B38 0x6B37 \ + 0x76DC 0x6B39 0x98EE 0x6B47 0x6B43 0x6B49 0x6B50 0x6B59 \ + 0x6B54 0x6B5B 0x6B5F 0x6B61 0x6B78 0x6B79 0x6B7F 0x6B80 \ + 0x6B84 0x6B83 0x6B8D 0x6B98 0x6B95 0x6B9E 0x6BA4 0x6BAA \ + 0x6BAB 0x6BAF 0x6BB2 0x6BB1 0x6BB3 0x6BB7 0x6BBC 0x6BC6 \ + 0x6BCB 0x6BD3 0x6BDF 0x6BEC 0x6BEB 0x6BF3 0x6BEF 0x9EBE \ + 0x6C08 0x6C13 0x6C14 0x6C1B 0x6C24 0x6C23 0x6C5E 0x6C55 \ + 0x6C62 0x6C6A 0x6C82 0x6C8D 0x6C9A 0x6C81 0x6C9B 0x6C7E \ + 0x6C68 0x6C73 0x6C92 0x6C90 0x6CC4 0x6CF1 0x6CD3 0x6CBD \ + 0x6CD7 0x6CC5 0x6CDD 0x6CAE 0x6CB1 0x6CBE 0x6CBA 0x6CDB \ + 0x6CEF 0x6CD9 0x6CEA 0x6D1F 0x884D 0x6D36 0x6D2B 0x6D3D \ + 0x6D38 0x6D19 0x6D35 0x6D33 0x6D12 0x6D0C 0x6D63 0x6D93 \ + 0x6D64 0x6D5A 0x6D79 0x6D59 0x6D8E 0x6D95 0x6FE4 0x6D85 \ + 0x6DF9 0x6E15 0x6E0A 0x6DB5 0x6DC7 0x6DE6 0x6DB8 0x6DC6 \ + 0x6DEC 0x6DDE 0x6DCC 0x6DE8 0x6DD2 0x6DC5 0x6DFA 0x6DD9 \ + 0x6DE4 0x6DD5 0x6DEA 0x6DEE 0x6E2D 0x6E6E 0x6E2E 0x6E19 \ + 0x6E72 0x6E5F 0x6E3E 0x6E23 0x6E6B 0x6E2B 0x6E76 0x6E4D \ + 0x6E1F 0x6E43 0x6E3A 0x6E4E 0x6E24 0x6EFF 0x6E1D 0x6E38 \ + 0x6E82 0x6EAA 0x6E98 0x6EC9 0x6EB7 0x6ED3 0x6EBD 0x6EAF \ + 0x6EC4 0x6EB2 0x6ED4 0x6ED5 0x6E8F 0x6EA5 0x6EC2 0x6E9F \ + 0x6F41 0x6F11 0x704C 0x6EEC 0x6EF8 0x6EFE 0x6F3F 0x6EF2 \ + 0x6F31 0x6EEF 0x6F32 0x6ECC 0x6F3E 0x6F13 0x6EF7 0x6F86 \ + 0x6F7A 0x6F78 0x6F81 0x6F80 0x6F6F 0x6F5B 0x6FF3 0x6F6D \ + 0x6F82 0x6F7C 0x6F58 0x6F8E 0x6F91 0x6FC2 0x6F66 0x6FB3 \ + 0x6FA3 0x6FA1 0x6FA4 0x6FB9 0x6FC6 0x6FAA 0x6FDF 0x6FD5 \ + 0x6FEC 0x6FD4 0x6FD8 0x6FF1 0x6FEE 0x6FDB 0x7009 0x700B \ + 0x6FFA 0x7011 0x7001 0x700F 0x6FFE 0x701B 0x701A 0x6F74 \ + 0x701D 0x7018 0x701F 0x7030 0x703E 0x7032 0x7051 0x7063 \ + 0x7099 0x7092 0x70AF 0x70F1 0x70AC 0x70B8 0x70B3 0x70AE +24 0x70DF 0x70CB 0x70DD 0x70D9 0x7109 0x70FD 0x711C 0x7119 \ + 0x7165 0x7155 0x7188 0x7166 0x7162 0x714C 0x7156 0x716C \ + 0x718F 0x71FB 0x7184 0x7195 0x71A8 0x71AC 0x71D7 0x71B9 \ + 0x71BE 0x71D2 0x71C9 0x71D4 0x71CE 0x71E0 0x71EC 0x71E7 \ + 0x71F5 0x71FC 0x71F9 0x71FF 0x720D 0x7210 0x721B 0x7228 \ + 0x722D 0x722C 0x7230 0x7232 0x723B 0x723C 0x723F 0x7240 \ + 0x7246 0x724B 0x7258 0x7274 0x727E 0x7282 0x7281 0x7287 \ + 0x7292 0x7296 0x72A2 0x72A7 0x72B9 0x72B2 0x72C3 0x72C6 \ + 0x72C4 0x72CE 0x72D2 0x72E2 0x72E0 0x72E1 0x72F9 0x72F7 \ + 0x500F 0x7317 0x730A 0x731C 0x7316 0x731D 0x7334 0x732F \ + 0x7329 0x7325 0x733E 0x734E 0x734F 0x9ED8 0x7357 0x736A \ + 0x7368 0x7370 0x7378 0x7375 0x737B 0x737A 0x73C8 0x73B3 \ + 0x73CE 0x73BB 0x73C0 0x73E5 0x73EE 0x73DE 0x74A2 0x7405 \ + 0x746F 0x7425 0x73F8 0x7432 0x743A 0x7455 0x743F 0x745F \ + 0x7459 0x7441 0x745C 0x7469 0x7470 0x7463 0x746A 0x7476 \ + 0x747E 0x748B 0x749E 0x74A7 0x74CA 0x74CF 0x74D4 0x73F1 \ + 0x74E0 0x74E3 0x74E7 0x74E9 0x74EE 0x74F2 0x74F0 0x74F1 \ + 0x74F8 0x74F7 0x7504 0x7503 0x7505 0x750C 0x750E 0x750D \ + 0x7515 0x7513 0x751E 0x7526 0x752C 0x753C 0x7544 0x754D \ + 0x754A 0x7549 0x755B 0x7546 0x755A 0x7569 0x7564 0x7567 \ + 0x756B 0x756D 0x7578 0x7576 0x7586 0x7587 0x7574 0x758A \ + 0x7589 0x7582 0x7594 0x759A 0x759D 0x75A5 0x75A3 0x75C2 \ + 0x75B3 0x75C3 0x75B5 0x75BD 0x75B8 0x75BC 0x75B1 0x75CD \ + 0x75CA 0x75D2 0x75D9 0x75E3 0x75DE 0x75FE 0x75FF 0x75FC \ + 0x7601 0x75F0 0x75FA 0x75F2 0x75F3 0x760B 0x760D 0x7609 \ + 0x761F 0x7627 0x7620 0x7621 0x7622 0x7624 0x7634 0x7630 \ + 0x763B 0x7647 0x7648 0x7646 0x765C 0x7658 0x7661 0x7662 \ + 0x7668 0x7669 0x766A 0x7667 0x766C 0x7670 0x7672 0x7676 \ + 0x7678 0x767C 0x7680 0x7683 0x7688 0x768B 0x768E 0x7696 \ + 0x7693 0x7699 0x769A 0x76B0 0x76B4 0x76B8 0x76B9 0x76BA \ + 0x76C2 0x76CD 0x76D6 0x76D2 0x76DE 0x76E1 0x76E5 0x76E7 \ + 0x76EA 0x862F 0x76FB 0x7708 0x7707 0x7704 0x7729 0x7724 +25 0x771E 0x7725 0x7726 0x771B 0x7737 0x7738 0x7747 0x775A \ + 0x7768 0x776B 0x775B 0x7765 0x777F 0x777E 0x7779 0x778E \ + 0x778B 0x7791 0x77A0 0x779E 0x77B0 0x77B6 0x77B9 0x77BF \ + 0x77BC 0x77BD 0x77BB 0x77C7 0x77CD 0x77D7 0x77DA 0x77DC \ + 0x77E3 0x77EE 0x77FC 0x780C 0x7812 0x7926 0x7820 0x792A \ + 0x7845 0x788E 0x7874 0x7886 0x787C 0x789A 0x788C 0x78A3 \ + 0x78B5 0x78AA 0x78AF 0x78D1 0x78C6 0x78CB 0x78D4 0x78BE \ + 0x78BC 0x78C5 0x78CA 0x78EC 0x78E7 0x78DA 0x78FD 0x78F4 \ + 0x7907 0x7912 0x7911 0x7919 0x792C 0x792B 0x7940 0x7960 \ + 0x7957 0x795F 0x795A 0x7955 0x7953 0x797A 0x797F 0x798A \ + 0x799D 0x79A7 0x9F4B 0x79AA 0x79AE 0x79B3 0x79B9 0x79BA \ + 0x79C9 0x79D5 0x79E7 0x79EC 0x79E1 0x79E3 0x7A08 0x7A0D \ + 0x7A18 0x7A19 0x7A20 0x7A1F 0x7980 0x7A31 0x7A3B 0x7A3E \ + 0x7A37 0x7A43 0x7A57 0x7A49 0x7A61 0x7A62 0x7A69 0x9F9D \ + 0x7A70 0x7A79 0x7A7D 0x7A88 0x7A97 0x7A95 0x7A98 0x7A96 \ + 0x7AA9 0x7AC8 0x7AB0 0x7AB6 0x7AC5 0x7AC4 0x7ABF 0x9083 \ + 0x7AC7 0x7ACA 0x7ACD 0x7ACF 0x7AD5 0x7AD3 0x7AD9 0x7ADA \ + 0x7ADD 0x7AE1 0x7AE2 0x7AE6 0x7AED 0x7AF0 0x7B02 0x7B0F \ + 0x7B0A 0x7B06 0x7B33 0x7B18 0x7B19 0x7B1E 0x7B35 0x7B28 \ + 0x7B36 0x7B50 0x7B7A 0x7B04 0x7B4D 0x7B0B 0x7B4C 0x7B45 \ + 0x7B75 0x7B65 0x7B74 0x7B67 0x7B70 0x7B71 0x7B6C 0x7B6E \ + 0x7B9D 0x7B98 0x7B9F 0x7B8D 0x7B9C 0x7B9A 0x7B8B 0x7B92 \ + 0x7B8F 0x7B5D 0x7B99 0x7BCB 0x7BC1 0x7BCC 0x7BCF 0x7BB4 \ + 0x7BC6 0x7BDD 0x7BE9 0x7C11 0x7C14 0x7BE6 0x7BE5 0x7C60 \ + 0x7C00 0x7C07 0x7C13 0x7BF3 0x7BF7 0x7C17 0x7C0D 0x7BF6 \ + 0x7C23 0x7C27 0x7C2A 0x7C1F 0x7C37 0x7C2B 0x7C3D 0x7C4C \ + 0x7C43 0x7C54 0x7C4F 0x7C40 0x7C50 0x7C58 0x7C5F 0x7C64 \ + 0x7C56 0x7C65 0x7C6C 0x7C75 0x7C83 0x7C90 0x7CA4 0x7CAD \ + 0x7CA2 0x7CAB 0x7CA1 0x7CA8 0x7CB3 0x7CB2 0x7CB1 0x7CAE \ + 0x7CB9 0x7CBD 0x7CC0 0x7CC5 0x7CC2 0x7CD8 0x7CD2 0x7CDC \ + 0x7CE2 0x9B3B 0x7CEF 0x7CF2 0x7CF4 0x7CF6 0x7CFA 0x7D06 \ + 0x7D02 0x7D1C 0x7D15 0x7D0A 0x7D45 0x7D4B 0x7D2E 0x7D32 +26 0x7D3F 0x7D35 0x7D46 0x7D73 0x7D56 0x7D4E 0x7D72 0x7D68 \ + 0x7D6E 0x7D4F 0x7D63 0x7D93 0x7D89 0x7D5B 0x7D8F 0x7D7D \ + 0x7D9B 0x7DBA 0x7DAE 0x7DA3 0x7DB5 0x7DC7 0x7DBD 0x7DAB \ + 0x7E3D 0x7DA2 0x7DAF 0x7DDC 0x7DB8 0x7D9F 0x7DB0 0x7DD8 \ + 0x7DDD 0x7DE4 0x7DDE 0x7DFB 0x7DF2 0x7DE1 0x7E05 0x7E0A \ + 0x7E23 0x7E21 0x7E12 0x7E31 0x7E1F 0x7E09 0x7E0B 0x7E22 \ + 0x7E46 0x7E66 0x7E3B 0x7E35 0x7E39 0x7E43 0x7E37 0x7E32 \ + 0x7E3A 0x7E67 0x7E5D 0x7E56 0x7E5E 0x7E59 0x7E5A 0x7E79 \ + 0x7E6A 0x7E69 0x7E7C 0x7E7B 0x7E83 0x7DD5 0x7E7D 0x8FAE \ + 0x7E7F 0x7E88 0x7E89 0x7E8C 0x7E92 0x7E90 0x7E93 0x7E94 \ + 0x7E96 0x7E8E 0x7E9B 0x7E9C 0x7F38 0x7F3A 0x7F45 0x7F4C \ + 0x7F4D 0x7F4E 0x7F50 0x7F51 0x7F55 0x7F54 0x7F58 0x7F5F \ + 0x7F60 0x7F68 0x7F69 0x7F67 0x7F78 0x7F82 0x7F86 0x7F83 \ + 0x7F88 0x7F87 0x7F8C 0x7F94 0x7F9E 0x7F9D 0x7F9A 0x7FA3 \ + 0x7FAF 0x7FB2 0x7FB9 0x7FAE 0x7FB6 0x7FB8 0x8B71 0x7FC5 \ + 0x7FC6 0x7FCA 0x7FD5 0x7FD4 0x7FE1 0x7FE6 0x7FE9 0x7FF3 \ + 0x7FF9 0x98DC 0x8006 0x8004 0x800B 0x8012 0x8018 0x8019 \ + 0x801C 0x8021 0x8028 0x803F 0x803B 0x804A 0x8046 0x8052 \ + 0x8058 0x805A 0x805F 0x8062 0x8068 0x8073 0x8072 0x8070 \ + 0x8076 0x8079 0x807D 0x807F 0x8084 0x8086 0x8085 0x809B \ + 0x8093 0x809A 0x80AD 0x5190 0x80AC 0x80DB 0x80E5 0x80D9 \ + 0x80DD 0x80C4 0x80DA 0x80D6 0x8109 0x80EF 0x80F1 0x811B \ + 0x8129 0x8123 0x812F 0x814B 0x968B 0x8146 0x813E 0x8153 \ + 0x8151 0x80FC 0x8171 0x816E 0x8165 0x8166 0x8174 0x8183 \ + 0x8188 0x818A 0x8180 0x8182 0x81A0 0x8195 0x81A4 0x81A3 \ + 0x815F 0x8193 0x81A9 0x81B0 0x81B5 0x81BE 0x81B8 0x81BD \ + 0x81C0 0x81C2 0x81BA 0x81C9 0x81CD 0x81D1 0x81D9 0x81D8 \ + 0x81C8 0x81DA 0x81DF 0x81E0 0x81E7 0x81FA 0x81FB 0x81FE \ + 0x8201 0x8202 0x8205 0x8207 0x820A 0x820D 0x8210 0x8216 \ + 0x8229 0x822B 0x8238 0x8233 0x8240 0x8259 0x8258 0x825D \ + 0x825A 0x825F 0x8264 0x8262 0x8268 0x826A 0x826B 0x822E \ + 0x8271 0x8277 0x8278 0x827E 0x828D 0x8292 0x82AB 0x829F +27 0x82BB 0x82AC 0x82E1 0x82E3 0x82DF 0x82D2 0x82F4 0x82F3 \ + 0x82FA 0x8393 0x8303 0x82FB 0x82F9 0x82DE 0x8306 0x82DC \ + 0x8309 0x82D9 0x8335 0x8334 0x8316 0x8332 0x8331 0x8340 \ + 0x8339 0x8350 0x8345 0x832F 0x832B 0x8317 0x8318 0x8385 \ + 0x839A 0x83AA 0x839F 0x83A2 0x8396 0x8323 0x838E 0x8387 \ + 0x838A 0x837C 0x83B5 0x8373 0x8375 0x83A0 0x8389 0x83A8 \ + 0x83F4 0x8413 0x83EB 0x83CE 0x83FD 0x8403 0x83D8 0x840B \ + 0x83C1 0x83F7 0x8407 0x83E0 0x83F2 0x840D 0x8422 0x8420 \ + 0x83BD 0x8438 0x8506 0x83FB 0x846D 0x842A 0x843C 0x855A \ + 0x8484 0x8477 0x846B 0x84AD 0x846E 0x8482 0x8469 0x8446 \ + 0x842C 0x846F 0x8479 0x8435 0x84CA 0x8462 0x84B9 0x84BF \ + 0x849F 0x84D9 0x84CD 0x84BB 0x84DA 0x84D0 0x84C1 0x84C6 \ + 0x84D6 0x84A1 0x8521 0x84FF 0x84F4 0x8517 0x8518 0x852C \ + 0x851F 0x8515 0x8514 0x84FC 0x8540 0x8563 0x8558 0x8548 \ + 0x8541 0x8602 0x854B 0x8555 0x8580 0x85A4 0x8588 0x8591 \ + 0x858A 0x85A8 0x856D 0x8594 0x859B 0x85EA 0x8587 0x859C \ + 0x8577 0x857E 0x8590 0x85C9 0x85BA 0x85CF 0x85B9 0x85D0 \ + 0x85D5 0x85DD 0x85E5 0x85DC 0x85F9 0x860A 0x8613 0x860B \ + 0x85FE 0x85FA 0x8606 0x8622 0x861A 0x8630 0x863F 0x864D \ + 0x4E55 0x8654 0x865F 0x8667 0x8671 0x8693 0x86A3 0x86A9 \ + 0x86AA 0x868B 0x868C 0x86B6 0x86AF 0x86C4 0x86C6 0x86B0 \ + 0x86C9 0x8823 0x86AB 0x86D4 0x86DE 0x86E9 0x86EC 0x86DF \ + 0x86DB 0x86EF 0x8712 0x8706 0x8708 0x8700 0x8703 0x86FB \ + 0x8711 0x8709 0x870D 0x86F9 0x870A 0x8734 0x873F 0x8737 \ + 0x873B 0x8725 0x8729 0x871A 0x8760 0x875F 0x8778 0x874C \ + 0x874E 0x8774 0x8757 0x8768 0x876E 0x8759 0x8753 0x8763 \ + 0x876A 0x8805 0x87A2 0x879F 0x8782 0x87AF 0x87CB 0x87BD \ + 0x87C0 0x87D0 0x96D6 0x87AB 0x87C4 0x87B3 0x87C7 0x87C6 \ + 0x87BB 0x87EF 0x87F2 0x87E0 0x880F 0x880D 0x87FE 0x87F6 \ + 0x87F7 0x880E 0x87D2 0x8811 0x8816 0x8815 0x8822 0x8821 \ + 0x8831 0x8836 0x8839 0x8827 0x883B 0x8844 0x8842 0x8852 \ + 0x8859 0x885E 0x8862 0x886B 0x8881 0x887E 0x889E 0x8875 +28 0x887D 0x88B5 0x8872 0x8882 0x8897 0x8892 0x88AE 0x8899 \ + 0x88A2 0x888D 0x88A4 0x88B0 0x88BF 0x88B1 0x88C3 0x88C4 \ + 0x88D4 0x88D8 0x88D9 0x88DD 0x88F9 0x8902 0x88FC 0x88F4 \ + 0x88E8 0x88F2 0x8904 0x890C 0x890A 0x8913 0x8943 0x891E \ + 0x8925 0x892A 0x892B 0x8941 0x8944 0x893B 0x8936 0x8938 \ + 0x894C 0x891D 0x8960 0x895E 0x8966 0x8964 0x896D 0x896A \ + 0x896F 0x8974 0x8977 0x897E 0x8983 0x8988 0x898A 0x8993 \ + 0x8998 0x89A1 0x89A9 0x89A6 0x89AC 0x89AF 0x89B2 0x89BA \ + 0x89BD 0x89BF 0x89C0 0x89DA 0x89DC 0x89DD 0x89E7 0x89F4 \ + 0x89F8 0x8A03 0x8A16 0x8A10 0x8A0C 0x8A1B 0x8A1D 0x8A25 \ + 0x8A36 0x8A41 0x8A5B 0x8A52 0x8A46 0x8A48 0x8A7C 0x8A6D \ + 0x8A6C 0x8A62 0x8A85 0x8A82 0x8A84 0x8AA8 0x8AA1 0x8A91 \ + 0x8AA5 0x8AA6 0x8A9A 0x8AA3 0x8AC4 0x8ACD 0x8AC2 0x8ADA \ + 0x8AEB 0x8AF3 0x8AE7 0x8AE4 0x8AF1 0x8B14 0x8AE0 0x8AE2 \ + 0x8AF7 0x8ADE 0x8ADB 0x8B0C 0x8B07 0x8B1A 0x8AE1 0x8B16 \ + 0x8B10 0x8B17 0x8B20 0x8B33 0x97AB 0x8B26 0x8B2B 0x8B3E \ + 0x8B28 0x8B41 0x8B4C 0x8B4F 0x8B4E 0x8B49 0x8B56 0x8B5B \ + 0x8B5A 0x8B6B 0x8B5F 0x8B6C 0x8B6F 0x8B74 0x8B7D 0x8B80 \ + 0x8B8C 0x8B8E 0x8B92 0x8B93 0x8B96 0x8B99 0x8B9A 0x8C3A \ + 0x8C41 0x8C3F 0x8C48 0x8C4C 0x8C4E 0x8C50 0x8C55 0x8C62 \ + 0x8C6C 0x8C78 0x8C7A 0x8C82 0x8C89 0x8C85 0x8C8A 0x8C8D \ + 0x8C8E 0x8C94 0x8C7C 0x8C98 0x621D 0x8CAD 0x8CAA 0x8CBD \ + 0x8CB2 0x8CB3 0x8CAE 0x8CB6 0x8CC8 0x8CC1 0x8CE4 0x8CE3 \ + 0x8CDA 0x8CFD 0x8CFA 0x8CFB 0x8D04 0x8D05 0x8D0A 0x8D07 \ + 0x8D0F 0x8D0D 0x8D10 0x9F4E 0x8D13 0x8CCD 0x8D14 0x8D16 \ + 0x8D67 0x8D6D 0x8D71 0x8D73 0x8D81 0x8D99 0x8DC2 0x8DBE \ + 0x8DBA 0x8DCF 0x8DDA 0x8DD6 0x8DCC 0x8DDB 0x8DCB 0x8DEA \ + 0x8DEB 0x8DDF 0x8DE3 0x8DFC 0x8E08 0x8E09 0x8DFF 0x8E1D \ + 0x8E1E 0x8E10 0x8E1F 0x8E42 0x8E35 0x8E30 0x8E34 0x8E4A \ + 0x8E47 0x8E49 0x8E4C 0x8E50 0x8E48 0x8E59 0x8E64 0x8E60 \ + 0x8E2A 0x8E63 0x8E55 0x8E76 0x8E72 0x8E7C 0x8E81 0x8E87 \ + 0x8E85 0x8E84 0x8E8B 0x8E8A 0x8E93 0x8E91 0x8E94 0x8E99 +29 0x8EAA 0x8EA1 0x8EAC 0x8EB0 0x8EC6 0x8EB1 0x8EBE 0x8EC5 \ + 0x8EC8 0x8ECB 0x8EDB 0x8EE3 0x8EFC 0x8EFB 0x8EEB 0x8EFE \ + 0x8F0A 0x8F05 0x8F15 0x8F12 0x8F19 0x8F13 0x8F1C 0x8F1F \ + 0x8F1B 0x8F0C 0x8F26 0x8F33 0x8F3B 0x8F39 0x8F45 0x8F42 \ + 0x8F3E 0x8F4C 0x8F49 0x8F46 0x8F4E 0x8F57 0x8F5C 0x8F62 \ + 0x8F63 0x8F64 0x8F9C 0x8F9F 0x8FA3 0x8FAD 0x8FAF 0x8FB7 \ + 0x8FDA 0x8FE5 0x8FE2 0x8FEA 0x8FEF 0x9087 0x8FF4 0x9005 \ + 0x8FF9 0x8FFA 0x9011 0x9015 0x9021 0x900D 0x901E 0x9016 \ + 0x900B 0x9027 0x9036 0x9035 0x9039 0x8FF8 0x904F 0x9050 \ + 0x9051 0x9052 0x900E 0x9049 0x903E 0x9056 0x9058 0x905E \ + 0x9068 0x906F 0x9076 0x96A8 0x9072 0x9082 0x907D 0x9081 \ + 0x9080 0x908A 0x9089 0x908F 0x90A8 0x90AF 0x90B1 0x90B5 \ + 0x90E2 0x90E4 0x6248 0x90DB 0x9102 0x9112 0x9119 0x9132 \ + 0x9130 0x914A 0x9156 0x9158 0x9163 0x9165 0x9169 0x9173 \ + 0x9172 0x918B 0x9189 0x9182 0x91A2 0x91AB 0x91AF 0x91AA \ + 0x91B5 0x91B4 0x91BA 0x91C0 0x91C1 0x91C9 0x91CB 0x91D0 \ + 0x91D6 0x91DF 0x91E1 0x91DB 0x91FC 0x91F5 0x91F6 0x921E \ + 0x91FF 0x9214 0x922C 0x9215 0x9211 0x925E 0x9257 0x9245 \ + 0x9249 0x9264 0x9248 0x9295 0x923F 0x924B 0x9250 0x929C \ + 0x9296 0x9293 0x929B 0x925A 0x92CF 0x92B9 0x92B7 0x92E9 \ + 0x930F 0x92FA 0x9344 0x932E 0x9319 0x9322 0x931A 0x9323 \ + 0x933A 0x9335 0x933B 0x935C 0x9360 0x937C 0x936E 0x9356 \ + 0x93B0 0x93AC 0x93AD 0x9394 0x93B9 0x93D6 0x93D7 0x93E8 \ + 0x93E5 0x93D8 0x93C3 0x93DD 0x93D0 0x93C8 0x93E4 0x941A \ + 0x9414 0x9413 0x9403 0x9407 0x9410 0x9436 0x942B 0x9435 \ + 0x9421 0x943A 0x9441 0x9452 0x9444 0x945B 0x9460 0x9462 \ + 0x945E 0x946A 0x9229 0x9470 0x9475 0x9477 0x947D 0x945A \ + 0x947C 0x947E 0x9481 0x947F 0x9582 0x9587 0x958A 0x9594 \ + 0x9596 0x9598 0x9599 0x95A0 0x95A8 0x95A7 0x95AD 0x95BC \ + 0x95BB 0x95B9 0x95BE 0x95CA 0x6FF6 0x95C3 0x95CD 0x95CC \ + 0x95D5 0x95D4 0x95D6 0x95DC 0x95E1 0x95E5 0x95E2 0x9621 \ + 0x9628 0x962E 0x962F 0x9642 0x964C 0x964F 0x964B 0x9677 +30 0x965C 0x965E 0x965D 0x965F 0x9666 0x9672 0x966C 0x968D \ + 0x9698 0x9695 0x9697 0x96AA 0x96A7 0x96B1 0x96B2 0x96B0 \ + 0x96B4 0x96B6 0x96B8 0x96B9 0x96CE 0x96CB 0x96C9 0x96CD \ + 0x894D 0x96DC 0x970D 0x96D5 0x96F9 0x9704 0x9706 0x9708 \ + 0x9713 0x970E 0x9711 0x970F 0x9716 0x9719 0x9724 0x972A \ + 0x9730 0x9739 0x973D 0x973E 0x9744 0x9746 0x9748 0x9742 \ + 0x9749 0x975C 0x9760 0x9764 0x9766 0x9768 0x52D2 0x976B \ + 0x9771 0x9779 0x9785 0x977C 0x9781 0x977A 0x9786 0x978B \ + 0x978F 0x9790 0x979C 0x97A8 0x97A6 0x97A3 0x97B3 0x97B4 \ + 0x97C3 0x97C6 0x97C8 0x97CB 0x97DC 0x97ED 0x9F4F 0x97F2 \ + 0x7ADF 0x97F6 0x97F5 0x980F 0x980C 0x9838 0x9824 0x9821 \ + 0x9837 0x983D 0x9846 0x984F 0x984B 0x986B 0x986F 0x9870 \ + 0x9871 0x9874 0x9873 0x98AA 0x98AF 0x98B1 0x98B6 0x98C4 \ + 0x98C3 0x98C6 0x98E9 0x98EB 0x9903 0x9909 0x9912 0x9914 \ + 0x9918 0x9921 0x991D 0x991E 0x9924 0x9920 0x992C 0x992E \ + 0x993D 0x993E 0x9942 0x9949 0x9945 0x9950 0x994B 0x9951 \ + 0x9952 0x994C 0x9955 0x9997 0x9998 0x99A5 0x99AD 0x99AE \ + 0x99BC 0x99DF 0x99DB 0x99DD 0x99D8 0x99D1 0x99ED 0x99EE \ + 0x99F1 0x99F2 0x99FB 0x99F8 0x9A01 0x9A0F 0x9A05 0x99E2 \ + 0x9A19 0x9A2B 0x9A37 0x9A45 0x9A42 0x9A40 0x9A43 0x9A3E \ + 0x9A55 0x9A4D 0x9A5B 0x9A57 0x9A5F 0x9A62 0x9A65 0x9A64 \ + 0x9A69 0x9A6B 0x9A6A 0x9AAD 0x9AB0 0x9ABC 0x9AC0 0x9ACF \ + 0x9AD1 0x9AD3 0x9AD4 0x9ADE 0x9ADF 0x9AE2 0x9AE3 0x9AE6 \ + 0x9AEF 0x9AEB 0x9AEE 0x9AF4 0x9AF1 0x9AF7 0x9AFB 0x9B06 \ + 0x9B18 0x9B1A 0x9B1F 0x9B22 0x9B23 0x9B25 0x9B27 0x9B28 \ + 0x9B29 0x9B2A 0x9B2E 0x9B2F 0x9B32 0x9B44 0x9B43 0x9B4F \ + 0x9B4D 0x9B4E 0x9B51 0x9B58 0x9B74 0x9B93 0x9B83 0x9B91 \ + 0x9B96 0x9B97 0x9B9F 0x9BA0 0x9BA8 0x9BB4 0x9BC0 0x9BCA \ + 0x9BB9 0x9BC6 0x9BCF 0x9BD1 0x9BD2 0x9BE3 0x9BE2 0x9BE4 \ + 0x9BD4 0x9BE1 0x9C3A 0x9BF2 0x9BF1 0x9BF0 0x9C15 0x9C14 \ + 0x9C09 0x9C13 0x9C0C 0x9C06 0x9C08 0x9C12 0x9C0A 0x9C04 \ + 0x9C2E 0x9C1B 0x9C25 0x9C24 0x9C21 0x9C30 0x9C47 0x9C32 +31 0x9C46 0x9C3E 0x9C5A 0x9C60 0x9C67 0x9C76 0x9C78 0x9CE7 \ + 0x9CEC 0x9CF0 0x9D09 0x9D08 0x9CEB 0x9D03 0x9D06 0x9D2A \ + 0x9D26 0x9DAF 0x9D23 0x9D1F 0x9D44 0x9D15 0x9D12 0x9D41 \ + 0x9D3F 0x9D3E 0x9D46 0x9D48 0x9D5D 0x9D5E 0x9D64 0x9D51 \ + 0x9D50 0x9D59 0x9D72 0x9D89 0x9D87 0x9DAB 0x9D6F 0x9D7A \ + 0x9D9A 0x9DA4 0x9DA9 0x9DB2 0x9DC4 0x9DC1 0x9DBB 0x9DB8 \ + 0x9DBA 0x9DC6 0x9DCF 0x9DC2 0x9DD9 0x9DD3 0x9DF8 0x9DE6 \ + 0x9DED 0x9DEF 0x9DFD 0x9E1A 0x9E1B 0x9E1E 0x9E75 0x9E79 \ + 0x9E7D 0x9E81 0x9E88 0x9E8B 0x9E8C 0x9E92 0x9E95 0x9E91 \ + 0x9E9D 0x9EA5 0x9EA9 0x9EB8 0x9EAA 0x9EAD 0x9761 0x9ECC \ + 0x9ECE 0x9ECF 0x9ED0 0x9ED4 0x9EDC 0x9EDE 0x9EDD 0x9EE0 \ + 0x9EE5 0x9EE8 0x9EEF 0x9EF4 0x9EF6 0x9EF7 0x9EF9 0x9EFB \ + 0x9EFC 0x9EFD 0x9F07 0x9F08 0x76B7 0x9F15 0x9F21 0x9F2C \ + 0x9F3E 0x9F4A 0x9F52 0x9F54 0x9F63 0x9F5F 0x9F60 0x9F61 \ + 0x9F66 0x9F67 0x9F6C 0x9F6A 0x9F77 0x9F72 0x9F76 0x9F95 \ + 0x9F9C 0x9FA0 0x582F 0x69C7 0x9059 0x7464 0x51DC 0x7199 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +32 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +33 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +34 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +35 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/UKS.sfd b/contrib/ttf2pk/data/UKS.sfd new file mode 100644 index 0000000..c90314a --- /dev/null +++ b/contrib/ttf2pk/data/UKS.sfd @@ -0,0 +1,1114 @@ +# UKS.sfd +# +# subfont numbers for KSC 5601 encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. +# +# The input encoding is Unicode. + +01 0x3000 0x3001 0x3002 0x00B7 0x2025 0x2026 0x00A8 0x3003 \ + 0x00AD 0x2015 0x2225 0xFF3C 0x223C 0x2018 0x2019 0x201C \ + 0x201D 0x3014 0x3015 0x3008 0x3009 0x300A 0x300B 0x300C \ + 0x300D 0x300E 0x300F 0x3010 0x3011 0x00B1 0x00D7 0x00F7 \ + 0x2260 0x2264 0x2265 0x221E 0x2234 0x00B0 0x2032 0x2033 \ + 0x2103 0x212B 0xFFE0 0xFFE1 0xFFE5 0x2642 0x2640 0x2220 \ + 0x22A5 0x2312 0x2202 0x2207 0x2261 0x2252 0x00A7 0x203B \ + 0x2606 0x2605 0x25CB 0x25CF 0x25CE 0x25C7 0x25C6 0x25A1 \ + 0x25A0 0x25B3 0x25B2 0x25BD 0x25BC 0x2192 0x2190 0x2191 \ + 0x2193 0x2194 0x3013 0x226A 0x226B 0x221A 0x223D 0x221D \ + 0x2235 0x222B 0x222C 0x2208 0x220B 0x2286 0x2287 0x2282 \ + 0x2283 0x222A 0x2229 0x2227 0x2228 0xFFE2 0x21D2 0x21D4 \ + 0x2200 0x2203 0x00B4 0xFF5E 0x02C7 0x02D8 0x02DD 0x02DA \ + 0x02D9 0x00B8 0x02DB 0x00A1 0x00BF 0x02D0 0x222E 0x2211 \ + 0x220F 0x00A4 0x2109 0x2030 0x25C1 0x25C0 0x25B7 0x25B6 \ + 0x2664 0x2660 0x2661 0x2665 0x2667 0x2663 0x2299 0x25C8 \ + 0x25A3 0x25D0 0x25D1 0x2592 0x25A4 0x25A5 0x25A8 0x25A7 \ + 0x25A6 0x25A9 0x2668 0x260F 0x260E 0x261C 0x261E 0x00B6 \ + 0x2020 0x2021 0x2195 0x2197 0x2199 0x2196 0x2198 0x266D \ + 0x2669 0x266A 0x266C 0x327F 0x321C 0x2116 0x33C7 0x2122 \ + 0x33C2 0x33D8 0x2121 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFF01 0xFF02 0xFF03 0xFF04 \ + 0xFF05 0xFF06 0xFF07 0xFF08 0xFF09 0xFF0A 0xFF0B 0xFF0C \ + 0xFF0D 0xFF0E 0xFF0F 0xFF10 0xFF11 0xFF12 0xFF13 0xFF14 \ + 0xFF15 0xFF16 0xFF17 0xFF18 0xFF19 0xFF1A 0xFF1B 0xFF1C \ + 0xFF1D 0xFF1E 0xFF1F 0xFF20 0xFF21 0xFF22 0xFF23 0xFF24 \ + 0xFF25 0xFF26 0xFF27 0xFF28 0xFF29 0xFF2A 0xFF2B 0xFF2C \ + 0xFF2D 0xFF2E 0xFF2F 0xFF30 0xFF31 0xFF32 0xFF33 0xFF34 \ + 0xFF35 0xFF36 0xFF37 0xFF38 0xFF39 0xFF3A 0xFF3B 0xFFE6 \ + 0xFF3D 0xFF3E 0xFF3F 0xFF40 0xFF41 0xFF42 0xFF43 0xFF44 +02 0xFF45 0xFF46 0xFF47 0xFF48 0xFF49 0xFF4A 0xFF4B 0xFF4C \ + 0xFF4D 0xFF4E 0xFF4F 0xFF50 0xFF51 0xFF52 0xFF53 0xFF54 \ + 0xFF55 0xFF56 0xFF57 0xFF58 0xFF59 0xFF5A 0xFF5B 0xFF5C \ + 0xFF5D 0xFFE3 0x3131 0x3132 0x3133 0x3134 0x3135 0x3136 \ + 0x3137 0x3138 0x3139 0x313A 0x313B 0x313C 0x313D 0x313E \ + 0x313F 0x3140 0x3141 0x3142 0x3143 0x3144 0x3145 0x3146 \ + 0x3147 0x3148 0x3149 0x314A 0x314B 0x314C 0x314D 0x314E \ + 0x314F 0x3150 0x3151 0x3152 0x3153 0x3154 0x3155 0x3156 \ + 0x3157 0x3158 0x3159 0x315A 0x315B 0x315C 0x315D 0x315E \ + 0x315F 0x3160 0x3161 0x3162 0x3163 0x3164 0x3165 0x3166 \ + 0x3167 0x3168 0x3169 0x316A 0x316B 0x316C 0x316D 0x316E \ + 0x316F 0x3170 0x3171 0x3172 0x3173 0x3174 0x3175 0x3176 \ + 0x3177 0x3178 0x3179 0x317A 0x317B 0x317C 0x317D 0x317E \ + 0x317F 0x3180 0x3181 0x3182 0x3183 0x3184 0x3185 0x3186 \ + 0x3187 0x3188 0x3189 0x318A 0x318B 0x318C 0x318D 0x318E \ + 0x2170 0x2171 0x2172 0x2173 0x2174 0x2175 0x2176 0x2177 \ + 0x2178 0x2179 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2160 \ + 0x2161 0x2162 0x2163 0x2164 0x2165 0x2166 0x2167 0x2168 \ + 0x2169 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x0391 0x0392 0x0393 0x0394 0x0395 0x0396 0x0397 0x0398 \ + 0x0399 0x039A 0x039B 0x039C 0x039D 0x039E 0x039F 0x03A0 \ + 0x03A1 0x03A3 0x03A4 0x03A5 0x03A6 0x03A7 0x03A8 0x03A9 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0x03B1 0x03B2 0x03B3 0x03B4 0x03B5 0x03B6 0x03B7 0x03B8 \ + 0x03B9 0x03BA 0x03BB 0x03BC 0x03BD 0x03BE 0x03BF 0x03C0 \ + 0x03C1 0x03C3 0x03C4 0x03C5 0x03C6 0x03C7 0x03C8 0x03C9 \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x2500 0x2502 \ + 0x250C 0x2510 0x2518 0x2514 0x251C 0x252C 0x2524 0x2534 \ + 0x253C 0x2501 0x2503 0x250F 0x2513 0x251B 0x2517 0x2523 \ + 0x2533 0x252B 0x253B 0x254B 0x2520 0x252F 0x2528 0x2537 \ + 0x253F 0x251D 0x2530 0x2525 0x2538 0x2542 0x2512 0x2511 \ + 0x251A 0x2519 0x2516 0x2515 0x250E 0x250D 0x251E 0x251F +03 0x2521 0x2522 0x2526 0x2527 0x2529 0x252A 0x252D 0x252E \ + 0x2531 0x2532 0x2535 0x2536 0x2539 0x253A 0x253D 0x253E \ + 0x2540 0x2541 0x2543 0x2544 0x2545 0x2546 0x2547 0x2548 \ + 0x2549 0x254A 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x3395 0x3396 0x3397 0x2113 \ + 0x3398 0x33C4 0x33A3 0x33A4 0x33A5 0x33A6 0x3399 0x339A \ + 0x339B 0x339C 0x339D 0x339E 0x339F 0x33A0 0x33A1 0x33A2 \ + 0x33CA 0x338D 0x338E 0x338F 0x33CF 0x3388 0x3389 0x33C8 \ + 0x33A7 0x33A8 0x33B0 0x33B1 0x33B2 0x33B3 0x33B4 0x33B5 \ + 0x33B6 0x33B7 0x33B8 0x33B9 0x3380 0x3381 0x3382 0x3383 \ + 0x3384 0x33BA 0x33BB 0x33BC 0x33BD 0x33BE 0x33BF 0x3390 \ + 0x3391 0x3392 0x3393 0x3394 0x2126 0x33C0 0x33C1 0x338A \ + 0x338B 0x338C 0x33D6 0x33C5 0x33AD 0x33AE 0x33AF 0x33DB \ + 0x33A9 0x33AA 0x33AB 0x33AC 0x33DD 0x33D0 0x33D3 0x33C3 \ + 0x33C9 0x33DC 0x33C6 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x00C6 0x00D0 0x00AA 0x0126 0xFFFE 0x0132 \ + 0xFFFE 0x013F 0x0141 0x00D8 0x0152 0x00BA 0x00DE 0x0166 \ + 0x014A 0xFFFE 0x3260 0x3261 0x3262 0x3263 0x3264 0x3265 \ + 0x3266 0x3267 0x3268 0x3269 0x326A 0x326B 0x326C 0x326D \ + 0x326E 0x326F 0x3270 0x3271 0x3272 0x3273 0x3274 0x3275 \ + 0x3276 0x3277 0x3278 0x3279 0x327A 0x327B 0x24D0 0x24D1 \ + 0x24D2 0x24D3 0x24D4 0x24D5 0x24D6 0x24D7 0x24D8 0x24D9 \ + 0x24DA 0x24DB 0x24DC 0x24DD 0x24DE 0x24DF 0x24E0 0x24E1 \ + 0x24E2 0x24E3 0x24E4 0x24E5 0x24E6 0x24E7 0x24E8 0x24E9 \ + 0x2460 0x2461 0x2462 0x2463 0x2464 0x2465 0x2466 0x2467 \ + 0x2468 0x2469 0x246A 0x246B 0x246C 0x246D 0x246E 0x00BD \ + 0x2153 0x2154 0x00BC 0x00BE 0x215B 0x215C 0x215D 0x215E \ + 0x00E6 0x0111 0x00F0 0x0127 0x0131 0x0133 0x0138 0x0140 \ + 0x0142 0x00F8 0x0153 0x00DF 0x00FE 0x0167 0x014B 0x0149 +04 0x3200 0x3201 0x3202 0x3203 0x3204 0x3205 0x3206 0x3207 \ + 0x3208 0x3209 0x320A 0x320B 0x320C 0x320D 0x320E 0x320F \ + 0x3210 0x3211 0x3212 0x3213 0x3214 0x3215 0x3216 0x3217 \ + 0x3218 0x3219 0x321A 0x321B 0x249C 0x249D 0x249E 0x249F \ + 0x24A0 0x24A1 0x24A2 0x24A3 0x24A4 0x24A5 0x24A6 0x24A7 \ + 0x24A8 0x24A9 0x24AA 0x24AB 0x24AC 0x24AD 0x24AE 0x24AF \ + 0x24B0 0x24B1 0x24B2 0x24B3 0x24B4 0x24B5 0x2474 0x2475 \ + 0x2476 0x2477 0x2478 0x2479 0x247A 0x247B 0x247C 0x247D \ + 0x247E 0x247F 0x2480 0x2481 0x2482 0x00B9 0x00B2 0x00B3 \ + 0x2074 0x207F 0x2081 0x2082 0x2083 0x2084 0x3041 0x3042 \ + 0x3043 0x3044 0x3045 0x3046 0x3047 0x3048 0x3049 0x304A \ + 0x304B 0x304C 0x304D 0x304E 0x304F 0x3050 0x3051 0x3052 \ + 0x3053 0x3054 0x3055 0x3056 0x3057 0x3058 0x3059 0x305A \ + 0x305B 0x305C 0x305D 0x305E 0x305F 0x3060 0x3061 0x3062 \ + 0x3063 0x3064 0x3065 0x3066 0x3067 0x3068 0x3069 0x306A \ + 0x306B 0x306C 0x306D 0x306E 0x306F 0x3070 0x3071 0x3072 \ + 0x3073 0x3074 0x3075 0x3076 0x3077 0x3078 0x3079 0x307A \ + 0x307B 0x307C 0x307D 0x307E 0x307F 0x3080 0x3081 0x3082 \ + 0x3083 0x3084 0x3085 0x3086 0x3087 0x3088 0x3089 0x308A \ + 0x308B 0x308C 0x308D 0x308E 0x308F 0x3090 0x3091 0x3092 \ + 0x3093 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x30A1 0x30A2 0x30A3 0x30A4 \ + 0x30A5 0x30A6 0x30A7 0x30A8 0x30A9 0x30AA 0x30AB 0x30AC \ + 0x30AD 0x30AE 0x30AF 0x30B0 0x30B1 0x30B2 0x30B3 0x30B4 \ + 0x30B5 0x30B6 0x30B7 0x30B8 0x30B9 0x30BA 0x30BB 0x30BC \ + 0x30BD 0x30BE 0x30BF 0x30C0 0x30C1 0x30C2 0x30C3 0x30C4 \ + 0x30C5 0x30C6 0x30C7 0x30C8 0x30C9 0x30CA 0x30CB 0x30CC \ + 0x30CD 0x30CE 0x30CF 0x30D0 0x30D1 0x30D2 0x30D3 0x30D4 \ + 0x30D5 0x30D6 0x30D7 0x30D8 0x30D9 0x30DA 0x30DB 0x30DC \ + 0x30DD 0x30DE 0x30DF 0x30E0 0x30E1 0x30E2 0x30E3 0x30E4 \ + 0x30E5 0x30E6 0x30E7 0x30E8 0x30E9 0x30EA 0x30EB 0x30EC \ + 0x30ED 0x30EE 0x30EF 0x30F0 0x30F1 0x30F2 0x30F3 0x30F4 +05 0x30F5 0x30F6 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 \ + 0x0401 0x0416 0x0417 0x0418 0x0419 0x041A 0x041B 0x041C \ + 0x041D 0x041E 0x041F 0x0420 0x0421 0x0422 0x0423 0x0424 \ + 0x0425 0x0426 0x0427 0x0428 0x0429 0x042A 0x042B 0x042C \ + 0x042D 0x042E 0x042F 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0x0430 0x0431 0x0432 0x0433 0x0434 0x0435 \ + 0x0451 0x0436 0x0437 0x0438 0x0439 0x043A 0x043B 0x043C \ + 0x043D 0x043E 0x043F 0x0440 0x0441 0x0442 0x0443 0x0444 \ + 0x0445 0x0446 0x0447 0x0448 0x0449 0x044A 0x044B 0x044C \ + 0x044D 0x044E 0x044F 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +06 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xAC00 0xAC01 0xAC04 0xAC07 0xAC08 0xAC09 \ + 0xAC0A 0xAC10 0xAC11 0xAC12 0xAC13 0xAC14 0xAC15 0xAC16 \ + 0xAC17 0xAC19 0xAC1A 0xAC1B 0xAC1C 0xAC1D 0xAC20 0xAC24 \ + 0xAC2C 0xAC2D 0xAC2F 0xAC30 0xAC31 0xAC38 0xAC39 0xAC3C \ + 0xAC40 0xAC4B 0xAC4D 0xAC54 0xAC58 0xAC5C 0xAC70 0xAC71 \ + 0xAC74 0xAC77 0xAC78 0xAC7A 0xAC80 0xAC81 0xAC83 0xAC84 \ + 0xAC85 0xAC86 0xAC89 0xAC8A 0xAC8B 0xAC8C 0xAC90 0xAC94 \ + 0xAC9C 0xAC9D 0xAC9F 0xACA0 0xACA1 0xACA8 0xACA9 0xACAA \ + 0xACAC 0xACAF 0xACB0 0xACB8 0xACB9 0xACBB 0xACBC 0xACBD \ + 0xACC1 0xACC4 0xACC8 0xACCC 0xACD5 0xACD7 0xACE0 0xACE1 \ + 0xACE4 0xACE7 0xACE8 0xACEA 0xACEC 0xACEF 0xACF0 0xACF1 \ + 0xACF3 0xACF5 0xACF6 0xACFC 0xACFD 0xAD00 0xAD04 0xAD06 \ + 0xAD0C 0xAD0D 0xAD0F 0xAD11 0xAD18 0xAD1C 0xAD20 0xAD29 \ + 0xAD2C 0xAD2D 0xAD34 0xAD35 0xAD38 0xAD3C 0xAD44 0xAD45 \ + 0xAD47 0xAD49 0xAD50 0xAD54 0xAD58 0xAD61 0xAD63 0xAD6C \ + 0xAD6D 0xAD70 0xAD73 0xAD74 0xAD75 0xAD76 0xAD7B 0xAD7C +07 0xAD7D 0xAD7F 0xAD81 0xAD82 0xAD88 0xAD89 0xAD8C 0xAD90 \ + 0xAD9C 0xAD9D 0xADA4 0xADB7 0xADC0 0xADC1 0xADC4 0xADC8 \ + 0xADD0 0xADD1 0xADD3 0xADDC 0xADE0 0xADE4 0xADF8 0xADF9 \ + 0xADFC 0xADFF 0xAE00 0xAE01 0xAE08 0xAE09 0xAE0B 0xAE0D \ + 0xAE14 0xAE30 0xAE31 0xAE34 0xAE37 0xAE38 0xAE3A 0xAE40 \ + 0xAE41 0xAE43 0xAE45 0xAE46 0xAE4A 0xAE4C 0xAE4D 0xAE4E \ + 0xAE50 0xAE54 0xAE56 0xAE5C 0xAE5D 0xAE5F 0xAE60 0xAE61 \ + 0xAE65 0xAE68 0xAE69 0xAE6C 0xAE70 0xAE78 0xAE79 0xAE7B \ + 0xAE7C 0xAE7D 0xAE84 0xAE85 0xAE8C 0xAEBC 0xAEBD 0xAEBE \ + 0xAEC0 0xAEC4 0xAECC 0xAECD 0xAECF 0xAED0 0xAED1 0xAED8 \ + 0xAED9 0xAEDC 0xAEE8 0xAEEB 0xAEED 0xAEF4 0xAEF8 0xAEFC \ + 0xAF07 0xAF08 0xAF0D 0xAF10 0xAF2C 0xAF2D 0xAF30 0xAF32 \ + 0xAF34 0xAF3C 0xAF3D 0xAF3F 0xAF41 0xAF42 0xAF43 0xAF48 \ + 0xAF49 0xAF50 0xAF5C 0xAF5D 0xAF64 0xAF65 0xAF79 0xAF80 \ + 0xAF84 0xAF88 0xAF90 0xAF91 0xAF95 0xAF9C 0xAFB8 0xAFB9 \ + 0xAFBC 0xAFC0 0xAFC7 0xAFC8 0xAFC9 0xAFCB 0xAFCD 0xAFCE \ + 0xAFD4 0xAFDC 0xAFE8 0xAFE9 0xAFF0 0xAFF1 0xAFF4 0xAFF8 \ + 0xB000 0xB001 0xB004 0xB00C 0xB010 0xB014 0xB01C 0xB01D \ + 0xB028 0xB044 0xB045 0xB048 0xB04A 0xB04C 0xB04E 0xB053 \ + 0xB054 0xB055 0xB057 0xB059 0xB05D 0xB07C 0xB07D 0xB080 \ + 0xB084 0xB08C 0xB08D 0xB08F 0xB091 0xB098 0xB099 0xB09A \ + 0xB09C 0xB09F 0xB0A0 0xB0A1 0xB0A2 0xB0A8 0xB0A9 0xB0AB \ + 0xB0AC 0xB0AD 0xB0AE 0xB0AF 0xB0B1 0xB0B3 0xB0B4 0xB0B5 \ + 0xB0B8 0xB0BC 0xB0C4 0xB0C5 0xB0C7 0xB0C8 0xB0C9 0xB0D0 \ + 0xB0D1 0xB0D4 0xB0D8 0xB0E0 0xB0E5 0xB108 0xB109 0xB10B \ + 0xB10C 0xB110 0xB112 0xB113 0xB118 0xB119 0xB11B 0xB11C \ + 0xB11D 0xB123 0xB124 0xB125 0xB128 0xB12C 0xB134 0xB135 \ + 0xB137 0xB138 0xB139 0xB140 0xB141 0xB144 0xB148 0xB150 \ + 0xB151 0xB154 0xB155 0xB158 0xB15C 0xB160 0xB178 0xB179 \ + 0xB17C 0xB180 0xB182 0xB188 0xB189 0xB18B 0xB18D 0xB192 \ + 0xB193 0xB194 0xB198 0xB19C 0xB1A8 0xB1CC 0xB1D0 0xB1D4 \ + 0xB1DC 0xB1DD 0xB1DF 0xB1E8 0xB1E9 0xB1EC 0xB1F0 0xB1F9 +08 0xB1FB 0xB1FD 0xB204 0xB205 0xB208 0xB20B 0xB20C 0xB214 \ + 0xB215 0xB217 0xB219 0xB220 0xB234 0xB23C 0xB258 0xB25C \ + 0xB260 0xB268 0xB269 0xB274 0xB275 0xB27C 0xB284 0xB285 \ + 0xB289 0xB290 0xB291 0xB294 0xB298 0xB299 0xB29A 0xB2A0 \ + 0xB2A1 0xB2A3 0xB2A5 0xB2A6 0xB2AA 0xB2AC 0xB2B0 0xB2B4 \ + 0xB2C8 0xB2C9 0xB2CC 0xB2D0 0xB2D2 0xB2D8 0xB2D9 0xB2DB \ + 0xB2DD 0xB2E2 0xB2E4 0xB2E5 0xB2E6 0xB2E8 0xB2EB 0xB2EC \ + 0xB2ED 0xB2EE 0xB2EF 0xB2F3 0xB2F4 0xB2F5 0xB2F7 0xB2F8 \ + 0xB2F9 0xB2FA 0xB2FB 0xB2FF 0xB300 0xB301 0xB304 0xB308 \ + 0xB310 0xB311 0xB313 0xB314 0xB315 0xB31C 0xB354 0xB355 \ + 0xB356 0xB358 0xB35B 0xB35C 0xB35E 0xB35F 0xB364 0xB365 \ + 0xB367 0xB369 0xB36B 0xB36E 0xB370 0xB371 0xB374 0xB378 \ + 0xB380 0xB381 0xB383 0xB384 0xB385 0xB38C 0xB390 0xB394 \ + 0xB3A0 0xB3A1 0xB3A8 0xB3AC 0xB3C4 0xB3C5 0xB3C8 0xB3CB \ + 0xB3CC 0xB3CE 0xB3D0 0xB3D4 0xB3D5 0xB3D7 0xB3D9 0xB3DB \ + 0xB3DD 0xB3E0 0xB3E4 0xB3E8 0xB3FC 0xB410 0xB418 0xB41C \ + 0xB420 0xB428 0xB429 0xB42B 0xB434 0xB450 0xB451 0xB454 \ + 0xB458 0xB460 0xB461 0xB463 0xB465 0xB46C 0xB480 0xB488 \ + 0xB49D 0xB4A4 0xB4A8 0xB4AC 0xB4B5 0xB4B7 0xB4B9 0xB4C0 \ + 0xB4C4 0xB4C8 0xB4D0 0xB4D5 0xB4DC 0xB4DD 0xB4E0 0xB4E3 \ + 0xB4E4 0xB4E6 0xB4EC 0xB4ED 0xB4EF 0xB4F1 0xB4F8 0xB514 \ + 0xB515 0xB518 0xB51B 0xB51C 0xB524 0xB525 0xB527 0xB528 \ + 0xB529 0xB52A 0xB530 0xB531 0xB534 0xB538 0xB540 0xB541 \ + 0xB543 0xB544 0xB545 0xB54B 0xB54C 0xB54D 0xB550 0xB554 \ + 0xB55C 0xB55D 0xB55F 0xB560 0xB561 0xB5A0 0xB5A1 0xB5A4 \ + 0xB5A8 0xB5AA 0xB5AB 0xB5B0 0xB5B1 0xB5B3 0xB5B4 0xB5B5 \ + 0xB5BB 0xB5BC 0xB5BD 0xB5C0 0xB5C4 0xB5CC 0xB5CD 0xB5CF \ + 0xB5D0 0xB5D1 0xB5D8 0xB5EC 0xB610 0xB611 0xB614 0xB618 \ + 0xB625 0xB62C 0xB634 0xB648 0xB664 0xB668 0xB69C 0xB69D \ + 0xB6A0 0xB6A4 0xB6AB 0xB6AC 0xB6B1 0xB6D4 0xB6F0 0xB6F4 \ + 0xB6F8 0xB700 0xB701 0xB705 0xB728 0xB729 0xB72C 0xB72F \ + 0xB730 0xB738 0xB739 0xB73B 0xB744 0xB748 0xB74C 0xB754 +09 0xB755 0xB760 0xB764 0xB768 0xB770 0xB771 0xB773 0xB775 \ + 0xB77C 0xB77D 0xB780 0xB784 0xB78C 0xB78D 0xB78F 0xB790 \ + 0xB791 0xB792 0xB796 0xB797 0xB798 0xB799 0xB79C 0xB7A0 \ + 0xB7A8 0xB7A9 0xB7AB 0xB7AC 0xB7AD 0xB7B4 0xB7B5 0xB7B8 \ + 0xB7C7 0xB7C9 0xB7EC 0xB7ED 0xB7F0 0xB7F4 0xB7FC 0xB7FD \ + 0xB7FF 0xB800 0xB801 0xB807 0xB808 0xB809 0xB80C 0xB810 \ + 0xB818 0xB819 0xB81B 0xB81D 0xB824 0xB825 0xB828 0xB82C \ + 0xB834 0xB835 0xB837 0xB838 0xB839 0xB840 0xB844 0xB851 \ + 0xB853 0xB85C 0xB85D 0xB860 0xB864 0xB86C 0xB86D 0xB86F \ + 0xB871 0xB878 0xB87C 0xB88D 0xB8A8 0xB8B0 0xB8B4 0xB8B8 \ + 0xB8C0 0xB8C1 0xB8C3 0xB8C5 0xB8CC 0xB8D0 0xB8D4 0xB8DD \ + 0xB8DF 0xB8E1 0xB8E8 0xB8E9 0xB8EC 0xB8F0 0xB8F8 0xB8F9 \ + 0xB8FB 0xB8FD 0xB904 0xB918 0xB920 0xB93C 0xB93D 0xB940 \ + 0xB944 0xB94C 0xB94F 0xB951 0xB958 0xB959 0xB95C 0xB960 \ + 0xB968 0xB969 0xB96B 0xB96D 0xB974 0xB975 0xB978 0xB97C \ + 0xB984 0xB985 0xB987 0xB989 0xB98A 0xB98D 0xB98E 0xB9AC \ + 0xB9AD 0xB9B0 0xB9B4 0xB9BC 0xB9BD 0xB9BF 0xB9C1 0xB9C8 \ + 0xB9C9 0xB9CC 0xB9CE 0xB9CF 0xB9D0 0xB9D1 0xB9D2 0xB9D8 \ + 0xB9D9 0xB9DB 0xB9DD 0xB9DE 0xB9E1 0xB9E3 0xB9E4 0xB9E5 \ + 0xB9E8 0xB9EC 0xB9F4 0xB9F5 0xB9F7 0xB9F8 0xB9F9 0xB9FA \ + 0xBA00 0xBA01 0xBA08 0xBA15 0xBA38 0xBA39 0xBA3C 0xBA40 \ + 0xBA42 0xBA48 0xBA49 0xBA4B 0xBA4D 0xBA4E 0xBA53 0xBA54 \ + 0xBA55 0xBA58 0xBA5C 0xBA64 0xBA65 0xBA67 0xBA68 0xBA69 \ + 0xBA70 0xBA71 0xBA74 0xBA78 0xBA83 0xBA84 0xBA85 0xBA87 \ + 0xBA8C 0xBAA8 0xBAA9 0xBAAB 0xBAAC 0xBAB0 0xBAB2 0xBAB8 \ + 0xBAB9 0xBABB 0xBABD 0xBAC4 0xBAC8 0xBAD8 0xBAD9 0xBAFC \ + 0xBB00 0xBB04 0xBB0D 0xBB0F 0xBB11 0xBB18 0xBB1C 0xBB20 \ + 0xBB29 0xBB2B 0xBB34 0xBB35 0xBB36 0xBB38 0xBB3B 0xBB3C \ + 0xBB3D 0xBB3E 0xBB44 0xBB45 0xBB47 0xBB49 0xBB4D 0xBB4F \ + 0xBB50 0xBB54 0xBB58 0xBB61 0xBB63 0xBB6C 0xBB88 0xBB8C \ + 0xBB90 0xBBA4 0xBBA8 0xBBAC 0xBBB4 0xBBB7 0xBBC0 0xBBC4 \ + 0xBBC8 0xBBD0 0xBBD3 0xBBF8 0xBBF9 0xBBFC 0xBBFF 0xBC00 +10 0xBC02 0xBC08 0xBC09 0xBC0B 0xBC0C 0xBC0D 0xBC0F 0xBC11 \ + 0xBC14 0xBC15 0xBC16 0xBC17 0xBC18 0xBC1B 0xBC1C 0xBC1D \ + 0xBC1E 0xBC1F 0xBC24 0xBC25 0xBC27 0xBC29 0xBC2D 0xBC30 \ + 0xBC31 0xBC34 0xBC38 0xBC40 0xBC41 0xBC43 0xBC44 0xBC45 \ + 0xBC49 0xBC4C 0xBC4D 0xBC50 0xBC5D 0xBC84 0xBC85 0xBC88 \ + 0xBC8B 0xBC8C 0xBC8E 0xBC94 0xBC95 0xBC97 0xBC99 0xBC9A \ + 0xBCA0 0xBCA1 0xBCA4 0xBCA7 0xBCA8 0xBCB0 0xBCB1 0xBCB3 \ + 0xBCB4 0xBCB5 0xBCBC 0xBCBD 0xBCC0 0xBCC4 0xBCCD 0xBCCF \ + 0xBCD0 0xBCD1 0xBCD5 0xBCD8 0xBCDC 0xBCF4 0xBCF5 0xBCF6 \ + 0xBCF8 0xBCFC 0xBD04 0xBD05 0xBD07 0xBD09 0xBD10 0xBD14 \ + 0xBD24 0xBD2C 0xBD40 0xBD48 0xBD49 0xBD4C 0xBD50 0xBD58 \ + 0xBD59 0xBD64 0xBD68 0xBD80 0xBD81 0xBD84 0xBD87 0xBD88 \ + 0xBD89 0xBD8A 0xBD90 0xBD91 0xBD93 0xBD95 0xBD99 0xBD9A \ + 0xBD9C 0xBDA4 0xBDB0 0xBDB8 0xBDD4 0xBDD5 0xBDD8 0xBDDC \ + 0xBDE9 0xBDF0 0xBDF4 0xBDF8 0xBE00 0xBE03 0xBE05 0xBE0C \ + 0xBE0D 0xBE10 0xBE14 0xBE1C 0xBE1D 0xBE1F 0xBE44 0xBE45 \ + 0xBE48 0xBE4C 0xBE4E 0xBE54 0xBE55 0xBE57 0xBE59 0xBE5A \ + 0xBE5B 0xBE60 0xBE61 0xBE64 0xBE68 0xBE6A 0xBE70 0xBE71 \ + 0xBE73 0xBE74 0xBE75 0xBE7B 0xBE7C 0xBE7D 0xBE80 0xBE84 \ + 0xBE8C 0xBE8D 0xBE8F 0xBE90 0xBE91 0xBE98 0xBE99 0xBEA8 \ + 0xBED0 0xBED1 0xBED4 0xBED7 0xBED8 0xBEE0 0xBEE3 0xBEE4 \ + 0xBEE5 0xBEEC 0xBF01 0xBF08 0xBF09 0xBF18 0xBF19 0xBF1B \ + 0xBF1C 0xBF1D 0xBF40 0xBF41 0xBF44 0xBF48 0xBF50 0xBF51 \ + 0xBF55 0xBF94 0xBFB0 0xBFC5 0xBFCC 0xBFCD 0xBFD0 0xBFD4 \ + 0xBFDC 0xBFDF 0xBFE1 0xC03C 0xC051 0xC058 0xC05C 0xC060 \ + 0xC068 0xC069 0xC090 0xC091 0xC094 0xC098 0xC0A0 0xC0A1 \ + 0xC0A3 0xC0A5 0xC0AC 0xC0AD 0xC0AF 0xC0B0 0xC0B3 0xC0B4 \ + 0xC0B5 0xC0B6 0xC0BC 0xC0BD 0xC0BF 0xC0C0 0xC0C1 0xC0C5 \ + 0xC0C8 0xC0C9 0xC0CC 0xC0D0 0xC0D8 0xC0D9 0xC0DB 0xC0DC \ + 0xC0DD 0xC0E4 0xC0E5 0xC0E8 0xC0EC 0xC0F4 0xC0F5 0xC0F7 \ + 0xC0F9 0xC100 0xC104 0xC108 0xC110 0xC115 0xC11C 0xC11D \ + 0xC11E 0xC11F 0xC120 0xC123 0xC124 0xC126 0xC127 0xC12C +11 0xC12D 0xC12F 0xC130 0xC131 0xC136 0xC138 0xC139 0xC13C \ + 0xC140 0xC148 0xC149 0xC14B 0xC14C 0xC14D 0xC154 0xC155 \ + 0xC158 0xC15C 0xC164 0xC165 0xC167 0xC168 0xC169 0xC170 \ + 0xC174 0xC178 0xC185 0xC18C 0xC18D 0xC18E 0xC190 0xC194 \ + 0xC196 0xC19C 0xC19D 0xC19F 0xC1A1 0xC1A5 0xC1A8 0xC1A9 \ + 0xC1AC 0xC1B0 0xC1BD 0xC1C4 0xC1C8 0xC1CC 0xC1D4 0xC1D7 \ + 0xC1D8 0xC1E0 0xC1E4 0xC1E8 0xC1F0 0xC1F1 0xC1F3 0xC1FC \ + 0xC1FD 0xC200 0xC204 0xC20C 0xC20D 0xC20F 0xC211 0xC218 \ + 0xC219 0xC21C 0xC21F 0xC220 0xC228 0xC229 0xC22B 0xC22D \ + 0xC22F 0xC231 0xC232 0xC234 0xC248 0xC250 0xC251 0xC254 \ + 0xC258 0xC260 0xC265 0xC26C 0xC26D 0xC270 0xC274 0xC27C \ + 0xC27D 0xC27F 0xC281 0xC288 0xC289 0xC290 0xC298 0xC29B \ + 0xC29D 0xC2A4 0xC2A5 0xC2A8 0xC2AC 0xC2AD 0xC2B4 0xC2B5 \ + 0xC2B7 0xC2B9 0xC2DC 0xC2DD 0xC2E0 0xC2E3 0xC2E4 0xC2EB \ + 0xC2EC 0xC2ED 0xC2EF 0xC2F1 0xC2F6 0xC2F8 0xC2F9 0xC2FB \ + 0xC2FC 0xC300 0xC308 0xC309 0xC30C 0xC30D 0xC313 0xC314 \ + 0xC315 0xC318 0xC31C 0xC324 0xC325 0xC328 0xC329 0xC345 \ + 0xC368 0xC369 0xC36C 0xC370 0xC372 0xC378 0xC379 0xC37C \ + 0xC37D 0xC384 0xC388 0xC38C 0xC3C0 0xC3D8 0xC3D9 0xC3DC \ + 0xC3DF 0xC3E0 0xC3E2 0xC3E8 0xC3E9 0xC3ED 0xC3F4 0xC3F5 \ + 0xC3F8 0xC408 0xC410 0xC424 0xC42C 0xC430 0xC434 0xC43C \ + 0xC43D 0xC448 0xC464 0xC465 0xC468 0xC46C 0xC474 0xC475 \ + 0xC479 0xC480 0xC494 0xC49C 0xC4B8 0xC4BC 0xC4E9 0xC4F0 \ + 0xC4F1 0xC4F4 0xC4F8 0xC4FA 0xC4FF 0xC500 0xC501 0xC50C \ + 0xC510 0xC514 0xC51C 0xC528 0xC529 0xC52C 0xC530 0xC538 \ + 0xC539 0xC53B 0xC53D 0xC544 0xC545 0xC548 0xC549 0xC54A \ + 0xC54C 0xC54D 0xC54E 0xC553 0xC554 0xC555 0xC557 0xC558 \ + 0xC559 0xC55D 0xC55E 0xC560 0xC561 0xC564 0xC568 0xC570 \ + 0xC571 0xC573 0xC574 0xC575 0xC57C 0xC57D 0xC580 0xC584 \ + 0xC587 0xC58C 0xC58D 0xC58F 0xC591 0xC595 0xC597 0xC598 \ + 0xC59C 0xC5A0 0xC5A9 0xC5B4 0xC5B5 0xC5B8 0xC5B9 0xC5BB \ + 0xC5BC 0xC5BD 0xC5BE 0xC5C4 0xC5C5 0xC5C6 0xC5C7 0xC5C8 +12 0xC5C9 0xC5CA 0xC5CC 0xC5CE 0xC5D0 0xC5D1 0xC5D4 0xC5D8 \ + 0xC5E0 0xC5E1 0xC5E3 0xC5E5 0xC5EC 0xC5ED 0xC5EE 0xC5F0 \ + 0xC5F4 0xC5F6 0xC5F7 0xC5FC 0xC5FD 0xC5FE 0xC5FF 0xC600 \ + 0xC601 0xC605 0xC606 0xC607 0xC608 0xC60C 0xC610 0xC618 \ + 0xC619 0xC61B 0xC61C 0xC624 0xC625 0xC628 0xC62C 0xC62D \ + 0xC62E 0xC630 0xC633 0xC634 0xC635 0xC637 0xC639 0xC63B \ + 0xC640 0xC641 0xC644 0xC648 0xC650 0xC651 0xC653 0xC654 \ + 0xC655 0xC65C 0xC65D 0xC660 0xC66C 0xC66F 0xC671 0xC678 \ + 0xC679 0xC67C 0xC680 0xC688 0xC689 0xC68B 0xC68D 0xC694 \ + 0xC695 0xC698 0xC69C 0xC6A4 0xC6A5 0xC6A7 0xC6A9 0xC6B0 \ + 0xC6B1 0xC6B4 0xC6B8 0xC6B9 0xC6BA 0xC6C0 0xC6C1 0xC6C3 \ + 0xC6C5 0xC6CC 0xC6CD 0xC6D0 0xC6D4 0xC6DC 0xC6DD 0xC6E0 \ + 0xC6E1 0xC6E8 0xC6E9 0xC6EC 0xC6F0 0xC6F8 0xC6F9 0xC6FD \ + 0xC704 0xC705 0xC708 0xC70C 0xC714 0xC715 0xC717 0xC719 \ + 0xC720 0xC721 0xC724 0xC728 0xC730 0xC731 0xC733 0xC735 \ + 0xC737 0xC73C 0xC73D 0xC740 0xC744 0xC74A 0xC74C 0xC74D \ + 0xC74F 0xC751 0xC752 0xC753 0xC754 0xC755 0xC756 0xC757 \ + 0xC758 0xC75C 0xC760 0xC768 0xC76B 0xC774 0xC775 0xC778 \ + 0xC77C 0xC77D 0xC77E 0xC783 0xC784 0xC785 0xC787 0xC788 \ + 0xC789 0xC78A 0xC78E 0xC790 0xC791 0xC794 0xC796 0xC797 \ + 0xC798 0xC79A 0xC7A0 0xC7A1 0xC7A3 0xC7A4 0xC7A5 0xC7A6 \ + 0xC7AC 0xC7AD 0xC7B0 0xC7B4 0xC7BC 0xC7BD 0xC7BF 0xC7C0 \ + 0xC7C1 0xC7C8 0xC7C9 0xC7CC 0xC7CE 0xC7D0 0xC7D8 0xC7DD \ + 0xC7E4 0xC7E8 0xC7EC 0xC800 0xC801 0xC804 0xC808 0xC80A \ + 0xC810 0xC811 0xC813 0xC815 0xC816 0xC81C 0xC81D 0xC820 \ + 0xC824 0xC82C 0xC82D 0xC82F 0xC831 0xC838 0xC83C 0xC840 \ + 0xC848 0xC849 0xC84C 0xC84D 0xC854 0xC870 0xC871 0xC874 \ + 0xC878 0xC87A 0xC880 0xC881 0xC883 0xC885 0xC886 0xC887 \ + 0xC88B 0xC88C 0xC88D 0xC894 0xC89D 0xC89F 0xC8A1 0xC8A8 \ + 0xC8BC 0xC8BD 0xC8C4 0xC8C8 0xC8CC 0xC8D4 0xC8D5 0xC8D7 \ + 0xC8D9 0xC8E0 0xC8E1 0xC8E4 0xC8F5 0xC8FC 0xC8FD 0xC900 \ + 0xC904 0xC905 0xC906 0xC90C 0xC90D 0xC90F 0xC911 0xC918 +13 0xC92C 0xC934 0xC950 0xC951 0xC954 0xC958 0xC960 0xC961 \ + 0xC963 0xC96C 0xC970 0xC974 0xC97C 0xC988 0xC989 0xC98C \ + 0xC990 0xC998 0xC999 0xC99B 0xC99D 0xC9C0 0xC9C1 0xC9C4 \ + 0xC9C7 0xC9C8 0xC9CA 0xC9D0 0xC9D1 0xC9D3 0xC9D5 0xC9D6 \ + 0xC9D9 0xC9DA 0xC9DC 0xC9DD 0xC9E0 0xC9E2 0xC9E4 0xC9E7 \ + 0xC9EC 0xC9ED 0xC9EF 0xC9F0 0xC9F1 0xC9F8 0xC9F9 0xC9FC \ + 0xCA00 0xCA08 0xCA09 0xCA0B 0xCA0C 0xCA0D 0xCA14 0xCA18 \ + 0xCA29 0xCA4C 0xCA4D 0xCA50 0xCA54 0xCA5C 0xCA5D 0xCA5F \ + 0xCA60 0xCA61 0xCA68 0xCA7D 0xCA84 0xCA98 0xCABC 0xCABD \ + 0xCAC0 0xCAC4 0xCACC 0xCACD 0xCACF 0xCAD1 0xCAD3 0xCAD8 \ + 0xCAD9 0xCAE0 0xCAEC 0xCAF4 0xCB08 0xCB10 0xCB14 0xCB18 \ + 0xCB20 0xCB21 0xCB41 0xCB48 0xCB49 0xCB4C 0xCB50 0xCB58 \ + 0xCB59 0xCB5D 0xCB64 0xCB78 0xCB79 0xCB9C 0xCBB8 0xCBD4 \ + 0xCBE4 0xCBE7 0xCBE9 0xCC0C 0xCC0D 0xCC10 0xCC14 0xCC1C \ + 0xCC1D 0xCC21 0xCC22 0xCC27 0xCC28 0xCC29 0xCC2C 0xCC2E \ + 0xCC30 0xCC38 0xCC39 0xCC3B 0xCC3C 0xCC3D 0xCC3E 0xCC44 \ + 0xCC45 0xCC48 0xCC4C 0xCC54 0xCC55 0xCC57 0xCC58 0xCC59 \ + 0xCC60 0xCC64 0xCC66 0xCC68 0xCC70 0xCC75 0xCC98 0xCC99 \ + 0xCC9C 0xCCA0 0xCCA8 0xCCA9 0xCCAB 0xCCAC 0xCCAD 0xCCB4 \ + 0xCCB5 0xCCB8 0xCCBC 0xCCC4 0xCCC5 0xCCC7 0xCCC9 0xCCD0 \ + 0xCCD4 0xCCE4 0xCCEC 0xCCF0 0xCD01 0xCD08 0xCD09 0xCD0C \ + 0xCD10 0xCD18 0xCD19 0xCD1B 0xCD1D 0xCD24 0xCD28 0xCD2C \ + 0xCD39 0xCD5C 0xCD60 0xCD64 0xCD6C 0xCD6D 0xCD6F 0xCD71 \ + 0xCD78 0xCD88 0xCD94 0xCD95 0xCD98 0xCD9C 0xCDA4 0xCDA5 \ + 0xCDA7 0xCDA9 0xCDB0 0xCDC4 0xCDCC 0xCDD0 0xCDE8 0xCDEC \ + 0xCDF0 0xCDF8 0xCDF9 0xCDFB 0xCDFD 0xCE04 0xCE08 0xCE0C \ + 0xCE14 0xCE19 0xCE20 0xCE21 0xCE24 0xCE28 0xCE30 0xCE31 \ + 0xCE33 0xCE35 0xCE58 0xCE59 0xCE5C 0xCE5F 0xCE60 0xCE61 \ + 0xCE68 0xCE69 0xCE6B 0xCE6D 0xCE74 0xCE75 0xCE78 0xCE7C \ + 0xCE84 0xCE85 0xCE87 0xCE89 0xCE90 0xCE91 0xCE94 0xCE98 \ + 0xCEA0 0xCEA1 0xCEA3 0xCEA4 0xCEA5 0xCEAC 0xCEAD 0xCEC1 \ + 0xCEE4 0xCEE5 0xCEE8 0xCEEB 0xCEEC 0xCEF4 0xCEF5 0xCEF7 +14 0xCEF8 0xCEF9 0xCF00 0xCF01 0xCF04 0xCF08 0xCF10 0xCF11 \ + 0xCF13 0xCF15 0xCF1C 0xCF20 0xCF24 0xCF2C 0xCF2D 0xCF2F \ + 0xCF30 0xCF31 0xCF38 0xCF54 0xCF55 0xCF58 0xCF5C 0xCF64 \ + 0xCF65 0xCF67 0xCF69 0xCF70 0xCF71 0xCF74 0xCF78 0xCF80 \ + 0xCF85 0xCF8C 0xCFA1 0xCFA8 0xCFB0 0xCFC4 0xCFE0 0xCFE1 \ + 0xCFE4 0xCFE8 0xCFF0 0xCFF1 0xCFF3 0xCFF5 0xCFFC 0xD000 \ + 0xD004 0xD011 0xD018 0xD02D 0xD034 0xD035 0xD038 0xD03C \ + 0xD044 0xD045 0xD047 0xD049 0xD050 0xD054 0xD058 0xD060 \ + 0xD06C 0xD06D 0xD070 0xD074 0xD07C 0xD07D 0xD081 0xD0A4 \ + 0xD0A5 0xD0A8 0xD0AC 0xD0B4 0xD0B5 0xD0B7 0xD0B9 0xD0C0 \ + 0xD0C1 0xD0C4 0xD0C8 0xD0C9 0xD0D0 0xD0D1 0xD0D3 0xD0D4 \ + 0xD0D5 0xD0DC 0xD0DD 0xD0E0 0xD0E4 0xD0EC 0xD0ED 0xD0EF \ + 0xD0F0 0xD0F1 0xD0F8 0xD10D 0xD130 0xD131 0xD134 0xD138 \ + 0xD13A 0xD140 0xD141 0xD143 0xD144 0xD145 0xD14C 0xD14D \ + 0xD150 0xD154 0xD15C 0xD15D 0xD15F 0xD161 0xD168 0xD16C \ + 0xD17C 0xD184 0xD188 0xD1A0 0xD1A1 0xD1A4 0xD1A8 0xD1B0 \ + 0xD1B1 0xD1B3 0xD1B5 0xD1BA 0xD1BC 0xD1C0 0xD1D8 0xD1F4 \ + 0xD1F8 0xD207 0xD209 0xD210 0xD22C 0xD22D 0xD230 0xD234 \ + 0xD23C 0xD23D 0xD23F 0xD241 0xD248 0xD25C 0xD264 0xD280 \ + 0xD281 0xD284 0xD288 0xD290 0xD291 0xD295 0xD29C 0xD2A0 \ + 0xD2A4 0xD2AC 0xD2B1 0xD2B8 0xD2B9 0xD2BC 0xD2BF 0xD2C0 \ + 0xD2C2 0xD2C8 0xD2C9 0xD2CB 0xD2D4 0xD2D8 0xD2DC 0xD2E4 \ + 0xD2E5 0xD2F0 0xD2F1 0xD2F4 0xD2F8 0xD300 0xD301 0xD303 \ + 0xD305 0xD30C 0xD30D 0xD30E 0xD310 0xD314 0xD316 0xD31C \ + 0xD31D 0xD31F 0xD320 0xD321 0xD325 0xD328 0xD329 0xD32C \ + 0xD330 0xD338 0xD339 0xD33B 0xD33C 0xD33D 0xD344 0xD345 \ + 0xD37C 0xD37D 0xD380 0xD384 0xD38C 0xD38D 0xD38F 0xD390 \ + 0xD391 0xD398 0xD399 0xD39C 0xD3A0 0xD3A8 0xD3A9 0xD3AB \ + 0xD3AD 0xD3B4 0xD3B8 0xD3BC 0xD3C4 0xD3C5 0xD3C8 0xD3C9 \ + 0xD3D0 0xD3D8 0xD3E1 0xD3E3 0xD3EC 0xD3ED 0xD3F0 0xD3F4 \ + 0xD3FC 0xD3FD 0xD3FF 0xD401 0xD408 0xD41D 0xD440 0xD444 \ + 0xD45C 0xD460 0xD464 0xD46D 0xD46F 0xD478 0xD479 0xD47C +15 0xD47F 0xD480 0xD482 0xD488 0xD489 0xD48B 0xD48D 0xD494 \ + 0xD4A9 0xD4CC 0xD4D0 0xD4D4 0xD4DC 0xD4DF 0xD4E8 0xD4EC \ + 0xD4F0 0xD4F8 0xD4FB 0xD4FD 0xD504 0xD508 0xD50C 0xD514 \ + 0xD515 0xD517 0xD53C 0xD53D 0xD540 0xD544 0xD54C 0xD54D \ + 0xD54F 0xD551 0xD558 0xD559 0xD55C 0xD560 0xD565 0xD568 \ + 0xD569 0xD56B 0xD56D 0xD574 0xD575 0xD578 0xD57C 0xD584 \ + 0xD585 0xD587 0xD588 0xD589 0xD590 0xD5A5 0xD5C8 0xD5C9 \ + 0xD5CC 0xD5D0 0xD5D2 0xD5D8 0xD5D9 0xD5DB 0xD5DD 0xD5E4 \ + 0xD5E5 0xD5E8 0xD5EC 0xD5F4 0xD5F5 0xD5F7 0xD5F9 0xD600 \ + 0xD601 0xD604 0xD608 0xD610 0xD611 0xD613 0xD614 0xD615 \ + 0xD61C 0xD620 0xD624 0xD62D 0xD638 0xD639 0xD63C 0xD640 \ + 0xD645 0xD648 0xD649 0xD64B 0xD64D 0xD651 0xD654 0xD655 \ + 0xD658 0xD65C 0xD667 0xD669 0xD670 0xD671 0xD674 0xD683 \ + 0xD685 0xD68C 0xD68D 0xD690 0xD694 0xD69D 0xD69F 0xD6A1 \ + 0xD6A8 0xD6AC 0xD6B0 0xD6B9 0xD6BB 0xD6C4 0xD6C5 0xD6C8 \ + 0xD6CC 0xD6D1 0xD6D4 0xD6D7 0xD6D9 0xD6E0 0xD6E4 0xD6E8 \ + 0xD6F0 0xD6F5 0xD6FC 0xD6FD 0xD700 0xD704 0xD711 0xD718 \ + 0xD719 0xD71C 0xD720 0xD728 0xD729 0xD72B 0xD72D 0xD734 \ + 0xD735 0xD738 0xD73C 0xD744 0xD747 0xD749 0xD750 0xD751 \ + 0xD754 0xD756 0xD757 0xD758 0xD759 0xD760 0xD761 0xD763 \ + 0xD765 0xD769 0xD76C 0xD770 0xD774 0xD77C 0xD77D 0xD781 \ + 0xD788 0xD789 0xD78C 0xD790 0xD798 0xD799 0xD79B 0xD79D \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE +16 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0x4F3D 0x4F73 \ + 0x5047 0x50F9 0x52A0 0x53EF 0x5475 0x54E5 0x5609 0x5AC1 \ + 0x5BB6 0x6687 0x67B6 0x67B7 0x67EF 0x6B4C 0x73C2 0x75C2 \ + 0x7A3C 0x82DB 0x8304 0x8857 0x8888 0x8A36 0x8CC8 0x8DCF \ + 0x8EFB 0x8FE6 0x99D5 0x523B 0x5374 0x5404 0x606A 0x6164 \ + 0x6BBC 0x73CF 0x811A 0x89BA 0x89D2 0x95A3 0x4F83 0x520A \ + 0x58BE 0x5978 0x59E6 0x5E72 0x5E79 0x61C7 0x63C0 0x6746 \ + 0x67EC 0x687F 0x6F97 0x764E 0x770B 0x78F5 0x7A08 0x7AFF \ + 0x7C21 0x809D 0x826E 0x8271 0x8AEB 0x9593 0x4E6B 0x559D \ + 0x66F7 0x6E34 0x78A3 0x7AED 0x845B 0x8910 0x874E 0x97A8 \ + 0x52D8 0x574E 0x582A 0x5D4C 0x611F 0x61BE 0x6221 0x6562 \ + 0x67D1 0x6A44 0x6E1B 0x7518 0x75B3 0x76E3 0x77B0 0x7D3A \ + 0x90AF 0x9451 0x9452 0x9F95 0x5323 0x5CAC 0x7532 0x80DB \ + 0x9240 0x9598 0x525B 0x5808 0x59DC 0x5CA1 0x5D17 0x5EB7 \ + 0x5F3A 0x5F4A 0x6177 0x6C5F 0x757A 0x7586 0x7CE0 0x7D73 \ + 0x7DB1 0x7F8C 0x8154 0x8221 0x8591 0x8941 0x8B1B 0x92FC \ + 0x964D 0x9C47 0x4ECB 0x4EF7 0x500B 0x51F1 0x584F 0x6137 \ + 0x613E 0x6168 0x6539 0x69EA 0x6F11 0x75A5 0x7686 0x76D6 \ + 0x7B87 0x82A5 0x84CB 0xF900 0x93A7 0x958B 0x5580 0x5BA2 \ + 0x5751 0xF901 0x7CB3 0x7FB9 0x91B5 0x5028 0x53BB 0x5C45 \ + 0x5DE8 0x62D2 0x636E 0x64DA 0x64E7 0x6E20 0x70AC 0x795B \ + 0x8DDD 0x8E1E 0xF902 0x907D 0x9245 0x92F8 0x4E7E 0x4EF6 \ + 0x5065 0x5DFE 0x5EFA 0x6106 0x6957 0x8171 0x8654 0x8E47 \ + 0x9375 0x9A2B 0x4E5E 0x5091 0x6770 0x6840 0x5109 0x528D \ + 0x5292 0x6AA2 0x77BC 0x9210 0x9ED4 0x52AB 0x602F 0x8FF2 \ + 0x5048 0x61A9 0x63ED 0x64CA 0x683C 0x6A84 0x6FC0 0x8188 \ + 0x89A1 0x9694 0x5805 0x727D 0x72AC 0x7504 0x7D79 0x7E6D \ + 0x80A9 0x898B 0x8B74 0x9063 0x9D51 0x6289 0x6C7A 0x6F54 \ + 0x7D50 0x7F3A 0x8A23 0x517C 0x614A 0x7B9D 0x8B19 0x9257 \ + 0x938C 0x4EAC 0x4FD3 0x501E 0x50BE 0x5106 0x52C1 0x52CD \ + 0x537F 0x5770 0x5883 0x5E9A 0x5F91 0x6176 0x61AC 0x64CE +17 0x656C 0x666F 0x66BB 0x66F4 0x6897 0x6D87 0x7085 0x70F1 \ + 0x749F 0x74A5 0x74CA 0x75D9 0x786C 0x78EC 0x7ADF 0x7AF6 \ + 0x7D45 0x7D93 0x8015 0x803F 0x811B 0x8396 0x8B66 0x8F15 \ + 0x9015 0x93E1 0x9803 0x9838 0x9A5A 0x9BE8 0x4FC2 0x5553 \ + 0x583A 0x5951 0x5B63 0x5C46 0x60B8 0x6212 0x6842 0x68B0 \ + 0x68E8 0x6EAA 0x754C 0x7678 0x78CE 0x7A3D 0x7CFB 0x7E6B \ + 0x7E7C 0x8A08 0x8AA1 0x8C3F 0x968E 0x9DC4 0x53E4 0x53E9 \ + 0x544A 0x5471 0x56FA 0x59D1 0x5B64 0x5C3B 0x5EAB 0x62F7 \ + 0x6537 0x6545 0x6572 0x66A0 0x67AF 0x69C1 0x6CBD 0x75FC \ + 0x7690 0x777E 0x7A3F 0x7F94 0x8003 0x80A1 0x818F 0x82E6 \ + 0x82FD 0x83F0 0x85C1 0x8831 0x88B4 0x8AA5 0xF903 0x8F9C \ + 0x932E 0x96C7 0x9867 0x9AD8 0x9F13 0x54ED 0x659B 0x66F2 \ + 0x688F 0x7A40 0x8C37 0x9D60 0x56F0 0x5764 0x5D11 0x6606 \ + 0x68B1 0x68CD 0x6EFE 0x7428 0x889E 0x9BE4 0x6C68 0xF904 \ + 0x9AA8 0x4F9B 0x516C 0x5171 0x529F 0x5B54 0x5DE5 0x6050 \ + 0x606D 0x62F1 0x63A7 0x653B 0x73D9 0x7A7A 0x86A3 0x8CA2 \ + 0x978F 0x4E32 0x5BE1 0x6208 0x679C 0x74DC 0x79D1 0x83D3 \ + 0x8A87 0x8AB2 0x8DE8 0x904E 0x934B 0x9846 0x5ED3 0x69E8 \ + 0x85FF 0x90ED 0xF905 0x51A0 0x5B98 0x5BEC 0x6163 0x68FA \ + 0x6B3E 0x704C 0x742F 0x74D8 0x7BA1 0x7F50 0x83C5 0x89C0 \ + 0x8CAB 0x95DC 0x9928 0x522E 0x605D 0x62EC 0x9002 0x4F8A \ + 0x5149 0x5321 0x58D9 0x5EE3 0x66E0 0x6D38 0x709A 0x72C2 \ + 0x73D6 0x7B50 0x80F1 0x945B 0x5366 0x639B 0x7F6B 0x4E56 \ + 0x5080 0x584A 0x58DE 0x602A 0x6127 0x62D0 0x69D0 0x9B41 \ + 0x5B8F 0x7D18 0x80B1 0x8F5F 0x4EA4 0x50D1 0x54AC 0x55AC \ + 0x5B0C 0x5DA0 0x5DE7 0x652A 0x654E 0x6821 0x6A4B 0x72E1 \ + 0x768E 0x77EF 0x7D5E 0x7FF9 0x81A0 0x854E 0x86DF 0x8F03 \ + 0x8F4E 0x90CA 0x9903 0x9A55 0x9BAB 0x4E18 0x4E45 0x4E5D \ + 0x4EC7 0x4FF1 0x5177 0x52FE 0x5340 0x53E3 0x53E5 0x548E \ + 0x5614 0x5775 0x57A2 0x5BC7 0x5D87 0x5ED0 0x61FC 0x62D8 \ + 0x6551 0x67B8 0x67E9 0x69CB 0x6B50 0x6BC6 0x6BEC 0x6C42 \ + 0x6E9D 0x7078 0x72D7 0x7396 0x7403 0x77BF 0x77E9 0x7A76 +18 0x7D7F 0x8009 0x81FC 0x8205 0x820A 0x82DF 0x8862 0x8B33 \ + 0x8CFC 0x8EC0 0x9011 0x90B1 0x9264 0x92B6 0x99D2 0x9A45 \ + 0x9CE9 0x9DD7 0x9F9C 0x570B 0x5C40 0x83CA 0x97A0 0x97AB \ + 0x9EB4 0x541B 0x7A98 0x7FA4 0x88D9 0x8ECD 0x90E1 0x5800 \ + 0x5C48 0x6398 0x7A9F 0x5BAE 0x5F13 0x7A79 0x7AAE 0x828E \ + 0x8EAC 0x5026 0x5238 0x52F8 0x5377 0x5708 0x62F3 0x6372 \ + 0x6B0A 0x6DC3 0x7737 0x53A5 0x7357 0x8568 0x8E76 0x95D5 \ + 0x673A 0x6AC3 0x6F70 0x8A6D 0x8ECC 0x994B 0xF906 0x6677 \ + 0x6B78 0x8CB4 0x9B3C 0xF907 0x53EB 0x572D 0x594E 0x63C6 \ + 0x69FB 0x73EA 0x7845 0x7ABA 0x7AC5 0x7CFE 0x8475 0x898F \ + 0x8D73 0x9035 0x95A8 0x52FB 0x5747 0x7547 0x7B60 0x83CC \ + 0x921E 0xF908 0x6A58 0x514B 0x524B 0x5287 0x621F 0x68D8 \ + 0x6975 0x9699 0x50C5 0x52A4 0x52E4 0x61C3 0x65A4 0x6839 \ + 0x69FF 0x747E 0x7B4B 0x82B9 0x83EB 0x89B2 0x8B39 0x8FD1 \ + 0x9949 0xF909 0x4ECA 0x5997 0x64D2 0x6611 0x6A8E 0x7434 \ + 0x7981 0x79BD 0x82A9 0x887E 0x887F 0x895F 0xF90A 0x9326 \ + 0x4F0B 0x53CA 0x6025 0x6271 0x6C72 0x7D1A 0x7D66 0x4E98 \ + 0x5162 0x77DC 0x80AF 0x4F01 0x4F0E 0x5176 0x5180 0x55DC \ + 0x5668 0x573B 0x57FA 0x57FC 0x5914 0x5947 0x5993 0x5BC4 \ + 0x5C90 0x5D0E 0x5DF1 0x5E7E 0x5FCC 0x6280 0x65D7 0x65E3 \ + 0x671E 0x671F 0x675E 0x68CB 0x68C4 0x6A5F 0x6B3A 0x6C23 \ + 0x6C7D 0x6C82 0x6DC7 0x7398 0x7426 0x742A 0x7482 0x74A3 \ + 0x7578 0x757F 0x7881 0x78EF 0x7941 0x7947 0x7948 0x797A \ + 0x7B95 0x7D00 0x7DBA 0x7F88 0x8006 0x802D 0x808C 0x8A18 \ + 0x8B4F 0x8C48 0x8D77 0x9321 0x9324 0x98E2 0x9951 0x9A0E \ + 0x9A0F 0x9A65 0x9E92 0x7DCA 0x4F76 0x5409 0x62EE 0x6854 \ + 0x91D1 0x55AB 0x513A 0xF90B 0xF90C 0x5A1C 0x61E6 0xF90D \ + 0x62CF 0x62FF 0xF90E 0xF90F 0xF910 0xF911 0xF912 0xF913 \ + 0x90A3 0xF914 0xF915 0xF916 0xF917 0xF918 0x8AFE 0xF919 \ + 0xF91A 0xF91B 0xF91C 0x6696 0xF91D 0x7156 0xF91E 0xF91F \ + 0x96E3 0xF920 0x634F 0x637A 0x5357 0xF921 0x678F 0x6960 \ + 0x6E73 0xF922 0x7537 0xF923 0xF924 0xF925 0x7D0D 0xF926 +19 0xF927 0x8872 0x56CA 0x5A18 0xF928 0xF929 0xF92A 0xF92B \ + 0xF92C 0x4E43 0xF92D 0x5167 0x5948 0x67F0 0x8010 0xF92E \ + 0x5973 0x5E74 0x649A 0x79CA 0x5FF5 0x606C 0x62C8 0x637B \ + 0x5BE7 0x5BD7 0x52AA 0xF92F 0x5974 0x5F29 0x6012 0xF930 \ + 0xF931 0xF932 0x7459 0xF933 0xF934 0xF935 0xF936 0xF937 \ + 0xF938 0x99D1 0xF939 0xF93A 0xF93B 0xF93C 0xF93D 0xF93E \ + 0xF93F 0xF940 0xF941 0xF942 0xF943 0x6FC3 0xF944 0xF945 \ + 0x81BF 0x8FB2 0x60F1 0xF946 0xF947 0x8166 0xF948 0xF949 \ + 0x5C3F 0xF94A 0xF94B 0xF94C 0xF94D 0xF94E 0xF94F 0xF950 \ + 0xF951 0x5AE9 0x8A25 0x677B 0x7D10 0xF952 0xF953 0xF954 \ + 0xF955 0xF956 0xF957 0x80FD 0xF958 0xF959 0x5C3C 0x6CE5 \ + 0x533F 0x6EBA 0x591A 0x8336 0x4E39 0x4EB6 0x4F46 0x55AE \ + 0x5718 0x58C7 0x5F56 0x65B7 0x65E6 0x6A80 0x6BB5 0x6E4D \ + 0x77ED 0x7AEF 0x7C1E 0x7DDE 0x86CB 0x8892 0x9132 0x935B \ + 0x64BB 0x6FBE 0x737A 0x75B8 0x9054 0x5556 0x574D 0x61BA \ + 0x64D4 0x66C7 0x6DE1 0x6E5B 0x6F6D 0x6FB9 0x75F0 0x8043 \ + 0x81BD 0x8541 0x8983 0x8AC7 0x8B5A 0x931F 0x6C93 0x7553 \ + 0x7B54 0x8E0F 0x905D 0x5510 0x5802 0x5858 0x5E62 0x6207 \ + 0x649E 0x68E0 0x7576 0x7CD6 0x87B3 0x9EE8 0x4EE3 0x5788 \ + 0x576E 0x5927 0x5C0D 0x5CB1 0x5E36 0x5F85 0x6234 0x64E1 \ + 0x73B3 0x81FA 0x888B 0x8CB8 0x968A 0x9EDB 0x5B85 0x5FB7 \ + 0x60B3 0x5012 0x5200 0x5230 0x5716 0x5835 0x5857 0x5C0E \ + 0x5C60 0x5CF6 0x5D8B 0x5EA6 0x5F92 0x60BC 0x6311 0x6389 \ + 0x6417 0x6843 0x68F9 0x6AC2 0x6DD8 0x6E21 0x6ED4 0x6FE4 \ + 0x71FE 0x76DC 0x7779 0x79B1 0x7A3B 0x8404 0x89A9 0x8CED \ + 0x8DF3 0x8E48 0x9003 0x9014 0x9053 0x90FD 0x934D 0x9676 \ + 0x97DC 0x6BD2 0x7006 0x7258 0x72A2 0x7368 0x7763 0x79BF \ + 0x7BE4 0x7E9B 0x8B80 0x58A9 0x60C7 0x6566 0x65FD 0x66BE \ + 0x6C8C 0x711E 0x71C9 0x8C5A 0x9813 0x4E6D 0x7A81 0x4EDD \ + 0x51AC 0x51CD 0x52D5 0x540C 0x61A7 0x6771 0x6850 0x68DF \ + 0x6D1E 0x6F7C 0x75BC 0x77B3 0x7AE5 0x80F4 0x8463 0x9285 \ + 0x515C 0x6597 0x675C 0x6793 0x75D8 0x7AC7 0x8373 0xF95A +20 0x8C46 0x9017 0x982D 0x5C6F 0x81C0 0x829A 0x9041 0x906F \ + 0x920D 0x5F97 0x5D9D 0x6A59 0x71C8 0x767B 0x7B49 0x85E4 \ + 0x8B04 0x9127 0x9A30 0x5587 0x61F6 0xF95B 0x7669 0x7F85 \ + 0x863F 0x87BA 0x88F8 0x908F 0xF95C 0x6D1B 0x70D9 0x73DE \ + 0x7D61 0x843D 0xF95D 0x916A 0x99F1 0xF95E 0x4E82 0x5375 \ + 0x6B04 0x6B12 0x703E 0x721B 0x862D 0x9E1E 0x524C 0x8FA3 \ + 0x5D50 0x64E5 0x652C 0x6B16 0x6FEB 0x7C43 0x7E9C 0x85CD \ + 0x8964 0x89BD 0x62C9 0x81D8 0x881F 0x5ECA 0x6717 0x6D6A \ + 0x72FC 0x7405 0x746F 0x8782 0x90DE 0x4F86 0x5D0D 0x5FA0 \ + 0x840A 0x51B7 0x63A0 0x7565 0x4EAE 0x5006 0x5169 0x51C9 \ + 0x6881 0x6A11 0x7CAE 0x7CB1 0x7CE7 0x826F 0x8AD2 0x8F1B \ + 0x91CF 0x4FB6 0x5137 0x52F5 0x5442 0x5EEC 0x616E 0x623E \ + 0x65C5 0x6ADA 0x6FFE 0x792A 0x85DC 0x8823 0x95AD 0x9A62 \ + 0x9A6A 0x9E97 0x9ECE 0x529B 0x66C6 0x6B77 0x701D 0x792B \ + 0x8F62 0x9742 0x6190 0x6200 0x6523 0x6F23 0x7149 0x7489 \ + 0x7DF4 0x806F 0x84EE 0x8F26 0x9023 0x934A 0x51BD 0x5217 \ + 0x52A3 0x6D0C 0x70C8 0x88C2 0x5EC9 0x6582 0x6BAE 0x6FC2 \ + 0x7C3E 0x7375 0x4EE4 0x4F36 0x56F9 0xF95F 0x5CBA 0x5DBA \ + 0x601C 0x73B2 0x7B2D 0x7F9A 0x7FCE 0x8046 0x901E 0x9234 \ + 0x96F6 0x9748 0x9818 0x9F61 0x4F8B 0x6FA7 0x79AE 0x91B4 \ + 0x96B7 0x52DE 0xF960 0x6488 0x64C4 0x6AD3 0x6F5E 0x7018 \ + 0x7210 0x76E7 0x8001 0x8606 0x865C 0x8DEF 0x8F05 0x9732 \ + 0x9B6F 0x9DFA 0x9E75 0x788C 0x797F 0x7DA0 0x83C9 0x9304 \ + 0x9E7F 0x9E93 0x8AD6 0x58DF 0x5F04 0x6727 0x7027 0x74CF \ + 0x7C60 0x807E 0x5121 0x7028 0x7262 0x78CA 0x8CC2 0x8CDA \ + 0x8CF4 0x96F7 0x4E86 0x50DA 0x5BEE 0x5ED6 0x6599 0x71CE \ + 0x7642 0x77AD 0x804A 0x84FC 0x907C 0x9B27 0x9F8D 0x58D8 \ + 0x5A41 0x5C62 0x6A13 0x6DDA 0x6F0F 0x763B 0x7D2F 0x7E37 \ + 0x851E 0x8938 0x93E4 0x964B 0x5289 0x65D2 0x67F3 0x69B4 \ + 0x6D41 0x6E9C 0x700F 0x7409 0x7460 0x7559 0x7624 0x786B \ + 0x8B2C 0x985E 0x516D 0x622E 0x9678 0x4F96 0x502B 0x5D19 \ + 0x6DEA 0x7DB8 0x8F2A 0x5F8B 0x6144 0x6817 0xF961 0x9686 +21 0x52D2 0x808B 0x51DC 0x51CC 0x695E 0x7A1C 0x7DBE 0x83F1 \ + 0x9675 0x4FDA 0x5229 0x5398 0x540F 0x550E 0x5C65 0x60A7 \ + 0x674E 0x68A8 0x6D6C 0x7281 0x72F8 0x7406 0x7483 0xF962 \ + 0x75E2 0x7C6C 0x7F79 0x7FB8 0x8389 0x88CF 0x88E1 0x91CC \ + 0x91D0 0x96E2 0x9BC9 0x541D 0x6F7E 0x71D0 0x7498 0x85FA \ + 0x8EAA 0x96A3 0x9C57 0x9E9F 0x6797 0x6DCB 0x7433 0x81E8 \ + 0x9716 0x782C 0x7ACB 0x7B20 0x7C92 0x6469 0x746A 0x75F2 \ + 0x78BC 0x78E8 0x99AC 0x9B54 0x9EBB 0x5BDE 0x5E55 0x6F20 \ + 0x819C 0x83AB 0x9088 0x4E07 0x534D 0x5A29 0x5DD2 0x5F4E \ + 0x6162 0x633D 0x6669 0x66FC 0x6EFF 0x6F2B 0x7063 0x779E \ + 0x842C 0x8513 0x883B 0x8F13 0x9945 0x9C3B 0x551C 0x62B9 \ + 0x672B 0x6CAB 0x8309 0x896A 0x977A 0x4EA1 0x5984 0x5FD8 \ + 0x5FD9 0x671B 0x7DB2 0x7F54 0x8292 0x832B 0x83BD 0x8F1E \ + 0x9099 0x57CB 0x59B9 0x5A92 0x5BD0 0x6627 0x679A 0x6885 \ + 0x6BCF 0x7164 0x7F75 0x8CB7 0x8CE3 0x9081 0x9B45 0x8108 \ + 0x8C8A 0x964C 0x9A40 0x9EA5 0x5B5F 0x6C13 0x731B 0x76F2 \ + 0x76DF 0x840C 0x51AA 0x8993 0x514D 0x5195 0x52C9 0x68C9 \ + 0x6C94 0x7704 0x7720 0x7DBF 0x7DEC 0x9762 0x9EB5 0x6EC5 \ + 0x8511 0x51A5 0x540D 0x547D 0x660E 0x669D 0x6927 0x6E9F \ + 0x76BF 0x7791 0x8317 0x84C2 0x879F 0x9169 0x9298 0x9CF4 \ + 0x8882 0x4FAE 0x5192 0x52DF 0x59C6 0x5E3D 0x6155 0x6478 \ + 0x6479 0x66AE 0x67D0 0x6A21 0x6BCD 0x6BDB 0x725F 0x7261 \ + 0x7441 0x7738 0x77DB 0x8017 0x82BC 0x8305 0x8B00 0x8B28 \ + 0x8C8C 0x6728 0x6C90 0x7267 0x76EE 0x7766 0x7A46 0x9DA9 \ + 0x6B7F 0x6C92 0x5922 0x6726 0x8499 0x536F 0x5893 0x5999 \ + 0x5EDF 0x63CF 0x6634 0x6773 0x6E3A 0x732B 0x7AD7 0x82D7 \ + 0x9328 0x52D9 0x5DEB 0x61AE 0x61CB 0x620A 0x62C7 0x64AB \ + 0x65E0 0x6959 0x6B66 0x6BCB 0x7121 0x73F7 0x755D 0x7E46 \ + 0x821E 0x8302 0x856A 0x8AA3 0x8CBF 0x9727 0x9D61 0x58A8 \ + 0x9ED8 0x5011 0x520E 0x543B 0x554F 0x6587 0x6C76 0x7D0A \ + 0x7D0B 0x805E 0x868A 0x9580 0x96EF 0x52FF 0x6C95 0x7269 \ + 0x5473 0x5A9A 0x5C3E 0x5D4B 0x5F4C 0x5FAE 0x672A 0x68B6 +22 0x6963 0x6E3C 0x6E44 0x7709 0x7C73 0x7F8E 0x8587 0x8B0E \ + 0x8FF7 0x9761 0x9EF4 0x5CB7 0x60B6 0x610D 0x61AB 0x654F \ + 0x65FB 0x65FC 0x6C11 0x6CEF 0x739F 0x73C9 0x7DE1 0x9594 \ + 0x5BC6 0x871C 0x8B10 0x525D 0x535A 0x62CD 0x640F 0x64B2 \ + 0x6734 0x6A38 0x6CCA 0x73C0 0x749E 0x7B94 0x7C95 0x7E1B \ + 0x818A 0x8236 0x8584 0x8FEB 0x96F9 0x99C1 0x4F34 0x534A \ + 0x53CD 0x53DB 0x62CC 0x642C 0x6500 0x6591 0x69C3 0x6CEE \ + 0x6F58 0x73ED 0x7554 0x7622 0x76E4 0x76FC 0x78D0 0x78FB \ + 0x792C 0x7D46 0x822C 0x87E0 0x8FD4 0x9812 0x98EF 0x52C3 \ + 0x62D4 0x64A5 0x6E24 0x6F51 0x767C 0x8DCB 0x91B1 0x9262 \ + 0x9AEE 0x9B43 0x5023 0x508D 0x574A 0x59A8 0x5C28 0x5E47 \ + 0x5F77 0x623F 0x653E 0x65B9 0x65C1 0x6609 0x678B 0x699C \ + 0x6EC2 0x78C5 0x7D21 0x80AA 0x8180 0x822B 0x82B3 0x84A1 \ + 0x868C 0x8A2A 0x8B17 0x90A6 0x9632 0x9F90 0x500D 0x4FF3 \ + 0xF963 0x57F9 0x5F98 0x62DC 0x6392 0x676F 0x6E43 0x7119 \ + 0x76C3 0x80CC 0x80DA 0x88F4 0x88F5 0x8919 0x8CE0 0x8F29 \ + 0x914D 0x966A 0x4F2F 0x4F70 0x5E1B 0x67CF 0x6822 0x767D \ + 0x767E 0x9B44 0x5E61 0x6A0A 0x7169 0x71D4 0x756A 0xF964 \ + 0x7E41 0x8543 0x85E9 0x98DC 0x4F10 0x7B4F 0x7F70 0x95A5 \ + 0x51E1 0x5E06 0x68B5 0x6C3E 0x6C4E 0x6CDB 0x72AF 0x7BC4 \ + 0x8303 0x6CD5 0x743A 0x50FB 0x5288 0x58C1 0x64D8 0x6A97 \ + 0x74A7 0x7656 0x78A7 0x8617 0x95E2 0x9739 0xF965 0x535E \ + 0x5F01 0x8B8A 0x8FA8 0x8FAF 0x908A 0x5225 0x77A5 0x9C49 \ + 0x9F08 0x4E19 0x5002 0x5175 0x5C5B 0x5E77 0x661E 0x663A \ + 0x67C4 0x68C5 0x70B3 0x7501 0x75C5 0x79C9 0x7ADD 0x8F27 \ + 0x9920 0x9A08 0x4FDD 0x5821 0x5831 0x5BF6 0x666E 0x6B65 \ + 0x6D11 0x6E7A 0x6F7D 0x73E4 0x752B 0x83E9 0x88DC 0x8913 \ + 0x8B5C 0x8F14 0x4F0F 0x50D5 0x5310 0x535C 0x5B93 0x5FA9 \ + 0x670D 0x798F 0x8179 0x832F 0x8514 0x8907 0x8986 0x8F39 \ + 0x8F3B 0x99A5 0x9C12 0x672C 0x4E76 0x4FF8 0x5949 0x5C01 \ + 0x5CEF 0x5CF0 0x6367 0x68D2 0x70FD 0x71A2 0x742B 0x7E2B \ + 0x84EC 0x8702 0x9022 0x92D2 0x9CF3 0x4E0D 0x4ED8 0x4FEF +23 0x5085 0x5256 0x526F 0x5426 0x5490 0x57E0 0x592B 0x5A66 \ + 0x5B5A 0x5B75 0x5BCC 0x5E9C 0xF966 0x6276 0x6577 0x65A7 \ + 0x6D6E 0x6EA5 0x7236 0x7B26 0x7C3F 0x7F36 0x8150 0x8151 \ + 0x819A 0x8240 0x8299 0x83A9 0x8A03 0x8CA0 0x8CE6 0x8CFB \ + 0x8D74 0x8DBA 0x90E8 0x91DC 0x961C 0x9644 0x99D9 0x9CE7 \ + 0x5317 0x5206 0x5429 0x5674 0x58B3 0x5954 0x596E 0x5FFF \ + 0x61A4 0x626E 0x6610 0x6C7E 0x711A 0x76C6 0x7C89 0x7CDE \ + 0x7D1B 0x82AC 0x8CC1 0x96F0 0xF967 0x4F5B 0x5F17 0x5F7F \ + 0x62C2 0x5D29 0x670B 0x68DA 0x787C 0x7E43 0x9D6C 0x4E15 \ + 0x5099 0x5315 0x532A 0x5351 0x5983 0x5A62 0x5E87 0x60B2 \ + 0x618A 0x6249 0x6279 0x6590 0x6787 0x69A7 0x6BD4 0x6BD6 \ + 0x6BD7 0x6BD8 0x6CB8 0xF968 0x7435 0x75FA 0x7812 0x7891 \ + 0x79D5 0x79D8 0x7C83 0x7DCB 0x7FE1 0x80A5 0x813E 0x81C2 \ + 0x83F2 0x871A 0x88E8 0x8AB9 0x8B6C 0x8CBB 0x9119 0x975E \ + 0x98DB 0x9F3B 0x56AC 0x5B2A 0x5F6C 0x658C 0x6AB3 0x6BAF \ + 0x6D5C 0x6FF1 0x7015 0x725D 0x73AD 0x8CA7 0x8CD3 0x983B \ + 0x6191 0x6C37 0x8058 0x9A01 0x4E4D 0x4E8B 0x4E9B 0x4ED5 \ + 0x4F3A 0x4F3C 0x4F7F 0x4FDF 0x50FF 0x53F2 0x53F8 0x5506 \ + 0x55E3 0x56DB 0x58EB 0x5962 0x5A11 0x5BEB 0x5BFA 0x5C04 \ + 0x5DF3 0x5E2B 0x5F99 0x601D 0x6368 0x659C 0x65AF 0x67F6 \ + 0x67FB 0x68AD 0x6B7B 0x6C99 0x6CD7 0x6E23 0x7009 0x7345 \ + 0x7802 0x793E 0x7940 0x7960 0x79C1 0x7BE9 0x7D17 0x7D72 \ + 0x8086 0x820D 0x838E 0x84D1 0x86C7 0x88DF 0x8A50 0x8A5E \ + 0x8B1D 0x8CDC 0x8D66 0x8FAD 0x90AA 0x98FC 0x99DF 0x9E9D \ + 0x524A 0xF969 0x6714 0xF96A 0x5098 0x522A 0x5C71 0x6563 \ + 0x6C55 0x73CA 0x7523 0x759D 0x7B97 0x849C 0x9178 0x9730 \ + 0x4E77 0x6492 0x6BBA 0x715E 0x85A9 0x4E09 0xF96B 0x6749 \ + 0x68EE 0x6E17 0x829F 0x8518 0x886B 0x63F7 0x6F81 0x9212 \ + 0x98AF 0x4E0A 0x50B7 0x50CF 0x511F 0x5546 0x55AA 0x5617 \ + 0x5B40 0x5C19 0x5CE0 0x5E38 0x5E8A 0x5EA0 0x5EC2 0x60F3 \ + 0x6851 0x6A61 0x6E58 0x723D 0x7240 0x72C0 0x76F8 0x7965 \ + 0x7BB1 0x7FD4 0x88F3 0x89F4 0x8A73 0x8C61 0x8CDE 0x971C +24 0x585E 0x74BD 0x8CFD 0x55C7 0xF96C 0x7A61 0x7D22 0x8272 \ + 0x7272 0x751F 0x7525 0xF96D 0x7B19 0x5885 0x58FB 0x5DBC \ + 0x5E8F 0x5EB6 0x5F90 0x6055 0x6292 0x637F 0x654D 0x6691 \ + 0x66D9 0x66F8 0x6816 0x68F2 0x7280 0x745E 0x7B6E 0x7D6E \ + 0x7DD6 0x7F72 0x80E5 0x8212 0x85AF 0x897F 0x8A93 0x901D \ + 0x92E4 0x9ECD 0x9F20 0x5915 0x596D 0x5E2D 0x60DC 0x6614 \ + 0x6673 0x6790 0x6C50 0x6DC5 0x6F5F 0x77F3 0x78A9 0x84C6 \ + 0x91CB 0x932B 0x4ED9 0x50CA 0x5148 0x5584 0x5B0B 0x5BA3 \ + 0x6247 0x657E 0x65CB 0x6E32 0x717D 0x7401 0x7444 0x7487 \ + 0x74BF 0x766C 0x79AA 0x7DDA 0x7E55 0x7FA8 0x817A 0x81B3 \ + 0x8239 0x861A 0x87EC 0x8A75 0x8DE3 0x9078 0x9291 0x9425 \ + 0x994D 0x9BAE 0x5368 0x5C51 0x6954 0x6CC4 0x6D29 0x6E2B \ + 0x820C 0x859B 0x893B 0x8A2D 0x8AAA 0x96EA 0x9F67 0x5261 \ + 0x66B9 0x6BB2 0x7E96 0x87FE 0x8D0D 0x9583 0x965D 0x651D \ + 0x6D89 0x71EE 0xF96E 0x57CE 0x59D3 0x5BAC 0x6027 0x60FA \ + 0x6210 0x661F 0x665F 0x7329 0x73F9 0x76DB 0x7701 0x7B6C \ + 0x8056 0x8072 0x8165 0x8AA0 0x9192 0x4E16 0x52E2 0x6B72 \ + 0x6D17 0x7A05 0x7B39 0x7D30 0xF96F 0x8CB0 0x53EC 0x562F \ + 0x5851 0x5BB5 0x5C0F 0x5C11 0x5DE2 0x6240 0x6383 0x6414 \ + 0x662D 0x68B3 0x6CBC 0x6D88 0x6EAF 0x701F 0x70A4 0x71D2 \ + 0x7526 0x758F 0x758E 0x7619 0x7B11 0x7BE0 0x7C2B 0x7D20 \ + 0x7D39 0x852C 0x856D 0x8607 0x8A34 0x900D 0x9061 0x90B5 \ + 0x92B7 0x97F6 0x9A37 0x4FD7 0x5C6C 0x675F 0x6D91 0x7C9F \ + 0x7E8C 0x8B16 0x8D16 0x901F 0x5B6B 0x5DFD 0x640D 0x84C0 \ + 0x905C 0x98E1 0x7387 0x5B8B 0x609A 0x677E 0x6DDE 0x8A1F \ + 0x8AA6 0x9001 0x980C 0x5237 0xF970 0x7051 0x788E 0x9396 \ + 0x8870 0x91D7 0x4FEE 0x53D7 0x55FD 0x56DA 0x5782 0x58FD \ + 0x5AC2 0x5B88 0x5CAB 0x5CC0 0x5E25 0x6101 0x620D 0x624B \ + 0x6388 0x641C 0x6536 0x6578 0x6A39 0x6B8A 0x6C34 0x6D19 \ + 0x6F31 0x71E7 0x72E9 0x7378 0x7407 0x74B2 0x7626 0x7761 \ + 0x79C0 0x7A57 0x7AEA 0x7CB9 0x7D8F 0x7DAC 0x7E61 0x7F9E \ + 0x8129 0x8331 0x8490 0x84DA 0x85EA 0x8896 0x8AB0 0x8B90 +25 0x8F38 0x9042 0x9083 0x916C 0x9296 0x92B9 0x968B 0x96A7 \ + 0x96A8 0x96D6 0x9700 0x9808 0x9996 0x9AD3 0x9B1A 0x53D4 \ + 0x587E 0x5919 0x5B70 0x5BBF 0x6DD1 0x6F5A 0x719F 0x7421 \ + 0x74B9 0x8085 0x83FD 0x5DE1 0x5F87 0x5FAA 0x6042 0x65EC \ + 0x6812 0x696F 0x6A53 0x6B89 0x6D35 0x6DF3 0x73E3 0x76FE \ + 0x77AC 0x7B4D 0x7D14 0x8123 0x821C 0x8340 0x84F4 0x8563 \ + 0x8A62 0x8AC4 0x9187 0x931E 0x9806 0x99B4 0x620C 0x8853 \ + 0x8FF0 0x9265 0x5D07 0x5D27 0x5D69 0x745F 0x819D 0x8768 \ + 0x6FD5 0x62FE 0x7FD2 0x8936 0x8972 0x4E1E 0x4E58 0x50E7 \ + 0x52DD 0x5347 0x627F 0x6607 0x7E69 0x8805 0x965E 0x4F8D \ + 0x5319 0x5636 0x59CB 0x5AA4 0x5C38 0x5C4E 0x5C4D 0x5E02 \ + 0x5F11 0x6043 0x65BD 0x662F 0x6642 0x67BE 0x67F4 0x731C \ + 0x77E2 0x793A 0x7FC5 0x8494 0x84CD 0x8996 0x8A66 0x8A69 \ + 0x8AE1 0x8C55 0x8C7A 0x57F4 0x5BD4 0x5F0F 0x606F 0x62ED \ + 0x690D 0x6B96 0x6E5C 0x7184 0x7BD2 0x8755 0x8B58 0x8EFE \ + 0x98DF 0x98FE 0x4F38 0x4F81 0x4FE1 0x547B 0x5A20 0x5BB8 \ + 0x613C 0x65B0 0x6668 0x71FC 0x7533 0x795E 0x7D33 0x814E \ + 0x81E3 0x8398 0x85AA 0x85CE 0x8703 0x8A0A 0x8EAB 0x8F9B \ + 0xF971 0x8FC5 0x5931 0x5BA4 0x5BE6 0x6089 0x5BE9 0x5C0B \ + 0x5FC3 0x6C81 0xF972 0x6DF1 0x700B 0x751A 0x82AF 0x8AF6 \ + 0x4EC0 0x5341 0xF973 0x96D9 0x6C0F 0x4E9E 0x4FC4 0x5152 \ + 0x555E 0x5A25 0x5CE8 0x6211 0x7259 0x82BD 0x83AA 0x86FE \ + 0x8859 0x8A1D 0x963F 0x96C5 0x9913 0x9D09 0x9D5D 0x580A \ + 0x5CB3 0x5DBD 0x5E44 0x60E1 0x6115 0x63E1 0x6A02 0x6E25 \ + 0x9102 0x9354 0x984E 0x9C10 0x9F77 0x5B89 0x5CB8 0x6309 \ + 0x664F 0x6848 0x773C 0x96C1 0x978D 0x9854 0x9B9F 0x65A1 \ + 0x8B01 0x8ECB 0x95BC 0x5535 0x5CA9 0x5DD6 0x5EB5 0x6697 \ + 0x764C 0x83F4 0x95C7 0x58D3 0x62BC 0x72CE 0x9D28 0x4EF0 \ + 0x592E 0x600F 0x663B 0x6B83 0x79E7 0x9D26 0x5393 0x54C0 \ + 0x57C3 0x5D16 0x611B 0x66D6 0x6DAF 0x788D 0x827E 0x9698 \ + 0x9744 0x5384 0x627C 0x6396 0x6DB2 0x7E0A 0x814B 0x984D \ + 0x6AFB 0x7F4C 0x9DAF 0x9E1A 0x4E5F 0x503B 0x51B6 0x591C +26 0x60F9 0x63F6 0x6930 0x723A 0x8036 0xF974 0x91CE 0x5F31 \ + 0xF975 0xF976 0x7D04 0x82E5 0x846F 0x84BB 0x85E5 0x8E8D \ + 0xF977 0x4F6F 0xF978 0xF979 0x58E4 0x5B43 0x6059 0x63DA \ + 0x6518 0x656D 0x6698 0xF97A 0x694A 0x6A23 0x6D0B 0x7001 \ + 0x716C 0x75D2 0x760D 0x79B3 0x7A70 0xF97B 0x7F8A 0xF97C \ + 0x8944 0xF97D 0x8B93 0x91C0 0x967D 0xF97E 0x990A 0x5704 \ + 0x5FA1 0x65BC 0x6F01 0x7600 0x79A6 0x8A9E 0x99AD 0x9B5A \ + 0x9F6C 0x5104 0x61B6 0x6291 0x6A8D 0x81C6 0x5043 0x5830 \ + 0x5F66 0x7109 0x8A00 0x8AFA 0x5B7C 0x8616 0x4FFA 0x513C \ + 0x56B4 0x5944 0x63A9 0x6DF9 0x5DAA 0x696D 0x5186 0x4E88 \ + 0x4F59 0xF97F 0xF980 0xF981 0x5982 0xF982 0xF983 0x6B5F \ + 0x6C5D 0xF984 0x74B5 0x7916 0xF985 0x8207 0x8245 0x8339 \ + 0x8F3F 0x8F5D 0xF986 0x9918 0xF987 0xF988 0xF989 0x4EA6 \ + 0xF98A 0x57DF 0x5F79 0x6613 0xF98B 0xF98C 0x75AB 0x7E79 \ + 0x8B6F 0xF98D 0x9006 0x9A5B 0x56A5 0x5827 0x59F8 0x5A1F \ + 0x5BB4 0xF98E 0x5EF6 0xF98F 0xF990 0x6350 0x633B 0xF991 \ + 0x693D 0x6C87 0x6CBF 0x6D8E 0x6D93 0x6DF5 0x6F14 0xF992 \ + 0x70DF 0x7136 0x7159 0xF993 0x71C3 0x71D5 0xF994 0x784F \ + 0x786F 0xF995 0x7B75 0x7DE3 0xF996 0x7E2F 0xF997 0x884D \ + 0x8EDF 0xF998 0xF999 0xF99A 0x925B 0xF99B 0x9CF6 0xF99C \ + 0xF99D 0xF99E 0x6085 0x6D85 0xF99F 0x71B1 0xF9A0 0xF9A1 \ + 0x95B1 0x53AD 0xF9A2 0xF9A3 0xF9A4 0x67D3 0xF9A5 0x708E \ + 0x7130 0x7430 0x8276 0x82D2 0xF9A6 0x95BB 0x9AE5 0x9E7D \ + 0x66C4 0xF9A7 0x71C1 0x8449 0xF9A8 0xF9A9 0x584B 0xF9AA \ + 0xF9AB 0x5DB8 0x5F71 0xF9AC 0x6620 0x668E 0x6979 0x69AE \ + 0x6C38 0x6CF3 0x6E36 0x6F41 0x6FDA 0x701B 0x702F 0x7150 \ + 0x71DF 0x7370 0xF9AD 0x745B 0xF9AE 0x74D4 0x76C8 0x7A4E \ + 0x7E93 0xF9AF 0xF9B0 0x82F1 0x8A60 0x8FCE 0xF9B1 0x9348 \ + 0xF9B2 0x9719 0xF9B3 0xF9B4 0x4E42 0x502A 0xF9B5 0x5208 \ + 0x53E1 0x66F3 0x6C6D 0x6FCA 0x730A 0x777F 0x7A62 0x82AE \ + 0x85DD 0x8602 0xF9B6 0x88D4 0x8A63 0x8B7D 0x8C6B 0xF9B7 \ + 0x92B3 0xF9B8 0x9713 0x9810 0x4E94 0x4F0D 0x4FC9 0x50B2 +27 0x5348 0x543E 0x5433 0x55DA 0x5862 0x58BA 0x5967 0x5A1B \ + 0x5BE4 0x609F 0xF9B9 0x61CA 0x6556 0x65FF 0x6664 0x68A7 \ + 0x6C5A 0x6FB3 0x70CF 0x71AC 0x7352 0x7B7D 0x8708 0x8AA4 \ + 0x9C32 0x9F07 0x5C4B 0x6C83 0x7344 0x7389 0x923A 0x6EAB \ + 0x7465 0x761F 0x7A69 0x7E15 0x860A 0x5140 0x58C5 0x64C1 \ + 0x74EE 0x7515 0x7670 0x7FC1 0x9095 0x96CD 0x9954 0x6E26 \ + 0x74E6 0x7AA9 0x7AAA 0x81E5 0x86D9 0x8778 0x8A1B 0x5A49 \ + 0x5B8C 0x5B9B 0x68A1 0x6900 0x6D63 0x73A9 0x7413 0x742C \ + 0x7897 0x7DE9 0x7FEB 0x8118 0x8155 0x839E 0x8C4C 0x962E \ + 0x9811 0x66F0 0x5F80 0x65FA 0x6789 0x6C6A 0x738B 0x502D \ + 0x5A03 0x6B6A 0x77EE 0x5916 0x5D6C 0x5DCD 0x7325 0x754F \ + 0xF9BA 0xF9BB 0x50E5 0x51F9 0x582F 0x592D 0x5996 0x59DA \ + 0x5BE5 0xF9BC 0xF9BD 0x5DA2 0x62D7 0x6416 0x6493 0x64FE \ + 0xF9BE 0x66DC 0xF9BF 0x6A48 0xF9C0 0x71FF 0x7464 0xF9C1 \ + 0x7A88 0x7AAF 0x7E47 0x7E5E 0x8000 0x8170 0xF9C2 0x87EF \ + 0x8981 0x8B20 0x9059 0xF9C3 0x9080 0x9952 0x617E 0x6B32 \ + 0x6D74 0x7E1F 0x8925 0x8FB1 0x4FD1 0x50AD 0x5197 0x52C7 \ + 0x57C7 0x5889 0x5BB9 0x5EB8 0x6142 0x6995 0x6D8C 0x6E67 \ + 0x6EB6 0x7194 0x7462 0x7528 0x752C 0x8073 0x8338 0x84C9 \ + 0x8E0A 0x9394 0x93DE 0xF9C4 0x4E8E 0x4F51 0x5076 0x512A \ + 0x53C8 0x53CB 0x53F3 0x5B87 0x5BD3 0x5C24 0x611A 0x6182 \ + 0x65F4 0x725B 0x7397 0x7440 0x76C2 0x7950 0x7991 0x79B9 \ + 0x7D06 0x7FBD 0x828B 0x85D5 0x865E 0x8FC2 0x9047 0x90F5 \ + 0x91EA 0x9685 0x96E8 0x96E9 0x52D6 0x5F67 0x65ED 0x6631 \ + 0x682F 0x715C 0x7A36 0x90C1 0x980A 0x4E91 0xF9C5 0x6A52 \ + 0x6B9E 0x6F90 0x7189 0x8018 0x82B8 0x8553 0x904B 0x9695 \ + 0x96F2 0x97FB 0x851A 0x9B31 0x4E90 0x718A 0x96C4 0x5143 \ + 0x539F 0x54E1 0x5713 0x5712 0x57A3 0x5A9B 0x5AC4 0x5BC3 \ + 0x6028 0x613F 0x63F4 0x6C85 0x6D39 0x6E72 0x6E90 0x7230 \ + 0x733F 0x7457 0x82D1 0x8881 0x8F45 0x9060 0xF9C6 0x9662 \ + 0x9858 0x9D1B 0x6708 0x8D8A 0x925E 0x4F4D 0x5049 0x50DE \ + 0x5371 0x570D 0x59D4 0x5A01 0x5C09 0x6170 0x6690 0x6E2D +28 0x7232 0x744B 0x7DEF 0x80C3 0x840E 0x8466 0x853F 0x875F \ + 0x885B 0x8918 0x8B02 0x9055 0x97CB 0x9B4F 0x4E73 0x4F91 \ + 0x5112 0x516A 0xF9C7 0x552F 0x55A9 0x5B7A 0x5BA5 0x5E7C \ + 0x5E7D 0x5EBE 0x60A0 0x60DF 0x6108 0x6109 0x63C4 0x6538 \ + 0x6709 0xF9C8 0x67D4 0x67DA 0xF9C9 0x6961 0x6962 0x6CB9 \ + 0x6D27 0xF9CA 0x6E38 0xF9CB 0x6FE1 0x7336 0x7337 0xF9CC \ + 0x745C 0x7531 0xF9CD 0x7652 0xF9CE 0xF9CF 0x7DAD 0x81FE \ + 0x8438 0x88D5 0x8A98 0x8ADB 0x8AED 0x8E30 0x8E42 0x904A \ + 0x903E 0x907A 0x9149 0x91C9 0x936E 0xF9D0 0xF9D1 0x5809 \ + 0xF9D2 0x6BD3 0x8089 0x80B2 0xF9D3 0xF9D4 0x5141 0x596B \ + 0x5C39 0xF9D5 0xF9D6 0x6F64 0x73A7 0x80E4 0x8D07 0xF9D7 \ + 0x9217 0x958F 0xF9D8 0xF9D9 0xF9DA 0xF9DB 0x807F 0x620E \ + 0x701C 0x7D68 0x878D 0xF9DC 0x57A0 0x6069 0x6147 0x6BB7 \ + 0x8ABE 0x9280 0x96B1 0x4E59 0x541F 0x6DEB 0x852D 0x9670 \ + 0x97F3 0x98EE 0x63D6 0x6CE3 0x9091 0x51DD 0x61C9 0x81BA \ + 0x9DF9 0x4F9D 0x501A 0x5100 0x5B9C 0x610F 0x61FF 0x64EC \ + 0x6905 0x6BC5 0x7591 0x77E3 0x7FA9 0x8264 0x858F 0x87FB \ + 0x8863 0x8ABC 0x8B70 0x91AB 0x4E8C 0x4EE5 0x4F0A 0xF9DD \ + 0xF9DE 0x5937 0x59E8 0xF9DF 0x5DF2 0x5F1B 0x5F5B 0x6021 \ + 0xF9E0 0xF9E1 0xF9E2 0xF9E3 0x723E 0x73E5 0xF9E4 0x7570 \ + 0x75CD 0xF9E5 0x79FB 0xF9E6 0x800C 0x8033 0x8084 0x82E1 \ + 0x8351 0xF9E7 0xF9E8 0x8CBD 0x8CB3 0x9087 0xF9E9 0xF9EA \ + 0x98F4 0x990C 0xF9EB 0xF9EC 0x7037 0x76CA 0x7FCA 0x7FCC \ + 0x7FFC 0x8B1A 0x4EBA 0x4EC1 0x5203 0x5370 0xF9ED 0x54BD \ + 0x56E0 0x59FB 0x5BC5 0x5F15 0x5FCD 0x6E6E 0xF9EE 0xF9EF \ + 0x7D6A 0x8335 0xF9F0 0x8693 0x8A8D 0xF9F1 0x976D 0x9777 \ + 0xF9F2 0xF9F3 0x4E00 0x4F5A 0x4F7E 0x58F9 0x65E5 0x6EA2 \ + 0x9038 0x93B0 0x99B9 0x4EFB 0x58EC 0x598A 0x59D9 0x6041 \ + 0xF9F4 0xF9F5 0x7A14 0xF9F6 0x834F 0x8CC3 0x5165 0x5344 \ + 0xF9F7 0xF9F8 0xF9F9 0x4ECD 0x5269 0x5B55 0x82BF 0x4ED4 \ + 0x523A 0x54A8 0x59C9 0x59FF 0x5B50 0x5B57 0x5B5C 0x6063 \ + 0x6148 0x6ECB 0x7099 0x716E 0x7386 0x74F7 0x75B5 0x78C1 +29 0x7D2B 0x8005 0x81EA 0x8328 0x8517 0x85C9 0x8AEE 0x8CC7 \ + 0x96CC 0x4F5C 0x52FA 0x56BC 0x65AB 0x6628 0x707C 0x70B8 \ + 0x7235 0x7DBD 0x828D 0x914C 0x96C0 0x9D72 0x5B71 0x68E7 \ + 0x6B98 0x6F7A 0x76DE 0x5C91 0x66AB 0x6F5B 0x7BB4 0x7C2A \ + 0x8836 0x96DC 0x4E08 0x4ED7 0x5320 0x5834 0x58BB 0x58EF \ + 0x596C 0x5C07 0x5E33 0x5E84 0x5F35 0x638C 0x66B2 0x6756 \ + 0x6A1F 0x6AA3 0x6B0C 0x6F3F 0x7246 0xF9FA 0x7350 0x748B \ + 0x7AE0 0x7CA7 0x8178 0x81DF 0x81E7 0x838A 0x846C 0x8523 \ + 0x8594 0x85CF 0x88DD 0x8D13 0x91AC 0x9577 0x969C 0x518D \ + 0x54C9 0x5728 0x5BB0 0x624D 0x6750 0x683D 0x6893 0x6E3D \ + 0x6ED3 0x707D 0x7E21 0x88C1 0x8CA1 0x8F09 0x9F4B 0x9F4E \ + 0x722D 0x7B8F 0x8ACD 0x931A 0x4F47 0x4F4E 0x5132 0x5480 \ + 0x59D0 0x5E95 0x62B5 0x6775 0x696E 0x6A17 0x6CAE 0x6E1A \ + 0x72D9 0x732A 0x75BD 0x7BB8 0x7D35 0x82E7 0x83F9 0x8457 \ + 0x85F7 0x8A5B 0x8CAF 0x8E87 0x9019 0x90B8 0x96CE 0x9F5F \ + 0x52E3 0x540A 0x5AE1 0x5BC2 0x6458 0x6575 0x6EF4 0x72C4 \ + 0xF9FB 0x7684 0x7A4D 0x7B1B 0x7C4D 0x7E3E 0x7FDF 0x837B \ + 0x8B2B 0x8CCA 0x8D64 0x8DE1 0x8E5F 0x8FEA 0x8FF9 0x9069 \ + 0x93D1 0x4F43 0x4F7A 0x50B3 0x5168 0x5178 0x524D 0x526A \ + 0x5861 0x587C 0x5960 0x5C08 0x5C55 0x5EDB 0x609B 0x6230 \ + 0x6813 0x6BBF 0x6C08 0x6FB1 0x714E 0x7420 0x7530 0x7538 \ + 0x7551 0x7672 0x7B4C 0x7B8B 0x7BAD 0x7BC6 0x7E8F 0x8A6E \ + 0x8F3E 0x8F49 0x923F 0x9293 0x9322 0x942B 0x96FB 0x985A \ + 0x986B 0x991E 0x5207 0x622A 0x6298 0x6D59 0x7664 0x7ACA \ + 0x7BC0 0x7D76 0x5360 0x5CBE 0x5E97 0x6F38 0x70B9 0x7C98 \ + 0x9711 0x9B8E 0x9EDE 0x63A5 0x647A 0x8776 0x4E01 0x4E95 \ + 0x4EAD 0x505C 0x5075 0x5448 0x59C3 0x5B9A 0x5E40 0x5EAD \ + 0x5EF7 0x5F81 0x60C5 0x633A 0x653F 0x6574 0x65CC 0x6676 \ + 0x6678 0x67FE 0x6968 0x6A89 0x6B63 0x6C40 0x6DC0 0x6DE8 \ + 0x6E1F 0x6E5E 0x701E 0x70A1 0x738E 0x73FD 0x753A 0x775B \ + 0x7887 0x798E 0x7A0B 0x7A7D 0x7CBE 0x7D8E 0x8247 0x8A02 \ + 0x8AEA 0x8C9E 0x912D 0x914A 0x91D8 0x9266 0x92CC 0x9320 +30 0x9706 0x9756 0x975C 0x9802 0x9F0E 0x5236 0x5291 0x557C \ + 0x5824 0x5E1D 0x5F1F 0x608C 0x63D0 0x68AF 0x6FDF 0x796D \ + 0x7B2C 0x81CD 0x85BA 0x88FD 0x8AF8 0x8E44 0x918D 0x9664 \ + 0x969B 0x973D 0x984C 0x9F4A 0x4FCE 0x5146 0x51CB 0x52A9 \ + 0x5632 0x5F14 0x5F6B 0x63AA 0x64CD 0x65E9 0x6641 0x66FA \ + 0x66F9 0x671D 0x689D 0x68D7 0x69FD 0x6F15 0x6F6E 0x7167 \ + 0x71E5 0x722A 0x74AA 0x773A 0x7956 0x795A 0x79DF 0x7A20 \ + 0x7A95 0x7C97 0x7CDF 0x7D44 0x7E70 0x8087 0x85FB 0x86A4 \ + 0x8A54 0x8ABF 0x8D99 0x8E81 0x9020 0x906D 0x91E3 0x963B \ + 0x96D5 0x9CE5 0x65CF 0x7C07 0x8DB3 0x93C3 0x5B58 0x5C0A \ + 0x5352 0x62D9 0x731D 0x5027 0x5B97 0x5F9E 0x60B0 0x616B \ + 0x68D5 0x6DD9 0x742E 0x7A2E 0x7D42 0x7D9C 0x7E31 0x816B \ + 0x8E2A 0x8E35 0x937E 0x9418 0x4F50 0x5750 0x5DE6 0x5EA7 \ + 0x632B 0x7F6A 0x4E3B 0x4F4F 0x4F8F 0x505A 0x59DD 0x80C4 \ + 0x546A 0x5468 0x55FE 0x594F 0x5B99 0x5DDE 0x5EDA 0x665D \ + 0x6731 0x67F1 0x682A 0x6CE8 0x6D32 0x6E4A 0x6F8D 0x70B7 \ + 0x73E0 0x7587 0x7C4C 0x7D02 0x7D2C 0x7DA2 0x821F 0x86DB \ + 0x8A3B 0x8A85 0x8D70 0x8E8A 0x8F33 0x9031 0x914E 0x9152 \ + 0x9444 0x99D0 0x7AF9 0x7CA5 0x4FCA 0x5101 0x51C6 0x57C8 \ + 0x5BEF 0x5CFB 0x6659 0x6A3D 0x6D5A 0x6E96 0x6FEC 0x710C \ + 0x756F 0x7AE3 0x8822 0x9021 0x9075 0x96CB 0x99FF 0x8301 \ + 0x4E2D 0x4EF2 0x8846 0x91CD 0x537D 0x6ADB 0x696B 0x6C41 \ + 0x847A 0x589E 0x618E 0x66FE 0x62EF 0x70DD 0x7511 0x75C7 \ + 0x7E52 0x84B8 0x8B49 0x8D08 0x4E4B 0x53EA 0x54AB 0x5730 \ + 0x5740 0x5FD7 0x6301 0x6307 0x646F 0x652F 0x65E8 0x667A \ + 0x679D 0x67B3 0x6B62 0x6C60 0x6C9A 0x6F2C 0x77E5 0x7825 \ + 0x7949 0x7957 0x7D19 0x80A2 0x8102 0x81F3 0x829D 0x82B7 \ + 0x8718 0x8A8C 0xF9FC 0x8D04 0x8DBE 0x9072 0x76F4 0x7A19 \ + 0x7A37 0x7E54 0x8077 0x5507 0x55D4 0x5875 0x632F 0x6422 \ + 0x6649 0x664B 0x686D 0x699B 0x6B84 0x6D25 0x6EB1 0x73CD \ + 0x7468 0x74A1 0x755B 0x75B9 0x76E1 0x771E 0x778B 0x79E6 \ + 0x7E09 0x7E1D 0x81FB 0x852F 0x8897 0x8A3A 0x8CD1 0x8EEB +31 0x8FB0 0x9032 0x93AD 0x9663 0x9673 0x9707 0x4F84 0x53F1 \ + 0x59EA 0x5AC9 0x5E19 0x684E 0x74C6 0x75BE 0x79E9 0x7A92 \ + 0x81A3 0x86ED 0x8CEA 0x8DCC 0x8FED 0x659F 0x6715 0xF9FD \ + 0x57F7 0x6F57 0x7DDD 0x8F2F 0x93F6 0x96C6 0x5FB5 0x61F2 \ + 0x6F84 0x4E14 0x4F98 0x501F 0x53C9 0x55DF 0x5D6F 0x5DEE \ + 0x6B21 0x6B64 0x78CB 0x7B9A 0xF9FE 0x8E49 0x8ECA 0x906E \ + 0x6349 0x643E 0x7740 0x7A84 0x932F 0x947F 0x9F6A 0x64B0 \ + 0x6FAF 0x71E6 0x74A8 0x74DA 0x7AC4 0x7C12 0x7E82 0x7CB2 \ + 0x7E98 0x8B9A 0x8D0A 0x947D 0x9910 0x994C 0x5239 0x5BDF \ + 0x64E6 0x672D 0x7D2E 0x50ED 0x53C3 0x5879 0x6158 0x6159 \ + 0x61FA 0x65AC 0x7AD9 0x8B92 0x8B96 0x5009 0x5021 0x5275 \ + 0x5531 0x5A3C 0x5EE0 0x5F70 0x6134 0x655E 0x660C 0x6636 \ + 0x66A2 0x69CD 0x6EC4 0x6F32 0x7316 0x7621 0x7A93 0x8139 \ + 0x8259 0x83D6 0x84BC 0x50B5 0x57F0 0x5BC0 0x5BE8 0x5F69 \ + 0x63A1 0x7826 0x7DB5 0x83DC 0x8521 0x91C7 0x91F5 0x518A \ + 0x67F5 0x7B56 0x8CAC 0x51C4 0x59BB 0x60BD 0x8655 0x501C \ + 0xF9FF 0x5254 0x5C3A 0x617D 0x621A 0x62D3 0x64F2 0x65A5 \ + 0x6ECC 0x7620 0x810A 0x8E60 0x965F 0x96BB 0x4EDF 0x5343 \ + 0x5598 0x5929 0x5DDD 0x64C5 0x6CC9 0x6DFA 0x7394 0x7A7F \ + 0x821B 0x85A6 0x8CE4 0x8E10 0x9077 0x91E7 0x95E1 0x9621 \ + 0x97C6 0x51F8 0x54F2 0x5586 0x5FB9 0x64A4 0x6F88 0x7DB4 \ + 0x8F1F 0x8F4D 0x9435 0x50C9 0x5C16 0x6CBE 0x6DFB 0x751B \ + 0x77BB 0x7C3D 0x7C64 0x8A79 0x8AC2 0x581E 0x59BE 0x5E16 \ + 0x6377 0x7252 0x758A 0x776B 0x8ADC 0x8CBC 0x8F12 0x5EF3 \ + 0x6674 0x6DF8 0x807D 0x83C1 0x8ACB 0x9751 0x9BD6 0xFA00 \ + 0x5243 0x66FF 0x6D95 0x6EEF 0x7DE0 0x8AE6 0x902E 0x905E \ + 0x9AD4 0x521D 0x527F 0x54E8 0x6194 0x6284 0x62DB 0x68A2 \ + 0x6912 0x695A 0x6A35 0x7092 0x7126 0x785D 0x7901 0x790E \ + 0x79D2 0x7A0D 0x8096 0x8278 0x82D5 0x8349 0x8549 0x8C82 \ + 0x8D85 0x9162 0x918B 0x91AE 0x4FC3 0x56D1 0x71ED 0x77D7 \ + 0x8700 0x89F8 0x5BF8 0x5FD6 0x6751 0x90A8 0x53E2 0x585A \ + 0x5BF5 0x60A4 0x6181 0x6460 0x7E3D 0x8070 0x8525 0x9283 +32 0x64AE 0x50AC 0x5D14 0x6700 0x589C 0x62BD 0x63A8 0x690E \ + 0x6978 0x6A1E 0x6E6B 0x76BA 0x79CB 0x82BB 0x8429 0x8ACF \ + 0x8DA8 0x8FFD 0x9112 0x914B 0x919C 0x9310 0x9318 0x939A \ + 0x96DB 0x9A36 0x9C0D 0x4E11 0x755C 0x795D 0x7AFA 0x7B51 \ + 0x7BC9 0x7E2E 0x84C4 0x8E59 0x8E74 0x8EF8 0x9010 0x6625 \ + 0x693F 0x7443 0x51FA 0x672E 0x9EDC 0x5145 0x5FE0 0x6C96 \ + 0x87F2 0x885D 0x8877 0x60B4 0x81B5 0x8403 0x8D05 0x53D6 \ + 0x5439 0x5634 0x5A36 0x5C31 0x708A 0x7FE0 0x805A 0x8106 \ + 0x81ED 0x8DA3 0x9189 0x9A5F 0x9DF2 0x5074 0x4EC4 0x53A0 \ + 0x60FB 0x6E2C 0x5C64 0x4F88 0x5024 0x55E4 0x5CD9 0x5E5F \ + 0x6065 0x6894 0x6CBB 0x6DC4 0x71BE 0x75D4 0x75F4 0x7661 \ + 0x7A1A 0x7A49 0x7DC7 0x7DFB 0x7F6E 0x81F4 0x86A9 0x8F1C \ + 0x96C9 0x99B3 0x9F52 0x5247 0x52C5 0x98ED 0x89AA 0x4E03 \ + 0x67D2 0x6F06 0x4FB5 0x5BE2 0x6795 0x6C88 0x6D78 0x741B \ + 0x7827 0x91DD 0x937C 0x87C4 0x79E4 0x7A31 0x5FEB 0x4ED6 \ + 0x54A4 0x553E 0x58AE 0x59A5 0x60F0 0x6253 0x62D6 0x6736 \ + 0x6955 0x8235 0x9640 0x99B1 0x99DD 0x502C 0x5353 0x5544 \ + 0x577C 0xFA01 0x6258 0xFA02 0x64E2 0x666B 0x67DD 0x6FC1 \ + 0x6FEF 0x7422 0x7438 0x8A17 0x9438 0x5451 0x5606 0x5766 \ + 0x5F48 0x619A 0x6B4E 0x7058 0x70AD 0x7DBB 0x8A95 0x596A \ + 0x812B 0x63A2 0x7708 0x803D 0x8CAA 0x5854 0x642D 0x69BB \ + 0x5B95 0x5E11 0x6E6F 0xFA03 0x8569 0x514C 0x53F0 0x592A \ + 0x6020 0x614B 0x6B86 0x6C70 0x6CF0 0x7B1E 0x80CE 0x82D4 \ + 0x8DC6 0x90B0 0x98B1 0xFA04 0x64C7 0x6FA4 0x6491 0x6504 \ + 0x514E 0x5410 0x571F 0x8A0E 0x615F 0x6876 0xFA05 0x75DB \ + 0x7B52 0x7D71 0x901A 0x5806 0x69CC 0x817F 0x892A 0x9000 \ + 0x9839 0x5078 0x5957 0x59AC 0x6295 0x900F 0x9B2A 0x615D \ + 0x7279 0x95D6 0x5761 0x5A46 0x5DF4 0x628A 0x64AD 0x64FA \ + 0x6777 0x6CE2 0x6D3E 0x722C 0x7436 0x7834 0x7F77 0x82AD \ + 0x8DDB 0x9817 0x5224 0x5742 0x677F 0x7248 0x74E3 0x8CA9 \ + 0x8FA6 0x9211 0x962A 0x516B 0x53ED 0x634C 0x4F69 0x5504 \ + 0x6096 0x6557 0x6C9B 0x6D7F 0x724C 0x72FD 0x7A17 0x8987 +33 0x8C9D 0x5F6D 0x6F8E 0x70F9 0x81A8 0x610E 0x4FBF 0x504F \ + 0x6241 0x7247 0x7BC7 0x7DE8 0x7FE9 0x904D 0x97AD 0x9A19 \ + 0x8CB6 0x576A 0x5E73 0x67B0 0x840D 0x8A55 0x5420 0x5B16 \ + 0x5E63 0x5EE2 0x5F0A 0x6583 0x80BA 0x853D 0x9589 0x965B \ + 0x4F48 0x5305 0x530D 0x530F 0x5486 0x54FA 0x5703 0x5E03 \ + 0x6016 0x629B 0x62B1 0x6355 0xFA06 0x6CE1 0x6D66 0x75B1 \ + 0x7832 0x80DE 0x812F 0x82DE 0x8461 0x84B2 0x888D 0x8912 \ + 0x900B 0x92EA 0x98FD 0x9B91 0x5E45 0x66B4 0x66DD 0x7011 \ + 0x7206 0xFA07 0x4FF5 0x527D 0x5F6A 0x6153 0x6753 0x6A19 \ + 0x6F02 0x74E2 0x7968 0x8868 0x8C79 0x98C7 0x98C4 0x9A43 \ + 0x54C1 0x7A1F 0x6953 0x8AF7 0x8C4A 0x98A8 0x99AE 0x5F7C \ + 0x62AB 0x75B2 0x76AE 0x88AB 0x907F 0x9642 0x5339 0x5F3C \ + 0x5FC5 0x6CCC 0x73CC 0x7562 0x758B 0x7B46 0x82FE 0x999D \ + 0x4E4F 0x903C 0x4E0B 0x4F55 0x53A6 0x590F 0x5EC8 0x6630 \ + 0x6CB3 0x7455 0x8377 0x8766 0x8CC0 0x9050 0x971E 0x9C15 \ + 0x58D1 0x5B78 0x8650 0x8B14 0x9DB4 0x5BD2 0x6068 0x608D \ + 0x65F1 0x6C57 0x6F22 0x6FA3 0x701A 0x7F55 0x7FF0 0x9591 \ + 0x9592 0x9650 0x97D3 0x5272 0x8F44 0x51FD 0x542B 0x54B8 \ + 0x5563 0x558A 0x6ABB 0x6DB5 0x7DD8 0x8266 0x929C 0x9677 \ + 0x9E79 0x5408 0x54C8 0x76D2 0x86E4 0x95A4 0x95D4 0x965C \ + 0x4EA2 0x4F09 0x59EE 0x5AE6 0x5DF7 0x6052 0x6297 0x676D \ + 0x6841 0x6C86 0x6E2F 0x7F38 0x809B 0x822A 0xFA08 0xFA09 \ + 0x9805 0x4EA5 0x5055 0x54B3 0x5793 0x595A 0x5B69 0x5BB3 \ + 0x61C8 0x6977 0x6D77 0x7023 0x87F9 0x89E3 0x8A72 0x8AE7 \ + 0x9082 0x99ED 0x9AB8 0x52BE 0x6838 0x5016 0x5E78 0x674F \ + 0x8347 0x884C 0x4EAB 0x5411 0x56AE 0x73E6 0x9115 0x97FF \ + 0x9909 0x9957 0x9999 0x5653 0x589F 0x865B 0x8A31 0x61B2 \ + 0x6AF6 0x737B 0x8ED2 0x6B47 0x96AA 0x9A57 0x5955 0x7200 \ + 0x8D6B 0x9769 0x4FD4 0x5CF4 0x5F26 0x61F8 0x665B 0x6CEB \ + 0x70AB 0x7384 0x73B9 0x73FE 0x7729 0x774D 0x7D43 0x7D62 \ + 0x7E23 0x8237 0x8852 0xFA0A 0x8CE2 0x9249 0x986F 0x5B51 \ + 0x7A74 0x8840 0x9801 0x5ACC 0x4FE0 0x5354 0x593E 0x5CFD +34 0x633E 0x6D79 0x72F9 0x8105 0x8107 0x83A2 0x92CF 0x9830 \ + 0x4EA8 0x5144 0x5211 0x578B 0x5F62 0x6CC2 0x6ECE 0x7005 \ + 0x7050 0x70AF 0x7192 0x73E9 0x7469 0x834A 0x87A2 0x8861 \ + 0x9008 0x90A2 0x93A3 0x99A8 0x516E 0x5F57 0x60E0 0x6167 \ + 0x66B3 0x8559 0x8E4A 0x91AF 0x978B 0x4E4E 0x4E92 0x547C \ + 0x58D5 0x58FA 0x597D 0x5CB5 0x5F27 0x6236 0x6248 0x660A \ + 0x6667 0x6BEB 0x6D69 0x6DCF 0x6E56 0x6EF8 0x6F94 0x6FE0 \ + 0x6FE9 0x705D 0x72D0 0x7425 0x745A 0x74E0 0x7693 0x795C \ + 0x7CCA 0x7E1E 0x80E1 0x82A6 0x846B 0x84BF 0x864E 0x865F \ + 0x8774 0x8B77 0x8C6A 0x93AC 0x9800 0x9865 0x60D1 0x6216 \ + 0x9177 0x5A5A 0x660F 0x6DF7 0x6E3E 0x743F 0x9B42 0x5FFD \ + 0x60DA 0x7B0F 0x54C4 0x5F18 0x6C5E 0x6CD3 0x6D2A 0x70D8 \ + 0x7D05 0x8679 0x8A0C 0x9D3B 0x5316 0x548C 0x5B05 0x6A3A \ + 0x706B 0x7575 0x798D 0x79BE 0x82B1 0x83EF 0x8A71 0x8B41 \ + 0x8CA8 0x9774 0xFA0B 0x64F4 0x652B 0x78BA 0x78BB 0x7A6B \ + 0x4E38 0x559A 0x5950 0x5BA6 0x5E7B 0x60A3 0x63DB 0x6B61 \ + 0x6665 0x6853 0x6E19 0x7165 0x74B0 0x7D08 0x9084 0x9A69 \ + 0x9C25 0x6D3B 0x6ED1 0x733E 0x8C41 0x95CA 0x51F0 0x5E4C \ + 0x5FA8 0x604D 0x60F6 0x6130 0x614C 0x6643 0x6644 0x69A5 \ + 0x6CC1 0x6E5F 0x6EC9 0x6F62 0x714C 0x749C 0x7687 0x7BC1 \ + 0x7C27 0x8352 0x8757 0x9051 0x968D 0x9EC3 0x532F 0x56DE \ + 0x5EFB 0x5F8A 0x6062 0x6094 0x61F7 0x6666 0x6703 0x6A9C \ + 0x6DEE 0x6FAE 0x7070 0x736A 0x7E6A 0x81BE 0x8334 0x86D4 \ + 0x8AA8 0x8CC4 0x5283 0x7372 0x5B96 0x6A6B 0x9404 0x54EE \ + 0x5686 0x5B5D 0x6548 0x6585 0x66C9 0x689F 0x6D8D 0x6DC6 \ + 0x723B 0x80B4 0x9175 0x9A4D 0x4FAF 0x5019 0x539A 0x540E \ + 0x543C 0x5589 0x55C5 0x5E3F 0x5F8C 0x673D 0x7166 0x73DD \ + 0x9005 0x52DB 0x52F3 0x5864 0x58CE 0x7104 0x718F 0x71FB \ + 0x85B0 0x8A13 0x6688 0x85A8 0x55A7 0x6684 0x714A 0x8431 \ + 0x5349 0x5599 0x6BC1 0x5F59 0x5FBD 0x63EE 0x6689 0x7147 \ + 0x8AF1 0x8F1D 0x9EBE 0x4F11 0x643A 0x70CB 0x7566 0x8667 \ + 0x6064 0x8B4E 0x9DF8 0x5147 0x51F6 0x5308 0x6D36 0x80F8 +35 0x9ED1 0x6615 0x6B23 0x7098 0x75D5 0x5403 0x5C79 0x7D07 \ + 0x8A16 0x6B20 0x6B3D 0x6B46 0x5438 0x6070 0x6D3D 0x7FD5 \ + 0x8208 0x50D6 0x51DE 0x559C 0x566B 0x56CD 0x59EC 0x5B09 \ + 0x5E0C 0x6199 0x6198 0x6231 0x665E 0x66E6 0x7199 0x71B9 \ + 0x71BA 0x72A7 0x79A7 0x7A00 0x7FB2 0x8A70 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE 0xFFFE \ + 0xFFFE 0xFFFE 0xFFFE 0xFFFE + +# eof diff --git a/contrib/ttf2pk/data/Unicode.sfd b/contrib/ttf2pk/data/Unicode.sfd new file mode 100644 index 0000000..fc23b6b --- /dev/null +++ b/contrib/ttf2pk/data/Unicode.sfd @@ -0,0 +1,265 @@ +# Unicode.sfd +# +# subfont numbers for Unicode encoding and its corresponding code ranges +# to be used with the CJK package for LaTeX. + +00 0x0_0xFF +01 0x100_0x1FF +02 0x200_0x2FF +03 0x300_0x3FF +04 0x400_0x4FF +05 0x500_0x5FF +06 0x600_0x6FF +07 0x700_0x7FF +08 0x800_0x8FF +09 0x900_0x9FF +0a 0xA00_0xAFF +0b 0xB00_0xBFF +0c 0xC00_0xCFF +0d 0xD00_0xDFF +0e 0xE00_0xEFF +0f 0xF00_0xFFF +10 0x1000_0x10FF +11 0x1100_0x11FF +12 0x1200_0x12FF +13 0x1300_0x13FF +14 0x1400_0x14FF +15 0x1500_0x15FF +16 0x1600_0x16FF +17 0x1700_0x17FF +18 0x1800_0x18FF +19 0x1900_0x19FF +1a 0x1A00_0x1AFF +1b 0x1B00_0x1BFF +1c 0x1C00_0x1CFF +1d 0x1D00_0x1DFF +1e 0x1E00_0x1EFF +1f 0x1F00_0x1FFF +20 0x2000_0x20FF +21 0x2100_0x21FF +22 0x2200_0x22FF +23 0x2300_0x23FF +24 0x2400_0x24FF +25 0x2500_0x25FF +26 0x2600_0x26FF +27 0x2700_0x27FF +28 0x2800_0x28FF +29 0x2900_0x29FF +2a 0x2A00_0x2AFF +2b 0x2B00_0x2BFF +2c 0x2C00_0x2CFF +2d 0x2D00_0x2DFF +2e 0x2E00_0x2EFF +2f 0x2F00_0x2FFF +30 0x3000_0x30FF +31 0x3100_0x31FF +32 0x3200_0x32FF +33 0x3300_0x33FF +34 0x3400_0x34FF +35 0x3500_0x35FF +36 0x3600_0x36FF +37 0x3700_0x37FF +38 0x3800_0x38FF +39 0x3900_0x39FF +3a 0x3A00_0x3AFF +3b 0x3B00_0x3BFF +3c 0x3C00_0x3CFF +3d 0x3D00_0x3DFF +3e 0x3E00_0x3EFF +3f 0x3F00_0x3FFF +40 0x4000_0x40FF +41 0x4100_0x41FF +42 0x4200_0x42FF +43 0x4300_0x43FF +44 0x4400_0x44FF +45 0x4500_0x45FF +46 0x4600_0x46FF +47 0x4700_0x47FF +48 0x4800_0x48FF +49 0x4900_0x49FF +4a 0x4A00_0x4AFF +4b 0x4B00_0x4BFF +4c 0x4C00_0x4CFF +4d 0x4D00_0x4DFF +4e 0x4E00_0x4EFF +4f 0x4F00_0x4FFF +50 0x5000_0x50FF +51 0x5100_0x51FF +52 0x5200_0x52FF +53 0x5300_0x53FF +54 0x5400_0x54FF +55 0x5500_0x55FF +56 0x5600_0x56FF +57 0x5700_0x57FF +58 0x5800_0x58FF +59 0x5900_0x59FF +5a 0x5A00_0x5AFF +5b 0x5B00_0x5BFF +5c 0x5C00_0x5CFF +5d 0x5D00_0x5DFF +5e 0x5E00_0x5EFF +5f 0x5F00_0x5FFF +60 0x6000_0x60FF +61 0x6100_0x61FF +62 0x6200_0x62FF +63 0x6300_0x63FF +64 0x6400_0x64FF +65 0x6500_0x65FF +66 0x6600_0x66FF +67 0x6700_0x67FF +68 0x6800_0x68FF +69 0x6900_0x69FF +6a 0x6A00_0x6AFF +6b 0x6B00_0x6BFF +6c 0x6C00_0x6CFF +6d 0x6D00_0x6DFF +6e 0x6E00_0x6EFF +6f 0x6F00_0x6FFF +70 0x7000_0x70FF +71 0x7100_0x71FF +72 0x7200_0x72FF +73 0x7300_0x73FF +74 0x7400_0x74FF +75 0x7500_0x75FF +76 0x7600_0x76FF +77 0x7700_0x77FF +78 0x7800_0x78FF +79 0x7900_0x79FF +7a 0x7A00_0x7AFF +7b 0x7B00_0x7BFF +7c 0x7C00_0x7CFF +7d 0x7D00_0x7DFF +7e 0x7E00_0x7EFF +7f 0x7F00_0x7FFF +80 0x8000_0x80FF +81 0x8100_0x81FF +82 0x8200_0x82FF +83 0x8300_0x83FF +84 0x8400_0x84FF +85 0x8500_0x85FF +86 0x8600_0x86FF +87 0x8700_0x87FF +88 0x8800_0x88FF +89 0x8900_0x89FF +8a 0x8A00_0x8AFF +8b 0x8B00_0x8BFF +8c 0x8C00_0x8CFF +8d 0x8D00_0x8DFF +8e 0x8E00_0x8EFF +8f 0x8F00_0x8FFF +90 0x9000_0x90FF +91 0x9100_0x91FF +92 0x9200_0x92FF +93 0x9300_0x93FF +94 0x9400_0x94FF +95 0x9500_0x95FF +96 0x9600_0x96FF +97 0x9700_0x97FF +98 0x9800_0x98FF +99 0x9900_0x99FF +9a 0x9A00_0x9AFF +9b 0x9B00_0x9BFF +9c 0x9C00_0x9CFF +9d 0x9D00_0x9DFF +9e 0x9E00_0x9EFF +9f 0x9F00_0x9FFF +a0 0xA000_0xA0FF +a1 0xA100_0xA1FF +a2 0xA200_0xA2FF +a3 0xA300_0xA3FF +a4 0xA400_0xA4FF +a5 0xA500_0xA5FF +a6 0xA600_0xA6FF +a7 0xA700_0xA7FF +a8 0xA800_0xA8FF +a9 0xA900_0xA9FF +aa 0xAA00_0xAAFF +ab 0xAB00_0xABFF +ac 0xAC00_0xACFF +ad 0xAD00_0xADFF +ae 0xAE00_0xAEFF +af 0xAF00_0xAFFF +b0 0xB000_0xB0FF +b1 0xB100_0xB1FF +b2 0xB200_0xB2FF +b3 0xB300_0xB3FF +b4 0xB400_0xB4FF +b5 0xB500_0xB5FF +b6 0xB600_0xB6FF +b7 0xB700_0xB7FF +b8 0xB800_0xB8FF +b9 0xB900_0xB9FF +ba 0xBA00_0xBAFF +bb 0xBB00_0xBBFF +bc 0xBC00_0xBCFF +bd 0xBD00_0xBDFF +be 0xBE00_0xBEFF +bf 0xBF00_0xBFFF +c0 0xC000_0xC0FF +c1 0xC100_0xC1FF +c2 0xC200_0xC2FF +c3 0xC300_0xC3FF +c4 0xC400_0xC4FF +c5 0xC500_0xC5FF +c6 0xC600_0xC6FF +c7 0xC700_0xC7FF +c8 0xC800_0xC8FF +c9 0xC900_0xC9FF +ca 0xCA00_0xCAFF +cb 0xCB00_0xCBFF +cc 0xCC00_0xCCFF +cd 0xCD00_0xCDFF +ce 0xCE00_0xCEFF +cf 0xCF00_0xCFFF +d0 0xD000_0xD0FF +d1 0xD100_0xD1FF +d2 0xD200_0xD2FF +d3 0xD300_0xD3FF +d4 0xD400_0xD4FF +d5 0xD500_0xD5FF +d6 0xD600_0xD6FF +d7 0xD700_0xD7FF +# Surrogates +# +# d8 0xD800_0xD8FF +# d9 0xD900_0xD9FF +# da 0xDA00_0xDAFF +# db 0xDB00_0xDBFF +dc 0xDC00_0xDCFF +dd 0xDD00_0xDDFF +de 0xDE00_0xDEFF +df 0xDF00_0xDFFF +e0 0xE000_0xE0FF +e1 0xE100_0xE1FF +e2 0xE200_0xE2FF +e3 0xE300_0xE3FF +e4 0xE400_0xE4FF +e5 0xE500_0xE5FF +e6 0xE600_0xE6FF +e7 0xE700_0xE7FF +e8 0xE800_0xE8FF +e9 0xE900_0xE9FF +ea 0xEA00_0xEAFF +eb 0xEB00_0xEBFF +ec 0xEC00_0xECFF +ed 0xED00_0xEDFF +ee 0xEE00_0xEEFF +ef 0xEF00_0xEFFF +f0 0xF000_0xF0FF +f1 0xF100_0xF1FF +f2 0xF200_0xF2FF +f3 0xF300_0xF3FF +f4 0xF400_0xF4FF +f5 0xF500_0xF5FF +f6 0xF600_0xF6FF +f7 0xF700_0xF7FF +f8 0xF800_0xF8FF +f9 0xF900_0xF9FF +fa 0xFA00_0xFAFF +fb 0xFB00_0xFBFF +fc 0xFC00_0xFCFF +fd 0xFD00_0xFDFF +fe 0xFE00_0xFEFF +ff 0xFF00_0xFFFF + +# eof diff --git a/contrib/ttf2pk/data/VPS.rpl b/contrib/ttf2pk/data/VPS.rpl new file mode 100644 index 0000000..cbd179f --- /dev/null +++ b/contrib/ttf2pk/data/VPS.rpl @@ -0,0 +1,244 @@ +% VPS.rpl +% +% +% This file maps VPS encoding for Vietnamese to Adobe glyph names used +% in the file ET5.enc. +% +% VPS is a commonly used program to write Vietnamese. +% +% This file has been tested with the font vpsdlac.ttf using cmap (3,0) + +.c0x0002 Adotbelow +.c0x0003 Acircumflexdotbelow +.c0x0004 Abrevedotbelow +.c0x0005 Edotbelow +.c0x0006 Ecircumflexdotbelow +.c0x0015 Uhorndotbelow +.c0x0019 Ydotbelow +.c0x001c Acircumflextilde +.c0x001d Uhorntilde +.c0x0020 space +.c0x0021 exclam +.c0x0022 quotedbl +.c0x0023 numbersign +.c0x0024 dollar +.c0x0025 percent +.c0x0026 ampersand +.c0x0027 quotesingle +.c0x0028 parenleft +.c0x0029 parenright +.c0x002a asterisk +.c0x002b plus +.c0x002c comma +.c0x002d hyphen +.c0x002e period +.c0x002f slash +.c0x0030 zero +.c0x0031 one +.c0x0032 two +.c0x0033 three +.c0x0034 four +.c0x0035 five +.c0x0036 six +.c0x0037 seven +.c0x0038 eight +.c0x0039 nine +.c0x003a colon +.c0x003b semicolon +.c0x003c less +.c0x003d equal +.c0x003e greater +.c0x003f question +.c0x0040 at +.c0x0041 A +.c0x0042 B +.c0x0043 C +.c0x0044 D +.c0x0045 E +.c0x0046 F +.c0x0047 G +.c0x0048 H +.c0x0049 I +.c0x004a J +.c0x004b K +.c0x004c L +.c0x004d M +.c0x004e N +.c0x004f O +.c0x0050 P +.c0x0051 Q +.c0x0052 R +.c0x0053 S +.c0x0054 T +.c0x0055 U +.c0x0056 V +.c0x0057 W +.c0x0058 X +.c0x0059 Y +.c0x005a Z +.c0x005b bracketleft +.c0x005c backslash +.c0x005d bracketright +.c0x005e asciicircum +.c0x005f underscore +.c0x0060 grave +.c0x0061 a +.c0x0062 b +.c0x0063 c +.c0x0064 d +.c0x0065 e +.c0x0066 f +.c0x0067 g +.c0x0068 h +.c0x0069 i +.c0x006a j +.c0x006b k +.c0x006c l +.c0x006d m +.c0x006e n +.c0x006f o +.c0x0070 p +.c0x0071 q +.c0x0072 r +.c0x0073 s +.c0x0074 t +.c0x0075 u +.c0x0076 v +.c0x0077 w +.c0x0078 x +.c0x0079 y +.c0x007a z +.c0x007b braceleft +.c0x007c bar +.c0x007d braceright +.c0x007e asciitilde +.c0x0080 Agrave +.c0x0081 Ahookabove +.c0x008d Abreveacute +.c0x008e Abrevegrave +.c0x008f Abrevehookabove +.c0x0090 Ecircumflexacute +.c0x009d Ohornacute +.c0x009e Ohorngrave +.c0x00a0 nbspace +.c0x00a1 abreveacute +.c0x00a2 abrevegrave +.c0x00a3 abrevehookabove +.c0x00a4 abrevetilde +.c0x00a5 abrevedotbelow +.c0x00a6 Ohorntilde +.c0x00a7 ohornacute +.c0x00a8 Ugrave +.c0x00a9 ohorngrave +.c0x00aa ohornhookabove +.c0x00ab ohorntilde +.c0x00ac Utilde +.c0x00ad Uhornacute +.c0x00ae ohorndotbelow +.c0x00af Uhorngrave +.c0x00b0 ocircumflexhookabove +.c0x00b1 Uhornhookabove +.c0x00b2 Ygrave +.c0x00b3 Ytilde +.c0x00b4 Iacute +.c0x00b5 Igrave +.c0x00b6 ocircumflexdotbelow +.c0x00b8 Itilde +.c0x00b9 Oacute +.c0x00ba uhornhookabove +.c0x00bb uhorntilde +.c0x00bc Ograve +.c0x00bd Ohookabove +.c0x00be Otilde +.c0x00bf uhorndotbelow +.c0x00c0 acircumflexgrave +.c0x00c1 Aacute +.c0x00c2 Acircumflex +.c0x00c3 acircumflexacute +.c0x00c4 acircumflexhookabove +.c0x00c5 acircumflextilde +.c0x00c6 acircumflexdotbelow +.c0x00c7 dbar +.c0x00c8 ehookabove +.c0x00c9 Eacute +.c0x00ca Ecircumflex +.c0x00cb edotbelow +.c0x00cc ihookabove +.c0x00cd ecircumflextilde +.c0x00ce idotbelow +.c0x00cf ytilde +.c0x00d0 Uhorn +.c0x00d1 Uhookabove +.c0x00d2 ocircumflexgrave +.c0x00d3 ocircumflexacute +.c0x00d4 Ocircumflex +.c0x00d5 ohookabove +.c0x00d6 ohorn +.c0x00d7 Egrave +.c0x00d8 uhorngrave +.c0x00d9 uhornacute +.c0x00da Uacute +.c0x00db utilde +.c0x00dc uhorn +.c0x00dd Yacute +.c0x00de Ehookabove +.c0x00df germandbls +.c0x00e0 agrave +.c0x00e1 aacute +.c0x00e2 acircumflex +.c0x00e3 atilde +.c0x00e4 ahookabove +.c0x00e5 adotbelow +.c0x00e6 abreve +.c0x00e7 ccedilla +.c0x00e8 egrave +.c0x00e9 eacute +.c0x00ea ecircumflex +.c0x00eb etilde +.c0x00ec igrave +.c0x00ed iacute +.c0x00ee icircumflex +.c0x00ef itilde +.c0x00f0 Abrevetilde +.c0x00f1 Dbar +.c0x00f2 ograve +.c0x00f3 oacute +.c0x00f4 ocircumflex +.c0x00f5 otilde +.c0x00f6 odieresis +.c0x00f7 Ohorn +.c0x00f8 udotbelow +.c0x00f9 ugrave +.c0x00fa uacute +.c0x00fb uhookabove +.c0x00fc udieresis +.c0x00fd Yhookabove +.c0x00fe Etilde +.c0x00ff ygrave +.c0x0152 ecircumflexdotbelow +.c0x0153 ydotbelow +.c0x0160 ecircumflexgrave +.c0x0161 yacute +.c0x0178 Ohornhookabove +.c0x0192 Acircumflexacute +.c0x02c6 Abreve +.c0x02dc Ocircumflexhookabove +.c0x2013 Ocircumflexacute +.c0x2014 Ocircumflexgrave +.c0x2018 quoteleft +.c0x2019 quoteright +.c0x201a Atilde +.c0x201c Ecircumflexgrave +.c0x201d Ecircumflexhookabove +.c0x201e Acircumflexgrave +.c0x2020 odotbelow +.c0x2021 ocircumflextilde +.c0x2022 Ecircumflextilde +.c0x2026 Acircumflexhookabove +.c0x2030 ecircumflexacute +.c0x2039 ecircumflexhookabove +.c0x203a yhookabove +.c0x2122 Ocircumflextilde +.c0x2219 Ihookabove + +% eof diff --git a/contrib/ttf2pk/data/ttfonts.map b/contrib/ttf2pk/data/ttfonts.map new file mode 100644 index 0000000..55a7a03 --- /dev/null +++ b/contrib/ttf2pk/data/ttfonts.map @@ -0,0 +1,18 @@ +% These entries are just examples! + +arials arial.ttf Slant=0.25 +arial arial.ttf Slant=0 Extend=1 Pid = 1 Eid = 0 +arialx arial.ttf Slant=0 Extend=1.5 + +times times.ttf Encoding=T1-WGL4.enc \ + .g0xc7=ring .g0xc9=caron .g0xc4=dotlessi +times95 times95.ttf Encoding=T1-WGL4.enc + +ntukai@Big5@ ntu_kai.ttf Pid = 3 Eid = 4 +cyberb@Unicode@ cyberbit.ttf + +% the next entry maps the Unicode encoded font to Big 5 encoding; thus you +% can say \begin{CJK}{Big5}{...} (this is an environment from the CJK +% package for LaTeX). + +mingli@UBig5@ mingliu.ttc Fontindex = 0 diff --git a/contrib/ttf2pk/dvidrv.btm b/contrib/ttf2pk/dvidrv.btm new file mode 100644 index 0000000..aee27a3 --- /dev/null +++ b/contrib/ttf2pk/dvidrv.btm @@ -0,0 +1,334 @@ +:: +:: This is dvidrv.btm, a batch file for 4DOS/4OS2 written by +:: Werner Lemberg partially based on the +:: dvidrv.btm file of the 4allTeX package written by Phons Bloemen. +:: +:: It is a replacement for dvidrv.exe of the emTeX package. +:: +:: Additional features: support of ps2pk +:: support of ttf2pk +:: support of hbf2gf for HBFs (Hanzi bitmap fonts) +:: +:: Only quadratic printer modes are supported for ttf2pk! +:: +:: All needed binaries will be searched in the path. + +iff %# lt 2 then + echo `` + echo Usage: %0 dvi-driver dvi-file [parameters] + quit +endiff + +setlocal + :: we set a default value only if the corresponding environment variable + :: is empty. The `=' must follow the variable name immediately. + alias set_def `iff "%[%@word["=",0,%1]]" eq "" then %+ set %& %+ endiff` + + :: ========================================= + :: ======== User defined variables. ======== + :: ========================================= + :: + :: Can be overridden in the environment (except %ps2pk, %ttf2pk, %hbf2gf, + :: %pre_dpi, and %post_dpi). + + :: Set these values to `no' for the programs you don't want to use. + set ps2pk=yes + set ttf2pk=yes + set hbf2gf=yes + + :: where the PK files will be installed created by ps2pk, ttf2pk, and + :: hbf2gf. + :: dvidrv.btm adds `\modeless\XXXdpi' to this string (see below for the + :: exact string). + set_def pkdir=%emtexdir\pixel\tmp\pk + + :: where the TrueType fonts reside. Supports trailing `!' and `!!'. + set_def ttfonts=%emtexdir\fonts\truetype + :: where auxiliary files of ttf2pk are located. Supports trailing `!' + :: and `!!'. + set_def ttfcfg=%emtexdir\ttf2pk + + :: where the HBF files reside. Supports trailing `!' and `!!'. + set_def hbfonts=%emtexdir\fonts\hbf + :: where the hbf2gf config files are. Supports trailing `!' and `!!'. + set_def hbfcfg=%emtexdir\hbf2gf + + :: the dpi-subdirectory has various forms; the most common are XXXdpi and + :: dpiXXX, e.g. 300dpi and dpi300. Here we define two variables which + :: control this behaviour. + :: [dpiXXX is used for TDS compatible TeX trees.] + set pre_dpi=dpi + set post_dpi= + + :: ================================================ + :: ======== End of user defined variables. ======== + :: ================================================ + + :: the base name for log files etc. + set basename=%@name[%1] + + :: do we run dvips? + iff "%basename" ne "dvips" then + goto nodvips1 + endiff + + :: we delete dvips.mfj if it exists. + del dvips.mfj >& nul + + :: now we run dvips with all supplied parameters. + %& + + :: do we have to generate fonts? + iff exist dvips.mfj then + goto generate_fonts + endiff + + :: else all is done. + goto end + + +:nodvips1 + :: here we call the dvi driver with all supplied parameters. + %& -pj:%basename.mfj + + :: do we have to generate fonts? + iff errorlevel 8 then + goto generate_fonts + endiff + + :: else all is done. + goto end + + +:generate_fonts + gosub call_mfjob + + :: do we run dvips? + iff "%basename" ne "dvips" then + goto nodvips2 + endiff + + :: we now call dvips a second time + %& + + :: since no fonts will be generated in the second run we remove dvips.mfj + del dvips.mfj >& nul + + goto end + + +:nodvips2 + :: we call the dvi driver a second time (without font generation). + %& -pj -fm + + del %basename.mfj >& nul + + goto end + + +:: this is the main subroutine which calls mfjob and then parses the mfjob +:: file for fonts which can be handled by ps2pk, ttf2pk, or hbf2gf. +:call_mfjob + :: this alias prints a message on the screen and writes it into the logfile. + alias echolog=`echo %& | tee /a %basename.mlg` + + echo ======== DVIDRV.BTM logfile ======== > %basename.mlg + echo Commandline: dvidrv.btm %& >> %basename.mlg + echo `` >> %basename.mlg + echo basename=%basename >> %basename.mlg + echo emtexdir=%emtexdir >> %basename.mlg + echo dvidrvfonts=%dvidrvfonts >> %basename.mlg + echo mfinput=%mfinput >> %basename.mlg + echo mfjobopt=%mfjobopt >> %basename.mlg + echo textfm=%textfm >> %basename.mlg + echo psfonts=%psfonts >> %basename.mlg + echo ttfonts=%ttfonts >> %basename.mlg + echo ttfcfg=%ttfcfg >> %basename.mlg + echo hbfonts=%hbfonts >> %basename.mlg + echo hbfcfg=%hbfcfg >> %basename.mlg + echo `` >> %basename.mlg + + iff "%@search[mfjob]" eq "" then + echolog MFJOB not found in the path. + echolog Can't generate PK fonts from METAFONT automatically. + echo `` + quit + endiff + + :: now we call mfjob. + echolog mfjob %mfjobopt -g%basename.mfl %basename.mfj + mfjob %mfjobopt -g%basename.mfl %basename.mfj + iff %? gt 0 then + echolog `` + echolog Something went wrong while running METAFONT. + echolog Look into the log files... + echolog `` + endiff + + :: after running mfjob we scan the mfjob input file for fonts which can + :: be handled by ps2pk, ttf2pk, or hbf2gf. + set lnnr=0 + set totlines=%@lines[%basename.mfj] + + do while %lnnr le %totlines + :: input a line. + set scratch=%@line[%basename.mfj,%lnnr] + set lnnr=%@inc[%lnnr] + + :: get resolutions (METAFONT mode will be ignored). + :: example: + :: mode=lqlores[180 180]; + iff %@index[%scratch,mode] ge 0 then + set temp=%@word["[]",1,%scratch] + set xdpi=%@word[0,%temp] + set ydpi=%@word[1,%temp] + endiff + + :: get fontname and magnification; we then compute the font resolutions + :: (rounded to the nearest integer---there is no necessity to adjust + :: these values further because of possible rounding errors since both + :: emTeX's dvi drivers and dvips check neighbored values too). + :: example: + :: {font=cmr10; mag=0.5;} + iff %@index[%scratch,{font] ge 0 then + set testfont=%@word["=;",1,%scratch] + set temp=%@word["=;",3,%scratch] + :: we use highest arithmetic precision for these calculations. + :: Additionally we write 1/2 instead of 0.5 to avoid problems with + :: countries which use a comma instead of a colon as the decimal + :: separator. + set fontresx=%@int[%@eval[%xdpi*%temp+1/2=8]] + set fontresy=%@int[%@eval[%ydpi*%temp+1/2=8]] + set pksubdir=modeless\%[pre_dpi]%[fontresx]%post_dpi + + set success=0 + + :: check whether %testfont leads to a PS font (we call ps2pkmfj). + iff %success == 0 .and. "%ps2pk" eq "yes" then + gosub call_ps2pk + endiff + + :: check whether %testfont leads to a TrueType font. + iff %success == 0 .and. "%ttf2pk" eq "yes" then + gosub call_ttf2pk + endiff + + :: check whether %testfont leads to a HBF file. + iff %success == 0 .and. "%hbf2gf" eq "yes" then + gosub call_hbf2gf + endiff + endiff + enddo + + iff exist %basename.mfp then + echo `` >> %basename.mlg + echo `` >> %basename.mlg + echo ======== PS2PK logfile ======== >> %basename.mlg + echo `` >> %basename.mlg + type %basename.mfp >> %basename.mlg + echo `` >> %basename.mlg + del %basename.mfp >& nul + endiff + + iff exist %basename.mfl then + echo `` >> %basename.mlg + type %basename.mfl >> %basename.mlg + echo `` >> %basename.mlg + del %basename.mfl >& nul + endiff + + return + + +:call_ttf2pk + iff "%@search[ttf2pk]" eq "" then + echolog TTF2PK not found in the path. + echolog Can't generate PK fonts from TrueType fonts automatically. + echo `` + quit + endiff + + echolog ttf2pk -q -n %testfont %fontresx + ttf2pk -q -n %testfont %fontresx + + iff %? == 0 then + echolog Font %pkdir\%pksubdir\%testfont.pk generated. + mkdir /s %pkdir\%pksubdir >& nul + move %testfont.pk %pkdir\%pksubdir >& nul + set success=1 + elseiff %? == 2 then + echolog (%lnnr/%totlines): Font %testfont is no TrueType font. + set success=0 + else + echolog Error running TTF2PK for font %testfont! + endiff + + return + + +:call_hbf2gf + iff "%@search[hbf2gf]" eq "" then + echolog HBF2GF not found in the path. + echolog Can't generate PK fonts from HBF files automatically. + echo `` + quit + endiff + + echolog hbf2gf -q -p -n %testfont %fontresx %fontresy + hbf2gf -q -p -n %testfont %fontresx %fontresy + + iff %? == 0 then + echolog Font %pkdir\%pksubdir\%testfont.pk generated. + mkdir /s %pkdir\%pksubdir >& nul + gftopk %testfont.gf %testfont.pk + move %testfont.pk %pkdir\%pksubdir >& nul + del %testfont.gf >& nul + set success=1 + elseiff %? == 2 then + echolog (%lnnr/%totlines): Font %testfont is no HBF. + set success=0 + else + echolog Error running HBF2GF for font %testfont! + endiff + + return + + +:call_ps2pk + iff not exist %pkdir\%pksubdir\%testfont.pk then + iff "%@search[ps2pkmfj]" eq "" .or. "%@search[ps2pk]" eq "" then + echolog PS2PKMFJ and/or PS2PK not found in the path. + echolog Can't generate PK fonts from PostScript fonts automatically. + echo `` + quit + endiff + + echolog ps2pkmfj -X%fontresx -Y%fontresy %testfont %testfont.pk + ps2pkmfj -X%fontresx -Y%fontresy %testfont %testfont.pk | input %%pspkline + + iff errorlevel != 1 then + %pspkline >> %basename.mfp + iff %? == 0 then + echolog Font %pkdir\%pksubdir\%testfont.pk generated. + mkdir /s %pkdir\%pksubdir >& nul + move %testfont.pk %pkdir\%pksubdir >& nul + success=1 + else + echolog Error running PS2PK for font %testfont! + endiff + else + echolog (%lnnr/%totlines): Font %testfont is no PS font. + success=0 + endiff + else + echolog Font %pkdir\%pksubdir\%testfont.pk already exists. + endiff + + return + + +:end + +endlocal + +:: ==== end of dvidrv.btm ==== diff --git a/contrib/ttf2pk/dvidrv.doc b/contrib/ttf2pk/dvidrv.doc new file mode 100644 index 0000000..f1ecc5b --- /dev/null +++ b/contrib/ttf2pk/dvidrv.doc @@ -0,0 +1,56 @@ +Using dvidrv.btm [emTeX for DOS and OS/2] +------------------------------------------- + +This batch file does the same as MakeTeXPK does; it is a replacement for +dvidrv.exe of emTeX which can handle ttf2pk, hbf2gf, and ps2pk additionally +(the ps2pk part is untested yet; it uses ps2pkmfj of the 4allTeX +distribution and was basically copied from a similar script, also part of +4allTeX). + +First of all, create and install a set of TFM files as described in the +previous section. + +Then configure the following variables in dvidrv.btm: + + ps2pk ... set it to `yes' if you want to use this program + ttf2pk ... ditto + hbf2gf ... ditto + + pkdir ... the place where PK files created by ps2pk, ttf2pk, + or hbf2gf should go to. dvidrv.btm adds + `\modeless\XXXdpi' resp. `\modeless\dpiXXX' to this + string (depending on the variables `pre_dpi' and + `post_dpi') + + ttfonts ... where the TrueType fonts files reside + ttfcfg ... where the auxiliary data files of ttf2pk reside + + hbfonts ... where the HBF files reside + hbfcfg ... the place where the hbf2gf configuration files are + +The last four variables in the above list support trailing `!' and `!!' for +recursive directory searching (see the dvidrv.doc of the emTeX package for +details). + +Alternatively, you can set these variables in the environment; please note +that no spaces are allowed before and after the equal sign, e.g. + + set foo=bar + +is OK, but + + set foo = bar + +will fail. + +Rename dvidrv.exe to dvidrv.ori or something similar and copy dvidrv.btm to +a directory in the path. + +Don't forget to update the DVIDRVFONTS and TEXTFM environment variables if +necessary. + +Under OS/2 dvips will call mfjob or hbf2gf itself; under DOS it will create +a batch file which must be called afterwards. + + +--- end of dvidrv.doc --- diff --git a/contrib/ttf2pk/emdir.c b/contrib/ttf2pk/emdir.c new file mode 100644 index 0000000..4e759c8 --- /dev/null +++ b/contrib/ttf2pk/emdir.c @@ -0,0 +1,109 @@ +/* emdir.c -- Written by Eberhard Mattes, donated to the public domain */ + +#include "emdir.h" + +#ifdef OS2 + +#undef HPS +#define INCL_DOSFILEMGR +#include +#include + +#define FHDIR(b) (*(HDIR *)(b)->reserved) + +static void fconv (struct ll_findbuffer *dst, const FILEFINDBUF *src) +{ + dst->attr = src->attrFile; + dst->time = *(unsigned *)&src->ftimeLastWrite; + dst->date = *(unsigned *)&src->fdateLastWrite; + dst->size = src->cbFile; + strcpy (dst->name, src->achName); +} + + +int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer) +{ + USHORT rc; + ULONG count; + HDIR hdir; + FILEFINDBUF ffbuf; + + hdir = HDIR_CREATE; + count = 1; + rc = DosFindFirst ((PSZ)path, &hdir, attr, &ffbuf, sizeof (ffbuf), + &count, 0L); + if (rc != 0 || count != 1) + return 0; + FHDIR (buffer) = hdir; + fconv (buffer, &ffbuf); + return 1; +} + + +int ll_findnext (struct ll_findbuffer *buffer) +{ + USHORT rc; + ULONG count; + HDIR hdir; + FILEFINDBUF ffbuf; + + hdir = FHDIR (buffer); + count = 1; + rc = DosFindNext (hdir, &ffbuf, sizeof (ffbuf), &count); + if (rc != 0 || count != 1) + { + DosFindClose (hdir); + return 0; + } + fconv (buffer, &ffbuf); + return 1; +} + + +#elif defined(DJGPP) + +/* djgpp support by Hartmut Schirmer (hsc@techfak.uni-kiel.de), May 30, 1997 */ + +#include +#include + +static int ll_attr = 0; +int ll_findnext (struct ll_findbuffer *buffer) +{ + int res; + do { + res = _dos_findnext ((struct find_t *)buffer); + if (res != 0) return 0; + } while ( (buffer->attrib&ll_attr) == 0); + return 1; +} + +int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer) +{ + int res; + ll_attr = attr; + res = _dos_findfirst((char *)path, attr, (struct find_t *)buffer); + if (res != 0) return 0; + if ( (buffer->attrib&ll_attr) == 0) + return ll_findnext(buffer); + return 1; +} + +#elif !defined(__EMX__) /* if not OS2 nor DJGPP nor __EMX__ defined */ + +/* Not tested */ + +#include + +int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer) +{ + return _dos_findfirst (path, attr, (struct find_t *)buffer) == 0; +} + + +int ll_findnext (struct ll_findbuffer *buffer) +{ + return _dos_findnext ((struct find_t *)buffer) == 0; +} + +#endif diff --git a/contrib/ttf2pk/emdir.h b/contrib/ttf2pk/emdir.h new file mode 100644 index 0000000..0606d47 --- /dev/null +++ b/contrib/ttf2pk/emdir.h @@ -0,0 +1,25 @@ +/* emdir.h -- Written by Eberhard Mattes, donated to the public domain */ + +#if defined(DJGPP) + +/* djgpp support by Hartmut Schirmer (hsc@techfak.uni-kiel.de), May 30, 1997 */ +#include +#define ll_findbuffer find_t +#define attr attrib + +#else + +struct ll_findbuffer +{ + char reserved[21]; + unsigned char attr; + unsigned time; + unsigned date; + long size; + char name[257]; +}; + +#endif + +int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer); +int ll_findnext (struct ll_findbuffer *buffer); diff --git a/contrib/ttf2pk/emtexdir.c b/contrib/ttf2pk/emtexdir.c new file mode 100644 index 0000000..9a35570 --- /dev/null +++ b/contrib/ttf2pk/emtexdir.c @@ -0,0 +1,405 @@ +/* emtexdir.c -- written by Eberhard Mattes, donated to the public domain */ + +#if defined (__EMX__) +#include +#else +#include "emdir.h" +#endif +#if defined(DJGPP) || defined(GO32) +#include +#endif +#include +#include +#include +#include +#include "emtexdir.h" + +#define FALSE 0 +#define TRUE 1 + +void (*emtex_dir_find_callback)(const char *name, int ok) = NULL; + +static int setup_add (struct emtex_dir *dst, const char *path) +{ + char *p; + + if (dst->used >= dst->alloc) + { + dst->alloc += 8; + dst->list = realloc (dst->list, dst->alloc * sizeof (*dst->list)); + if (dst->list == NULL) + return (FALSE); + } + p = strdup (path); + if (p == NULL) + return (FALSE); + dst->list[dst->used++] = p; + return (TRUE); +} + + +static int setup_subdir (struct emtex_dir *dst, char *path, size_t add, + unsigned flags, int recurse) +{ + int ok, i, end, len; +#if defined (__EMX__) + struct _find find; +#else + struct ll_findbuffer find; +#endif + + i = dst->used; + strcpy (path + add, "*.*"); +#if defined (__EMX__) + ok = __findfirst (path, 0x10, &find) == 0; +#else + ok = ll_findfirst (path, 0x10, &find); +#endif + while (ok) + { + if ((find.attr & 0x10) + && !(strcmp (find.name, ".") == 0 || strcmp (find.name, "..") == 0)) + { + len = strlen (find.name); + memcpy (path + add, find.name, len); + path[add+len] = '\\'; + path[add+len+1] = 0; + if (!setup_add (dst, path)) + return (FALSE); + } +#if defined (__EMX__) + ok = __findnext (&find) == 0; +#else + ok = ll_findnext (&find); +#endif + } + if (recurse) + { + end = dst->used; + while (i < end) + { + strcpy (path, dst->list[i]); + if (!setup_subdir (dst, path, strlen (path), flags, TRUE)) + return (FALSE); + ++i; + } + } + return (TRUE); +} + + +static int setup_dir (struct emtex_dir *dst, char *path, + const char *base_dir, size_t base_dir_len, + const char *sub_dir, + unsigned flags) +{ + size_t i, len; + + memcpy (path, base_dir, base_dir_len); + i = base_dir_len; + if ((flags & EDS_BANG) && sub_dir == NULL) + { + flags &= ~(EDS_ONESUBDIR|EDS_ALLSUBDIR); + if (i >= 2 && path[i-1] == '!' && path[i-2] == '!') + { + flags |= EDS_ALLSUBDIR; + i -= 2; + } + else if (i >= 1 && path[i-1] == '!') + { + flags |= EDS_ONESUBDIR; + --i; + } + } + if (sub_dir != NULL && *sub_dir != 0) + { + if (i != 0 && path[i-1] != ':' && path[i-1] != '/' && path[i-1] != '\\') + path[i++] = '\\'; + len = strlen (sub_dir); + memcpy (path+i, sub_dir, len); + i += len; + } + if (path[i-1] != ':' && path[i-1] != '/' && path[i-1] != '\\') + path[i++] = '\\'; + path[i] = 0; + if (!setup_add (dst, path)) + return (FALSE); + if (flags & EDS_ALLSUBDIR) + return (setup_subdir (dst, path, i, flags, TRUE)); + else if (flags & EDS_ONESUBDIR) + return (setup_subdir (dst, path, i, flags, FALSE)); + else + return (TRUE); +} + + +/*static */int setup_list (struct emtex_dir *dst, char *path, + const char *list, unsigned flags) +{ + const char *end; + size_t i; + + for (;;) + { + while (*list == ' ' || *list == '\t') + ++list; + if (*list == 0) + return (TRUE); + end = list; + while (*end != 0 && *end != ';') + ++end; + i = end - list; + while (i > 0 && (list[i-1] == ' ' || list[i-1] == '\t')) + --i; + if (i != 0 && !setup_dir (dst, path, list, i, NULL, flags)) + return (FALSE); + if (*end == 0) + return (TRUE); + list = end + 1; + } +} + + +int emtex_dir_setup (struct emtex_dir *ed, const char *env, const char *dir, + unsigned flags) +{ + const char *val; + char path[260]; + + ed->alloc = 0; + ed->used = 0; + ed->list = NULL; + if (env != NULL && (val = getenv (env)) != NULL) + return (setup_list (ed, path, val, flags)); + else if ((val = getenv ("EMTEXDIR")) != NULL) + return (setup_dir (ed, path, val, strlen (val), dir, flags)); + else + return (setup_dir (ed, path, "\\emtex", 6, dir, flags)); +} + + +static void pretty (char *path, unsigned flags) +{ + char *p; + + if (flags & EDF_FSLASH) + for (p = path; *p != 0; ++p) + if (*p == '\\') + *p = '/'; +} + + +#define ADDCHAR(C) \ + if (dst_size < 1) return (EDT_TOOLONG); \ + *dst++ = (C); --dst_size + +int emtex_dir_trunc (char *dst, size_t dst_size, const char *src, + unsigned flags, int method) +{ + int len, truncated, dot; + + if (src[0] != 0 && src[1] == ':') + { + ADDCHAR (src[0]); + ADDCHAR (src[1]); + src += 2; + } + + truncated = FALSE; dot = FALSE; len = 0; + for (;;) + { + switch (*src) + { + case 0: + ADDCHAR (0); + return (truncated ? EDT_CHANGED : EDT_UNCHANGED); + + case ':': + return (EDT_INVALID); + + case '/': + case '\\': + ADDCHAR (*src); + len = 0; dot = FALSE; + break; + + case '.': + if (dot) + return (EDT_INVALID); + ADDCHAR (*src); + + /* ".." is allowed -- don't return EDT_INVALID for the next + dot. */ + + if (!(len == 0 && src[1] == '.' + && (src[2] == 0 || src[2] == '/' || src[2] == '\\'))) + { + len = 0; dot = TRUE; + } + break; + + default: + if (dot && len == 3) + truncated = TRUE; + else if (!dot && len == 8) + { + truncated = TRUE; + if (method == 0) + { + dst[-3] = dst[-2]; + dst[-2] = dst[-1]; + dst[-1] = *src; + } + } + else + { + ADDCHAR (*src); + ++len; + } + break; + } + ++src; + } +} + + +static int find2 (const char *name, unsigned flags) +{ + int ok; + + ok = (access (name, 4) == 0); + if (flags & EDF_TRACE) + emtex_dir_find_callback (name, ok); + return (ok); +} + + +static int find1 (char *path, size_t path_size, const char *dir, + const char *fname, unsigned flags) +{ + char buf[260]; + int method, rc; + size_t len, tmp; + + len = 0; + if (dir != NULL) + { + tmp = strlen (dir); + if (tmp >= sizeof (buf)) + return (FALSE); + memcpy (buf, dir, tmp); + len = tmp; + } + tmp = strlen (fname); + if (len + tmp >= sizeof (buf)) + return (FALSE); + memcpy (buf + len, fname, tmp + 1); + len += tmp; +#if 0 /* wkim */ +/* disabled for Win95's long file name support */ +/* -- Wonkoo Kim (wkim+@pitt.edu), May 18, 1997 */ + if (_osmode == DOS_MODE) + { + rc = emtex_dir_trunc (path, path_size, buf, flags, EDT_5_PLUS_3); + if ((rc == EDT_UNCHANGED || rc == EDT_CHANGED) && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + rc = emtex_dir_trunc (path, path_size, buf, flags, EDT_8); + if (rc == EDT_CHANGED && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + return (FALSE); + } + else +#endif /* wkim */ + { + if (len < path_size && find2 (buf, flags)) + { + memcpy (path, buf, len + 1); + pretty (path, flags); + return (TRUE); + } + for (method = 0; method < 2; ++method) + { + rc = emtex_dir_trunc (path, path_size, buf, flags, method); + if (rc == EDT_CHANGED && find2 (path, flags)) + { + pretty (path, flags); + return (TRUE); + } + } + return (FALSE); + } +} + + +int emtex_dir_find (char *path, size_t path_size, + const struct emtex_dir *ed, + const char *fname, unsigned flags) +{ + int i, absp; + const char *p; + + absp = FALSE; + for (p = fname; *p != 0; ++p) + if (*p == ':' || *p == '/' || *p == '\\') + { + absp = TRUE; + break; + } + + if (absp) + return (find1 (path, path_size, NULL, fname, flags)); + + if ((flags & EDF_CWD) && find1 (path, path_size, NULL, fname, flags)) + return (TRUE); + + for (i = 0; i < ed->used; ++i) + if (find1 (path, path_size, ed->list[i], fname, flags)) + return (TRUE); + return (FALSE); +} + + +#if defined (TEST) + +#include + +int main (int argc, char *argv[]) +{ + struct emtex_dir ed; + int i; + unsigned flags1, flags2; + char path[260]; + + if (argc != 6) + { + puts ("Usage: emtexdir "); + return (1); + } + + flags1 = (unsigned)strtol (argv[1], NULL, 0); + flags2 = (unsigned)strtol (argv[2], NULL, 0); + + if (!emtex_dir_setup (&ed, argv[3], argv[4], flags1)) + { + fputs ("emtex_dir_setup failed\n", stderr); + return (2); + } + + printf ("Directories:\n"); + for (i = 0; i < ed.used; ++i) + printf (" %s\n", ed.list[i]); + + if (!emtex_dir_find (path, sizeof (path), &ed, argv[5], flags2)) + puts ("File not found"); + else + printf ("Path: %s\n", path); + return (0); +} + +#endif diff --git a/contrib/ttf2pk/emtexdir.h b/contrib/ttf2pk/emtexdir.h new file mode 100644 index 0000000..a9a986d --- /dev/null +++ b/contrib/ttf2pk/emtexdir.h @@ -0,0 +1,57 @@ +/* emtexdir.h -- written by Eberhard Mattes, donated to the public domain */ + +#if !defined (_EMTEXDIR_H) +#define _EMTEXDIR_H + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* Flags for emtex_dir_setup */ + +#define EDS_ONESUBDIR 0x0001 +#define EDS_ALLSUBDIR 0x0002 +#define EDS_BANG 0x0004 + +/* Flags for emtex_dir_find */ + +#define EDF_CWD 0x0001 +#define EDF_FSLASH 0x0002 +#define EDF_TRACE 0x8000 + +/* Methods for emtex_dir_trunc */ + +#define EDT_5_PLUS_3 0 /* 5+3.3 */ +#define EDT_8 1 /* 8.3 */ + +/* Return values for emtex_dir_trunc */ + +#define EDT_UNCHANGED 0 /* Path name not changed */ +#define EDT_CHANGED 1 /* Path name truncated */ +#define EDT_TOOLONG 2 /* Path name too long */ +#define EDT_INVALID 3 /* Path name invalid */ + +struct emtex_dir +{ + char **list; + int used; + int alloc; +}; + +extern void (*emtex_dir_find_callback)(const char *name, int ok); + +int emtex_dir_setup (struct emtex_dir *ed, const char *env, const char *dir, + unsigned flags); + +int emtex_dir_find (char *path, size_t path_size, const struct emtex_dir *ed, + const char *fname, unsigned flags); + +int emtex_dir_trunc (char *dst, size_t dst_size, const char *src, + unsigned flags, int method); + +#if defined (__cplusplus) +} +#endif + +#endif /* !defined (_EMTEXDIR_H) */ diff --git a/contrib/ttf2pk/errormsg.c b/contrib/ttf2pk/errormsg.c new file mode 100644 index 0000000..3969b12 --- /dev/null +++ b/contrib/ttf2pk/errormsg.c @@ -0,0 +1,96 @@ +/* + * errormsg.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include /* for size_t */ +#include +#include + +#include "errormsg.h" + + +extern char progname[]; /* the origin of the error/warning message */ + + +/* + * Print error message and quit. + */ + +void +oops(const char *message, + ...) +{ + va_list args; + + + va_start(args, message); + fprintf(stderr, "%s: ERROR: ", progname); + vfprintf(stderr, message, args); + va_end(args); + putc('\n', stderr); + + exit(1); +} + + +/* + * Print error message, a buffer, a '^' at the buffer offset, and quit. + */ + +void +boops(const char *buffer, + size_t offset, + const char *message, + ...) +{ + va_list args; + + + va_start(args, message); + fprintf(stderr, "%s: ERROR: ", progname); + vfprintf(stderr, message, args); + va_end(args); + putc('\n', stderr); + + if (*buffer) + { + fprintf(stderr, "%s\n", buffer); + while (offset) + { + fprintf(stderr, " "); + offset--; + } + fprintf(stderr, "^\n"); + } + + exit(1); +} + + +/* + * Print warning message and continue. + */ + +void +warning(const char *message, + ...) +{ + va_list args; + + + va_start(args, message); + fprintf(stderr, "%s: WARNING: ", progname); + vfprintf(stderr, message, args); + va_end(args); + putc('\n', stderr); +} + + +/* end */ diff --git a/contrib/ttf2pk/errormsg.h b/contrib/ttf2pk/errormsg.h new file mode 100644 index 0000000..d069753 --- /dev/null +++ b/contrib/ttf2pk/errormsg.h @@ -0,0 +1,43 @@ +/* + * errormsg.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef ERRORMSG_H +#define ERRORMSG_H + + +/* + Disable some annoying warnings when you compile with -W3. Namely the + warnings about missing __cdecl specifiers at some places where they are + not really needed because the compiler can generate them. + + This is relevant only if you compile with -Gr option, i.e., use fastcall + calling convention. + + This is needed for fpTeX. + */ + +#ifdef WIN32 +#pragma warning (disable : 4007 4096) +#endif + + +void oops(const char *message, + ...); +void boops(const char *buffer, + size_t offset, + const char *message, + ...); +void warning(const char *message, + ...); + +#endif /* ERRORMSG_H */ + + +/* end */ diff --git a/contrib/ttf2pk/filesrch.c b/contrib/ttf2pk/filesrch.c new file mode 100644 index 0000000..0b1761f --- /dev/null +++ b/contrib/ttf2pk/filesrch.c @@ -0,0 +1,602 @@ +/* + * filesrch.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +/* + * Interface to the system specific TeX file search routines. + */ + +#include /* for size_t */ +#include +#include + +#include "filesrch.h" +#include "newobj.h" + + +/**************************** + * kpathsea library support * + ****************************/ + +#if defined(HAVE_LIBKPATHSEA) + +#ifdef VERY_OLD_KPATHSEA +#include "kpathsea/proginit.h" +#include "kpathsea/progname.h" +#include "kpathsea/tex-glyph.h" +#else +#include "kpathsea/kpathsea.h" +#endif + +#ifdef KPSEDLL +/* this is kpathsea 3.3 and newer */ +extern KPSEDLL char *kpathsea_version_string; +#else +extern DllImport char *kpathsea_version_string; +#endif + +/* + * Initialize kpathsea library; arguments are the full name of the + * executable (e.g. `/usr/bin/ttf2pk') and two identification strings; + * the former for the program itself (to have texmf.cnf constructs like + * `TFMFONTS.ttf2pk'), the latter for the environment (to have environment + * constructs like `TTF2PKMAKEPK'). + */ + +void +TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier) +{ +#ifdef OLD_KPATHSEA + kpse_set_progname(exec_name); +#else + kpse_set_program_name(exec_name, program_identifier); +#endif + +#ifdef VERY_OLD_KPATHSEA + kpse_init_prog(env_identifier, 300, "cx", true, "cmr10"); +#else + kpse_init_prog(env_identifier, 300, "cx", "cmr10"); +#endif +} + + +char * +TeX_search_version(void) +{ + return kpathsea_version_string; +} + + +char * +TeX_search_tfm(char **name) +{ + /* no extra extension handling necessary */ + + return kpse_find_file(*name, kpse_tfm_format, True); +} + + +char * +TeX_search_encoding_file(char **name) +{ + handle_extension(name, ".enc"); + +#ifdef OLD_KPATHSEA +#ifdef VERY_OLD_KPATHSEA + return kpse_find_file(*name, kpse_dvips_header_format, True); +#else + return kpse_find_file(*name, kpse_tex_ps_header_format, True); +#endif +#else + return kpse_find_file(*name, kpse_program_text_format, True); +#endif +} + + +char * +TeX_search_replacement_file(char **name) +{ + handle_extension(name, ".rpl"); + +#ifdef OLD_KPATHSEA +#ifdef VERY_OLD_KPATHSEA + return kpse_find_file(*name, kpse_dvips_header_format, True); +#else + return kpse_find_file(*name, kpse_tex_ps_header_format, True); +#endif +#else + return kpse_find_file(*name, kpse_program_text_format, True); +#endif +} + + +char * +TeX_search_sfd_file(char **name) +{ + handle_extension(name, ".sfd"); + +#ifdef OLD_KPATHSEA +#ifdef VERY_OLD_KPATHSEA + return kpse_find_file(*name, kpse_dvips_header_format, True); +#else + return kpse_find_file(*name, kpse_tex_ps_header_format, True); +#endif +#else + return kpse_find_file(*name, kpse_program_text_format, True); +#endif +} + + +char * +TeX_search_config_file(char **name) +{ + /* no extra extension handling necessary */ + +#ifdef OLD_KPATHSEA + return kpse_find_file(*name, kpse_dvips_config_format, True); +#else + return kpse_find_file(*name, kpse_program_text_format, True); +#endif +} + + +char * +TeX_search_ttf_file(char **name) +{ +#ifdef OLD_KPATHSEA + + size_t l; + char* real_name; + + + l = strlen(*name); + handle_extension(name, ".ttf"); +#ifdef VERY_OLD_KPATHSEA + real_name = kpse_find_file(*name, kpse_dvips_header_format, True); +#else + real_name = kpse_find_file(*name, kpse_type1_format, True); +#endif + + /* test for .ttc, but only if no extension was given initially */ + if (!real_name && l != strlen(*name)) + { + (*name)[strlen(*name) - 1] = 'c'; +#ifdef VERY_OLD_KPATHSEA + real_name = kpse_find_file(*name, kpse_dvips_header_format, True); +#else + real_name = kpse_find_file(*name, kpse_type1_format, True); +#endif + } + + return real_name; + +#else /* OLD_KPATHSEA */ + + /* no extra extension handling necessary */ + + return kpse_find_file(*name, kpse_truetype_format, True); + +#endif +} + + +/**************************** + * emtexdir library support * + ****************************/ + +#elif defined(HAVE_EMTEXDIR) + +#include "emtexdir.h" +#include "errormsg.h" + +extern int setup_list(struct emtex_dir *dst, char *path, + const char *list, unsigned flags); + +char emtex_version_string[] = "emTeXdir"; + +struct emtex_dir tfm_path, + enc_path, + rpl_path, + sfd_path, + cfg_path, + ttf_path; + + +/* + * We slightly modify emtex_dir_setup() to output a warning in case + * the environment variable isn't set properly. + */ + +static int +dir_setup(struct emtex_dir *ed, + const char *env, + const char *dir, + unsigned flags) +{ + const char *val; + char path[260]; + + + ed->alloc = 0; + ed->used = 0; + ed->list = NULL; + + if (env != NULL && (val = getenv(env)) != NULL) + return setup_list(ed, path, val, flags); + else + warning("Environment variable %s not set; use current directory.", env); + + return True; +} + + +static char * +file_find(char *name, struct emtex_dir *list) +{ + char buffer[1024]; + + + if (emtex_dir_find(buffer, sizeof (buffer), list, name, EDF_CWD)) + return newstring(buffer); + + return NULL; +} + + +/* + * Initialize emtexdir library; arguments are the full name of the + * executable (e.g. `c:\bin\ttf2pk.exe') and two identification strings; + * the former for the program itself, the latter for the environment. + * We ignore all of them. + */ + +void +TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier) +{ + if (!dir_setup(&tfm_path, "TEXTFM", NULL, EDS_BANG)) + oops("Cannot setup search path for tfm files"); + if (!dir_setup(&enc_path, "TTFCFG", NULL, EDS_BANG)) + oops("Cannot setup search path for encoding files"); +#if 0 + if (!dir_setup(&rpl_path, "TTFCFG", NULL, EDS_BANG)) + oops("Cannot setup search path for replacement files"); + if (!dir_setup(&sfd_path, "TTFCFG", NULL, EDS_BANG)) + oops("Cannot setup search path for subfont definition files"); + if (!dir_setup(&cfg_path, "TTFCFG", NULL, EDS_BANG)) + oops("Cannot setup search path for configuration file"); +#else + rpl_path = sfd_path = cfg_path = enc_path; +#endif + if (!dir_setup(&ttf_path, "TTFONTS", NULL, EDS_BANG)) + oops("Cannot setup search path for TrueType font files"); +} + + +char * +TeX_search_version(void) +{ + return emtex_version_string; +} + + +char * +TeX_search_tfm(char **name) +{ + handle_extension(name, ".tfm"); + return file_find(*name, &tfm_path); +} + + +char * +TeX_search_encoding_file(char **name) +{ + handle_extension(name, ".enc"); + return file_find(*name, &enc_path); +} + + +char * +TeX_search_replacement_file(char **name) +{ + handle_extension(name, ".rpl"); + return file_find(*name, &rpl_path); +} + + +char * +TeX_search_sfd_file(char **name) +{ + handle_extension(name, ".sfd"); + return file_find(*name, &sfd_path); +} + + +char * +TeX_search_config_file(char **name) +{ + /* no extra extension handling necessary */ + return file_find(*name, &cfg_path); +} + + +char * +TeX_search_ttf_file(char **name) +{ + size_t l; + char* real_name; + + + l = strlen(*name); + handle_extension(name, ".ttf"); + real_name = file_find(*name, &ttf_path); + + /* test for .ttc, but only if no extension was given initially */ + if (!real_name && l != strlen(*name)) + { + (*name)[strlen(*name) - 1] = 'c'; + real_name = file_find(*name, &ttf_path); + } + + return real_name; +} + + +/************************** + * MiKTeX library support * + **************************/ + +#elif defined(MIKTEX) + +#include "miktex.h" + +void +TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier) +{ + /* empty */ +} + + +char * +TeX_search_version(void) +{ + char buf[200]; + + + strcpy(buf, "MiKTeX "); + miktex_get_miktex_version_string_ex(buf + 7, sizeof (buf) - 7); + + return buf; +} + + +char * +TeX_search_tfm(char **name) +{ + char result[_MAX_PATH]; + + + if (!miktex_find_tfm_file(*name, result)) + return 0; + + return strdup(result); +} + + +char * +TeX_search_encoding_file(char **name) +{ + char result[_MAX_PATH]; + + + if (!miktex_find_enc_file(*name, result)) + return 0; + + return strdup(result); +} + + +char * +TeX_search_replacement_file(char **name) +{ + char result[_MAX_PATH]; + + + handle_extension(name, ".rpl"); + if (!miktex_find_input_file("ttf2tfm", *name, result)) + return 0; + + return strdup(result); +} + + +char * +TeX_search_sfd_file(char **name) +{ + char result[_MAX_PATH]; + + + handle_extension(name, ".sfd"); + if (!miktex_find_input_file("ttf2tfm", *name, result)) + return 0; + return strdup(result); +} + + +char * +TeX_search_config_file(char **name) +{ + char result[_MAX_PATH]; + + + if (!miktex_find_input_file("ttf2tfm", *name, result)) + return 0; + return strdup(result); +} + + +char * +TeX_search_ttf_file(char **name) +{ + char result[_MAX_PATH]; + + + if (!miktex_find_ttf_file(*name, result)) + return 0; + return strdup(result); +} + + +/********************** + * no library support * + **********************/ + +#else + +#include + +char version_string[] = "no search library"; + +void +TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier) +{ + /* empty */ +} + + +char * +TeX_search_version(void) +{ + return version_string; +} + + +char * +TeX_search_tfm(char **name) +{ + handle_extension(name, ".tfm"); + return *name; +} + + +char * +TeX_search_encoding_file(char **name) +{ + handle_extension(name, ".enc"); + return *name; +} + + +char * +TeX_search_replacement_file(char **name) +{ + handle_extension(name, ".rpl"); + return *name; +} + + +char * +TeX_search_sfd_file(char **name) +{ + handle_extension(name, ".sfd"); + return *name; +} + + +char * +TeX_search_config_file(char **name) +{ + /* no extra extension handling necessary */ + return *name; +} + + +/* we only handle .ttf extension */ + +char * +TeX_search_ttf_file(char **name) +{ + handle_extension(name, ".ttf"); + return *name; +} + +#endif + + + +void +get_tfm_fullname(Font *fnt) +{ + size_t len = 0; + + + if (fnt->fullname) + free(fnt->fullname); + + if (fnt->outname) + len += strlen(fnt->outname); + if (fnt->subfont_name) + len += strlen(fnt->subfont_name); + if (fnt->outname_postfix) + len += strlen(fnt->outname_postfix); + len++; + + fnt->fullname = (char *)mymalloc(len); + fnt->fullname[0] = '\0'; + + if (fnt->outname) + strcat(fnt->fullname, fnt->outname); + if (fnt->subfont_name) + strcat(fnt->fullname, fnt->subfont_name); + if (fnt->outname_postfix) + strcat(fnt->fullname, fnt->outname_postfix); +} + + +/* + * This function takes the address of a pointer to a string allocated + * with malloc() and checks whether it has an extension. If not, a default + * extension given as a second argument will be appended using first + * realloc() and then strcat(). + * + * '/', ':', and '\\' will be recognized as directory separators. + */ + +void +handle_extension(char **stringp, + char *extension) +{ + int i, lastext = -1; + + + for (i = 0; (*stringp)[i]; i++) + if ((*stringp)[i] == '.') + lastext = i; + else if ((*stringp)[i] == '/' || + (*stringp)[i] == ':' || + (*stringp)[i] == '\\') + lastext = -1; + + if (lastext == -1) + { + *stringp = (char *)myrealloc((void *)*stringp, + strlen(*stringp) + strlen(extension) + 1); + strcat(*stringp, extension); + } +} + + +/* end */ diff --git a/contrib/ttf2pk/filesrch.h b/contrib/ttf2pk/filesrch.h new file mode 100644 index 0000000..88dc2d9 --- /dev/null +++ b/contrib/ttf2pk/filesrch.h @@ -0,0 +1,51 @@ +/* + * filesrch.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef FILESRCH_H +#define FILESRCH_H + +#include "ttf2tfm.h" + +/* + * Arguments are the full program name and two identification strings + * (for the program and the environment). + */ + +void TeX_search_init(char *exec_name, + char *program_identifier, + char *env_identifier); + +/* + * The next function returns a version string. + */ + +char *TeX_search_version(void); + +/* + * The following functions take a file name (either relative or absolute), + * probably append a default extension, and return the complete path to the + * file. + */ + +char *TeX_search_tfm(char **name); +char *TeX_search_encoding_file(char **name); +char *TeX_search_replacement_file(char **name); +char *TeX_search_sfd_file(char **name); +char *TeX_search_config_file(char **name); +char *TeX_search_ttf_file(char **name); + +void get_tfm_fullname(Font *fnt); +void handle_extension(char **stringp, + char *extension); + +#endif /* FILESRCH_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ligkern.c b/contrib/ttf2pk/ligkern.c new file mode 100644 index 0000000..922ae40 --- /dev/null +++ b/contrib/ttf2pk/ligkern.c @@ -0,0 +1,275 @@ +/* + * ligkern.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include /* for size_t */ +#include + +#include "ttf2tfm.h" +#include "ligkern.h" +#include "ttfenc.h" +#include "texenc.h" +#include "newobj.h" +#include "errormsg.h" + + +static char * +paramstring(char **curp) +{ + register char *p, *q; + + + p = *curp; + while (*p && !isspace(*p)) + p++; + q = *curp; + if (*p != '\0') + *p++ = '\0'; + while (isspace(*p)) + p++; + *curp = p; + return q; +} + + +/* + * Some routines to remove kerns that match certain patterns. + */ + +static kern * +rmkernmatch(kern *k, + char *s) +{ + kern *nk; + + + while (k && strcmp(k->succ, s) == 0) + k = k->next; + + if (k) + { + for (nk = k; nk; nk = nk->next) + while (nk->next && strcmp(nk->next->succ, s) == 0) + nk->next = nk->next->next; + } + return k; +} + + +/* + * Recursive to one level. + */ + +static void +rmkern(char *s1, char *s2, + ttfinfo *ti, + Font *fnt) +{ + if (ti == NULL) + { + if (strcmp(s1, "*") == 0) + { + for (ti = fnt->charlist; ti; ti = ti->next) + rmkern(s1, s2, ti, fnt); + return; + } + else + { + ti = findadobe(s1, fnt->charlist); + if (ti == NULL) + return; + } + } + + if (strcmp(s2, "*") == 0) + ti->kerns = NULL; /* drop them on the floor */ + else + ti->kerns = rmkernmatch(ti->kerns, s2); +} + + +/* + * Make the kerning for character S1 equivalent to that for S2. + * If either S1 or S2 do not exist, do nothing. + * If S1 already has kerning, do nothing. + */ + +static void +addkern(char *s1, char *s2, + Font *fnt) +{ + ttfinfo *ti1 = findadobe(s1, fnt->charlist); + ttfinfo *ti2 = findadobe(s2, fnt->charlist); + + + if (ti1 && ti2 && !ti1->kerns) + { + /* Put the new one at the head of the list, since order is immaterial. */ + ttfptr *ap = (ttfptr *)mymalloc(sizeof (ttfptr)); + + + ap->next = ti2->kern_equivs; + ap->ch = ti1; + ti2->kern_equivs = ap; + } +} + + +/* + * Reads a ligkern line, if this is one. Assumes the first character + * passed is `%'. + */ + +void +checkligkern(char *s, Font *fnt) +{ + char *mlist[5]; + char *os; + char *orig_s, *pos; + size_t offset[5]; + int n; + + + os = newstring(s); + orig_s = s; + + s++; + while (isspace(*s)) + s++; + if (strncmp(s, "LIGKERN", 7) == 0) + { + fnt->sawligkern = True; + s += 7; + while (isspace(*s)) + s++; + pos = s; + while (*pos) + { + for (n = 0; n < 5;) + { + if (*pos == '\0') + break; + offset[n] = pos - orig_s; + mlist[n] = paramstring(&pos); + if (strcmp(mlist[n], ";") == 0) + break; + n++; + } + + if (n > 4) + boops(os, pos - orig_s, "Too many parameters in lig kern data."); + if (n < 3) + boops(os, pos - orig_s, "Too few parameters in lig kern data."); + + if (n == 3 && strcmp(mlist[1], "{}") == 0) /* rmkern command */ + rmkern(mlist[0], mlist[2], (ttfinfo *)0, fnt); + else if (n == 3 && strcmp(mlist[1], "<>") == 0) /* addkern */ + addkern(mlist[0], mlist[2], fnt); + else if (n == 3 && strcmp(mlist[0], "||") == 0 && + strcmp(mlist[1], "=") == 0) /* bc command */ + { + ttfinfo *ti = findadobe("||", fnt->charlist); + + + if (fnt->boundarychar != -1) + boops(os, offset[0], "Multiple boundary character commands?"); + if (sscanf(mlist[2], "%d", &n) != 1) + boops(os, offset[2], + "Expected number assignment for boundary char."); + if (n < 0 || n > 0xFF) + boops(os, offset[2], "Boundary character number must be 0..0xFF."); + + fnt->boundarychar = n; + if (ti == NULL) + oops("Internal error: boundary char."); + ti->outcode = n; /* prime the pump, so to speak, for lig/kerns */ + } + else if (n == 4) + { + int op = -1; + ttfinfo *ti; + + + for (n = 0; encligops[n]; n++) + if (strcmp(mlist[2], encligops[n]) == 0) + { + op = n; + break; + } + if (op < 0) + boops(os, offset[2], "Bad ligature op specified."); + + if (NULL != (ti = findadobe(mlist[0], fnt->charlist))) + { + lig *lig; + + + if (findadobe(mlist[2], fnt->charlist)) + /* remove coincident kerns */ + rmkern(mlist[0], mlist[1], ti, fnt); + + if (strcmp(mlist[3], "||") == 0) + boops(os, offset[3], "You can't lig to the boundary character!"); + + if (!fnt->fixedpitch) /* fixed pitch fonts get *0* ligs */ + { + for (lig = ti->ligs; lig; lig = lig->next) + if (strcmp(lig->succ, mlist[1]) == 0) + break; /* we'll re-use this structure */ + + if (lig == NULL) + { + lig = newlig(); + lig->succ = newstring(mlist[1]); + lig->next = ti->ligs; + ti->ligs = lig; + } + lig->sub = newstring(mlist[3]); + lig->op = op; + + if (strcmp(mlist[1], "||") == 0) + { + lig->boundleft = 1; + if (strcmp(mlist[0], "||") == 0) + boops(os, offset[0], + "You can't lig boundarychar boundarychar!"); + } + else + lig->boundleft = 0; + } + } + } + else + boops(os, offset[0], "Bad form in LIGKERN command."); + } + } + + free(os); +} + + +void +getligkerndefaults(Font *fnt) +{ + int i; + char *buffer; + + + for (i = 0; staticligkern[i]; i++) + { + buffer = newstring(staticligkern[i]); + checkligkern(buffer, fnt); + free(buffer); + } +} + + +/* end */ diff --git a/contrib/ttf2pk/ligkern.h b/contrib/ttf2pk/ligkern.h new file mode 100644 index 0000000..2b43a25 --- /dev/null +++ b/contrib/ttf2pk/ligkern.h @@ -0,0 +1,23 @@ +/* + * ligkern.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef LIGKERN_H +#define LIGKERN_H + +#include "ttf2tfm.h" + + +void checkligkern(char *s, Font *fnt); +void getligkerndefaults(Font *fnt); + +#endif /* LIGKERN_H */ + + +/* end */ diff --git a/contrib/ttf2pk/newobj.c b/contrib/ttf2pk/newobj.c new file mode 100644 index 0000000..2d87094 --- /dev/null +++ b/contrib/ttf2pk/newobj.c @@ -0,0 +1,352 @@ +/* + * newobj.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include /* for size_t */ +#include + +#include "newobj.h" +#include "ttf2tfm.h" +#include "errormsg.h" +#include "texenc.h" + + +void * +mymalloc(size_t len) +{ + void *p; + + +#ifdef SMALLMALLOC + if (len > 65500L) + oops("Cannot allocate more than 64kByte."); +#endif + + if (len) + p = malloc(len); + else + p = malloc(1); + + if (p == NULL) + oops("Out of memory."); + + return p; +} + + +void * +myrealloc(void *oldp, size_t len) +{ + void *p; + + +#ifdef SMALLMALLOC + if (len > 65500L) + oops("Cannot allocate more than 64kByte."); +#endif + + if (len) + p = realloc(oldp, len); + else + p = realloc(oldp, 1); + + if (p == NULL) + oops("Out of memory."); + + return p; +} + + +/* + * This routine gets a line from a file, supporting continuation with + * '\' as the last character on the line. + * + * In case of error, NULL is returned. If EOF is reached a pointer to + * a null string is returned. The final newline will be retained. + */ + +char * +get_line(FILE *f) +{ + size_t linelen, len; + char *buffer; + int c; + + + linelen = 80; + len = 0; + + buffer = (char *)mymalloc(linelen); + + while (1) + { + c = fgetc(f); + buffer[len++] = c; + + if (len == linelen - 1) + { + linelen += 80; + buffer = (char *)myrealloc(buffer, linelen); + } + + again: + switch (c) + { + case '\\': + c = fgetc(f); + if (c == '\n') + { + len--; + break; + } + else + { + buffer[len++] = c; + goto again; + } + case '\n': + buffer[len] = '\0'; + return buffer; + case EOF: + buffer[len - 1] = '\0'; + if (feof(f)) + return buffer; + else + return NULL; + default: + break; + } + } +} + + +/* + * getline() is a wrapper function for get_line(). It returns `False' in + * case of error and expects a pointer to a buffer to store the current + * line. Additionally, the final newline character is stripped. + */ + +Boolean +getline(char **bufferp, FILE *f) +{ + size_t l; + + + *bufferp = get_line(f); + + if (!(*bufferp && **bufferp)) + return 0; + + l = strlen(*bufferp); + if (l > 0) + (*bufferp)[l - 1] = '\0'; + + return 1; +} + + +char * +newstring(char *s) +{ + char *q; + + if (s) + { + q = mymalloc(strlen(s) + 1); + (void)strcpy(q, s); + return q; + } + else + return NULL; +} + + +ttfinfo * +newchar(Font *fnt) +{ + register ttfinfo *ti; + + + ti = (ttfinfo *)mymalloc(sizeof (ttfinfo)); + + ti->next = fnt->charlist; + + ti->charcode = -1; + ti->glyphindex = -1; + ti->incode = -1; + ti->outcode = -1; + ti->adobename = NULL; + + ti->width = -1; + ti->llx = -1; + ti->lly = -1; + ti->urx = -1; + ti->ury = -1; + + ti->ligs = NULL; + ti->kerns = NULL; + ti->kern_equivs = NULL; + ti->pccs = NULL; + + ti->constructed = False; + + ti->wptr = 0; + ti->hptr = 0; + ti->dptr = 0; + ti->iptr = 0; + + fnt->charlist = ti; + + return ti; +} + + +kern * +newkern(void) +{ + register kern *nk; + + + nk = (kern *)mymalloc(sizeof (kern)); + nk->next = NULL; + nk->succ = NULL; + nk->delta = 0; + + return nk; +} + + +pcc * +newpcc(void) +{ + register pcc *np; + + + np = (pcc *)mymalloc(sizeof (pcc)); + np->next = NULL; + np->partname = NULL; + np->xoffset = 0; + np->yoffset = 0; + + return np; +} + + +lig * +newlig(void) +{ + register lig *nl; + + + nl = (lig *)mymalloc(sizeof (lig)); + nl->next = NULL; + nl->succ = NULL; + nl->sub = NULL; + nl->op = 0; /* the default =: op */ + nl->boundleft = 0; + + return nl; +} + + +stringlist * +newstringlist(void) +{ + register stringlist *sl; + + + sl = (stringlist *)mymalloc(sizeof (stringlist)); + sl->next = NULL; + sl->old_name = NULL; + sl->new_name = NULL; + sl->single_replacement = False; + + return sl; +} + + +void +init_font_structure(Font *fnt) +{ + int i; + + + fnt->ttfname = NULL; + + fnt->tfm_path = NULL; + fnt->tfm_ext = NULL; + + fnt->outname = NULL; + fnt->subfont_name = NULL; + fnt->outname_postfix = NULL; + fnt->fullname = NULL; + + fnt->vplout = NULL; + fnt->tfmout = NULL; + + fnt->inencname = NULL; + fnt->inencoding = NULL; + + fnt->replacements = NULL; + fnt->replacementname = NULL; + + fnt->outencname = NULL; + fnt->outencoding = NULL; + + fnt->sfdname = NULL; + + fnt->sawligkern = False; + fnt->subfont_ligs = False; + + fnt->charlist = NULL; + + fnt->boundarychar = -1; + fnt->codingscheme = default_codingscheme; + fnt->titlebuf = NULL; + + fnt->units_per_em = 0; + fnt->italicangle = 0.0; + fnt->fixedpitch = 0; + + fnt->fontindex = 0; + fnt->pid = 3; + fnt->eid = 1; + + fnt->xheight = 400; + fnt->fontspace = 0; + + fnt->y_offset = 0.25; + + fnt->efactor = 1.0; + fnt->slant = 0; + fnt->capheight = 0.8; + fnt->PSnames = No; + fnt->rotate = No; + + fnt->efactorparam = NULL; + fnt->slantparam = NULL; + fnt->fontindexparam = NULL; + fnt->pidparam = NULL; + fnt->eidparam = NULL; + fnt->y_offsetparam = NULL; + + for (i = 0; i < 256; i++) + { + fnt->inencptrs[i] = NULL; + fnt->outencptrs[i] = NULL; + fnt->uppercase[i] = NULL; + fnt->lowercase[i] = NULL; + fnt->sf_code[i] = -1; + fnt->nextout[i] = -1; /* encoding chains have length 0 */ + } +} + + +/* end */ diff --git a/contrib/ttf2pk/newobj.h b/contrib/ttf2pk/newobj.h new file mode 100644 index 0000000..d238361 --- /dev/null +++ b/contrib/ttf2pk/newobj.h @@ -0,0 +1,43 @@ +/* + * newobj.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef NEWOBJ_H +#define NEWOBJ_H + +#include +#include "ttf2tfm.h" + + +#if (defined(MSDOS) && defined(__TURBOC__)) || \ + (defined(OS2) && defined(_MSC_VER)) +#define SMALLMALLOC +#endif + + +void *mymalloc(size_t len); +void *mycalloc(size_t len); +void *myrealloc(void *oldp, size_t len); + +char *get_line(FILE *f); +Boolean getline(char **bufferp, FILE *f); +char *newstring(char *s); + +ttfinfo *newchar(Font *fnt); +kern *newkern(void); +pcc *newpcc(void); +lig *newlig(void); +stringlist *newstringlist(void); + +void init_font_structure(Font *fnt); + +#endif /* NEWOBJ_H */ + + +/* end */ diff --git a/contrib/ttf2pk/parse.c b/contrib/ttf2pk/parse.c new file mode 100644 index 0000000..2426a8e --- /dev/null +++ b/contrib/ttf2pk/parse.c @@ -0,0 +1,304 @@ +/* + * parse.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include /* for size_t */ +#include +#include + +#include "ttf2tfm.h" +#include "errormsg.h" +#include "newobj.h" +#include "ligkern.h" +#include "texenc.h" +#include "parse.h" +#include "filesrch.h" + + +/* + * Here we get a token from the encoding file. We parse just as much + * PostScript as we expect to find in an encoding file. We allow + * commented lines and names like 0, .notdef, _foo_. We do not allow + * //abc. + * + * `bufferp' is a pointer to the current line; the offset of the beginning + * of the token to be parsed relative to `bufferp' will be returned in + * `offsetp'. On the first call of gettoken() `init' must be set to 1 and + * to 0 on the following calls. + * + * If `ignoreligkern' is `True', no LIGKERN data will be extracted from the + * encoding file. + * + * Don't modify `bufferp'! + * + * The memory management of `bufferp' will be done by gettoken() itself; + * nevertheless, it returns a pointer to the current token which should be + * freed after it has been used. + */ + +static char * +gettoken(char **bufferp, size_t *offsetp, FILE *f, Font *fnt, + Boolean ignoreligkern, Boolean init) +{ + char *p, *q; + char tempchar; + static char *curp; + + + if (init) + curp = NULL; + + while (1) + { + while (curp == NULL || *curp == '\0') + { + if (*bufferp) + free(*bufferp); + + if (getline(bufferp, f) == False) + oops("Premature end in encoding file."); + + curp = *bufferp; + + for (p = *bufferp; *p; p++) + if (*p == '%') + { + if (ignoreligkern == False) + checkligkern(p, fnt); + *p = '\0'; + break; + } + } + + while (isspace(*curp)) + curp++; + + *offsetp = curp - *bufferp; + + if (*curp) + { + if (*curp == '[' || *curp == ']' || + *curp == '{' || *curp == '}') + q = curp++; + else if (*curp == '/' || + *curp == '-' || *curp == '_' || *curp == '.' || + ('0' <= *curp && *curp <= '9') || + ('a' <= *curp && *curp <= 'z') || + ('A' <= *curp && *curp <= 'Z')) + { + q = curp++; + while (*curp == '-' || *curp == '_' || *curp == '.' || + ('0' <= *curp && *curp <= '9') || + ('a' <= *curp && *curp <= 'z') || + ('A' <= *curp && *curp <= 'Z')) + curp++; + } + else + q = curp; + + tempchar = *curp; + *curp = '\0'; + p = newstring(q); + *curp = tempchar; + return p; + } + } +} + + +/* + * This routine reads in an encoding file, given the name. It returns + * the final total structure. It performs a number of consistency checks. + */ + +encoding * +readencoding(char **enc, Font *fnt, Boolean ignoreligkern) +{ + char *real_encname; + FILE *enc_file; + char *p, *q, c; + char *buffer; + char numbuf[9]; + size_t offset; + int i; + long l; + encoding *e = (encoding *)mymalloc(sizeof (encoding)); + + + if (enc && *enc) + { + real_encname = TeX_search_encoding_file(enc); + if (!real_encname) + oops("Cannot find encoding file `%s'.", *enc); + + enc_file = fopen(real_encname, "rt"); + if (enc_file == NULL) + oops("Cannot open encoding file `%s'.", real_encname); + + buffer = NULL; + p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, True); + if (*p != '/' || p[1] == '\0') + boops(buffer, offset, + "First token in encoding must be literal encoding name."); + e->name = newstring(p + 1); + free(p); + + p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False); + if (strcmp(p, "[")) + boops(buffer, offset, + "Second token in encoding must be mark ([) token."); + free(p); + + for (i = 0; i < 256; i++) + { + p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False); + if (*p != '/' || p[1] == 0) + boops(buffer, offset, + "Tokens 3 to 257 in encoding must be literal names."); + + /* now we test for a generic code point resp. glyph index value */ + + c = p[2]; + if (p[1] == '.' && (c == 'c' || c == 'g') && '0' <= p[3] && p[3] <= '9') + { + l = strtol(p + 3, &q, 0); + if (*q != '\0' || l < 0 || l > 0xFFFF) + boops(buffer, offset, "Invalid encoding token."); + sprintf(numbuf, ".%c0x%x", c, (unsigned int)l); + e->vec[i] = newstring(numbuf); + } + else + e->vec[i] = newstring(p + 1); + + free(p); + } + + p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False); + if (strcmp(p, "]")) + boops(buffer, offset, + "Token 258 in encoding must be make-array (])."); + free(p); + + while (getline(&buffer, enc_file)) + { + for (p = buffer; *p; p++) + if (*p == '%') + { + if (ignoreligkern == False) + checkligkern(p, fnt); + *p = '\0'; + break; + } + } + + fclose(enc_file); + + if (ignoreligkern == False && fnt->sawligkern == False) + getligkerndefaults(fnt); + } + else + { + if (ignoreligkern == False) + { + e = &staticencoding; + getligkerndefaults(fnt); + } + else + e = NULL; + } + + return e; +} + + +/* + * We scan a glyph replacement file. + * `%' is the comment character. + */ + +void +get_replacements(Font *fnt) +{ + char *real_replacement_name; + FILE *replacement_file; + char *buffer = NULL, *oldbuffer = NULL; + char *p; + char *old_name, *new_name; + stringlist *sl; + + + if (!fnt->replacementname) + return; + + real_replacement_name = TeX_search_replacement_file(&fnt->replacementname); + if (!real_replacement_name) + oops("Cannot find replacement file `%s'.", fnt->replacementname); + + replacement_file = fopen(real_replacement_name, "rt"); + if (replacement_file == NULL) + oops("Cannot open replacement file `%s'.", real_replacement_name); + + while (getline(&buffer, replacement_file)) + { + for (p = buffer; *p; p++) + if (*p == '%') + { + *p = '\0'; + break; + } + + if (oldbuffer) + free(oldbuffer); + oldbuffer = newstring(buffer); + + p = buffer; + + while (isspace(*p)) + p++; + if (!*p) + continue; + + old_name = p; + + while (*p && !isspace(*p)) + p++; + if (*p) + *p++ = '\0'; + + while (*p && isspace(*p)) + p++; + if (!*p) + boops(oldbuffer, old_name - oldbuffer, "Replacement glyph missing."); + + new_name = p; + + while (*p && !isspace(*p)) + p++; + if (*p) + *p++ = '\0'; + + while (*p && isspace(*p)) + p++; + if (*p) + boops(oldbuffer, p - oldbuffer, "Invalid replacement syntax."); + + sl = newstringlist(); + sl->new_name = newstring(new_name); + sl->old_name = newstring(old_name); + sl->next = fnt->replacements; + fnt->replacements = sl; + } + + fclose(replacement_file); +} + + +/* end */ diff --git a/contrib/ttf2pk/parse.h b/contrib/ttf2pk/parse.h new file mode 100644 index 0000000..0816d4e --- /dev/null +++ b/contrib/ttf2pk/parse.h @@ -0,0 +1,22 @@ +/* + * parse.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef PARSE_H +#define PARSE_H + +#include "ttf2tfm.h" + +encoding *readencoding(char **enc, Font *fnt, Boolean ignoreligkern); +void get_replacements(Font *fnt); + +#endif /* PARSE_H */ + + +/* end */ diff --git a/contrib/ttf2pk/pklib.c b/contrib/ttf2pk/pklib.c new file mode 100644 index 0000000..51c4805 --- /dev/null +++ b/contrib/ttf2pk/pklib.c @@ -0,0 +1,872 @@ +/* + * pklib.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +/* + * This code has been derived from the program gsftopk. + * Here the original copyright. + */ + +/* + * Copyright (c) 1994 Paul Vojta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include +#include +#include /* for size_t */ +#include +#include +#include + +#include "newobj.h" +#include "pklib.h" +#include "errormsg.h" +#include "filesrch.h" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 256 +#endif + +#define PK_PRE (char)247 +#define PK_ID 89 +#define PK_POST (char)245 +#define PK_NOP (char)246 + +int dpi; + +FILE *pk_file; + + +/* + * Information from the .tfm file. + */ + +int tfm_lengths[12]; + +#define lh tfm_lengths[1] +#define bc tfm_lengths[2] +#define ec tfm_lengths[3] +#define nw tfm_lengths[4] + +long checksum; +long design; +byte width_index[256]; +long tfm_widths[256]; + +/* + * Information on the bitmap currently being worked on. + */ + +byte *bitmap; +int width; +int skip; +int height; +int hoff; +int voff; +int bytes_wide; +size_t bm_size; +byte *bitmap_end; +int pk_len; + +/* + * Here's the path searching stuff. First the typedefs and variables. + */ + +static char searchpath[MAXPATHLEN + 1]; + +#define HUNKSIZE (MAXPATHLEN + 2) + +struct spacenode /* used for storage of directory names */ +{ + struct spacenode *next; + char *sp_end; /* end of data for this chunk */ + char sp[HUNKSIZE]; +} firstnode; + + + +static FILE * +search_tfm(char **name) +{ + char *p; + FILE *f; + + + p = TeX_search_tfm(name); + if (p == NULL) + return NULL; + strcpy(searchpath, p); + f = fopen(searchpath, "rb"); + return f; +} + + +static long +getlong(FILE *f) +{ + unsigned long value; + + + value = (unsigned long)getc(f) << 24; + value |= (unsigned long)getc(f) << 16; + value |= (unsigned long)getc(f) << 8; + value |= (unsigned long)getc(f); + return value; +} + + +char line[82]; + + +static byte masks[] = {0, 1, 3, 7, 017, 037, 077, 0177, 0377}; + +byte flag; +int pk_dyn_f; +int pk_dyn_g; +int base; /* cost of this character if pk_dyn_f = 0 */ +int deltas[13]; /* cost of increasing pk_dyn_f from i to i+1 */ + + +/* + * Add up statistics for putting out the given shift count. + */ + +static void +tallyup(int n) +{ + int m; + + + if (n > 208) + { + ++base; + n -= 192; + for (m = 0x100; m != 0 && m < n; m <<= 4) + base += 2; + if (m != 0 && (m = (m - n) / 15) < 13) + deltas[m] += 2; + } + else if (n > 13) + ++deltas[(208 - n) / 15]; + else + --deltas[n - 1]; +} + + +/* + * Routines for storing the shift counts. + */ + +static Boolean odd = False; +static byte part; + + +static void +pk_put_nyb(int n) +{ + if (odd) + { + *bitmap_end++ = (part << 4) | n; + odd = False; + } + else + { + part = n; + odd = True; + } +} + + +static void +pk_put_long(int n) +{ + if (n >= 16) + { + pk_put_nyb(0); + pk_put_long(n / 16); + } + pk_put_nyb(n % 16); +} + + +static void +pk_put_count(int n) +{ + if (n > pk_dyn_f) + { + if (n > pk_dyn_g) + pk_put_long(n - pk_dyn_g + 15); + else + { + pk_put_nyb(pk_dyn_f + (n - pk_dyn_f + 15) / 16); + pk_put_nyb((n - pk_dyn_f - 1) % 16); + } + } + else + pk_put_nyb(n); +} + + +static void +trim_bitmap(void) +{ + byte *p; + byte mask; + + + /* clear out garbage bits in bitmap */ + + if (width % 8 != 0) + { + mask = ~masks[8 - width % 8]; + for (p = bitmap + bytes_wide - 1; p < bitmap_end; p += bytes_wide) + *p &= mask; + } + + /* Find the bounding box of the bitmap. */ + + /* trim top */ + + skip = 0; + mask = 0; + + for (;;) + { + if (bitmap >= bitmap_end) /* if bitmap is empty */ + { + width = height = hoff = voff = 0; + return; + } + + p = bitmap + bytes_wide; + while (p > bitmap) + mask |= *--p; + if (mask) + break; + ++skip; + bitmap += bytes_wide; + } + + height -= skip; + voff -= skip; + +#ifdef DEBUG + if (skip < 2 || skip > 3) + printf("Character has %d empty rows at top\n", skip); +#endif + + /* trim bottom */ + + skip = 0; + mask = 0; + + for (;;) + { + p = bitmap_end - bytes_wide; + while (p < bitmap_end) + mask |= *p++; + if (mask) + break; + ++skip; + bitmap_end -= bytes_wide; + } + + height -= skip; + +#ifdef DEBUG + if (skip < 2 || skip > 3) + printf("Character has %d empty rows at bottom\n", skip); +#endif + + /* trim right */ + + skip = 0; + --width; + + for (;;) + { + mask = 0; + for (p = bitmap + width / 8; p < bitmap_end; p += bytes_wide) + mask |= *p; + if (mask & (0x80 >> (width % 8))) + break; + + --width; + ++skip; + } + + ++width; + +#ifdef DEBUG + if (skip < 2 || skip > 3) + printf("Character has %d empty columns at right\n", skip); +#endif + + /* trim left */ + + skip = 0; + + for (;;) + { + mask = 0; + for (p = bitmap + skip / 8; p < bitmap_end; p += bytes_wide) + mask |= *p; + if (mask & (0x80 >> (skip % 8))) + break; + + ++skip; + } + + width -= skip; + hoff -= skip; + +#ifdef DEBUG + if (skip < 2 || skip > 3) + printf("Character has %d empty columns at left\n", skip); +#endif + + bitmap += skip / 8; + skip = skip % 8; +} + + +/* + * Pack the bitmap using the rll method. (Return false if it's better + * to just pack the bits.) + */ + +static Boolean +pk_rll_cvt(void) +{ + static int *counts = NULL; /* area for saving bit counts */ + static int maxcounts = 0; /* size of this area */ + unsigned int ncounts; /* max to allow this time */ + int *nextcount; /* next count value */ + + int *counts_end; /* pointer to end */ + byte *rowptr; + byte *p; + byte mask; + byte *rowdup; /* last row checked for dup */ + byte paint_switch; /* 0 or 0xff */ + int bits_left; /* bits left in row */ + int cost; + int i; + + + /* Allocate space for bit counts. */ + + ncounts = (width * height + 3) / 4; + if (ncounts > maxcounts) + { + if (counts != NULL) + free(counts); + counts = (int *)mymalloc((ncounts + 2) * sizeof (int)); + maxcounts = ncounts; + } + counts_end = counts + ncounts; + + /* Form bit counts and collect statistics */ + + base = 0; + memset(deltas, 0, sizeof (deltas)); + rowdup = NULL; /* last row checked for duplicates */ + p = rowptr = bitmap; + mask = 0x80 >> skip; + flag = 0; + paint_switch = 0; + + if (*p & mask) + { + flag = 8; + paint_switch = 0xff; + } + + bits_left = width; + nextcount = counts; + + while (rowptr < bitmap_end) /* loop over shift counts */ + { + int shift_count = bits_left; + + + for (;;) + { + if (bits_left == 0) + { + if ((p = rowptr += bytes_wide) >= bitmap_end) + break; + mask = 0x80 >> skip; + bits_left = width; + shift_count += width; + } + if (((*p ^ paint_switch) & mask) != 0) + break; + --bits_left; + mask >>= 1; + if (mask == 0) + { + ++p; + while (*p == paint_switch && bits_left >= 8) + { + ++p; + bits_left -= 8; + } + mask = 0x80; + } + } + + if (nextcount >= counts_end) + return False; + shift_count -= bits_left; + *nextcount++ = shift_count; + tallyup(shift_count); + + /* check for duplicate rows */ + if (rowptr != rowdup && bits_left != width) + { + byte *p1 = rowptr; + byte *q = rowptr + bytes_wide; + int repeat_count; + + + while (q < bitmap_end && *p1 == *q) + { + ++p1; + ++q; + } + repeat_count = (p1 - rowptr) / bytes_wide; + if (repeat_count > 0) + { + *nextcount++ = -repeat_count; + if (repeat_count == 1) + --base; + else + { + ++base; + tallyup(repeat_count); + } + rowptr += repeat_count * bytes_wide; + } + rowdup = rowptr; + } + paint_switch = ~paint_switch; + } + +#ifdef DEBUG + /* + * Dump the bitmap + */ + + for (p = bitmap; p < bitmap_end; p += bytes_wide) + { + byte *p1 = p; + int j; + + + mask = 0x80 >> skip; + for (j = 0; j < width; ++j) + { + putchar(*p1 & mask ? '@' : '.'); + if ((mask >>= 1) == 0) + { + mask = 0x80; + ++p1; + } + } + putchar('\n'); + } + putchar('\n'); +#endif + + /* Determine the best pk_dyn_f */ + + pk_dyn_f = 0; + cost = base += 2 * (nextcount - counts); + + for (i = 1; i < 14; ++i) + { + base += deltas[i - 1]; + if (base < cost) + { + pk_dyn_f = i; + cost = base; + } + } + + /* last chance to bail out */ + + if (cost * 4 > width * height) + return False; + + /* Pack the bit counts */ + + pk_dyn_g = 208 - 15 * pk_dyn_f; + flag |= pk_dyn_f << 4; + bitmap_end = bitmap; + *nextcount = 0; + nextcount = counts; + + while (*nextcount != 0) + { + if (*nextcount > 0) + pk_put_count(*nextcount); + else + if (*nextcount == -1) + pk_put_nyb(15); + else + { + pk_put_nyb(14); + pk_put_count(-*nextcount); + } + ++nextcount; + } + + if (odd) + { + pk_put_nyb(0); + ++cost; + } + + if (cost != 2 * (bitmap_end - bitmap)) + printf("Cost miscalculation: expected %d, got %ld\n", + cost, (long)(2 * (bitmap_end - bitmap))); + pk_len = bitmap_end - bitmap; + return True; +} + + +static void +pk_bm_cvt(void) +{ + byte *rowptr; + byte *p; + int blib1; /* bits left in byte */ + int bits_left; /* bits left in row */ + byte *q; + int blib2; + byte nextbyte; + + + flag = 14 << 4; + q = bitmap; + blib2 = 8; + nextbyte = 0; + + for (rowptr = bitmap; rowptr < bitmap_end; rowptr += bytes_wide) + { + p = rowptr; + blib1 = 8 - skip; + bits_left = width; + + if (blib2 != 8) + { + int n; + + + if (blib1 < blib2) + { + nextbyte |= *p << (blib2 - blib1); + n = blib1; + } + else + { + nextbyte |= *p >> (blib1 - blib2); + n = blib2; + } + blib2 -= n; + if ((bits_left -= n) < 0) + { + blib2 -= bits_left; + continue; + } + if ((blib1 -= n) == 0) + { + blib1 = 8; + ++p; + if (blib2 > 0) + { + nextbyte |= *p >> (8 - blib2); + blib1 -= blib2; + bits_left -= blib2; + if (bits_left < 0) + { + blib2 = -bits_left; + continue; + } + } + } + *q++ = nextbyte; + } + + /* fill up whole (destination) bytes */ + + while (bits_left >= 8) + { + nextbyte = *p++ << (8 - blib1); + *q++ = nextbyte | (*p >> blib1); + bits_left -= 8; + } + + /* now do the remainder */ + + nextbyte = *p << (8 - blib1); + if (bits_left > blib1) + nextbyte |= p[1] >> blib1; + blib2 = 8 - bits_left; + } + + if (blib2 != 8) + *q++ = nextbyte; + + pk_len = q - bitmap; +} + + +static void +putshort(short w) +{ + putc(w >> 8, pk_file); + putc(w, pk_file); +} + + +static void +putmed(long w) +{ + putc(w >> 16, pk_file); + putc(w >> 8, pk_file); + putc(w, pk_file); +} + + +static void +putlong(long w) +{ + putc(w >> 24, pk_file); + putc(w >> 16, pk_file); + putc(w >> 8, pk_file); + putc(w, pk_file); +} + + +char +xgetc(FILE *f) +{ + int c; + + + c = getc(f); + if (c == EOF) + oops("Premature end of file."); + return (byte)c; +} + + +/* + * Open and read the tfm file. + */ + +void +TFMopen(char **filename) +{ + FILE *tfm_file; + int i; + int cc; + + + tfm_file = search_tfm(filename); + if (tfm_file == NULL) + oops("Cannot find tfm file."); + + for (i = 0; i < 12; i++) + { + int j; + + + j = (int)((byte)getc(tfm_file)) << 8; + tfm_lengths[i] = j | (int)((byte)xgetc(tfm_file)); + } + + checksum = getlong(tfm_file); + design = getlong(tfm_file); + fseek(tfm_file, 4 * (lh + 6), 0); + + for (cc = bc; cc <= ec; ++cc) + { + width_index[cc] = (byte)xgetc(tfm_file); + + (void)xgetc(tfm_file); + (void)xgetc(tfm_file); + (void)xgetc(tfm_file); + } + + for (i = 0; i < nw; ++i) + tfm_widths[i] = getlong(tfm_file); + + fclose(tfm_file); +} + + +/* + * Create pk file and write preamble. + */ + +void +PKopen(char *filename, + char *ident, + int resolution) +{ + int ppp; + int i; + + + dpi = resolution; + + if ((pk_file = fopen(filename, "wb")) == NULL) + { + perror(filename); + exit(1); + } + + putc(PK_PRE, pk_file); + putc(PK_ID, pk_file); + + i = strlen(ident); + + putc(i, pk_file); + fwrite(ident, 1, i, pk_file); + putlong(design); + putlong(checksum); + ppp = dpi / 72.27 * 65536.0 + 0.5; + putlong(ppp); /* hppp */ + putlong(ppp); /* vppp */ +} + + +void +PKputglyph(int cc, + int llx, int lly, int urx, int ury, + int w, int h, + byte *b) +{ + float char_width; + + long dm; + long tfm_wid; + + + bitmap = b; + width = w; + height = h; + + hoff = -llx; + voff = ury - 2; /* Don't ask me why `-2' */ + /* Fred */ + + if (width != urx - llx || height != ury - lly) + oops("Dimensions do not match: (%d - %d) (%d - %d) <=> %d %d", + llx, lly, urx, ury, width, height); + + bytes_wide = (width + 7) / 8; + bm_size = bytes_wide * height; + bitmap_end = bitmap + bm_size; + + trim_bitmap(); + + if (height == 0 || !pk_rll_cvt()) + pk_bm_cvt(); + + if (!width_index[cc]) + return; + + tfm_wid = tfm_widths[width_index[cc]]; + char_width = tfm_wid / 1048576.0 * design / 1048576.0 * dpi / 72.27; + dm = (long)(char_width + 0.5) - (char_width < -0.5); + + if (pk_len + 8 < 4 * 256 && tfm_wid < (1<<24) && + dm >= 0 && dm < 256 && width < 256 && height < 256 && + hoff >= -128 && hoff < 128 && voff >= -128 && voff < 128) + { + putc(flag | ((pk_len + 8) >> 8), pk_file); + putc(pk_len + 8, pk_file); + putc(cc, pk_file); + putmed(tfm_wid); + putc(dm, pk_file); + putc(width, pk_file); + putc(height, pk_file); + putc(hoff, pk_file); + putc(voff, pk_file); + } + else if (pk_len + 13 < 3 * 65536L && tfm_wid < (1<<24) && + dm >= 0 && dm < 65536L && width < 65536L && height < 65536L && + hoff >= -65536L && hoff < 65536L && + voff >= -65536L && voff < 65536L) + { + putc(flag | 4 | ((pk_len + 13) >> 16), pk_file); + putshort(pk_len + 13); + putc(cc, pk_file); + putmed(tfm_wid); + putshort(dm); + putshort(width); + putshort(height); + putshort(hoff); + putshort(voff); + } + else + { + putc(flag | 7, pk_file); + putlong(pk_len + 28); + putlong(cc); + putlong(tfm_wid); + putlong((long)(char_width * 65536.0 + 0.5) - (char_width < -0.5)); + putlong(0); + putlong(width); + putlong(height); + putlong(hoff); + putlong(voff); + } + fwrite(bitmap, 1, pk_len, pk_file); +} + + +void +PKclose(void) +{ + putc(PK_POST, pk_file); + while (ftell(pk_file) % 4 != 0) + putc(PK_NOP, pk_file); + + fclose(pk_file); +} + + +/* end */ diff --git a/contrib/ttf2pk/pklib.h b/contrib/ttf2pk/pklib.h new file mode 100644 index 0000000..5283603 --- /dev/null +++ b/contrib/ttf2pk/pklib.h @@ -0,0 +1,29 @@ +/* + * pklib.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef PKLIB_H +#define PKLIB_H + +typedef unsigned char byte; + + +void TFMopen(char **filename); + +void PKopen(char *filename, char *ident, int resolution); + +void PKputglyph(int cc, int llx, int lly, int urx, int ury, + int w, int h, byte *b); + +void PKclose(void); + +#endif /* PKLIB_H */ + + +/* end */ diff --git a/contrib/ttf2pk/scripts/README b/contrib/ttf2pk/scripts/README new file mode 100644 index 0000000..aa0f73d --- /dev/null +++ b/contrib/ttf2pk/scripts/README @@ -0,0 +1,8 @@ +In these subdirectories you can find diff files for various TeX +implementations which add support for on-the-fly pk-generation using ttf2pk +and hbf2gf (which is part of the CJK package for LaTeX 2e). + +In case you don't have/want hbf2gf, simply comment out the relevant if-Block +in the script. + +For web2c 7.3 resp. teTeX 1.0 or newer, no patches are needed. diff --git a/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK.diff b/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK.diff new file mode 100644 index 0000000..bc05c4b --- /dev/null +++ b/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK.diff @@ -0,0 +1,63 @@ +--- /root/scripts/teTeX-0.4/MakeTeXPK Sun Feb 23 22:12:05 1997 ++++ /home/ft/freetype/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK Sat Sep 5 07:57:34 1998 +@@ -80,6 +80,9 @@ + : ${MAKETEXDIR=$TEXMF/maketex} + export TEXMF MAKETEXDIR + ++unset cmd ++unset psline ++ + # grep for the font in $PSMAPFILE, if some ps-to-pk is claimed to be supported. + # We have to figure out the name of the base font -- $NAME is probably + # something like pplr, but it's rpplr or pplr0 or pplr8r that's in psfonts.map. +@@ -91,7 +94,40 @@ + # some installations have set up gs in such a way that creating files + # is only allowed if the parameter -DNOSAFER is used: + GS_OPTIONS=-DNOSAFER; export GS_OPTIONS +-else ++fi ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ MODE=ttf2pk # preferred mode for TDS would be `modeless' ++ cmd=true ++ psline=ttf2pk # suppress gftopk call ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ MODE=hbf2gf # preferred mode for TDS would be `modeless' ++ cmd=true ++ fi ++fi ++ ++if test -z "$cmd"; then + # If an explicit mode is not supplied, try to guess. You can get a + # list of extant modes from ftp.cs.umb.edu:pub/tex/modes.mf. + if test -z "$MODE" || test "$MODE" = default; then +@@ -141,7 +177,7 @@ + { echo "$progname: could not mkdir $PKDESTDIR."; exit 1; }' + eval "$mdir" + +-echo "$progname: Running $cmd" ++test "$cmd" = true || echo "$progname: Running $cmd" + $cmd &2; exit 1; } + if test -z "$psline"; then + test -r $GFNAME || diff --git a/contrib/ttf2pk/scripts/web2c-6.1/MakeTeXPK.diff b/contrib/ttf2pk/scripts/web2c-6.1/MakeTeXPK.diff new file mode 100644 index 0000000..0536dbc --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-6.1/MakeTeXPK.diff @@ -0,0 +1,75 @@ +--- MakeTeXPK.orig Sun Aug 16 08:05:07 1998 ++++ MakeTeXPK Tue Aug 18 07:53:57 1998 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# original MakeTeXPK -- make a new PK font, because one wasn't found. ++# MakeTeXPK -- make a new PK font, because one wasn't found. + # Version of 12dec94. + # + # (If you change or delete the word `original' on the previous line, +@@ -142,11 +142,52 @@ + test -d $TEMPDIR || mkdir $TEMPDIR + cd $TEMPDIR || exit 1 + ++unset cmd ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ test -z "$6" && DESTDIR="$DESTROOT/ttf2pk" # preferred mode for TDS ++ # would be `modeless' ++ echo "Successful call to ttf2pk" >&2 ++ cmd=ttf2pk ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ test -z "$6" && DESTDIR="$DESTROOT/hbf2gf" # preferred mode for TDS ++ # would be `modeless' ++ echo "Successful call to hbf2gf" >&2 ++ cmd=hbf2gf ++ ++ gftopk ./$GFNAME $PKNAME || exit 1 ++ fi ++fi ++ + # grep for the font in $PSMAPFILE, if some ps-to-pk is claimed to be supported. + # We have to figure out the name of the base font -- $NAME is probably + # something like pplr, but it's rpplr or pplr0 or pplr8r that's in psfonts.map. +-pattern="^r?$NAME"'(0|8r)?([ ]|$)' +-test -n "$ps_to_pk" && egrep "$pattern" $PSMAPFILE >psline ++if test -z "$cmd"; then ++ pattern="^r?$NAME"'(0|8r)?([ ]|$)' ++ test -n "$ps_to_pk" && egrep "$pattern" $PSMAPFILE > psline ++fi ++ + if test -s psline; then + # This is a PostScript font. + MODE=$ps_to_pk +@@ -173,8 +214,9 @@ + export DVIPSHEADERS + echo "$0: Running $cmd" >&2 + $cmd >&2 || { echo "$0: $ps_to_pk failed." >&2; exit 1; } ++fi + +-else ++if test -z "$cmd"; then + # Try Metafont. + MFINPUTS="$MFINPUTS:$SAVEPWD" + export MFINPUTS diff --git a/contrib/ttf2pk/scripts/web2c-6.1/README b/contrib/ttf2pk/scripts/web2c-6.1/README new file mode 100644 index 0000000..eb12bec --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-6.1/README @@ -0,0 +1 @@ +This is for web2c-6.1 with the patch for kpathsea 2.6 diff --git a/contrib/ttf2pk/scripts/web2c-7.0/MakeTeXPK.diff b/contrib/ttf2pk/scripts/web2c-7.0/MakeTeXPK.diff new file mode 100644 index 0000000..23f7cb5 --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-7.0/MakeTeXPK.diff @@ -0,0 +1,67 @@ +--- MakeTeXPK.orig Sat Feb 8 15:52:00 1997 ++++ MakeTeXPK Tue Aug 18 07:58:22 1998 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# original MakeTeXPK -- make a new PK font, because one wasn't found. ++# MakeTeXPK -- make a new PK font, because one wasn't found. + # + # (If you change or delete the word `original' on the previous line, + # installation won't write this script over yours.) +@@ -44,15 +44,54 @@ + MODE=$5 + DEST=$6 + ++unset cmd ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++unset psline ++ + # grep for the font in $PSMAPFILE. These are base font names, such as + # rpplr (the original) or pplr0 (an interim step) or pplr8r (current). +-pattern="^r?$NAME"'(0|8r)?([ ]|$)' +-psline=`egrep "$pattern" $PSMAPFILE` ++if test -z "$cmd"; then ++ pattern="^r?$NAME"'(0|8r)?([ ]|$)' ++ psline=`egrep "$pattern" $PSMAPFILE` ++fi ++ + if test -n "$psline"; then + MODE=modeless + # ps_to_pk set in MakeTeXcommon and/or MakeTeX.site. + cmd="$ps_to_pk $NAME $DPI" +-else ++fi ++ ++if test -z "$cmd"; then + # Check that $BDPI and $MODE are consistent; if not, ignore the mode and + # hope we can correctly guess it from bdpi. (People like to specify the + # resolution on the command line, not the mode so much.) diff --git a/contrib/ttf2pk/scripts/web2c-7.1/MakeTeXPK.diff b/contrib/ttf2pk/scripts/web2c-7.1/MakeTeXPK.diff new file mode 100644 index 0000000..3ca0221 --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-7.1/MakeTeXPK.diff @@ -0,0 +1,72 @@ +--- MakeTeXPK.orig Fri Oct 31 09:30:54 1997 ++++ MakeTeXPK Tue Aug 18 08:01:33 1998 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# original MakeTeXPK -- make a new PK font, because one wasn't found. ++# MakeTeXPK -- make a new PK font, because one wasn't found. + # + # (If you change or delete the word `original' on the previous line, + # installation won't write this script over yours.) +@@ -57,11 +57,48 @@ + MODE=$5 + DEST=$6 + ++unset cmd ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++unset psline ++ + # grep for the font in $PSMAPFILE. These are base font names, such as + # rpplr (the original) or pplr0 (an interim step) or pplr8r (current). +-: ${PSMAPFILE=`kpsewhich psfonts.map`} +-pattern="^$NAME"'([ ]|$)' +-psline=`egrep "$pattern" $PSMAPFILE` ++if test -z "$cmd"; then ++ : ${PSMAPFILE=`kpsewhich psfonts.map`} ++ pattern="^$NAME"'([ ]|$)' ++ psline=`egrep "$pattern" $PSMAPFILE` ++fi ++ + if test -n "$psline"; then + MODE=modeless + # ps_to_pk is set in MakeTeX.cnf +@@ -100,7 +137,9 @@ + cmd="$ps_to_pk $NAME $DPI" + ;; + esac +-else ++fi ++ ++if test -z "$cmd"; then + # Check that $BDPI and $MODE are consistent; if not, ignore the mode and + # hope we can correctly guess it from bdpi. (People like to specify the + # resolution on the command line, not the mode so much.) diff --git a/contrib/ttf2pk/scripts/web2c-7.1/README b/contrib/ttf2pk/scripts/web2c-7.1/README new file mode 100644 index 0000000..ae64fa7 --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-7.1/README @@ -0,0 +1 @@ +The patch works with web2c-7.0 too (expect a fuzz offset). diff --git a/contrib/ttf2pk/scripts/web2c-7.2/mktexpk.diff b/contrib/ttf2pk/scripts/web2c-7.2/mktexpk.diff new file mode 100644 index 0000000..bc215d0 --- /dev/null +++ b/contrib/ttf2pk/scripts/web2c-7.2/mktexpk.diff @@ -0,0 +1,72 @@ +--- mktexpk.orig Fri Feb 20 16:23:22 1998 ++++ mktexpk Tue Aug 18 08:04:40 1998 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# original mktexpk -- make a new PK font, because one wasn't found. ++# mktexpk -- make a new PK font, because one wasn't found. + # + # (If you change or delete the word `original' on the previous line, + # installation won't write this script over yours.) +@@ -73,11 +73,48 @@ + + NAME=$1 + ++unset cmd ++ ++# test for TTF fonts ++if test -z "$cmd"; then ++ ttf2pk -q $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "ttf2pk failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++# test for HBF fonts ++if test -z "$cmd"; then ++ hbf2gf -q -p $NAME $DPI ++ errstatus=$? ++ ++ if test $errstatus -ne 2; then ++ if test $errstatus -ne 0; then ++ echo "hbf2gf failed" >&2 ++ exit 1 ++ fi ++ MODE=modeless ++ cmd=true ++ fi ++fi ++ ++unset psline ++ + # grep for the font in $PSMAPFILE. These are base font names, such as + # rpplr (the original) or pplr0 (an interim step) or pplr8r (current). +-: ${PSMAPFILE=`kpsewhich psfonts.map`} +-pattern="^$NAME"'([ ]|$)' +-psline=`egrep "$pattern" $PSMAPFILE` ++if test -z "$cmd"; then ++ : ${PSMAPFILE=`kpsewhich psfonts.map`} ++ pattern="^$NAME"'([ ]|$)' ++ psline=`egrep "$pattern" $PSMAPFILE` ++fi ++ + if test -n "$psline"; then + MODE=modeless + # ps_to_pk is set in mktex.opt +@@ -116,7 +153,9 @@ + cmd="$ps_to_pk $NAME $DPI" + ;; + esac +-else ++fi ++ ++if test -z "$cmd"; then + # Check that $BDPI and $MODE are consistent; if not, ignore the mode and + # hope we can correctly guess it from bdpi. (People like to specify the + # resolution on the command line, not the mode so much.) diff --git a/contrib/ttf2pk/subfont.c b/contrib/ttf2pk/subfont.c new file mode 100644 index 0000000..0380773 --- /dev/null +++ b/contrib/ttf2pk/subfont.c @@ -0,0 +1,264 @@ +/* + * subfont.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include /* for size_t */ +#include +#include + +#include "filesrch.h" +#include "subfont.h" +#include "newobj.h" +#include "errormsg.h" + + +static char *real_sfd_name; +static FILE *sfd; + + +/* + * Initialize subfont functionality. The argument is the subfont + * definition file name. If `fatal' is `True', the routine exits + * with an error. If `fatal' is `False', a warning message is emitted + * and `False' returned if an error occurs; in case of success `True' + * will be returned. + */ + +Boolean +init_sfd(Font *fnt, Boolean fatal) +{ + real_sfd_name = TeX_search_sfd_file(&(fnt->sfdname)); + if (!real_sfd_name) + { + if (fatal) + oops("Cannot find subfont definition file `%s'.", fnt->sfdname); + else + { + warning("Cannot find subfont definition file `%s'.", fnt->sfdname); + return False; + } + } + + sfd = fopen(real_sfd_name, "rt"); + if (sfd == NULL) + { + if (fatal) + oops("Cannot open subfont definition file `%s'.", fnt->sfdname); + else + { + warning("Cannot open subfont definition file `%s'.", fnt->sfdname); + return False; + } + } + + return True; +} + + +/* + * This function fills the font structure sequentially with subfont + * entries; it returns `False' if no more subfont entries are available, + * `True' otherwise. + * + * fnt->subfont_name must be set to NULL before the first call. + * + * The subset parser was inspired by ttf2bdf.c . + */ + +Boolean +get_sfd(Font *fnt) +{ + long i, offset; + long begin, end = -1; + char *buffer, *oldbuffer, *bufp, *bufp2, *bufp3; + + + for (i = 0; i < 256; i++) + fnt->sf_code[i] = -1; + +again: + + buffer = get_line(sfd); + if (!buffer) + oops("Error reading subfont definition file `%s'.", real_sfd_name); + if (!*buffer) + return False; + + oldbuffer = newstring(buffer); + bufp = buffer; + offset = 0; + + while (*bufp) /* remove comment */ + { + if (*bufp == '#') + { + bufp++; + break; + } + bufp++; + } + *(--bufp) = '\0'; /* remove final newline character */ + + bufp = buffer; + + while (isspace(*bufp)) + bufp++; + + if (*bufp == '\0') /* empty line? */ + { + free(buffer); + free(oldbuffer); + goto again; + } + + while (*bufp && !isspace(*bufp)) /* subfont name */ + bufp++; + *(bufp++) = '\0'; + + while (isspace(*bufp)) + bufp++; + + if (*bufp == '\0') + oops("Invalid subfont entry in `%s'.", real_sfd_name); + + if (fnt->subfont_name) + free(fnt->subfont_name); + fnt->subfont_name = newstring(buffer); + + while (1) + { + bufp3 = bufp; + + begin = strtol(bufp, &bufp2, 0); + + if (bufp == bufp2 || begin < 0 || begin > 0xFFFF) + boops(oldbuffer, bufp - buffer, + "Invalid subfont range or offset entry."); + + if (*bufp2 == ':') /* offset */ + { + offset = begin; + if (offset > 0xFF) + boops(oldbuffer, bufp - buffer, "Invalid subfont offset."); + + bufp = bufp2 + 1; + + while (isspace(*bufp)) + bufp++; + + continue; + } + else if (*bufp2 == '_') /* range */ + { + bufp = bufp2 + 1; + if (!isdigit(*bufp)) + boops(oldbuffer, bufp - buffer, "Invalid subfont range entry."); + + end = strtol(bufp, &bufp2, 0); + + if (bufp == bufp2 || end < 0 || end > 0xFFFFL) + boops(oldbuffer, bufp - buffer, "Invalid subfont range entry."); + if (*bufp2 && !isspace(*bufp2)) + boops(oldbuffer, bufp2 - buffer, "Invalid subfont range entry."); + if (end < begin) + boops(oldbuffer, bufp - buffer, "End of subfont range too small."); + if (offset + (end - begin) > 255) + boops(oldbuffer, bufp3 - buffer, + "Subfont range too large for current offset (%i).", offset); + } + else if (isspace(*bufp2) || !*bufp2) /* single value */ + end = begin; + else + boops(oldbuffer, bufp2 - buffer, "Invalid subfont range entry."); + + for (i = begin; i <= end; i++) + { + if (fnt->sf_code[offset] != -1) + boops(oldbuffer, bufp3 - buffer, "Overlapping subfont ranges."); + + fnt->sf_code[offset++] = i; + } + + bufp = bufp2; + + while (isspace(*bufp)) + bufp++; + + if (!*bufp) + break; + } + + free(buffer); + free(oldbuffer); + + return True; +} + + +void +close_sfd(void) +{ + if (sfd) + fclose(sfd); +} + + +/* + * We extract the subfont definition file name. The name must + * be embedded between two `@' characters. If there is no sfd file, + * `sfd_begin' is set to -1. + * + * The `@' characters will be replaced with null characters. + */ + +void +handle_sfd(char *s, int *sfd_begin, int *postfix_begin) +{ + size_t len; + int i; + Boolean have_atsign; + + + have_atsign = False; + len = strlen(s); + *sfd_begin = -1; + *postfix_begin = -1; + + for (i = 0; s[i]; i++) + { + if (s[i] == '@') + { + if (have_atsign) + { + *postfix_begin = i + 1; + + s[i] = '\0'; + break; + } + have_atsign = True; + *sfd_begin = i + 1; + + s[i] = '\0'; + } + } + + if (*sfd_begin != -1 && + (*postfix_begin == -1 || *postfix_begin < *sfd_begin + 2)) + oops("Invalid subfont definition file name."); + + if (*postfix_begin > -1) + for (i = *postfix_begin; s[i]; i++) + if (s[i] == '/' || s[i] == ':' || s[i] == '\\' || s[i] == '@') + oops("`/', `:', `\\', and `@' not allowed after second `@'."); +} + + +/* end */ diff --git a/contrib/ttf2pk/subfont.h b/contrib/ttf2pk/subfont.h new file mode 100644 index 0000000..db1948c --- /dev/null +++ b/contrib/ttf2pk/subfont.h @@ -0,0 +1,26 @@ +/* + * subfont.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef SUBFONT_H +#define SUBFONT_H + +#include "ttf2tfm.h" + + +Boolean init_sfd(Font *fnt, Boolean fatal); +Boolean get_sfd(Font *fnt); +void close_sfd(void); + +void handle_sfd(char *s, int *sfd_begin, int *postfix_begin); + +#endif /* SUBFONT_H */ + + +/* end */ diff --git a/contrib/ttf2pk/texenc.c b/contrib/ttf2pk/texenc.c new file mode 100644 index 0000000..aa09657 --- /dev/null +++ b/contrib/ttf2pk/texenc.c @@ -0,0 +1,203 @@ +/* + * texenc.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include /* for definition of NULL */ + +#include "ttf2tfm.h" +#include "texenc.h" + + +encoding staticencoding = +{ + "TeX text", + {"Gamma", "Delta", "Theta", "Lambda", + "Xi", "Pi", "Sigma", "Upsilon", + "Phi", "Psi", "Omega", "arrowup", + "arrowdown", "quotesingle", "exclamdown", "questiondown", + + "dotlessi", "dotlessj", "grave", "acute", + "caron", "breve", "macron", "ring", + "cedilla", "germandbls", "ae", "oe", + "oslash", "AE", "OE", "Oslash", + + "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quoteright", + "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", "circumflex", "underscore", + + "quoteleft", "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", "tilde", "dieresis", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", + } +}; + + +/* + * It's easier to put this in static storage and parse it as we go + * than to build the structures ourselves. + * + * The semicolons in the LIGKERN lines must be left isolated. + */ + +char *staticligkern[] = +{ + "% LIGKERN space l =: lslash ; space L =: Lslash ;", + "% LIGKERN question quoteleft =: questiondown ;", + "% LIGKERN exclam quoteleft =: exclamdown ;", + "% LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ;", + "% LIGKERN quoteleft quoteleft =: quotedblleft ;", + "% LIGKERN quoteright quoteright =: quotedblright ;", + "% LIGKERN space {} * ; * {} space ; zero {} * ; * {} zero ;", + "% LIGKERN one {} * ; * {} one ; two {} * ; * {} two ;", + "% LIGKERN three {} * ; * {} three ; four {} * ; * {} four ;", + "% LIGKERN five {} * ; * {} five ; six {} * ; * {} six ;", + "% LIGKERN seven {} * ; * {} seven ; eight {} * ; * {} eight ;", + "% LIGKERN nine {} * ; * {} nine ;", + + /* + * Kern accented characters the same way as their base. + */ + + "% LIGKERN Aacute <> A ; aacute <> a ;", + "% LIGKERN Acircumflex <> A ; acircumflex <> a ;", + "% LIGKERN Adieresis <> A ; adieresis <> a ;", + "% LIGKERN Agrave <> A ; agrave <> a ;", + "% LIGKERN Aring <> A ; aring <> a ;", + "% LIGKERN Atilde <> A ; atilde <> a ;", + "% LIGKERN Ccedilla <> C ; ccedilla <> c ;", + "% LIGKERN Eacute <> E ; eacute <> e ;", + "% LIGKERN Ecircumflex <> E ; ecircumflex <> e ;", + "% LIGKERN Edieresis <> E ; edieresis <> e ;", + "% LIGKERN Egrave <> E ; egrave <> e ;", + "% LIGKERN Iacute <> I ; iacute <> i ;", + "% LIGKERN Icircumflex <> I ; icircumflex <> i ;", + "% LIGKERN Idieresis <> I ; idieresis <> i ;", + "% LIGKERN Igrave <> I ; igrave <> i ;", + "% LIGKERN Ntilde <> N ; ntilde <> n ;", + "% LIGKERN Oacute <> O ; oacute <> o ;", + "% LIGKERN Ocircumflex <> O ; ocircumflex <> o ;", + "% LIGKERN Odieresis <> O ; odieresis <> o ;", + "% LIGKERN Ograve <> O ; ograve <> o ;", + "% LIGKERN Oslash <> O ; oslash <> o ;", + "% LIGKERN Otilde <> O ; otilde <> o ;", + "% LIGKERN Scaron <> S ; scaron <> s ;", + "% LIGKERN Uacute <> U ; uacute <> u ;", + "% LIGKERN Ucircumflex <> U ; ucircumflex <> u ;", + "% LIGKERN Udieresis <> U ; udieresis <> u ;", + "% LIGKERN Ugrave <> U ; ugrave <> u ;", + "% LIGKERN Yacute <> Y ; yacute <> y ;", + "% LIGKERN Ydieresis <> Y ; ydieresis <> y ;", + "% LIGKERN Zcaron <> Z ; zcaron <> z ;", + + /* lig commands for default ligatures */ + + "% LIGKERN f i =: fi ; f l =: fl ; f f =: ff ; ff i =: ffi ;", + "% LIGKERN ff l =: ffl ;", + NULL +}; + +/* + * The above layout corresponds to TeX Typewriter Type and is compatible + * with TeX Text because the position of ligatures is immaterial. + */ + + +/* + * These are the eight ligature ops, in VPL terms and in METAFONT terms. + */ + +char *vplligops[] = +{ + "LIG", "/LIG", "/LIG>", "LIG/", "LIG/>", "/LIG/", "/LIG/>", "/LIG/>>", 0 +}; + +char *encligops[] = +{ + "=:", "|=:", "|=:>", "=:|", "=:|>", "|=:|", "|=:|>", "|=:|>>", 0 +}; + + +/* + * For TeX we want to compute a character height that works properly + * with accents. The following list of accents doesn't need to be + * complete. + */ + +/* + * We only do this if the xheight has a reasonable value (>50). + */ + +char *accents[] = {"acute", "tilde", "caron", "dieresis", NULL}; + +char default_codingscheme[] = "Unspecified"; + + +/* end */ diff --git a/contrib/ttf2pk/texenc.h b/contrib/ttf2pk/texenc.h new file mode 100644 index 0000000..4df8339 --- /dev/null +++ b/contrib/ttf2pk/texenc.h @@ -0,0 +1,28 @@ +/* + * texenc.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TEXENC_H +#define TEXENC_H + +#include "ttf2tfm.h" + + +extern encoding staticencoding; +extern char *staticligkern[]; +extern char *vplligops[]; +extern char *encligops[]; +extern char *accents[]; + +extern char default_codingscheme[]; + +#endif /* TEXENC_H */ + + +/* end */ diff --git a/contrib/ttf2pk/tfmaux.c b/contrib/ttf2pk/tfmaux.c new file mode 100644 index 0000000..4befc95 --- /dev/null +++ b/contrib/ttf2pk/tfmaux.c @@ -0,0 +1,579 @@ +/* + * tfmaux.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include +#include + +#include "ttf2tfm.h" +#include "newobj.h" +#include "tfmaux.h" +#include "errormsg.h" + + +#undef PI +#define PI 3.14159265358979323846264338327 + + +struct sf /* we need this for subfont ligatures */ +{ + long sf_code; + int position; +}; + + +static long nextd; /* smallest value that will give a different mincover */ + + +static int lf, lh, nw, nh, nd, ni, nl, nk, ne, np; +static int bc, ec; + +static long *header, *charinfo, + *width, *height, *depth, + *ligkern, *kerns, *tparam, + *italic; + + +static int source[257]; /* utility variables for sorting tfm arrays */ +static int unsort[257]; + + +/* + * A simple function for sorting sf_array (in inverse order) + */ + +static int +compare_sf(const void *a, const void *b) +{ + return (int)(((struct sf *)b)->sf_code - ((struct sf *)a)->sf_code); +} + + +/* + * The next routine simply scales something. + * Input is in TFM units per em. Output is in FIXFACTORths of units + * per em. We use 1 em = 1000 TFM units. + */ + +static long +scale(long what) +{ + return ((what / 1000) * FIXFACTOR) + + (((what % 1000) * FIXFACTOR) + 500) / 1000; +} + + +/* + * Next we need a routine to reduce the number of distinct dimensions + * in a TFM file. Given an array what[0]..what[oldn-1], we want to + * group its elements into newn clusters, in such a way that the maximum + * difference between elements of a cluster is as small as possible. + * Furthermore, what[0]=0, and this value must remain in a cluster by + * itself. Data such as `0 4 6 7 9' with newn=3 shows that an iterative + * scheme in which 6 is first clustered with 7 will not work. So we + * borrow a neat algorithm from METAFONT to find the true optimum. + * Memory location what[oldn] is set to 0x7FFFFFFFL for convenience. + */ + + +/* + * Tells how many clusters result, given max difference d. + */ + +static int +mincover(long *what, + register long d) +{ + register int m; + register long l; + register long *p; + + + nextd = 0x7FFFFFFFL; + p = what+1; + m = 1; + + while (*p < 0x7FFFFFFFL) + { + m++; + l = *p; + while (*++p <= l + d) + ; + if (*p - l < nextd) + nextd = *p - l; + } + return m; +} + + +static void +remap(long *what, + int oldn, + int newn, + int *source, + int *unsort) +{ + register int i, j; + register long d, l; + + what[oldn] = 0x7FFFFFFFL; + for (i = oldn-1; i > 0; i--) + { + d = what[i]; + for (j = i; what[j+1] < d; j++) + { + what[j] = what[j+1]; + source[j] = source[j+1]; + } + what[j] = d; + source[j] = i; + } + + i = mincover(what, 0L); + d = nextd; + while (mincover(what, d + d) > newn) + d += d; + while (mincover(what, d) > newn) + d = nextd; + + i = 1; + j = 0; + while (i < oldn) + { + j++; + l = what[i]; + unsort[source[i]] = j; + while (what[++i] <= l + d) + { + unsort[source[i]] = j; + if (i - j == oldn - newn) + d = 0; + } + what[j] = (l + what[i-1])/2; + } +} + + +void +write16(register short what, + register FILE *out) +{ + (void)fputc(what >> 8, out); + (void)fputc(what & 0xFF, out); +} + + +void +writearr(register long *p, + register int n, + register FILE *out) +{ + while (n) + { + write16((short)(*p >> 16), out); + write16((short)(*p & 65535), out); + p++; + n--; + } +} + + +void +writesarr(long *what, + int len, + FILE *out) +{ + register long *p; + int i; + + + p = what; + i = len; + while (i) + { + *p = scale(*p); + (void)scale(*p); /* need this kludge for some compilers */ + p++; + i--; + } + writearr(what, len, out); +} + + +static long * +makebcpl(register long *p, + register char *s, + register int n) +{ + register long t; + register long sc; + + + if (strlen(s) < n) + n = strlen(s); + t = ((long)n) << 24; + sc = 16; + + while (n > 0) + { + t |= ((long)(*(unsigned char *)s++)) << sc; + sc -= 8; + if (sc < 0) + { + *p++ = t; + t = 0; + sc = 24; + } + n--; + } + if (t) + *p++ = t; + + return p; +} + + +static long +checksum(ttfinfo **array) +{ + int i; + unsigned long s1 = 0, s2 = 0; + char *p; + ttfinfo *ti; + + + for (i = 0; i < 256; i++) + if (NULL != (ti = array[i])) + { + s1 = ((s1 << 1) ^ (s1 >> 31)) ^ ti->width; /* cyclic left shift */ + s1 &= 0xFFFFFFFF; /* in case we're on a 64-bit machine */ + + for (p = ti->adobename; *p; p++) + s2 = (s2 * 3) + *p; + } + + s1 = (s1 << 1) ^ s2; + return s1; +} + + +int +transform(register int x, register int y, + float ef, float sl) +{ + register double acc; + + + acc = ef * x + sl * y; + return (int)(acc >= 0 ? floor(acc + 0.5) : ceil(acc - 0.5)); +} + + +int +buildtfm(Font *fnt) +{ + register int i, j; + register ttfinfo *ti; + int byte1, old_byte1, byte2; + long cksum; + double Slant; + char buffer[256]; + struct sf sf_array[256]; + + + if (fnt->subfont_ligs) + { + for (i = 0; i < 256; i++) + { + ti = fnt->inencptrs[i]; + if (ti) + { + sf_array[i].sf_code = ti->charcode; + sf_array[i].position = i; + } + else + { + sf_array[i].sf_code = -1; + sf_array[i].position = -1; + } + } + /* we sort the subfont character codes before we build a ligkern list */ + qsort(sf_array, 256, sizeof (struct sf), compare_sf); + + /* we need to create dummy characters for the ligatures in case the + character slots of the affected codes are unused */ + i = 0; + while (i < 256 && sf_array[i].sf_code > -1) + { + byte1 = sf_array[i].sf_code >> 8; + byte2 = sf_array[i].sf_code & 0xFF; + if (!fnt->inencptrs[byte1]) + { + ti = newchar(fnt); + ti->llx = ti->lly = 0; + ti->urx = ti->ury = 0; + ti->width = 0; + fnt->inencptrs[byte1] = ti; + ti->incode = byte1; + ti->adobename = ".dummy"; + } + if (!fnt->inencptrs[byte2]) + { + ti = newchar(fnt); + ti->llx = ti->lly = 0; + ti->urx = ti->ury = 0; + ti->width = 0; + fnt->inencptrs[byte2] = ti; + ti->incode = byte2; + ti->adobename = ".dummy"; + } + i++; + } + } + + for (i = 0; i <= 0xFF && fnt->inencptrs[i] == NULL; i++) + ; + bc = i; + for (i = 0xFF; i >= 0 && fnt->inencptrs[i] == NULL; i--) + ; + ec = i; + + if (ec < bc) + { + if (fnt->sfdname) + return 0; + else + oops("No TTF characters."); + } + + header = (long *)mymalloc(40000L); + cksum = checksum(fnt->inencptrs); + header[0] = cksum; + header[1] = 0xA00000; /* 10pt design size */ + + (void)makebcpl(header + 2, fnt->codingscheme, 39); + (void)makebcpl(header + 12, fnt->fullname, 19); + + /* 4 bytes are left free for the unused FACE value */ + + buffer[0] = '\0'; + strncat(buffer, "Created by `", 12); + strncat(buffer, fnt->titlebuf, 255 - 12 - 1); + strncat(buffer, "'", 1); + charinfo = makebcpl(header + 18, buffer, 255); + lh = charinfo - header; + + width = charinfo + (ec - bc + 1); + width[0] = 0; + nw = 1; + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + width[nw] = ti->width; + for (j = 1; width[j] != ti->width; j++) + ; + ti->wptr = j; + if (j == nw) + nw++; + } + if (nw > 256) + oops("256 chars with different widths."); + + depth = width + nw; + depth[0] = 0; + nd = 1; + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + depth[nd] = -ti->lly; + for (j = 0; depth[j] != -ti->lly; j++) + ; + ti->dptr = j; + if (j == nd) + nd++; + } + + if (nd > 16) + { + remap(depth, nd, 16, source, unsort); + nd = 16; + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + ti->dptr = unsort[ti->dptr]; + } + + height = depth + nd; + height[0] = 0; + nh = 1; + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + height[nh] = ti->ury; + for (j = 0; height[j] != ti->ury; j++) + ; + ti->hptr = j; + if (j == nh) + nh++; + } + + if (nh > 16) + { + remap(height, nh, 16, source, unsort); + nh = 16; + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + ti->hptr = unsort[ti->hptr]; + } + + italic = height + nh; + italic[0] = 0; + ni = 1; + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + italic[ni] = ti->urx - ti->width; + if (italic[ni] < 0) + italic[ni] = 0; + for (j = 0; italic[j] != italic[ni]; j++) + ; + ti->iptr = j; + if (j == ni) + ni++; + } + + if (ni > 64) + { + remap(italic, ni, 64, source, unsort); + ni = 64; + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + ti->iptr = unsort[ti->iptr]; + } + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->inencptrs[i])) + charinfo[i - bc] = ((long)(ti->wptr) << 24) + + ((long)(ti->hptr) << 20) + + ((long)(ti->dptr) << 16) + + ((long)(ti->iptr) << 10); + else + charinfo[i - bc] = 0; + + ligkern = italic + ni; + nl = 0; + + if (fnt->subfont_ligs) + { + /* Now we build the ligature list. The ligature consisting of character + code byte1 + byte2 should yield the actual character. The fonts of + the HLaTeX package for Korean use this mechanism. */ + + old_byte1 = -1; + while (nl < 256 && sf_array[nl].sf_code > -1) + { + byte1 = sf_array[nl].sf_code >> 8; + byte2 = sf_array[nl].sf_code & 0xFF; + if (byte1 != old_byte1) + { + charinfo[byte1 - bc] += 0x100L + /* set the lig tag */ + nl; /* set the position in array */ + if (old_byte1 > -1) + ligkern[nl - 1] |= 0x80000000L; /* set the STOP byte in previous + ligkern command */ + } + + ligkern[nl] = ((long)byte2 << 16) + + (long)sf_array[nl].position; + old_byte1 = byte1; + nl++; + } + ligkern[nl - 1] |= 0x80000000L; + } + + kerns = ligkern + nl; + nk = 0; /* kerns are omitted from raw TeX font */ + + Slant = fnt->slant - fnt->efactor * tan(fnt->italicangle * (PI / 180.0)); + + tparam = kerns + nk; + tparam[0] = (long)(FIXFACTOR * Slant + 0.5); + tparam[1] = scale((long)fnt->fontspace); + tparam[2] = (fnt->fixedpitch ? 0 : scale((long)(300 * fnt->efactor + 0.5))); + tparam[3] = (fnt->fixedpitch ? 0 : scale((long)(100 * fnt->efactor + 0.5))); + tparam[4] = scale((long)fnt->xheight); + tparam[5] = scale((long)(1000 * fnt->efactor + 0.5)); + np = 6; + + return 1; +} + + +void +writetfm(Font *fnt) +{ + FILE *out; + char *tfm_name; + int len = 0; + + + if (fnt->tfm_path) + len += strlen(fnt->tfm_path); + len += strlen(fnt->fullname); + len += strlen(fnt->tfm_ext); + len++; + + tfm_name = (char *)mymalloc(len); + tfm_name[0] = '\0'; + if (fnt->tfm_path) + strcat(tfm_name, fnt->tfm_path); + strcat(tfm_name, fnt->fullname); + strcat(tfm_name, fnt->tfm_ext); + + if ((out = fopen(tfm_name, "wb")) == NULL) + oops("Cannot open tfm file `%s'.", tfm_name); + + free(tfm_name); + + + lf = 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np; + + write16(lf, out); + write16(lh, out); + write16(bc, out); + write16(ec, out); + write16(nw, out); + write16(nh, out); + write16(nd, out); + write16(ni, out); + write16(nl, out); + write16(nk, out); + write16(ne, out); + write16(np, out); + writearr(header, lh, out); + writearr(charinfo, ec - bc + 1, out); + writesarr(width, nw, out); + writesarr(height, nh, out); + writesarr(depth, nd, out); + writesarr(italic, ni, out); + writearr(ligkern, nl, out); + writesarr(kerns, nk, out); + writearr(tparam, np, out); + + free(header); + fclose(out); +} + + +/* end */ diff --git a/contrib/ttf2pk/tfmaux.h b/contrib/ttf2pk/tfmaux.h new file mode 100644 index 0000000..1a951e4 --- /dev/null +++ b/contrib/ttf2pk/tfmaux.h @@ -0,0 +1,28 @@ +/* + * tfmaux.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TFMAUX_H +#define TFMAUX_H + +#include "ttf2tfm.h" + + +#define FIXFACTOR (0x100000L) /* 2^{20}, the unit fixnum */ + + +int transform(int x, int y, float ef, float sl); + +int buildtfm(Font *fnt); +void writetfm(Font *fnt); + +#endif /* TFMAUX_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ttf2pk.1 b/contrib/ttf2pk/ttf2pk.1 new file mode 100644 index 0000000..64d5ece --- /dev/null +++ b/contrib/ttf2pk/ttf2pk.1 @@ -0,0 +1,289 @@ +.\" man page for ttf2pk +. +.TH TTF2PK 1 15-Aug-1999 "FreeType version 1.3" +.SH NAME +ttf2pk \- convert a TrueType font into TeX's PK format +.SH SYNOPSIS +.na +.nh +.B ttf2pk +.RB [ -q ] +.RB [ -n ] +.I "\%font-name \%resolution" +.br +.B ttf2pk +.B -t +.RB [ -q ] +.I \%font-name +.br +.B "ttf2pk --version" +| +.B --help +.ad +.hy +. +. +. +.\" ==== +.\" ==== macro definitions +.\" ==== +. +.\" here we define \TeX for troff and nroff +.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP +.if n .ds TX TeX +. +.\" and here the same for \LaTeX +.if t \{\ +.ie '\*(.T'dvi' \ +.ds LX \fRL\h'-0.36m'\v'-0.15v'\s-3A\s0\h'-0.15m'\v'0.15v'\fP\*(TX +.el .ds LX \fRL\h'-0.36m'\v'-0.22v'\s-2A\s0\h'-0.15m'\v'0.22v'\fP\*(TX +.\} +.if n .ds LX LaTeX +. +.\" \LaTeXe +.\" note that we need \vareps for TeX instead of \eps which can only be +.\" accessed with the \N escape sequence (in the Math Italic font) +.if t \{\ +.ie '\*(.T'dvi' .ds LE \*(LX\h'0.15m'2\v'0.20v'\f(MI\N'34'\fP\v'-0.20v' +.el .ds LE \*(LX\h'0.15m'2\v'0.20v'\(*e\v'-0.20v' +.\} +.if n .ds LE LaTeX\ 2e +. +.\" a typewriter font +.if t \{\ +.de C +\fC\\$1\fP\\$2 +.. +.\} +.if n \{\ +.de C +\\$1\\$2 +.. +.\} +. +.\" ==== +.\" ==== end of macro definitions +.\" ==== +. +. +. +.SH DESCRIPTION +This program converts a TrueType font into a +.C PK +file; the created font can then be used with \*(TX +or \*(LX. +.PP +All TrueType fonts to be used must be registered in a configuration +file called +.C \%ttfonts.map ; +it specifies how to handle each font. +CJKV (Chinese/Japanese/Korean/old Vietnamese) subfonts as created by +.B ttf2tfm +are also supported. +.PP +.B ttf2pk +always assumes 10pt as the design size for the written \*(TX +font. +. +. +.SH PARAMETERS +.TP +.B -q +This optional switch makes +.B ttf2pk +quiet. +It suppresses any informational output except warning and error +messages. +.TP +.B -n +Use only `\c +.C \&.pk ' +as the extension instead of `\c +.C \&. \c +.RI < \%resolution >\c +.C pk '. +.TP +.B -t +Test for the existence of +.IR \%font-name . +Returns 0 on success and prints out the corresponding line in +.C \%ttfonts.map +(provided the +.B -q +switch isn't set). +.TP +.I font-name +The \*(TX +name of the font. +.B ttf2pk +looks this name up in a configuration file called +.C \%ttfonts.map +for further information how to process the font. +.TP +.I resolution +The resolution, given in dots per inch. +Currently the horizontal resolution is equal to the vertical +resolution. +The design size is always assumed to be 10pt. +.TP +.B --version +Shows the current version of +.B ttf2pk +and the used file search library (e.g.\ \c +.BR kpathsea ). +.TP +.B --help +Shows usage information. +.PP +Environment variables for file searching are described in the manual page +of +.BR ttf2tfm . +. +. +.SH "THE CONFIGURATION FILE" +.B ttf2pk +uses, similar to +.BR dvips , +a font definition file called +.C \%ttfonts.map . +The parameters specified to +.B ttf2tfm +are here preserved\(em\c +.B ttf2tfm +writes out to standard output, as the last line, a proper +configuration entry for +.C \%ttfonts.map . +.PP +As an example, a call to +.PP +.in +2m +.C "ttf2tfm arial -p T1.enc -s 0.25 -P 1 -E 0 arials" +.PP +will produce the following line: +.PP +.in +2m +.C "arials arial Slant=0.25 Pid=1 Eid=0 Encoding=T1.enc" +.PP +See +.BR ttf2tfm (1) +and +.BR afm2tfm (1) +of the +.B dvips +package for a detailed description of encoding files. +.PP +Here a table listing the various +.B ttf2tfm +parameters and the corresponding +.C \%ttfonts.map +entries: +.PP +.in +4m +.ta 2i +-s Slant +.br +-e Extend +.br +-p Encoding +.br +-f Fontindex +.br +-P Pid +.br +-E Eid +.br +-n PS=Yes +.br +-N PS=Only +.br +-R Replacement +.br +-x Rotate=Yes +.br +-y Y-Offset +.PP +Single replacement glyph names given to +.B ttf2tfm +with `\c +.BI -r \ old-glyphname\ new-glyphname\c +\&' +are directly specified with `\c +.IR old-glyphname = new-glyphname '. +They will be ignored if in subfont mode or if no encoding file is given. +.PP +One additional parameter in +.C \%ttfonts.map +is unique to +.BR ttf2pk : +`Hinting', which can take the values `On' or `Off'. +Some fonts (e.g.\ the CJK part of +.C \%cyberbit.ttf ) +are rendered incorrectly if hinting is activated. +Default is `On' (you can also use `Yes', `No', `1', and `0'). +.PP +For a description of subfonts (i.e., entries of the form `\c +.I \c +.C @\c +.I \c +.C @ ') +please refer to +.BR ttf2tfm (1). +.PP +The format of +.C \%ttfonts.map +is simple. +Each line defines a font; first comes the \*(TX +font name, then its TrueType font file name, followed by the +parameters in any order. +Case is significant (even for parameter names); the parameters are +separated from its values by an equal sign, with whitespace possibly +surrounding it. +.B ttf2pk +reads in +.C \%ttfonts.map +line by line, continuing until the \*(TX +font specified on the command line is found, otherwise the programs +exits with error code\ 2. +Thus you can use any character invalid in a \*(TX +font name to start a comment line. +.PP +You can use `\\' as the final character of a line to indicate that the +input is continued on the next line. +The backslash and the following newline character will be removed. +.PP +.B ttf2pk +will abort if it can't find or read the \*(TX +font metrics file of the given \*(TX +font name. +. +. +.SH "RETURN VALUE" +If the call was successful, 0\ will be returned. +In case of error, the return value is\ 1. +Finally, if the font can't be found in +.C \%ttfonts.map , +2\ is returned. +This simplifies the inclusion of +.B ttf2pk +into scripts like +.B mktexpk +for automatic font generation. +. +. +.SH "SEE ALSO" +.BR ttf2tfm (1), +.BR afm2tfm (1) +. +. +.SH AVAILABILITY +.B ttf2pk +is part of the FreeType package, a high quality TrueType rendering +library. +. +. +.SH AUTHORS +Werner LEMBERG +.C +.br +Fr\('ed\('eric LOYER +.C diff --git a/contrib/ttf2pk/ttf2pk.c b/contrib/ttf2pk/ttf2pk.c new file mode 100644 index 0000000..593f844 --- /dev/null +++ b/contrib/ttf2pk/ttf2pk.c @@ -0,0 +1,592 @@ +/* + * ttf2pk.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include /* for size_t */ +#include +#include +#include + + +#include "ttf2tfm.h" +#include "newobj.h" +#include "pklib.h" +#include "ttfenc.h" +#include "ttflib.h" +#include "errormsg.h" +#include "filesrch.h" +#include "parse.h" +#include "subfont.h" + + +char ident[] = "ttf2pk version 1.3"; +char progname[] = "ttf2pk"; /* for error/warning messages */ + + +Boolean have_sfd = False; +Boolean have_pid = False; +Boolean have_eid = False; + + +/* + * Checks for an equal sign surrounded by whitespace. + */ + +static char * +strip_equal(char *s, char *os, char *p) +{ + while (isspace(*p)) + p++; + if (*p != '=') + boops(os, p - s, "Missing `='."); + p++; + while (isspace(*p)) + p++; + return p; +} + + +#define USAGE "\ + Convert a TrueType font to TeX's PK format.\n\ +\n\ +-q suppress informational output\n\ +-n only use `.pk' as extension\n\ +-t test for (returns 0 on success)\n\ +--help print this message and exit\n\ +--version print version number and exit\n\ +" + +static void +usage(void) +{ + fputs("Usage: ttf2pk [-q] [-n] \n", stdout); + fputs(" ttf2pk -t [-q] \n", stdout); + fputs(USAGE, stdout); + exit(0); +} + + +#define VERSION "\ +Copyright (C) 1997-1999 Frederic Loyer and Werner Lemberg.\n\ +There is NO warranty. You may redistribute this software\n\ +under the terms of the GNU General Public License\n\ +and the gsftopk copyright.\n\ +\n\ +For more information about these matters, see the files\n\ +named COPYING and pklib.c.\n\ +\n\ +Primary authors of ttf2pk: F. Loyer and W. Lemberg.\n\ +\n\ +ttf2pk is partially based on gsftopk from P. Vojta\n\ +and the FreeType project from\n\ +David Turner, Robert Wilhelm, and Werner Lemberg\n\ +" + +static void +version(void) +{ + fputs(ident, stdout); + fprintf(stdout, " (%s)\n", TeX_search_version()); + fputs(VERSION, stdout); + exit(0); +} + + +static int +compare(Font *fnt, char *s, char *key) +{ + char c; + char *p; + char *temp, *temp1; + int value; + int sfd_begin, postfix_begin; + + + /* + * We isolate the fontname. + */ + + while (isspace(*s)) + s++; + + p = s; + while (*p && !isspace(*p)) + p++; + + c = *p; + *p = '\0'; + temp = newstring(s); + *p = c; + + /* + * We search for a subfont definition file name. + */ + + handle_sfd(temp, &sfd_begin, &postfix_begin); + + if (sfd_begin == -1) + value = strcmp(temp, key); + else + { + size_t len, len1, len2; + + + /* + * The sfd file will be only searched if prefix and postfix match. + */ + + len = strlen(key); + len1 = strlen(temp); + len2 = strlen(temp + postfix_begin); + + if (len1 + len2 >= len) + value = -1; + else if (!strncmp(temp, key, len1) && + !strcmp(temp + postfix_begin, key + (len - len2))) + { + c = key[len - len2]; + key[len - len2] = '\0'; + temp1 = newstring(key + len1); + key[len - len2] = c; + + if (fnt->sfdname) + free(fnt->sfdname); + fnt->sfdname = newstring(temp + sfd_begin); + + /* + * If the sfd file can't be opened the search is continued. + */ + + value = !init_sfd(fnt, False); + + if (!value) + { + value = -1; + + while (get_sfd(fnt)) + { + if (!strcmp(fnt->subfont_name, temp1)) + { + value = 0; /* success */ + have_sfd = True; + break; + } + } + + close_sfd(); + } + + free(temp1); + } + else + value = -1; + } + + free(temp); + + return value; +} + + +int +main(int argc, char** argv) +{ + size_t l; + unsigned int i; + long index, code; + FILE *config_file; + char *configline, *oldconfigline, *p, *q; + Font font; + encoding *enc; + long inenc_array[256]; + char *fontname; + size_t fontname_len; + char *pk_filename, *tfm_filename, *enc_filename, *cfg_filename; + char *real_ttfname, *real_cfg_filename; + int dpi = 0, ptsize; + Boolean hinting = True; + Boolean quiet = False; + Boolean no_dpi = False; + Boolean testing = False; + + + TeX_search_init(argv[0], "ttf2pk", "TTF2PK"); + + if (argc == 1) + oops("Need at least two arguments.\n" + "Try `ttf2pk --help' for more information."); + + if (argc == 2) + { + if (strcmp(argv[1], "--help") == 0) + usage(); + else if (strcmp(argv[1], "--version") == 0) + version(); + } + + while (argv[1][0] == '-') + { + if (argv[1][1] == 'q') + quiet = True; + else if (argv[1][1] == 'n') + no_dpi = True; + else if (argv[1][1] == 't') + testing = True; + else + oops("Unknown option `%s'.\n" + "Try `ttf2pk --help' for more information.", argv[1]); + + argv++; + argc--; + } + + if (testing) + { + if (argc != 2) + oops("Need exactly one parameter for `-t' option.\n" + "Try `ttf2pk --help' for more information."); + } + else if (argc != 3) + oops("Need at most two arguments.\n" + "Try `ttf2pk --help' for more information."); + + if (!quiet) + printf("This is %s\n", ident); + + if (!testing) + if ((dpi = atoi(argv[2])) <= 50) + oops("dpi value must be larger than 50."); + + fontname = argv[1]; + fontname_len = strlen(fontname); + enc_filename = NULL; + + ptsize = 10; + + init_font_structure(&font); + + cfg_filename = newstring("ttfonts.map"); + real_cfg_filename = TeX_search_config_file(&cfg_filename); + if (!real_cfg_filename) + oops("Cannot find file ttfonts.map."); + + config_file = fopen(real_cfg_filename, "rt"); + if (config_file == NULL) + oops("Cannot open file ttfonts.map."); + + do + { + configline = get_line(config_file); + if (!configline) + oops("Error while reading ttfonts.map."); + if (!*configline) + { + /* + * This is the only error message we suppress if the -q flag + * is set, making it possible to call ttf2pk silently. + */ + if (!quiet) + fprintf(stdout, + "%s: ERROR: Cannot find font %s in ttfonts.map.\n", + progname, fontname); + exit(2); + } + } while (compare(&font, configline, fontname)); + + fclose(config_file); + + if (testing) + { + if (!quiet) + fprintf(stdout, "%s\n", configline); + exit(0); + } + + /* + * Parse the line from the config file. We split the config line buffer + * into substrings according to the given options. + */ + + l = strlen(configline); + if (configline[l - 1] == '\n') + configline[l - 1] = '\0'; /* strip newline */ + + oldconfigline = newstring(configline); + + p = configline; + while (isspace(*p)) + p++; + while (*p && !isspace(*p)) + p++; + + q = p; + + while (*p && isspace(*p)) + p++; + if (!*p) + boops(oldconfigline, q - configline, "TTF file missing."); + + font.ttfname = p; + + while (*p && !isspace(*p)) + p++; + if (*p) + *p++ = '\0'; + + for (; *p; p++) + { + if (isspace(*p)) + continue; + + if (!strncmp(p, "Slant", 5)) + { + p = strip_equal(configline, oldconfigline, p + 5); + if (sscanf(p, "%f", &(font.slant)) == 0) + boops(oldconfigline, p - configline, "Bad `Slant' parameter."); + } + else if (!strncmp(p, "Encoding", 8)) + { + if (have_sfd) + boops(oldconfigline, p - configline, + "No `Encoding' parameter allowed for subfonts."); + + p = strip_equal(configline, oldconfigline, p + 8); + if (!*p) + boops(oldconfigline, p - configline, "Bad `Encoding' parameter."); + enc_filename = p; + } + else if (!strncmp(p, "Extend", 6)) + { + p = strip_equal(configline, oldconfigline, p + 6); + if (sscanf(p, "%f", &(font.efactor)) == 0) + boops(oldconfigline, p - configline, "Bad `Extend' parameter."); + } + else if (!strncmp(p, "Fontindex", 9)) + { + p = strip_equal(configline, oldconfigline, p + 9); + if (sscanf(p, "%lu", &(font.fontindex)) < 0) + boops(oldconfigline, p - configline, "Bad `Fontindex' parameter."); + } + else if (!strncmp(p, "Pid", 3)) + { + p = strip_equal(configline, oldconfigline, p + 3); + if (sscanf(p, "%hu", &(font.pid)) < 0) + boops(oldconfigline, p - configline, "Bad `Pid' parameter."); + have_pid = True; + } + else if (!strncmp(p, "Eid", 3)) + { + p = strip_equal(configline, oldconfigline, p + 3); + if (sscanf(p, "%hu", &(font.eid)) < 0) + boops(oldconfigline, p - configline, "Bad `Eid' parameter."); + have_eid = True; + } + else if (!strncmp(p, "Hinting", 7)) + { + p = strip_equal(configline, oldconfigline, p + 7); + if (p[1] == 'N' || p[1] == 'n' || + p[0] == 'Y' || p[1] == 'y' || + p[0] == '1') + hinting = True; + else if (p[1] == 'F' || p[1] == 'f' || + p[0] == 'N' || p[1] == 'n' || + p[0] == '0') + hinting = False; + else + boops(oldconfigline, p - configline, "Bad `Hinting' parameter."); + } + else if (!strncmp(p, "PS", 2)) + { + p = strip_equal(configline, oldconfigline, p + 2); + if (p[1] != '\0' && + (p[2] == 'l' || p[2] == 'L')) + font.PSnames = Only; + else if (p[1] == 'N' || p[1] == 'n' || + p[0] == 'Y' || p[0] == 'y' || + p[0] == '1') + font.PSnames = Yes; + else if (p[1] == 'F' || p[1] == 'f' || + p[0] == 'N' || p[0] == 'n' || + p[0] == '0') + font.PSnames = No; + else + boops(oldconfigline, p - configline, "Bad `PS' parameter."); + + if (have_sfd) + boops(oldconfigline, p - configline, + "No `PS' parameter allowed for subfonts."); + } + else if (!strncmp(p, "Rotate", 6)) + { + p = strip_equal(configline, oldconfigline, p + 6); + if (p[1] == 'N' || p[1] == 'n' || + p[0] == 'Y' || p[1] == 'y' || + p[0] == '1') + font.rotate = True; + else if (p[1] == 'F' || p[1] == 'f' || + p[0] == 'N' || p[1] == 'n' || + p[0] == '0') + font.rotate = False; + else + boops(oldconfigline, p - configline, "Bad `Rotate' parameter."); + + if (!have_sfd) + boops(oldconfigline, p - configline, + "No `Rotate' parameter allowed for non-subfonts."); + } + else if (!strncmp(p, "Y-Offset", 8)) + { + p = strip_equal(configline, oldconfigline, p + 8); + if (sscanf(p, "%f", &(font.y_offset)) == 0) + boops(oldconfigline, p - configline, "Bad `Y-Offset' parameter."); + } + else if (!strncmp(p, "Replacement", 11)) + { + p = strip_equal(configline, oldconfigline, p + 11); + if (!*p) + boops(oldconfigline, p - configline, "Bad `Replacement' parameter."); + font.replacementname = p; + } + else + { + char *new_name, *old_name; + stringlist *sl; + + + old_name = p; + while (*p && !isspace(*p) && *p != '=') + p++; + + q = p; + p = strip_equal(configline, oldconfigline, p); + *q = '\0'; + + new_name = p; + while (*p && !isspace(*p)) + p++; + if (*p) + *p++ = '\0'; + + sl = newstringlist(); + sl->new_name = new_name; + sl->old_name = old_name; + sl->next = font.replacements; + font.replacements = sl; + + p--; /* to make the next while loop work */ + } + + while (*p && !isspace(*p)) + p++; + if (*p) + *p = '\0'; + } + + if (font.PSnames == Only) + if (have_pid || have_eid) + boops(oldconfigline, 0, + "No `Pid' or `Eid' parameters allowed if `PS=Only' is set."); + + font.replacementname = newstring(font.replacementname); + get_replacements(&font); + + tfm_filename = newstring(fontname); + TFMopen(&tfm_filename); + + pk_filename = mymalloc(fontname_len + 10); + if (no_dpi) + sprintf(pk_filename, "%s.pk", fontname); + else + sprintf(pk_filename, "%s.%dpk", fontname, dpi); + PKopen(pk_filename, fontname, dpi); + + font.ttfname = newstring(font.ttfname); + real_ttfname = TeX_search_ttf_file(&(font.ttfname)); + if (!real_ttfname) + oops("Cannot find `%s'.", font.ttfname); + TTFopen(real_ttfname, &font, dpi, ptsize, quiet); + + enc_filename = newstring(enc_filename); + enc = readencoding(&enc_filename, &font, True); + if (enc) + { + char *name; + + + restore_glyph(enc, &font); + + for (i = 0; i <= 0xFF; i++) + { + name = enc->vec[i]; + if (!font.PSnames) + { + code = adobename_to_code(name); + if (code < 0 && strcmp(name, ".notdef") != 0) + warning("Cannot map character `%s'.", name); + inenc_array[i] = code; + } + else + { + /* we search the glyph index */ + index = TTFsearch_PS_name(name); + if (index < 0) + warning("Cannot map character `%s'.", name); + inenc_array[i] = index | 0x10000; + } + } + } + else + { + if (font.replacements) + warning("Replacement glyphs will be ignored."); + + if (have_sfd) + TTFget_subfont(&font, inenc_array); + else + /* get the table of glyph names too */ + enc = TTFget_first_glyphs(&font, inenc_array); + } + + for (i = 0; i <= 0xFF; i++) + { + byte *bitmap; + int w, h, hoff, voff; + + + if ((code = inenc_array[i]) >= 0) + { + if (!quiet) + { + printf("Processing glyph %3ld %s index 0x%04x %s\n", + (long)i, (code >= 0x10000) ? "glyph" : "code", + (unsigned int)(code & 0xFFFF), enc ? enc->vec[i] : ""); + fflush(stdout); + } + + if (TTFprocess(&font, code, + &bitmap, &w, &h, &hoff, &voff, hinting, quiet)) + PKputglyph(i, + -hoff, -voff, w - hoff, h - voff, + w, h, bitmap); + else + warning("Cannot render glyph with %s index 0x%x.", + (code >= 0x10000) ? "glyph" : "code", + (unsigned int)(code & 0xFFFF)); + } + } + + PKclose(); + exit(0); /* for safety reasons */ + return 0; /* never reached */ +} + + +/* end */ diff --git a/contrib/ttf2pk/ttf2pk.doc b/contrib/ttf2pk/ttf2pk.doc new file mode 100644 index 0000000..3cf50e2 --- /dev/null +++ b/contrib/ttf2pk/ttf2pk.doc @@ -0,0 +1,733 @@ + +ttf2tfm -- TrueType to TFM converter +ttf2pk -- TrueType to PK converter +==================================== + +These two auxiliary programs make TrueType fonts usable with TeX. +ttf2tfm extracts the metric and kerning information of a TrueType font +and converts it into metric files usable by TeX (quite similar to +afm2tfm which is part of the dvips package). ttf2pk rasterizes the +glyph outlines of a TrueType font into a bitmap font in PK format. + +Since a TrueType font often contains more than 256 glyphs, some means +are necessary to map a subset of the TrueType glyphs into a TeX font. +To do this, two mapping tables are needed: the first maps from the +TrueType font to a raw TeX font (this mapping table is used both by +ttf2tfm and ttf2pk), and the second maps from the raw TeX font to +another (virtual) TeX font providing all kerning and ligature +information needed by TeX. + +We sometimes refer to this first map as the `input' or `raw' map, and +to the second as the `output' or `virtual' map. + +This two stage mapping has the advantage that one raw font can be +accessed with various TeX encodings (e.g. T1 and OT1) via the virtual +font mechanism, and just one PK file is necessary. + +For CJK fonts, a different mechanism is provided (see section `Subfont +definition files' below). Additionally, rotated glyphs for +pseudo-vertical writing are supported -- if possible, vertical glyph +presentation forms are used from the font's GSUB table. + + + +ttf2tfm +======= + +Usage: + + ttf2tfm FILE[.ttf|.ttc] [OPTION]... [FILE[.tfm]] + +Options (default values are given in brackets): + +-c REAL use REAL for height of small caps made with -V [0.8] +-e REAL widen (extend) characters by a factor of REAL [1.0] +-E INT select INT as the TTF encoding ID [1] +-f INT select INT as the font index in a TTC [0] +-l create 1st/2nd byte ligatures in subfonts +-n use PS names of TrueType font +-N use only PS names and no cmap +-O use octal for all character codes in the vpl file +-p ENCFILE[.enc] read ENCFILE for the TTF->raw TeX mapping +-P INT select INT as the TTF platform ID [3] +-q suppress informational output +-r OLDNAME NEWNAME replace glyph name OLDNAME with NEWNAME +-R RPLFILE[.rpl] read RPLFILE containing glyph replacement names +-s REAL oblique (slant) characters by REAL, usually <<1 [0.0] +-t ENCFILE[.enc] read ENCFILE for the encoding of the vpl file +-T ENCFILE[.enc] equivalent to -p ENCFILE -t ENCFILE +-u output only characters from encodings, nothing extra +-v FILE[.vpl] make a VPL file for conversion to VF +-V SCFILE[.vpl] like -v, but synthesize smallcaps as lowercase +-x rotate subfont glyphs by 90 degrees +-y REAL move rotated glyphs down by a factor of REAL [0.25] +--help print this message and exit +--version print version number and exit + + +The usage is very similar to afm2tfm. Please consult the dvips info +file for more details on the various parameters. Here we will +concentrate on the differences between afm2tfm and ttf2tfm. + + +cmaps +----- + +Contrary to Type 1 PostScript fonts (but similar to the new CID-keyed +PostScript fonts), most TrueType fonts have more than one native +mapping table, also called `cmap', which maps the (internal) TTF glyph +indices to the (external) TTF character codes. Common examples are a +mapping table to Unicode encoded character positions and the standard +Macintosh mapping. To specify this TrueType mapping table, use the +options `-P' and `-E'. With `-P' you specify the platform ID; defined +values are: + + platform platform ID (pid) + ---------------------------------- + Apple Unicode 0 + Macintosh 1 + ISO 2 + Microsoft 3 + +The encoding ID depends on the platform. For pid=0, we ignore the +`-E' parameter (setting it to zero) since the mapping table is always +Unicode version 2.0. For pid=1, the following table lists the defined +values: + + platform ID = 1 + script encoding ID (eid) + --------------------------------- + Roman 0 + Japanese 1 + Chinese 2 + Korean 3 + Arabic 4 + Hebrew 5 + Greek 6 + Russian 7 + Roman Symbol 8 + Devanagari 9 + Gurmukhi 10 + Gujarati 11 + Oriya 12 + Bengali 13 + Tamil 14 + Telugu 15 + Kannada 16 + Malayalam 17 + Sinhalese 18 + Burmese 19 + Khmer 20 + Thai 21 + Laotian 22 + Georgian 23 + Armenian 24 + Maldivian 25 + Tibetan 26 + Mongolian 27 + Geez 28 + Slavic 29 + Vietnamese 30 + Sindhi 31 + Uninterpreted 32 + +Here are the ISO encoding IDs: + + platform ID = 2 + encoding encoding ID + ---------------------------- + ASCII 0 + ISO 10646 1 + ISO 8859-1 2 + +And finally, the Microsoft encoding IDs: + + platform ID = 3 + encoding encoding ID + --------------------------- + Symbol 0 + Unicode 2.0 1 + Shift JIS 2 + GB 2312 (1980) 3 + Big 5 4 + KSC 5601 (Wansung) 5 + KSC 5601 (Johab) 6 + +The program will abort if you specify an invalid platform/encoding ID +pair. Please note that most fonts have at most two or three cmaps, +usually corresponding to the pid/eid pairs (1,0), (3,0), or (3,1) in +case of Latin based fonts. Valid Microsoft fonts should have a (3,1) +mapping table, but some fonts exist (mostly Asian fonts) which have a +(3,1) cmap not encoded in Unicode. The reason for this strange +behavior is the fact that some MS Windows versions will reject fonts +having a non-Unicode cmap (since all non-Unicode Microsoft encoding +IDs are for Asian specific MS Windows versions). + +The `-P' and `-E' options to ttf2tfm must be equally specified for +ttf2pk; the corresponding parameters in ttfonts.map are `Pid' and +`Eid', respectively. + +The default pid/eid pair is (3,1). + +If you use the `-N' switch, all cmaps are ignored, using only the +PostScript names in the TrueType font. The corresponding option in +ttfonts.map is `PS=Only'. + +If you use the `-n' switch, the default glyph names built into ttf2tfm +are replaced with the PS glyph names found in the font. In many cases +this is not what you want because the glyph names in the font are +often incorrect or non-standard. The corresponding option in +ttfonts.map `PS=Yes'. + + +input and output encodings +-------------------------- + +You must specify the encoding vectors from the TrueType font to the +raw TeX font and from the raw TeX font to the virtual TeX font exactly +as with afm2tfm, but you have more possibilities to address the +character codes. [With `encoding vector' a mapping table with 256 +entries in form of a PostScript vector is meant; see the file +`T1-WGL4.enc' of this package for an example.] With afm2tfm, you must +access each glyph with its Adobe glyph name, e.g. `/quotedsingle' or +`/Acircumflex'. This has been extended with ttf2tfm; now you can (and +sometimes must) access the code points and/or glyphs directly using +the following syntax for specifying the character position in decimal, +octal, or hexadecimal notation: `/.c', +`/.c0', or `/.c0x'. Examples: +`/.c72', `/.c0646', `/.c0x48'. To access a glyph index directly, use +the character `g' instead of `c' in the just introduced notation. +Example: `/.g0x32'. + +[Note: The `.cXXX' notation makes no sense if `-N' is used.] + +Another possibility is to use the `-r old-glyphname new-glyphname' +switch to rename a glyph. Example: + + ttf2tfm ... -r .g0xc7 dotlessi -r hungarumlaut dblacute ... + +Nevertheless, it is not allowed to use the `.gXXX' or `.cXXX' glyph +name construct for `new-glyphname'. + +Alternatively, you can collect such replacement pairs in a file which +should have `.rpl' as extension, using the `-R' option. The syntax is +simple: Each line contains a pair `old-glyphname new-glyphname' +separated by whitespace (without the quotation marks). The percent +sign starts a line comment; you can continue a line with a backslash +as the last character. An example for a replacement file is `VPS.rpl' +(to be used in conjunction with `ET5.enc' for Vietnamese) which is +part of this package. + +The `-r' and `-R' switches are ignored for subfonts or if no encoding +tables are specified. For ttf2pk, the corresponding option to `-R' is +`Replacement'. Single replacements are directly given as +old_glyphname=newglyphname in ttfonts.map. + +For pid/eid pairs (1,0) and (3,1), both ttf2tfm and ttf2pk recognize +built-in default Adobe glyph names; the former pair follows the names +given in Appendix E of the book `Inside Macintosh', volume 6, the +latter uses the names given in the TrueType Specification (WGL4, a +Unicode subset). Note that Adobe glyph names are not unique and do +sometimes differ: E.g., many PS fonts have the glyph `mu', whereas +this glyph is called `mu1' in the WGL4 character set to distinguish it +from the real Greek letter mu. You can find those mapping tables in +the source code file `ttfenc.c'. + +On the other hand, the switches `-n' and `-N' make ttf2tfm read in and +use the PostScript names in the TrueType font itself (stored in the +font's `post' table) instead of the default Adobe glyph names. + +If you don't select an input encoding, the first 256 glyphs of the +TrueType font with a valid entry in the selected cmap will be mapped +to the TeX raw font (without the `-q' option ttf2tfm prints this +mapping table to standard output), followed by all glyphs not yet +addressed in the selected cmap. However, some code points for the +(1,0) pid/eid pair are omitted since they do not represent glyphs +useful for TeX: 0x00 (null), 0x08 (backspace), 0x09 (horizontal +tabulation), 0x0d (carriage return), and 0x1d (group separator). The +`invalid character' with glyph index 0 will be omitted too. + +If you select the `-N' switch, the first 256 glyphs of the TrueType +font with a valid PostScript name will be used in case no input +encoding is specified. Again, some glyphs are omitted: `.notdef', +`.null', and `nonmarkingreturn'. + +If you don't select an output encoding, ttf2tfm uses the same mapping +table as afm2tfm would use (you can find it in the source code file +texenc.c); it corresponds to TeX typewriter text. Unused positions +(either caused by empty code points in the mapping table or missing +glyphs in the TrueType font) will be filled (rather arbitrarily) with +characters present in the input encoding but not specified in the +output encoding (without the `-q' option ttf2tfm prints the final +output encoding to standard output). Use the `-u' option if you want +only glyphs in the virtual font which are defined in the output +encoding file, and nothing more. + +One feature missing in afm2tfm has been added which is needed by the +LaTeX T1 encoding: ttf2tfm will construct the glyph `Germandbls' (by +simply concatenating to `S' glyphs) even for normal fonts if possible. +It appears in the glyph list (written to stdout) as the last item, +marked with an asterisk. Since this isn't a real glyph it will be +available only in the virtual font. + +For both input and output encoding, an empty code position is +represented by the glyph name `.notdef'. + +In encoding files, you can use `\' as the final character of a line to +indicate that the input is continued on the next line. The backslash +and the following newline character will be removed. + +ttf2tfm returns 0 on success and 1 on error; warning and error +messages are written to standard error. + + +other options +------------- + +You can select the font in a TrueType font collection (which usually +has the extension `.ttc') with `-f'; the default value, zero, +specifies the first font. For fonts not being a collection, this +parameter is ignored. + +The option `-l' makes ttf2tfm create ligatures in subfonts between +first and second bytes of all the original character codes. Example: +Character code 0xABCD maps to character position 123 in subfont 45. +Then a ligature in subfont 45 between position 0xAB and 0xCD pointing +to character 123 will be produced. The fonts of the Korean HLaTeX +package use this feature. + +To produce glyphs rotated by 90 degrees counter-clockwise, use `-x'. +If the font contains a GSUB table (with feature `vert') to specify +vertical glyph presentation forms, both ttf2pk and ttf2tfm will use +it. This will work only in subfont mode. The y-offset of rotated +glyphs can be specified with the `-y' option; its parameter gives the +fractional amount of shifting downwards (the unit is one EM). If not +specified, a value of 0.25 (em) is used. + + + +ttf2pk +====== + +Usage: + + ttf2pk [-q] [-n] FONT DPI + ttf2pk -t [-q] FONT + +Options: + +-q suppresses informational output +-n only use `.pk' as extension +-t test for FONT (returns 0 on success) +--help print this message and exit +--version print version number and exit + + +The FONT parameter must correspond to an entry in the file ttfonts.map +(see below for details), otherwise error code 2 is returned -- this +can be used for scripts like mktexpk to test whether the given font +name is a (registered) TrueType font. + +Another possibility is to use the `-t' switch which will print the +line of ttfonts.map corresponding to FONT and return 0 on success +(`-q' suppresses any output). + +DPI specifies the intended resolution (we always assume a design size +of 10pt). + + +ttfonts.map +----------- + +ttf2pk uses, similar to dvips, a font definition file called +ttfonts.map. The parameters specified to ttf2tfm are here preserved +-- ttf2tfm writes out to standard output, as the last line, a proper +configuration entry for ttfonts.map. + +As an example, a call to + + ttf2tfm arial -s 0.25 -P 1 -E 0 -r .g0xc7 caron \ + -p 8r.enc -t T1-WGL4.enc -v arialsx arials + +will produce the following line: + + arials arial Slant=0.25 Encoding=8r.enc Pid=1 Eid=0 .g0xc7=caron + +The output encoding given with `-t' for the virtual font `arialsx' is +immaterial to ttf2pk (nevertheless, input encoding files must have the +same format as with ttf2tfm, and all said above about encoding files +holds). + +Here a table listing the various ttf2tfm parameters and its +corresponding ttfonts.map entries: + + -s Slant + -e Extend + -p Encoding + -f Fontindex + -P Pid + -E Eid + -n PS=Yes + -N PS=Only + -R Replacement + -x Rotate=Yes + -y Y-Offset + +Single replacement glyph names given to ttf2tfm with the `-r' switch +are directly specified with old-glyphname=new-glyphname. For subfonts +or if no encoding file is given, replacement glyphs are ignored. + +One additional parameter in ttfonts.map is unique to ttf2pk: +`Hinting', which can take the values `On' or `Off'. Some fonts (e.g. +the CJK part of cyberbit.ttf) are rendered incorrectly if hinting is +activated. Default is `On' (you can also use `Yes', `No', `1', and +`0'). + +The format of ttfonts.map is simple. Each line defines a font; first +comes the TeX font name, then its TrueType font file name, followed by +the parameters in any order. Case is significant (even for parameter +names); the parameters are separated from its values by an equal sign, +with possible whitespace surrounding it. ttf2pk reads in ttfonts.map +line by line, continuing until the TeX font specified on the command +line is found, otherwise the programs exits with error code 2. Thus +you can use any character invalid in a TeX font name to start a +comment line. + +In both ttfonts.map and encoding files, use `\' as the final character +of a line to indicate that the input is continued on the next line. +The backslash and the following newline character will be removed. + +ttf2pk will abort if it can't find and read the TeX font metrics file +of the given TeX font name. + + +Subfont definition files +======================== + +CJK (Chinese/Japanese/Korean) fonts usually contain several thousand +glyphs; to use them with TeX it is necessary to split such large fonts +into subfonts. Subfont definition files (usually having the extension +`.sfd') are a simple means to do this smoothly. A subfont file name +usually consists of a prefix, a subfont infix, and a postfix (which is +empty in most cases), e.g. + + ntukai23 -> prefix: ntukai, infix: 23, postfix: (empty) + +Here the syntax of a line in an SFD file, describing one subfont: + + `\n' + + := anything except whitespace. It's best to use only + alphanumerical characters. + := space, formfeed, carriage return, horizontal and + vertical tabs -- no newline characters. + := | + | + + + := + := `_' + := `:' + + := hexadecimal (prefix `0x'), decimal, or octal + (prefix `0') + +A line can be continued on the next line with a backslash ending the +line. The ranges must not overlap; offsets have to be in the range +0-255. + +Example: + + The line + + 03 10: 0x2349 0x2345_0x2347 + + assigns to the code positions 10, 11, 12, and 13 of the subfont + having the infix `03' the character codes 0x2349, 0x2345, 0x2346, + and 0x2347, respectively. + +The SFD files in the distribution are customized for the CJK package +for LaTeX. + +You have to embed the SFD file into the TFM font name (at the place +where the infix will appear) surrounded by two `@' signs, on the +command line resp. the ttfonts.map file; both ttf2tfm and ttf2pk +switch then to subfont mode. + +Subfont mode disables the options `-n', `-N', `-p', `-r', `-R', `-t', +`-T', `-u', `-v', and `-V' for ttf2tfm; similarly, no `Encoding' and +`Replacement' parameter resp. single replacement glyph names are +allowed in ttfonts.map. + +ttf2tfm will create ALL subfont TFM files specified in the SFD files +(provided the subfont contains glyphs) in one run. + +Example: + + The call + + ttf2tfm ntukai.ttf ntukai@/usr/local/lib/ttf2tfm/Big5@ + + will use `/usr/local/lib/ttf2tfm/Big5.sfd', producing the subfont + files ntukai01.tfm, ntukai02.tfm etc. + + ttf2pk should be then called on the subfonts directly: + + ttf2pk ntukai01 600 + ttf2pk ntukai02 600 + ... + + +Some notes on file searching +============================ + +Both ttf2pk and ttf2tfm use either the kpathsea, emtexdir, or MiKTeX +library for searching files (emtexdir will work only on operating +systems which have an MS-DOSish background, i.e. MS-DOS, OS/2, +Windows; MiKTeX is specific to MS Windows). + +During compilation, you have to define HAVE_KPATHSEA, HAVE_EMTEXDIR, +or MIKTEX to activate the specific file search code. + +As a last resort, both programs can be compiled without a search +library; the searched files must be then in the current directory or +specified with a path. Default extensions will be appended also (with +the exception that only `.ttf' is appended and not `.ttc'). + + +kpathsea +-------- + +Please note that older versions of kpathsea (<3.2) have no special +means to search for TrueType fonts and related files, thus we use the +paths for PostScript related stuff. The actual version of kpathsea is +displayed on screen if you call either ttf2pk or ttf2tfm with the +`--version' command line switch. + +Here is a table of the file type and the corresponding kpathsea +variables. TTF2PKINPUTS and TTF2TFMINPUTS are program specific +environment variables introduced in kpathsea version 3.2: + + .ttf and .ttc TTFONTS + ttfonts.map TTF2PKINPUTS + .enc TTF2PKINPUTS, TTF2TFMINPUTS + .rpl TTF2PKINPUTS, TTF2TFMINPUTS + .tfm TFMFONTS + .sfd TTF2PKINPUTS, TTF2TFMINPUTS + +And here the same for pre-3.2-versions of kpathsea: + + .ttf and .ttc T1FONTS + ttfonts.map TEXCONFIG + .enc TEXPSHEADERS + .rpl TEXPSHEADERS + .tfm TFMFONTS + .sfd TEXPSHEADERS + +Finally, the same for pre-3.0-versions: + + .ttf and .ttc DVIPSHEADERS + ttfonts.map TEXCONFIG + .enc DVIPSHEADERS + .rpl DVIPSHEADERS + .tfm TFMFONTS + .sfd DVIPSHEADERS + +Please consult the info files for kpathsea for details on these +variables. The decision whether to use the old or the new scheme will +be done during compilation. + +You should set the TEXMFCNF variable to the directory where your +texmf.cnf configuration file resides. + +The default TDS location for the files in the data subdirectory is + + $TEXMF/ttf2tfm + +(or $TEXMF/ttf2pk; you should either make a symbolic link + + % ln -s $TEXMF/ttf2tfm $TEXMF/ttf2pk + +or set the variable TTF2PKINPUTS to $TEXMF/ttf2tfm for newer kpathsea +versions) + +Here is the proper command to find out to which value a kpathsea +variable is set (we use `TTFONTS' as an example). This is especially +useful if a variable isn't set in texmf.cnf or in the environment, +thus pointing to the default value which is hard-coded into the +kpathsea library. + + % kpsewhich --progname=ttf2tfm --expand-var='$TTFONTS' + +We select the program name also since it is possible to specify +variables which are searched only for a certain program -- in our +example it would be `TTFONTS.ttf2tfm'. + +A similar but not identical method is to say + + % kpsewhich --progname=ttf2tfm --show-path='truetype fonts' + +[A full list of format types can be obtained by saying `kpsewhich +--help' on the command line prompt.] This is exactly the how ttf2tfm +(and ttf2pk) search for files; the disadvantage is that all variables +are expanded which can cause very long string. + + +emtexdir +-------- + +Here the list of suffixes and its related environment variables to be +set in autoexec.bat (resp. in config.sys for OS/2): + + .ttf and .ttc TTFONTS + ttfonts.map TTFCFG + .enc TTFCFG + .rpl TTFCFG + .tfm TEXTFM + .sfd TTFCFG + +With other words, all files in the data subdirectory should be moved +to a place in your emtex tree with TTFCFG pointing to this directory. + +If one of the variables isn't set, a warning message is emitted. The +current directory will always be searched. As usual, one exclamation +mark appended to a directory path causes subdirectories one level deep +to be searched, two exclamation marks causes all subdirectories to be +searched. Example: + + TTFONTS=c:\fonts\truetype!!;d:\myfonts\truetype! + +Constructions like `c:\fonts!!\truetype' aren't possible. + + +MiKTeX +------ + +Both ttf2tfm and ttf2pk have been fully integrated into MiKTeX. +Please refer to the documentation of MiKTeX for more details on file +searching. + + + +A full example +============== + +Here an example how to handle the font `verdana.ttf' and its variants. + + +1. Construct the font name +-------------------------- + + [This is the most complicated part -- in case you are too lazy to + construct font names compliant to TeX's `fontname' scheme, just use + your own names.] + + Using the `ftdump' utility (which is part of FreeType) you can find + out the PostScript name of the specific TTF which is probably the + best choice to adapt TrueType fonts to the PostScript-oriented + `fontname' scheme. + + In our example, the PostScript name is `Verdana'. + + `fontname' uses the scheme + + S TT W [V...] [N] [E] [DD] + + as documented in `fontname.texi' resp. `fontname.dvi'. Now you have + to check the various mapping files: + + S: supplier.map: `j' for `Microsoft' + TT: typeface.map: `vn' for `Verdana' + W: weight.map: `r' for `Regular Roman', + `b' for `bold' + V, + N: variant.map: `8r' for the raw base font + `8t' for the virtual font + (i.e., LaTeX's T1 encoding) + [additionally an inserted `c' for small caps, + `o' for slanted (`oblique'), or `i' for italic + fonts] + + Here the standard combinations: + + `jvnr8r' for the default base font. + `jvnr8t' for the virtual default font. + `jvnrc8t' for the virtual font with small caps. [As you can see, + no additional raw font is needed.] + `jvnro8r' for the slanted base font. + `jvnro8t' for the virtual slanted font. + + The corresponding variants are: + + bold: verdanab.ttf -> jvnb{8r,8t} + small caps: jvnbc8t + slanted: jvnbo{8r,8t} + italic: verdanai.ttf -> jvni{8r,8t} + bold and italic: verdanaz.ttf -> jvnbi{8r,8t} + + +2. Font definition files +------------------------ + + The FD file should be called `t1jvn.fd' (as you can see, this is T1 + encoding). It is very similar to `t1ptm.fd', part of the PSNFSS + package (which can be found in almost all TeX distributions). A + `verdana.sty' file can also be modeled after `times.sty'. + + +3. Calling ttf2tfm +------------------ + + To make the example simpler, we use `T1-WGL4.enc' for both the raw + and the virtual encoding. This should be sufficient for most + TrueType fonts mapped to T1 encoding. Other packages may define + other encodings (e.g. the `t2' package available from CTAN defines + mapping files for Cyrillic encodings) -- it may also be necessary to + use the `-n' or `-N' switch together with replacement glyph names to + access all glyph names in the TrueType font. + + To create `jvnr8r' and `jvnr8t', just call + + ttf2tfm verdana -T T1-WGL4 -v jvnr8t jvnr8r + vptovf jvnr8t + + For `jvnrc8t', do + + ttf2tfm verdana -T T1-WGL4 -V jvnrc8t jvnr8r + vptovf jvnrc8t + + Note that almost always some warnings will appear about missing + glyphs. + + The last line written to stdout by ttf2tfm is a suitable entry for + ttfonts.map -- since ttf2pk doesn't care about virtual fonts, both + calls below produce the same. + + Now just repeat this procedure. For slanted fonts you should + additionally use the switch `-s 0.176' (of course you can change the + slanting amount to make it fit your needs). + + + +Problems +======== + +Most vptovf implementations allow only 100 bytes for the TFM header +(the limit is 1024 in the TFM file itself): 8 bytes for checksum and +design size, 40 bytes for the family name, 20 bytes for the encoding, +and 4 bytes for a face byte. There remain only 28 bytes for some +additional information which is used by ttf2tfm for an identification +string (which is essentially a copy of the command line), and this +limit is always exceeded. + +The optimal solution is to increase the value of `max_header_bytes' in +the file vptovf.w (and probably pltotf.w) to, say, 400 and recompile +vptovf (and pltotf). Otherwise you'll get some (harmless) error +messages like + + This HEADER index is too big for my present table size + +which can be safely ignored. + + +--- end of ttf2pk.doc --- diff --git a/contrib/ttf2pk/ttf2tfm.1 b/contrib/ttf2pk/ttf2tfm.1 new file mode 100644 index 0000000..7e6bad9 --- /dev/null +++ b/contrib/ttf2pk/ttf2tfm.1 @@ -0,0 +1,1095 @@ +.\" man page for ttf2tfm +. +.TH TTF2TFM 1 15-Aug-1999 "FreeType version 1.3" +.SH NAME +ttf2tfm \- build TeX metric files from a TrueType font +.SH SYNOPSIS +.na +.nh +.B ttf2tfm +.in +\n(.ku +.sp -1 +.IR ttffile [ .ttf | .ttc ] +[\c +.BI -c \ \%caps-height-factor\c +] +[\c +.BI -e \ \%extension-factor\c +] +[\c +.BI -E \ \%encoding-id\^\c +] +[\c +.BI -f \ \%font-index\c +] +[\c +.B -l\c +] +[\c +.B -n\c +] +[\c +.B -N\c +] +[\c +.B -O\c +] +[\c +.B -p\ \c +.IR \%inencfile [ .enc ]\c +] +[\c +.BI -P \ \%platform-id\^\c +] +[\c +.B -q\c +] +[\c +.BI -r \ \%old-glyphname\ \%new-glyphname\c +] +[\c +.B -R\ \c +.IR \%replacement-file [ .rpl ]\c +] +[\c +.BI -s \ \%slant-factor\c +] +[\c +.B -t\ \c +.IR \%outencfile [ .enc ]\c +] +[\c +.B -T\ \c +.IR \%inoutencfile [ .enc ]\c +] +[\c +.B -u\c +] +[\c +.B -v\ \c +.IR \%vplfile [ .vpl ]\c +] +[\c +.B -V\ \c +.IR \%scvplfile [ .vpl ]\c +] +[\c +.B -x\c +] +[\c +.BI -y \ \%vertical-shift-factor\c +] +[\c +.IR \%tfmfile [ .tfm ]\c +] +.br +.in +.B "ttf2tfm --version" +| +.B --help +.ad +.hy +. +. +. +.\" ==== +.\" ==== macro definitions +.\" ==== +. +.\" here we define \TeX for troff and nroff +.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP +.if n .ds TX TeX +. +.\" and here the same for \LaTeX +.if t \{\ +.ie '\*(.T'dvi' \ +.ds LX \fRL\h'-0.36m'\v'-0.15v'\s-3A\s0\h'-0.15m'\v'0.15v'\fP\*(TX +.el .ds LX \fRL\h'-0.36m'\v'-0.22v'\s-2A\s0\h'-0.15m'\v'0.22v'\fP\*(TX +.\} +.if n .ds LX LaTeX +. +.\" \LaTeXe +.\" note that we need \vareps for TeX instead of \eps which can only be +.\" accessed with the \N escape sequence (in the Math Italic font) +.if t \{\ +.ie '\*(.T'dvi' .ds LE \*(LX\h'0.15m'2\v'0.20v'\f(MI\N'34'\fP\v'-0.20v' +.el .ds LE \*(LX\h'0.15m'2\v'0.20v'\(*e\v'-0.20v' +.\} +.if n .ds LE LaTeX\ 2e +. +.\" a typewriter font +.if t \{\ +.de C +\fC\\$1\fP\\$2\fC\\$3\fP\\$4 +.. +.\} +.if n \{\ +.de C +\\$1\\$2\\$3\\$4 +.. +.\} +. +.\" ==== +.\" ==== end of macro definitions +.\" ==== +. +. +. +.SH DESCRIPTION +This program extracts the metric and kerning information of a TrueType +font and converts it into metric files usable by \*(TX +(quite similar to +.B afm2tfm +which is part of the +.B dvips +package; please consult its info files for more details on the various +parameters (especially encoding files). +.PP +Since a TrueType font often contains more than 256\ glyphs, some means +are necessary to map a subset of the TrueType glyphs into a \*(TX +font. +To do this, two mapping tables are needed: the first (called `input' or +`raw' encoding) maps the TrueType font to a raw \*(TX font (this mapping +table is used by both +.B ttf2tfm +and +.BR ttf2pk ), +and the second (called `output' or `virtual' encoding) maps the raw \*(TX +font to another (virtual) \*(TX +font, providing all kerning and ligature information needed by \*(TX. +.PP +This two stage mapping has the advantage that one raw font can be +accessed with various \*(TX +encodings (e.g.\ T1 and OT1) via the virtual font mechanism, and just +one +.C PK +file is necessary. +.PP +For CJKV (Chinese/Japanese/Korean/old Vietnamese) fonts, a different +mechanism is provided (see +.B "SUBFONT DEFINITION FILES" +below). +. +. +.SH PARAMETERS +Most of the command line switch names are the same as in +.B afm2tfm +for convenience. +One or more space characters between an option and its value is mandatory; +options can't be concatenated. +For historical reasons, the first parameter can +.I not +be a switch but must be the font name. +.TP +.BI -c \ caps-height-factor +The height of small caps made with the +.B -V +switch. +Default value of this real number is\ 0.8 times the height of uppercase +glyphs. +Will be ignored in subfont mode. +.TP +.BI -e \ extension-factor +The extension factor to stretch the characters horizontally. +Default value of this real number is\ 1.0; if less than\ 1.0, you get a +condensed font. +.TP +.BI -E \ encoding-id +The TrueType encoding ID. +Default value of this non-negative integer is\ 1. +Will be ignored if +.B -N +is used. +.TP +.BI -f \ font-index +The font index in a TrueType Collection. +Default is the first font (index\ 0). +Will be ignored for ordinary TrueType fonts. +[TrueType collections are usually found in some CJK fonts; e.g.\ the first +font index specifies glyphs and metrics for horizontal writing, and the +second font index does the same for vertical writing. +TrueType collections usually have the extension `\c +.C \&.ttc '.] +.TP +.B -l +Create ligatures in subfonts between first and second bytes of all the +original character codes. +Example: Character code\ 0xABCD maps to character position\ 123 in +subfont\ 45. +Then a ligature in subfont\ 45 between position 0xAB and\ 0xCD pointing +to character\ 123 will be produced. +The fonts of the Korean H\*(LX +package use this feature. +Will be ignored if not in subfont mode. +.TP +.B -n +Use PS names (of glyphs) of the TrueType font. +Will be ignored in subfont mode. +Only glyphs with a valid entry in the selected cmap are used. +.TP +.B -N +Use only PS names of the TrueType font. +No cmap is used, thus the switches +.B -E +and +.B -P +have no effect, causing a warning message. +Will be ignored in subfont mode. +.TP +.B -O +Use octal values for all character codes in the +.C VPL +file rather than names; this is useful for symbol or CJK fonts where +character names such as `A' are meaningless. +.TP +.BI -p \ inencfile +The input encoding file name for the TTF\(->raw\ \*(TX +mapping. +This parameter has to be specified in +.C \%ttfonts.map +for successive +.B ttf2pk +calls. +Will be ignored in subfont mode. +.TP +.BI -P \ platform-id +The TrueType platform ID. +Default value of this non-negative integer is\ 3. +Will be ignored if +.B -N +is used. +.TP +.B -q +Make +.B ttf2tfm +quiet. +It suppresses any informational output except warning and error +messages. +For CJK fonts, the output can get quite large if you don't specify +this switch. +.TP +.BI -r \ old-glyphname\ new-glyphname +Replaces +.I \%old-glyphname +with +.IR \%new-glyphname . +This switch is useful if you want to give an unnamed glyph (i.e., a glyph +which can be represented with `.gXXX' or `.cXXX' only) a name or if you want +to rename an already existing glyph name. +You can't use the `.gXXX' or `.cXXX' glyph name constructs for +.IR \%new-glyphname ; +multiple occurrences of +.B -r +are possible. +If in subfont mode or if no encoding file is specified, this switch is +ignored. +.TP +.BI -R \ replacement-file +Use this switch if you have many replacement pairs; they can be collected +in a file which should have `\c +.C \&.rpl ' +as extension. +The syntax used in such replacement files is simple: Each non-empty +line must contain a pair `\c +.IR "\%old-glyphname \%new-glyphname" ' +separated by whitespace (without the quotation marks). +A percent sign starts a line comment; you can continue a line on the next +line with a backslash as the last character. +If in subfont mode or if no encoding file is specified, this switch is +ignored. +.TP +.BI -s \ slant-factor +The obliqueness factor to slant the font, usually much smaller than\ 1. +Default of this real number is\ 0.0; if the value is larger than zero, +the characters slope to the right, otherwise to the left. +.TP +.BI -t \ outencfile +The output encoding file name for the virtual font(s). +Only characters in the raw \*(TX +font are used. +Will be ignored in subfont mode. +.TP +.BI -T \ inoutencfile +This is equivalent to +.RB ` -p +.I inoutencfile +.B -t +.IR inoutencfile '. +Will be ignored in subfont mode. +.TP +.B -u +Use only those characters specified in the output encoding, and no +others. +By default, +.B ttf2tfm +tries to include all characters in the virtual font, even those not +present in the encoding for the virtual font (it puts them into +otherwise-unused positions, rather arbitrarily). +Will be ignored in subfont mode. +.TP +.BI -v \ vplfile +Output a +.C VPL +file in addition to the +.C TFM +file. +If no output encoding file is specified, +.B ttf2tfm +uses a default font encoding (cmtt10). +Will be ignored in subfont mode. +.TP +.BI -V \ scvplfile +Same as +.BR -v , +but the virtual font generated is a pseudo small caps font obtained by +scaling uppercase letters by\ 0.8 (resp. the value specified with +.BR -c ) +to typeset lowercase. +This font handles accented letters and retains proper kerning. +Will be ignored in subfont mode. +.TP +.B -x +Rotate all glyphs by 90 degrees counter-clockwise. +If no +.B -y +parameter is given, the rotated glyphs are shifted down vertically +by\ 0.25em. +Will be ignored if not in subfont mode. +.TP +.BI -y \ vertical-shift-factor +Shift down rotated glyphs by the given amount (the unit is +.IR em ). +Ignored if not in subfont mode or glyphs are not rotated. +.TP +.B --version +Shows the current version of +.B ttf2tfm +and the used file search library (e.g. +.BR kpathsea ). +.TP +.B --help +Shows usage information. +.PP +If no +.C TFM +file name is given, the name of the +.C TTF +file is used, including the full path and replacing the extension with `\c +.C \&.tfm '. +. +. +.SH CMAPS +Contrary to Type\ 1 PostScript fonts (but similar to the new CID +PostScript font format), most TrueType fonts have more than one native +mapping table, also called `cmap', which maps the (internal) TTF glyph +indices to the (external) TTF character codes. +Common examples are a mapping table to Unicode encoded character +positions, and the standard Macintosh mapping. + +To specify a TrueType mapping table, use the options +.B -P +and +.BR -E . +With +.B -P +you specify the platform ID; defined values are: +.PP +.in +4m +.ta 3iC +.I "platform platform ID (pid)" +.sp +.ta 3iR +Apple Unicode 0 +.br +Macintosh 1 +.br +ISO 2 +.br +Microsoft 3 +.PP +The encoding ID depends on the platform. +For pid=0, we ignore the +.B -E +parameter (setting it to zero) since the mapping table is always +Unicode version\ 2.0. +For pid=1, the following table lists the defined values: +.PP +.in +4m +.ta 3iC +.ti -2m +platform ID = 1 +.sp +.I "script encoding ID (eid)" +.sp +.ta 3iR +Roman 0 +.br +Japanese 1 +.br +Chinese 2 +.br +Korean 3 +.br +Arabic 4 +.br +Hebrew 5 +.br +Greek 6 +.br +Russian 7 +.br +Roman Symbol 8 +.br +Devanagari 9 +.br +Gurmukhi 10 +.br +Gujarati 11 +.br +Oriya 12 +.br +Bengali 13 +.br +Tamil 14 +.br +Telugu 15 +.br +Kannada 16 +.br +Malayalam 17 +.br +Sinhalese 18 +.br +Burmese 19 +.br +Khmer 20 +.br +Thai 21 +.br +Laotian 22 +.br +Georgian 23 +.br +Armenian 24 +.br +Maldivian 25 +.br +Tibetan 26 +.br +Mongolian 27 +.br +Geez 28 +.br +Slavic 29 +.br +Vietnamese 30 +.br +Sindhi 31 +.br +Uninterpreted 32 +.PP +Here are the ISO encoding IDs: +.PP +.in +4m +.ta 3iC +.ti -2m +platform ID = 2 +.sp +.I "encoding encoding ID (eid)" +.sp +.ta 3iR +ASCII 0 +.br +ISO 10646 1 +.br +ISO 8859-1 2 +.PP +And finally, the Microsoft encoding IDs: +.PP +.in +4m +.ta 3iC +.ti -2m +platform ID = 3 +.sp +.I "encoding encoding ID (eid)" +.sp +.ta 3iR +Symbol 0 +.br +Unicode 2.0 1 +.br +Shift JIS 2 +.br +GB 2312 (1980) 3 +.br +Big 5 4 +.br +KSC 5601 (Wansung) 5 +.br +KSC 5601 (Johab) 6 +.PP +The program will abort if you specify an invalid platform/encoding ID +pair. +It will then show the possible pid/eid pairs. +Please note that most fonts have at most two or three cmaps, usually +corresponding to the pid/eid pairs (1,0), (3,0), or (3,1) in case of +Latin based fonts. +Valid Microsoft fonts should have a (3,1) mapping table, but some +fonts exist (mostly Asian fonts) which have a (3,1) cmap not encoded +in Unicode. +The reason for this strange behavior is the fact that some MS\ Windows +versions will reject fonts having a non-(3,1) cmap (since all non-Unicode +Microsoft encoding IDs are for Asian MS\ Windows versions). +.PP +The +.B -P +and +.B -E +options of +.B ttf2tfm +must be equally specified for +.BR ttf2pk ; +the corresponding parameters in +.C \%ttfonts.map +are `Pid' and `Eid', respectively. +.PP +The default pid/eid pair is (3,1). +.PP +Similarly, an +.B -f +option must be specified as `Fontindex' parameter in +.C \%ttfonts.map . +.PP +If you use the +.B -N +switch, all cmaps are ignored, using only the PostScript names in the +TrueType font. +The corresponding option in +.C \%ttfonts.map +is \%`PS=Only'. +If you use the +.B -n +switch, the default glyph names built into +.B ttf2tfm +are replaced with the PS glyph names found in the font. +In many cases this is not what you want because the glyph names in the +font are often incorrect or non-standard. +The corresponding option in +.C \%ttfonts.map +is \%`PS=Yes'. +.PP +Single replacement glyph names specified with +.B -r +must be given directly as `\c +.IR old-glyphname = new-glyphname '; +.B -R +is equivalent to the `Replacement' option. +. +. +.SH INPUT AND OUTPUT ENCODINGS +You must specify the encoding vectors from the TrueType font to the +raw \*(TX +font and from the raw \*(TX +font to the virtual \*(TX +font exactly as with +.BR afm2tfm , +but you have more possibilities to address the character codes. +[With `encoding vector' a mapping table with 256\ entries in form of a +PostScript vector is meant; see the file +.C \%T1-WGL4.enc +of this package for an example.] +With +.BR afm2tfm , +you must access each glyph with its Adobe glyph name, e.g.\ \c +\%`/quotedsingle' or \%`/Acircumflex'. +This has been extended with +.BR ttf2tfm ; +now you can (and sometimes must) access the code points and/or glyphs +directly, using the following syntax for specifying the character position +in decimal, octal, or hexadecimal notation: +`/.c\c +.IR ', +`/.c0\c +.IR ', +or `/.c0x\c +.IR '. +Examples: \%`/.c72', \%`/.c0646', \%`/.c0x48'. +To access a glyph index directly, using the character `g' instead of +`c' in the just introduced notation. +Example: \%`/.g0x32'. +[Note: The `.cXXX' notation makes no sense if +.B -N +is used.] +.PP +For pid/eid pairs (1,0) and (3,1), both +.B ttf2tfm +and +.B ttf2pk +recognize built-in default Adobe glyph names; the former follows the names +given in Appendix\ E of the book `Inside Macintosh', volume\ 6, the latter +uses the names given in the TrueType Specification (WGL4, a Unicode subset). +Note that Adobe names for a given glyph are often not unique and do +sometimes differ, e.g., many PS fonts have the glyph `mu', whereas this +glyph is called `mu1' in the WGL4 character set to distinguish it from the +real Greek letter mu. +Be also aware that OpenType (i.e. TrueType\ 2.0) fonts use an updated WGL4 +table; we use the data from the latest published TrueType specification +(1.66). +You can find those mapping tables in the source code file +.C \%ttfenc.c . +.PP +On the other hand, the switches +.B -n +and +.B -N +makes +.B ttf2tfm +read in and use the PostScript names in the TrueType font itself (stored +in the `post' table) instead of the default Adobe glyph names. +.PP +Use the +.B -r +switch to remap single glyph names and +.B -R +to specify a file containing replacement glyph name pairs. +.PP +If you don't select an input encoding, the first 256\ glyphs of the +TrueType font with a valid entry in the selected cmap will be mapped +to the \*(TX +raw font (without the +.B -q +option, +.B ttf2tfm +prints this mapping table to standard output), followed by all glyphs +not yet addressed in the selected cmap. +However, some code points for the (1,0) pid/eid pair are omitted since +they do not represent glyphs useful for \*(TX: +0x00 (null), 0x08 (backspace), 0x09 (horizontal tabulation), 0x0d +(carriage return), and 0x1d (group separator). +The `invalid character' with glyph index\ 0 will be omitted too. +.PP +If you select the +.B -N +switch, the first 256\ glyphs of the TrueType font with a valid PostScript +name will be used in case no input encoding is specified. +Again, some glyphs are omitted: `.notdef', `.null', and +`nonmarkingreturn'. +.PP +If you don't select an output encoding, +.B ttf2tfm +uses the same mapping table as +.B afm2tfm +would use (you can find it in the source code file +.C \%texenc.c ); +it corresponds to \*(TX +typewriter text. +Unused positions (either caused by empty code points in the mapping +table or missing glyphs in the TrueType font) will be filled (rather +arbitrarily) with characters present in the input encoding but not +specified in the output encoding (without the +.B -q +option +.B ttf2tfm +prints the final output encoding to standard output). +Use the +.B -u +option if you want only glyphs in the virtual font which are defined +in the output encoding file, and nothing more. +.PP +One feature missing in +.B afm2tfm +has been added which is needed by the T1 encoding: +.B ttf2tfm +will construct the glyph `Germandbls' (by simply concatenating to `S' +glyphs) even for normal fonts if possible. +It appears in the glyph list as the last item, marked with an asterisk. +Since this isn't a real glyph it will be available only in the virtual +font. +.PP +For both input and output encoding, an empty code position is +represented by the glyph name \%`/.notdef'. +.PP +In encoding files, you can use `\\' as the final character of a line to +indicate that the input is continued on the next line. +The backslash and the following newline character will be removed. +.PP +. +. +.SH SUBFONT DEFINITION FILES +CJKV (Chinese/Japanese/Korean/old Vietnamese) fonts usually contain several +thousand glyphs; to use them with \*(TX +it is necessary to split such large fonts into subfonts. +Subfont definition files (usually having the extension `\c +.C \&.sfd ') +are a simple means to do this smoothly. +.PP +A subfont file name usually consists of a prefix, a subfont infix, and +a postfix (which is empty in most cases), e.g. +.PP +.in +2m +ntukai23 \(-> prefix: ntukai, infix: 23, postfix: (empty) +.PP +Here the syntax of a line in an +.C SFD +file, describing one subfont: +.in +2m +.TP +.I +.sp +.TP +.IR \ := +anything except whitespace. +It's best to use only alphanumerical characters. +.TP +.IR \ := +space, formfeed, carriage return, horizontal and vertical tabs -- no +newline characters. +.TP +.IR \ := +.IR " " \ | +.br +.IR " " \ | +.br +.I +.TP +.IR \ := +.I +.br +.TP +.IR \ := +.IR \ `_' \ +.br +.TP +.IR \ := +.IR \ `:' +.TP +.IR \ := +hexadecimal (prefix `0x'), decimal, or octal (prefix `0') +.PP +A line can be continued on the next line with a backslash ending the line. +The ranges must not overlap; offsets have to be in the range 0-255. +.PP +Example: +.PP +.in +2m +The line +.PP +.in +4m +.C "03 10: 0x2349 0x2345_0x2347" +.PP +.in +2m +assigns to the code positions 10, 11, 12, and\ 13 of the subfont +having the infix `03' the character codes 0x2349, 0x2345, 0x2346, and +0x2347 respectively. +.PP +The +.C SFD +files in the distribution are customized for the CJK package for +\*(LX. +.PP +You have to embed the +.C SFD +file name into the +.C TFM +font name (at the place where the infix will appear) surrounded by two +`@' signs, on the command line resp.\ the +.C \%ttfonts.map +file; both +.B ttf2tfm +and +.B ttf2pk +switch then to subfont mode. +.PP +Subfont mode disables the options +.BR -n , \ -N , \ -p , +.BR -r , \ -R , \ -t , +.BR -T , \ -u , \ -v , +and +.B -V +for +.BR ttf2tfm ; +similarly, no `Encoding' or `Replacement' parameter is allowed in +.C \%ttfonts.map . +Single replacement glyph names are ignored too. +.PP +.B ttf2tfm +will create all subfont +.C TFM +files specified in the +.C SFD +files (provided the subfont contains glyphs) in one run. +.PP +Example: +.PP +.in +2m +The call +.PP +.in +4m +.C "ttf2tfm ntukai.ttf ntukai@/usr/local/lib/ttf2tfm/Big5@" +.PP +.in +2m +will use +.C /usr/local/lib/ttf2tfm/Big5.sfd , +producing +.I all +subfont files +.C ntukai01.tfm , +.C ntukai02.tfm , +etc. +. +. +.SH "RETURN VALUE" +ttf2tfm returns 0 on success and 1 on error; warning and error +messages are written to standard error. +. +. +.SH "SOME NOTES ON FILE SEARCHING" +Both +.B ttf2pk +and +.B ttf2tfm +use either the +.BR kpathsea , +.BR emtexdir , +or +.B MiKTeX +library for searching files +.RB ( emtexdir +will work only on operating systems which have an MS-DOSish background, i.e. +MS-DOS, OS/2, Windows; +.B MiKTeX +is specific to MS Windows). +.PP +As a last resort, both programs can be compiled without a search library; +the searched files must be then in the current directory or specified with a +path. +Default extensions will be appended also (with the exception that only `\c +.C \&.ttf ' +is appended and not `\c +.C \&.ttc '). +.PP +KPATHSEA +.PP +Please note that older versions of +.B kpathsea +(<3.2) have no special means to seach for TrueType fonts and related +files, thus we use the paths for PostScript related stuff. +The actual version of kpathsea is displayed on screen if you call +either +.B ttf2pk +or +.B ttf2tfm +with the +.B --version +command line switch. +.PP +Here is a table of the file type and the corresponding +.B kpathsea +variables. +.C TTF2PKINPUTS +and +.C TTF2TFMINPUTS +are program specific environment variables introduced in +.B kpathsea +version\ 3.2: +.PP +.in +4m +.ta 2i +.C \&.ttf \ and "\ .ttc TTFONTS" +.br +.C "ttfonts.map TTF2PKINPUTS" +.br +.C "\&.enc TTF2PKINPUTS, TTF2TFMINPUTS" +.br +.C "\&.rpl TTF2PKINPUTS, TTF2TFMINPUTS" +.br +.C "\&.tfm TFMFONTS" +.br +.C "\&.sfd TTF2PKINPUTS, TTF2TFMINPUTS" +.PP +And here the same for pre-3.2-versions of +.B kpathsea: +.PP +.in +4m +.ta 2i +.C \&.ttf \ and "\ .ttc T1FONTS" +.br +.C "ttfonts.map TEXCONFIG" +.br +.C "\&.enc TEXPSHEADERS" +.br +.C "\&.rpl TEXPSHEADERS" +.br +.C "\&.tfm TFMFONTS" +.br +.C "\&.sfd TEXPSHEADERS" +.PP +Finally, the same for pre-3.0-versions (as used e.g. in te\*(TX\ 0.4): +.PP +.in +4m +.ta 2i +.C \&.ttf \ and "\ .ttc DVIPSHEADERS" +.br +.C "ttfonts.map TEXCONFIG" +.br +.C "\&.enc DVIPSHEADERS" +.br +.C "\&.rpl DVIPSHEADERS" +.br +.C "\&.tfm TFMFONTS" +.br +.C "\&.sfd DVIPSHEADERS" +.PP +Please consult the info files of +.B kpathsea +for details on these variables. +The decision whether to use the old or the new scheme will be done +during compilation. +.PP +You should set the +.C TEXMFCNF +variable to the directory where your +.C texmf.cnf +configuration file resides. +.PP +Here is the proper command to find out to which value a +.B kpathsea +variable is set (we use +.C TTFONTS +as an example). +This is especially useful if a variable isn't set in +.C texmf.cnf +or in the environment, thus pointing to the default value which is +hard-coded into the +.B kpathsea +library. +.PP +.in +2m +.C "kpsewhich -progname=ttf2tfm -expand-var='$TTFONTS'" +.PP +We select the program name also since it is possible to specify +variables which are searched only for a certain program -- in our +example it would be +.C TTFONTS.ttf2tfm . +.PP +A similar but not identical method is to say +.PP +.in +2m +.C "kpsewhich -progname=ttf2tfm -show-path='truetype fonts'" +.PP +[A full list of format types can be obtained by saying `\c +.C "kpsewhich --help" ' +on the command line prompt.] +This is exactly the how +.B ttf2tfm +(and +.BR ttf2pk ) +search for files; the disadvantage is that all variables are expanded +which can cause very long strings. +.PP +EMTEXDIR +.PP +Here the list of suffixes and its related environment variables to be +set in +.C autoexec.bat +(resp. in +.C config.sys +for OS/2): +.PP +.in +4m +.ta 2i +.C \&.ttf \ and "\ .ttc TTFONTS" +.br +.C "ttfonts.map TTFCFG" +.br +.C "\&.enc TTFCFG" +.br +.C "\&.rpl TTFCFG" +.br +.C "\&.tfm TEXTFM" +.br +.C "\&.sfd TTFCFG" +.PP +If one of the variables isn't set, a warning message is emitted. +The current directory will always be searched. +As usual, one exclamation mark appended to a directory path causes +subdirectories one level deep to be searched, two exclamation marks causes +all subdirectories to be searched. +Example: +.PP +.in +2m +.C TTFONTS=c:\\\\fonts\\\\truetype!!;d:\\\\myfonts\\\\truetype! +.PP +Constructions like `\c +.C c:\\\\fonts!!\\\\truetype ' +aren't possible. +.PP +MIKTEX +.PP +Both +.B ttf2tfm +and +.B ttf2pk +have been fully integrated into +.BR MiKTeX . +Please refer to the documentation of +.B MiKTeX +for more details on file searching. +. +. +.SH PROBLEMS +Most +.B vptovf +implementations allow only 100\ bytes for the +.C TFM +header (the limit is 1024 in the +.C TFM +file itself): 8\ bytes for checksum and design size, 40\ bytes for the +family name, 20\ bytes for the encoding, and 4\ bytes for a face byte. +There remain only 28\ bytes for some additional information which is used by +.B ttf2tfm +for an identification string (which is essentially a copy of the command +line), and this limit is always exceeded. + +The optimal solution is to increase the value of +.I \%max_header_bytes +in the file +.C vptovf.web +(and probably +.C pltotf.web +too) to, say,\ 400 +and recompile +.B vptovf +(and +.BR pltotf ). +Otherwise you'll get some (harmless) error messages like +.PP +.in +2m +.C "This HEADER index is too big for my present table size" +.PP +which can be safely ignored. +. +. +.SH "SEE ALSO" +.BR ttf2pk (1), +.BR afm2tfm (1), +.BR vptovf (1), +.br +the info pages for +.B dvips +and +.B kpathsea +. +. +.SH AVAILABILITY +.B ttf2tfm +is part of the FreeType package, a high quality TrueType rendering +library. +. +. +.SH AUTHORS +Werner LEMBERG +.C +.br +Fr\('ed\('eric LOYER +.C diff --git a/contrib/ttf2pk/ttf2tfm.c b/contrib/ttf2pk/ttf2tfm.c new file mode 100644 index 0000000..5d97420 --- /dev/null +++ b/contrib/ttf2pk/ttf2tfm.c @@ -0,0 +1,885 @@ +/* + * ttf2tfm.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg . + */ + +/* + * This program converts TTF files to TeX TFM files, and optionally + * to TeX VPL files that retain all kerning and ligature information. + * Both files make the characters not normally encoded by TeX available + * by character codes greater than 0x7F. + */ + +/* + * Adapted from afm2tfm by F. Loyer . + */ + +#include +#include +#include /* for size_t */ +#include + +#include "ttf2tfm.h" +#include "newobj.h" +#include "ttfenc.h" +#include "ligkern.h" +#include "texenc.h" +#include "ttfaux.h" +#include "tfmaux.h" +#include "vplaux.h" +#include "errormsg.h" +#include "filesrch.h" +#include "parse.h" +#include "subfont.h" + + +char ident[] = "ttf2tfm version 1.3"; +char progname[] = "ttf2tfm"; /* for error/warning messages */ + +/* command line options */ + +static char makevpl; /* can be 1 or 2 */ +static Boolean pedantic; +static Boolean quiet; +static Boolean forceoctal; + + +/* + * Re-encode the TTF font. + */ + +static void +handlereencoding(Font *fnt) +{ + int i; + ttfinfo *ti; + char *p; + + + if (fnt->inencname) + { + fnt->inencoding = readencoding(&(fnt->inencname), fnt, True); + + /* reset all pointers in the mapping table */ + for (i = 0; i <= 0xFF; i++) + if (NULL != (ti = fnt->inencptrs[i])) + { + ti->incode = -1; + fnt->inencptrs[i] = NULL; + } + + /* + * Reencode TTF <--> raw TeX. Only these code points will be used + * for the output encoding. + */ + + for (i = 0; i <= 0xFF; i++) + { + p = fnt->inencoding->vec[i]; + if (p && *p) + { + if ((ti = findadobe(p, fnt->charlist))) + { + if (ti->incode >= 0) + { + warning("Character `%s' encoded twice in input encoding\n" + " (positions %x and %x; the latter is ignored).", + p, ti->incode, i); + fnt->inencoding->vec[i] = ".notdef"; + continue; + } + if (ti->charcode >= 0) + { + ti->incode = i; + fnt->inencptrs[i] = ti; + } + } + else + { + warning("Cannot find character `%s'\n" + " specified in input encoding.", p); + } + } + } + fnt->codingscheme = fnt->inencoding->name; + } + + if (!quiet) + { + if (fnt->inencname) + printf("\nUsing %s as input encoding.\n", fnt->inencname); + else + { + printf( + "\nUsing the first 256 glyphs in the following input encoding:\n\n"); + for (i = 0; i <= 0xFF; i++) + { + if ((ti = fnt->inencptrs[i])) + printf(" 0x%02x %s\n", i, ti->adobename); + } + printf("\n"); + } + } + + if (fnt->outencname) + fnt->outencoding = readencoding(&(fnt->outencname), fnt, False); + else + fnt->outencoding = readencoding(NULL, fnt, False); +} + + +static void +assignchars(Font *fnt) +{ + register char **p; + register int i, j, k; + register ttfinfo *ti; + int nextfree = 0x80; + + + /* + * First, we assign all those that match perfectly. + */ + + for (i = 0, p = fnt->outencoding->vec; i <= 0xFF; i++, p++) + if ((ti = findmappedadobe(*p, fnt->inencptrs))) + { + if (ti->outcode >= 0) + fnt->nextout[i] = ti->outcode; /* linked list */ + ti->outcode = i; + fnt->outencptrs[i] = ti; + } + else if (strcmp(*p, ".notdef") != 0) + warning("Cannot map character `%s'\n" + " specified in output encoding.", *p); + + if (pedantic) + goto end; + + /* + * Next, we assign all the others, retaining the TTF code positions, + * possibly multiplying assigned characters, unless the output encoding + * was precisely specified. + */ + + for (i = 0; i <= 0xFF; i++) + if ((ti = fnt->inencptrs[i]) && + ti->charcode >= 0 && ti->charcode <= 0xFF && + ti->outcode < 0 && fnt->outencptrs[ti->charcode] == NULL) + { + ti->outcode = ti->charcode; + fnt->outencptrs[ti->charcode] = ti; + } + + /* + * Finally, we map all remaining characters into free locations beginning + * with 0x80. + */ + + for (i = 0; i <= 0xFF; i++) + if ((ti = fnt->inencptrs[i]) && ti->outcode < 0) + { + while (fnt->outencptrs[nextfree]) + { + nextfree = (nextfree + 1) & 0xFF; + if (nextfree == 0x80) + goto finishup; /* all slots full */ + } + ti->outcode = nextfree; + fnt->outencptrs[nextfree] = ti; + } + +finishup: + + /* + * Now, if any of the characters are encoded multiple times, we want + * ti->outcode to be the first one assigned, since that is most likely + * to be the most important one. So we reverse the above lists. + */ + + for (i = 0; i <= 0xFF; i++) + if ((ti = fnt->inencptrs[i]) && ti->outcode >= 0) + { + k = -1; + while (fnt->nextout[ti->outcode] >= 0) + { + j = fnt->nextout[ti->outcode]; + fnt->nextout[ti->outcode] = k; + k = ti->outcode; + ti->outcode = j; + } + fnt->nextout[ti->outcode] = k; + } + +end: + + if (!quiet) + { + printf("\nUsing the following output encoding:\n\n"); + for (i = 0; i <= 0xFF; i++) + { + if ((ti = fnt->outencptrs[i])) + printf(" 0x%02x %s\n", i, ti->adobename); + } + printf("\n"); + } +} + + +#define VERSION "\ +Copyright (C) 1997-1999 Frederic Loyer and Werner Lemberg.\n\ +There is NO warranty. You may redistribute this software\n\ +under the terms of the GNU General Public License\n\ +and the Dvips copyright.\n\ +\n\ +For more information about these matters, see the files\n\ +named COPYING and ttf2tfm.c.\n\ +\n\ +Primary authors of ttf2tfm: F. Loyer and W. Lemberg.\n\ +\n\ +ttf2tfm is based on afm2tfm from T. Rokicki\n\ +and the FreeType project from\n\ +David Turner, Robert Wilhelm, and Werner Lemberg.\n\ +" + +static void +version(void) +{ + fputs(ident, stdout); + fprintf(stdout, " (%s)\n", TeX_search_version()); + fputs(VERSION, stdout); + exit(0); +} + + +#define USAGE "\ + Convert a TrueType font table to TeX's font metric format.\n\ +\n\ +-c REAL use REAL for height of small caps made with -V [0.8]\n\ +-e REAL widen (extend) characters by a factor of REAL [1.0]\n\ +-E INT select INT as the TTF encoding ID [1]\n\ +-f INT select INT as the font index in a TTC [0]\n\ +-l create 1st/2nd byte ligatures in subfonts\n\ +-n use PS names of TrueType font\n\ +-N use only PS names and no cmap\n\ +-O use octal for all character codes in the vpl file\n\ +-p ENCFILE[.enc] read ENCFILE for the TTF->raw TeX mapping\n\ +-P INT select INT as the TTF platform ID [3]\n\ +-q suppress informational output\n\ +-r OLDNAME NEWNAME replace glyph name OLDNAME with NEWNAME\n\ +-R RPLFILE[.rpl] read RPLFILE containing glyph replacement names\n\ +-s REAL oblique (slant) characters by REAL, usually <<1 [0.0]\n\ +-t ENCFILE[.enc] read ENCFILE for the encoding of the vpl file\n\ +-T ENCFILE[.enc] equivalent to -p ENCFILE -t ENCFILE\n\ +-u output only characters from encodings, nothing extra\n\ +-v FILE[.vpl] make a VPL file for conversion to VF\n\ +-V SCFILE[.vpl] like -v, but synthesize smallcaps as lowercase\n\ +-x rotate subfont glyphs by 90 degrees\n\ +-y REAL move rotated glyphs down by a factor of REAL [0.25]\n\ +--help print this message and exit\n\ +--version print version number and exit\n\ +" + +static void +usage(void) +{ + fputs("Usage: ttf2tfm FILE[.ttf|.ttc] [OPTION]... [FILE[.tfm]]\n", stdout); + fputs(USAGE, stdout); + exit(0); +} + + +static void +handle_options(int argc, char *argv[], Font *fnt) +{ + register int lastext; + register int i; + size_t l; + int arginc; + char *temp; + char c; + char *vpl_name = NULL; + Boolean have_capheight = 0; + Boolean have_sfd = 0; + int sfd_begin, postfix_begin; + int base_name; + stringlist* sl; + + + /* scan first whether the -q switch is set */ + for (i = 1; i < argc; i++) + if (argv[i][0] == '-' && argv[i][1] == 'q') + quiet = True; + + if (!quiet) + printf("This is %s\n", ident); + +#if defined(MSDOS) || defined(OS2) || defined(ATARIST) + /* Make VPL file identical to that created under Unix */ + fnt->titlebuf = (char *)mymalloc(strlen(progname) + strlen(argv[1]) + + 1 + 1); + sprintf(fnt->titlebuf, "%s %s", progname, argv[1]); +#else + fnt->titlebuf = (char *)mymalloc(strlen(argv[0]) + strlen(argv[1]) + + 1 + 1); + sprintf(fnt->titlebuf, "%s %s", argv[0], argv[1]); +#endif + + + /* + * TrueType font name. + */ + + fnt->ttfname = newstring(argv[1]); + + /* + * The other arguments. We delay the final processing of some switches + * until the tfm font name has been scanned -- if it contains two `@'s, + * many switches are ignored. + */ + + while (argc > 2 && *argv[2] == '-') + { + arginc = 2; + i = argv[2][1]; + + switch (i) + { + case 'v': + makevpl = 1; + if (argc <= 3) + oops("Missing parameter for -v option."); + if (vpl_name) + free(vpl_name); + vpl_name = newstring(argv[3]); + handle_extension(&vpl_name, ".vpl"); + break; + + case 'V': + makevpl = 2; + if (argc <= 3) + oops("Missing parameter for -V option."); + if (vpl_name) + free(vpl_name); + vpl_name = newstring(argv[3]); + handle_extension(&vpl_name, ".vpl"); + break; + + case 'f': + if (argc <= 3) + oops("Missing parameter for -f option."); + if (sscanf(argv[3], "%lu", &(fnt->fontindex)) == 0) + oops("Invalid font index."); + fnt->fontindexparam = argv[3]; + break; + + case 'E': + if (argc <= 3) + oops("Missing parameter for -E option."); + if (sscanf(argv[3], "%hu", &(fnt->eid)) == 0) + oops("Invalid encoding ID."); + fnt->eidparam = argv[3]; + break; + + case 'P': + if (argc <= 3) + oops("Missing parameter for -P option."); + if (sscanf(argv[3], "%hu", &(fnt->pid)) == 0) + oops("Invalid platform ID."); + fnt->pidparam = argv[3]; + break; + + case 'e': + if (argc <= 3) + oops("Missing parameter for -e option."); + if (sscanf(argv[3], "%f", &(fnt->efactor)) == 0 || fnt->efactor < 0.01) + oops("Bad extension factor."); + fnt->efactorparam = argv[3]; + break; + + case 'c': + if (argc <= 3) + oops("Missing parameter for -c option."); + have_capheight = True; + if (sscanf(argv[3], "%f", &(fnt->capheight)) == 0) + fnt->capheight = 0; + break; + + case 's': + if (argc <= 3) + oops("Missing parameter for -s option."); + if (sscanf(argv[3], "%f", &(fnt->slant)) == 0) + oops("Bad slant parameter."); + fnt->slantparam = argv[3]; + break; + + case 'p': + if (argc <= 3) + oops("Missing parameter for -p option."); + if (fnt->inencname) + free(fnt->inencname); + fnt->inencname = newstring(argv[3]); + break; + + case 'T': + if (argc <= 3) + oops("Missing parameter for -T option."); + if (fnt->inencname) + free(fnt->inencname); + if (fnt->outencname) + free(fnt->outencname); + fnt->inencname = newstring(argv[3]); + fnt->outencname = newstring(argv[3]); + break; + + case 't': + if (argc <= 3) + oops("Missing parameter for -T option."); + if (fnt->outencname) + free(fnt->outencname); + fnt->outencname = newstring(argv[3]); + break; + + case 'r': + if (argc <= 4) + oops("Not enough parameters for -r option."); + sl = newstringlist(); + sl->old_name = newstring(argv[3]); + sl->new_name = newstring(argv[4]); + sl->single_replacement = True; + sl->next = fnt->replacements; + fnt->replacements = sl; + arginc = 3; + break; + + case 'R': + if (argc <= 3) + oops("Missing parameter for -R option."); + if (fnt->replacementname) + free(fnt->replacementname); + fnt->replacementname = newstring(argv[3]); + break; + + case 'y': + if (argc <= 3) + oops("Missing parameter for -y option."); + if (sscanf(argv[3], "%f", &(fnt->y_offset)) == 0) + oops("Invalid y-offset."); + fnt->y_offsetparam = argv[3]; + break; + + case 'O': + forceoctal = True; + arginc = 1; + break; + + case 'n': + fnt->PSnames = Yes; + arginc = 1; + break; + + case 'N': + fnt->PSnames = Only; + arginc = 1; + break; + + case 'u': + pedantic = True; + arginc = 1; + break; + + case 'q': + quiet = True; + arginc = 1; + break; + + case 'l': + fnt->subfont_ligs = True; + arginc = 1; + break; + + case 'x': + fnt->rotate = True; + arginc = 1; + break; + + default: + if (argc <= 3 || argv[3][0] == '-') + { + warning("Unknown option `%s' will be ignored.\n", argv[2]); + arginc = 1; + } + else + warning("Unknown option `%s %s' will be ignored.\n", + argv[2], argv[3]); + } + + for (i = 0; i < arginc; i++) + { + l = strlen(fnt->titlebuf); + fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf, + l + strlen(argv[2]) + 1 + 1); + sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]); + argv++; + argc--; + } + } + + /* Read replacement glyph name file */ + + get_replacements(fnt); + + if (argc > 3 || (argc == 3 && *argv[2] == '-')) + oops("Need at most two non-option arguments."); + + /* + * The tfm file name. + */ + + if (argc == 2) + temp = newstring(fnt->ttfname); + else + { + temp = newstring(argv[2]); + l = strlen(fnt->titlebuf); + fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf, + l + strlen(argv[2]) + 1 + 1); + sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]); + } + + handle_sfd(temp, &sfd_begin, &postfix_begin); + + if (sfd_begin > -1) + { + have_sfd = True; + i = sfd_begin - 2; + } + else + i = strlen(temp) - 1; + + /* + * Now we search the beginning of the name without directory. + */ + + for (; i >= 0; i--) + if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\') + break; + + base_name = i + 1; + + /* + * We store the path (with the final directory separator). + */ + + if (base_name > 0) + { + c = temp[base_name]; + temp[base_name] = '\0'; + fnt->tfm_path = newstring(temp); + temp[base_name] = c; + } + + if (have_sfd) + { + /* the prefix and the sfd file name */ + + if (temp[base_name]) + fnt->outname = newstring(temp + base_name); + + fnt->sfdname = newstring(temp + sfd_begin); + } + else + postfix_begin = base_name; + + /* + * Get the extension. + */ + + lastext = -1; + for (i = postfix_begin; temp[i]; i++) + if (temp[i] == '.') + lastext = i; + + if (argc == 2 && lastext >= 0) + { + temp[lastext] = '\0'; /* remove TTF file extension */ + lastext = -1; + } + + if (lastext == -1) + fnt->tfm_ext = newstring(".tfm"); + else + { + fnt->tfm_ext = newstring(temp + lastext); + temp[lastext] = '\0'; + } + + if (have_sfd) + { + if (temp[postfix_begin]) + fnt->outname_postfix = newstring(temp + postfix_begin); + } + else + { + if (temp[base_name]) + fnt->outname = newstring(temp + base_name); + else + oops("Invalid tfm file name."); + } + + + /* + * Now we can process the remaining parameters. + */ + + if (have_sfd) + { + if (makevpl) + { + warning("Ignoring `-v' and `-V' switches for subfonts."); + makevpl = 0; + } + if (have_capheight) + warning("Ignoring `-c' switch for subfonts."); + if (fnt->inencname || fnt->outencname) + { + warning("Ignoring `-p', `-t', and `-T' switches for subfonts."); + fnt->inencname = NULL; + fnt->outencname = NULL; + } + if (fnt->y_offsetparam && !fnt->rotate) + warning("Ignoring `-y' switch for non-rotated subfonts."); + if (fnt->PSnames) + { + warning("Ignoring `-n' or '-N' switch for subfonts."); + fnt->PSnames = No; + } + + init_sfd(fnt, True); + } + else + { + if (have_capheight && fnt->capheight < 0.01) + oops("Bad small caps height."); + + if (vpl_name) + if ((fnt->vplout = fopen(vpl_name, "wt")) == NULL) + oops("Cannot open vpl output file."); + + if (fnt->subfont_ligs) + { + warning("Ignoring `-l' switch for non-subfont."); + fnt->subfont_ligs = False; + } + + if (fnt->rotate) + { + warning("Ignoring `-x' switch for non-subfont."); + fnt->rotate = False; + } + + if (fnt->y_offsetparam) + warning("Ignoring `-y' switch for non-subfont."); + } + + if (fnt->PSnames == Only) + { + if (fnt->pidparam || fnt->eidparam) + { + warning("Ignoring `-P' and `-E' options if `-N' switch is selected."); + fnt->pidparam = NULL; + fnt->eidparam = NULL; + } + } + + if (vpl_name) + free(vpl_name); + free(temp); +} + + +/* + * This routine prints out the line that needs to be added to ttfonts.map. + */ + +static void +consttfonts(Font *fnt) +{ + if (!quiet) + printf("\n"); + if (fnt->outname) + printf("%s", fnt->outname); + if (fnt->sfdname) + printf("@%s@", fnt->sfdname); + if (fnt->outname_postfix) + printf("%s", fnt->outname_postfix); + + printf(" %s", fnt->ttfname); + + if (fnt->slantparam || fnt->efactorparam || + fnt->inencname || + fnt->pidparam || fnt->eidparam || + fnt->fontindexparam || + fnt->replacements || + fnt->replacementname || + fnt->PSnames || + fnt->rotate || fnt->y_offsetparam) + { + if (fnt->slantparam) + printf(" Slant=%s", fnt->slantparam); + if (fnt->efactorparam) + printf(" Extend=%s", fnt->efactorparam); + if (fnt->inencname) + printf(" Encoding=%s", fnt->inencname); + if (fnt->pidparam) + printf(" Pid=%s", fnt->pidparam); + if (fnt->eidparam) + printf(" Eid=%s", fnt->eidparam); + if (fnt->fontindexparam) + printf(" Fontindex=%s", fnt->fontindexparam); + if (fnt->PSnames) + printf(" PS=%s", fnt->PSnames == Yes ? "Yes" : "Only"); + if (fnt->rotate) + printf(" Rotate=Yes"); + if (fnt->y_offsetparam) + printf(" Y-Offset=%s", fnt->y_offsetparam); + if (fnt->replacementname && fnt->inencoding) + printf(" Replacement=%s", fnt->replacementname); + if (fnt->replacements && fnt->inencoding) + { + stringlist *sl; + + + for (sl = fnt->replacements; sl; sl = sl->next) + if (sl->single_replacement) + printf(" %s=%s", sl->old_name, sl->new_name); + } + } + printf("\n"); +} + + +int +main(int argc, char *argv[]) +{ + Font font; + ttfinfo *ti; + + + init_font_structure(&font); + + TeX_search_init(argv[0], "ttf2tfm", "TTF2TFM"); + + if (argc == 1) + { + fputs("ttf2tfm: Need at least one file argument.\n", stderr); + fputs("Try `ttf2tfm --help' for more information.\n", stderr); + exit(1); + } + if (argc == 2) + { + if (strcmp(argv[1], "--help") == 0) + usage(); + else if (strcmp(argv[1], "--version") == 0) + version(); + } + + handle_options(argc, argv, &font); + + if (font.sfdname) + { + while (get_sfd(&font)) + { + char *temp; + int i, start, end, len; + + + get_tfm_fullname(&font); + + /* + * Extract base name of sfd file. + */ + + temp = newstring(font.sfdname); + len = strlen(temp); + + start = 0; + for (i = len - 1; i >= 0; i--) + if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\') + { + start = i + 1; + break; + } + + end = len; + for (i = len - 1; i >= 0; i--) + if (temp[i] == '.') + { + end = i; + break; + } + temp[end] = '\0'; + + font.codingscheme = (char *)mymalloc(strlen(temp + start) + 4 + 1); + sprintf(font.codingscheme, "CJK-%s", temp + start); + free(temp); + + readttf(&font, quiet, True); + if (font.replacements) + warning("Replacement glyphs will be ignored."); + + if (NULL != (ti = findadobe("space", font.charlist))) + font.fontspace = ti->width; + else if (NULL != (ti = findadobe(".c0x20", font.charlist))) + font.fontspace = ti->width; + else + font.fontspace = transform(500, 0, font.efactor, font.slant); + + if (buildtfm(&font)) + writetfm(&font); + } + + close_sfd(); + } + else + { + get_tfm_fullname(&font); + + readttf(&font, quiet, False); + replace_glyphs(&font); + + if (NULL != (ti = findadobe("space", font.charlist))) + font.fontspace = ti->width; + else if (NULL != (ti = findadobe(".c0x20", font.charlist))) + font.fontspace = ti->width; + else + font.fontspace = transform(500, 0, font.efactor, font.slant); + + handlereencoding(&font); + + buildtfm(&font); + writetfm(&font); + } + + if (makevpl) + { + assignchars(&font); + if (makevpl > 1) + upmap(&font); + writevpl(&font, makevpl, forceoctal); + fclose(font.vplout); + } + + consttfonts(&font); + + exit(0); /* for safety reasons */ + return 0; /* never reached */ +} + + +/* end */ diff --git a/contrib/ttf2pk/ttf2tfm.h b/contrib/ttf2pk/ttf2tfm.h new file mode 100644 index 0000000..b4f54e4 --- /dev/null +++ b/contrib/ttf2pk/ttf2tfm.h @@ -0,0 +1,234 @@ +/* + * ttf2tfm.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TTF2TFM_H +#define TTF2TFM_H + +#include + + +enum Boolean_ +{ + False = 0, + True = 1 +}; +typedef enum Boolean_ Boolean; + +enum PSstate_ +{ + No = 0, + Yes = 1, + Only = 2 +}; +typedef enum PSstate_ PSstate; + + +struct _encoding +{ + char *name; + char *vec[256]; +}; +typedef struct _encoding encoding; + + +/* + * This is what we store character data in. + */ + +struct _ttfinfo; +typedef struct _ttfinfo ttfinfo; +struct _lig; +typedef struct _lig lig; +struct _kern; +typedef struct _kern kern; +struct _ttfptr; +typedef struct _ttfptr ttfptr; +struct _pcc; +typedef struct _pcc pcc; +struct _stringlist; +typedef struct _stringlist stringlist; + + + +struct _ttfinfo +{ + ttfinfo *next; + long charcode; /* the TTF character code (or glyph index */ + /* if bit 17 is set) */ + unsigned short glyphindex; /* the TTF glyph number */ + short incode; /* the code position in the raw TeX font */ + short outcode; /* the code position in the virtual font */ + char *adobename; + + short width; + short llx, lly, urx, ury; + + lig *ligs; + kern *kerns; + ttfptr *kern_equivs; + Boolean constructed; + pcc *pccs; /* we use the composite feature for */ + /* `germandbls' <--> `SS' only */ + unsigned char wptr, hptr, dptr, iptr; +}; + + +struct _lig +{ + lig *next; + char *succ, *sub; + short op, boundleft; +}; + + +struct _kern +{ + kern *next; + char *succ; + short delta; +}; + + +struct _ttfptr +{ + ttfptr *next; + ttfinfo *ch; +}; + + +struct _pcc +{ + pcc *next; + char *partname; + short xoffset, yoffset; +}; + + +struct _stringlist +{ + stringlist* next; + char *old_name; + char *new_name; + Boolean single_replacement; +}; + + +struct _Font +{ + char *ttfname; + + /* + * Full path and extension of the tfm file + */ + + char *tfm_path; + char *tfm_ext; + + /* + * The final tfm name is composed of the following three parts. + */ + + char *outname; /* only namestem without extension */ + char *subfont_name; /* NULL if not used */ + char *outname_postfix; /* NULL if not used */ + char *fullname; /* outname + subfont_name + outname_postfix */ + + FILE *vplout; + FILE *tfmout; + + /* + * The input encoding maps from the TrueType font to the raw TeX font. + */ + + char *inencname; /* name of input encoding file */ + encoding *inencoding; /* the input encoding vector */ + ttfinfo *inencptrs[256]; /* the input mapping table. Will be + filled initially with the first + 256 characters in the selected + cmap of the TrueType font */ + stringlist *replacements; /* replacements for glyph names given + with the -r option on the command + line */ + char *replacementname; /* name of replacement file */ + + /* + * The output encoding maps from the raw TeX font to the virtual font. + */ + + char *outencname; /* name of output encoding file */ + encoding *outencoding; /* the output encoding vector */ + ttfinfo *outencptrs[256]; /* the output mapping table */ + + short nextout[256]; /* for characters encoded multiple times + in output */ + + Boolean sawligkern; /* there were LIGKERN lines in the + output encoding file */ + Boolean subfont_ligs; /* ligatures 1st byte/2nd byte in + subfonts wanted */ + + ttfinfo *charlist; /* a linked list of all valid chars */ + + ttfinfo *uppercase[256]; /* needed for small caps fonts */ + ttfinfo *lowercase[256]; /* ditto */ + + short boundarychar; /* the boundary character */ + char *codingscheme; /* coding scheme for TeX */ + char *titlebuf; + + /* + * The name of the subfont definition file. + */ + + char *sfdname; + long sf_code[256]; + + /* + * We get the following three values from the TTF's postscript table. + */ + + short units_per_em; + float italicangle; + char fixedpitch; + + short xheight; /* xheight for TeX */ + short fontspace; /* font space for TeX */ + + /* + * These values can be specified on the command line. + */ + + unsigned short pid; /* the TTF platform ID */ + unsigned short eid; /* the TTF encoding ID */ + float efactor; /* to extend the glyphs horizontally */ + float slant; /* to slant the font */ + unsigned long fontindex; /* font number in TTC */ + float capheight; /* the height of small caps glyphs */ + PSstate PSnames; /* we use the PS names in the TTF */ + Boolean rotate; /* we rotate the glyphs by 90 degrees */ + float y_offset; /* y offset for rotated glyphs */ + + /* + * The command line parameter strings needed for ttf2pk. + */ + + char *pidparam; + char *eidparam; + char *efactorparam; + char *slantparam; + char *fontindexparam; + char *y_offsetparam; +}; +typedef struct _Font Font; + +#endif /* TEX2TFM_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ttfaux.c b/contrib/ttf2pk/ttfaux.c new file mode 100644 index 0000000..dc96917 --- /dev/null +++ b/contrib/ttf2pk/ttfaux.c @@ -0,0 +1,714 @@ +/* + * ttfaux.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include + +#include "freetype.h" +#include "extend/ftxkern.h" /* we are in the FreeType package tree */ +#include "extend/ftxpost.h" +#include "extend/ftxopen.h" + +#include "ttf2tfm.h" +#include "newobj.h" +#include "ligkern.h" +#include "ttfenc.h" +#include "tfmaux.h" +#include "errormsg.h" +#include "ttfaux.h" +#include "filesrch.h" + + +#define Macintosh_platform 1 +#define Macintosh_encoding 0 + +#define Microsoft_platform 3 +#define Microsoft_Unicode_encoding 1 + +#define SCRIPT_kana MAKE_TT_TAG('k', 'a', 'n', 'a') +#define SCRIPT_hani MAKE_TT_TAG('h', 'a', 'n', 'i') +#define SCRIPT_hang MAKE_TT_TAG('h', 'a', 'n', 'g') + +#define LANGUAGE_JAN MAKE_TT_TAG('J', 'A', 'N', ' ') +#define LANGUAGE_CHN MAKE_TT_TAG('C', 'H', 'N', ' ') +#define LANGUAGE_KOR MAKE_TT_TAG('K', 'O', 'R', ' ') + +#define FEATURE_vert MAKE_TT_TAG('v', 'e', 'r', 't') + + +extern char progname[]; + +char *real_ttfname; + +TT_Engine engine; +TT_Face face; +TT_Instance instance; +TT_Glyph glyph; +TT_Outline outline; +TT_CharMap char_map; +TT_Matrix matrix1, matrix2; + +TT_Big_Glyph_Metrics metrics; +TT_Face_Properties properties; +TT_BBox bbox; + +TT_Kerning directory; +TT_Post post; + +TTO_GSUBHeader gsub_; +TTO_GSUBHeader *gsub; + +Boolean has_gsub; + + + +static void +readttf_kern(Font *fnt) +{ + register kern *nk; + register ttfinfo *ti; + TT_Kern_0_Pair* pairs0; + TT_Error error; + unsigned int i, j; + + + if ((error = TT_Get_Kerning_Directory(face, &directory))) + oops("Cannot get kerning directory (error code = 0x%x).", error); + + if (directory.nTables == 0) + return; + + for (i = 0; i < directory.nTables; i++) + { + if ((error = TT_Load_Kerning_Table(face, i))) + oops("Cannot load kerning table (error code = 0x%x).", error); + + switch (directory.tables[i].format) + { + case 0: + pairs0 = directory.tables[i].t.kern0.pairs; + for (j = 0; j < directory.tables[i].t.kern0.nPairs; j++, pairs0++) + { + ti = findglyph(pairs0->left, fnt->charlist); + if (ti == NULL) + warning("kern char not found"); + else + { + nk = newkern(); + nk->succ = findglyph(pairs0->right, fnt->charlist)->adobename; + nk->delta = transform(pairs0->value * 1000 / fnt->units_per_em, 0, + fnt->efactor, fnt->slant); + nk->next = ti->kerns; + ti->kerns = nk; + } + } + return; /* we stop after the first format 0 kerning table */ + + default: + break; + } + } + return; +} + + +void +readttf(Font *fnt, Boolean quiet, Boolean only_range) +{ + TT_Error error; + ttfinfo *ti, *Ti; + long Num, index; + unsigned int i, j; + long k, max_k; + unsigned short num_cmap; + unsigned short cmap_plat, cmap_enc; + int index_array[257]; + + static Boolean initialized = False; + + TT_UShort in_string[2]; + TTO_GSUB_String in, out; + + TT_UShort script_index, language_index, feature_index; + TT_UShort req_feature_index = 0xFFFF; + + + /* + * We allocate a placeholder boundary and the `.notdef' character. + */ + + if (!only_range) + { + ti = newchar(fnt); + ti->charcode = -1; + ti->adobename = ".notdef"; + + ti = newchar(fnt); + ti->charcode = -1; + ti->adobename = "||"; /* boundary character name */ + } + + /* + * Initialize FreeType engine. + */ + + if (!initialized) + { + if ((error = TT_Init_FreeType(&engine))) + oops("Cannot initialize engine (error code = 0x%x).", error); + + if ((error = TT_Init_Kerning_Extension(engine))) + oops("Cannot initialize kerning (error code = 0x%x).", error); + + if (fnt->PSnames) + if ((error = TT_Init_Post_Extension(engine))) + oops("Cannot initialize PS name support (error code = 0x%x).", error); + + if (fnt->rotate) + if ((error = TT_Init_GSUB_Extension(engine))) + oops("Cannot initialize GSUB support (error code = 0x%x).", error); + + /* + * Load face. + */ + + real_ttfname = TeX_search_ttf_file(&(fnt->ttfname)); + if (!real_ttfname) + oops("Cannot find `%s'.", fnt->ttfname); + + if ((error = TT_Open_Face(engine, real_ttfname, &face))) + oops("Cannot open `%s'.", real_ttfname); + + /* + * Get face properties and allocate preload arrays. + */ + + TT_Get_Face_Properties(face, &properties); + + /* + * Now we try to open the proper font in a collection. + */ + + if (fnt->fontindex != 0) + { + if (properties.num_Faces == 1) + { + warning("This isn't a TrueType collection.\n" + "Parameter `-f' is ignored."); + fnt->fontindex = 0; + fnt->fontindexparam = NULL; + } + else + { + TT_Close_Face(face); + if ((error = TT_Open_Collection(engine, real_ttfname, + fnt->fontindex, &face))) + oops("Cannot open font %lu in TrueType Collection `%s'.", + fnt->fontindex, real_ttfname); + } + } + + /* + * Create instance. + */ + + if ((error = TT_New_Instance(face, &instance))) + oops("Cannot create instance for `%s' (error code = 0x%x).", + real_ttfname, error); + + /* + * We use a dummy glyph size of 10pt. + */ + + if ((error = TT_Set_Instance_CharSize(instance, 10 * 64))) + oops("Cannot set character size (error code = 0x%x).", error); + + matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1L<<16)/1024); + matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1L<<16)/1024); + matrix1.yx = (TT_Fixed)0; + matrix1.yy = (TT_Fixed)(1L<<16); + + if (fnt->rotate) + { + matrix2.xx = 0; + matrix2.yx = 1L << 16; + matrix2.xy = -matrix2.yx; + matrix2.yy = matrix2.xx; + } + + if ((error = TT_Set_Instance_Transform_Flags( + instance, + fnt->rotate ? 1 : 0, + fnt->efactor != 1.0 ? 1 : 0))) + oops("Cannot set transform flags (error code = 0x%x).", error); + + /* + * Create glyph container. + */ + + if ((error = TT_New_Glyph(face, &glyph))) + oops("Cannot create glyph container (error code = 0x%x).", error); + + fnt->units_per_em = properties.header->Units_Per_EM; + fnt->fixedpitch = properties.postscript->isFixedPitch; + fnt->italicangle = properties.postscript->italicAngle / 65536.0; + + if (fnt->PSnames != Only) + { + num_cmap = properties.num_CharMaps; + for (i = 0; i < num_cmap; i++) + { + if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc))) + oops("Cannot query cmap (error code = 0x%x).", error); + if (cmap_plat == fnt->pid && cmap_enc == fnt->eid) + break; + } + if (i == num_cmap) + { + fprintf(stderr, "%s: ERROR: Invalid platform and/or encoding ID.\n", + progname); + if (num_cmap == 1) + fprintf(stderr, " The only valid PID/EID pair is"); + else + fprintf(stderr, " Valid PID/EID pairs are:\n"); + for (i = 0; i < num_cmap; i++) + { + TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc); + fprintf(stderr, " (%i,%i)\n", cmap_plat, cmap_enc); + } + fprintf(stderr, "\n"); + exit(1); + } + + if ((error = TT_Get_CharMap(face, i, &char_map))) + oops("Cannot load cmap (error code = 0x%x).", error); + } + + if (fnt->PSnames) + { + if ((error = TT_Load_PS_Names(face, &post))) + oops("Cannot load TrueType PS names (error code = 0x%x).", error); + } + else if (cmap_plat == Microsoft_platform && + cmap_enc == Microsoft_Unicode_encoding) + set_encoding_scheme(encUnicode, fnt); + else if (cmap_plat == Macintosh_platform && + cmap_enc == Macintosh_encoding) + set_encoding_scheme(encMac, fnt); + else + set_encoding_scheme(encFontSpecific, fnt); + + if (fnt->rotate) + { + gsub = &gsub_; + + error = TT_Load_GSUB_Table(face, gsub, NULL); + if (!error) + has_gsub = True; + else if (error != TT_Err_Table_Missing) + warning("Cannot load GSUB table (error code = 0x%x).", error); + else + warning("No GSUB data available " + "for vertical glyph presentation forms."); + + /* we check for the `vert' feature in Chinese, Japanese, and Korean */ + + error = TT_GSUB_Select_Script(gsub, + SCRIPT_kana, + &script_index); + if (error) + goto check_hani; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_JAN, + script_index, + &language_index, + &req_feature_index); + if (error) + goto check_hani; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + if (error) + goto check_hani; + else + goto Done; + } + else + goto Done; + + check_hani: + error = TT_GSUB_Select_Script(gsub, + SCRIPT_hani, + &script_index); + if (error) + goto check_hang; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_CHN, + script_index, + &language_index, + &req_feature_index); + if (error) + goto check_hang; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + if (error) + goto check_hang; + else + goto Done; + } + else + goto Done; + + check_hang: + error = TT_GSUB_Select_Script(gsub, + SCRIPT_hang, + &script_index); + if (error) + goto Done; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_KOR, + script_index, + &language_index, + &req_feature_index); + if (error) + goto Done; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + } + + Done: + if (error) + { + warning("There is no data for vertical typesetting in GSUB table."); + has_gsub = False; + } + + if (req_feature_index != 0xFFFF) + TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS); + TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS); + + in.length = 1; + in.pos = 0; + in.string = in_string; + in.properties = NULL; + + out.pos = 0; + out.allocated = 0; + out.string = NULL; + out.properties = NULL; + } + + initialized = True; + } + + if (!quiet) + { + if (only_range) + printf("\n\n%s:\n", fnt->fullname); + printf("\n"); + printf("Glyph Code Glyph Name "); + printf("Width llx lly urx ury\n"); + printf("---------------------------------------"); + printf("---------------------------------\n"); + } + + /* + * We load only glyphs with a valid cmap entry. Nevertheless, for + * the default mapping, we use the first 256 glyphs addressed by + * ascending code points, followed by glyphs not in the cmap. + * + * If we compute a range, we take the character codes given in + * the fnt->sf_code array. + * + * If the -N flag is set, no cmap is used at all. Instead, the + * first 256 glyphs (with a valid PS name) are used for the default + * mapping. + */ + + if (!only_range) + for (i = 0; i < 257; i++) + index_array[i] = 0; + else + for (i = 0; i < 256; i++) + fnt->inencptrs[i] = 0; + + j = 0; + if (fnt->PSnames == Only) + max_k = properties.num_Glyphs - 1; + else + max_k = only_range ? 0xFF : 0xFFFF; + + for (k = 0; k <= max_k; k++) + { + char *an; + + + if (fnt->PSnames != Only) + { + if (only_range) + { + index = fnt->sf_code[k]; + if (index < 0) + continue; + j = k; + } + else + index = k; + + Num = TT_Char_Index(char_map, index); + + /* now we try to get a vertical glyph form */ + + if (has_gsub) + { + in_string[0] = Num; + error = TT_GSUB_Apply_String(gsub, &in, &out); + if (error && error != TTO_Err_Not_Covered) + warning("Cannot get the vertical glyph form for glyph index %d.", + Num); + else + Num = out.string[0]; + } + + if (Num < 0) + oops("Failure on cmap mapping from %s.", fnt->ttfname); + if (Num == 0) + continue; + if (!only_range) + if (Num <= 256) + index_array[Num] = 1; + } + else + { + Num = k; + index = 0; + } + + error = TT_Load_Glyph(instance, glyph, Num, 0); + if (!error) + error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); + if (!error) + error = TT_Get_Glyph_Outline(glyph, &outline); + if (!error) + { + if (fnt->efactor != 1.0 || fnt->slant != 0.0 ) + TT_Transform_Outline(&outline, &matrix1); + if (fnt->rotate) + TT_Transform_Outline(&outline, &matrix2); + } + if (!error) + error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non- + grid-fitted bbox */ + if (!error) + { + if (fnt->PSnames) + (void)TT_Get_PS_Name(face, Num, &an); + else + an = code_to_adobename(index); + + /* ignore characters not usable for typesetting with TeX */ + + if (strcmp(an, ".notdef") == 0) + continue; + if (strcmp(an, ".null") == 0) + continue; + if (strcmp(an, "nonmarkingreturn") == 0) + continue; + + ti = newchar(fnt); + ti->charcode = index; + ti->glyphindex = Num; + ti->adobename = an; + ti->llx = bbox.xMin * 1000 / fnt->units_per_em; + ti->lly = bbox.yMin * 1000 / fnt->units_per_em; + ti->urx = bbox.xMax * 1000 / fnt->units_per_em; + ti->ury = bbox.yMax * 1000 / fnt->units_per_em; + + /* + * We must now shift the rotated character both horizontally + * and vertically. The vertical amount is 25% by default. + */ + + if (fnt->rotate) + { + ti->llx += (metrics.vertBearingY - bbox.xMin) * + 1000 / fnt->units_per_em; + ti->lly -= 1000 * fnt->y_offset; + ti->urx += (metrics.vertBearingY - bbox.xMin) * + 1000 / fnt->units_per_em; + ti->ury -= 1000 * fnt->y_offset; + } + + /* + * We need to avoid negative heights or depths. They break accents + * in math mode, among other things. + */ + + if (ti->lly > 0) + ti->lly = 0; + if (ti->ury < 0) + ti->ury = 0; + if (fnt->rotate) + ti->width = metrics.vertAdvance * 1000 / fnt->units_per_em; + else + ti->width = transform(metrics.horiAdvance * 1000 / fnt->units_per_em, + 0, fnt->efactor, fnt->slant); + + if (!quiet) + printf("%5ld %04lx %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + Num, index, ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + + if (j < 256) + { + fnt->inencptrs[j] = ti; + ti->incode = j; + } + j++; + } + } + + /* + * Now we load glyphs without a cmap entry, provided some slots are + * still free -- we skip this if we have to compute a range or use + * PS names. + */ + + if (!only_range && !fnt->PSnames) + { + for (i = 1; i <= properties.num_Glyphs; i++) + { + char *an; + + + if (index_array[i] == 0) + { + error = TT_Load_Glyph(instance, glyph, i, 0); + if (!error) + error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); + if (!error) + error = TT_Get_Glyph_Outline(glyph, &outline); + if (!error) + error = TT_Get_Outline_BBox(&outline, &bbox); + if (!error) + { + an = code_to_adobename(i | 0x10000); + + ti = newchar(fnt); + ti->charcode = i | 0x10000; + ti->glyphindex = i; + ti->adobename = an; + ti->llx = bbox.xMin * 1000 / fnt->units_per_em; + ti->lly = bbox.yMin * 1000 / fnt->units_per_em; + ti->urx = bbox.xMax * 1000 / fnt->units_per_em; + ti->ury = bbox.yMax * 1000 / fnt->units_per_em; + + if (ti->lly > 0) + ti->lly = 0; + if (ti->ury < 0) + ti->ury = 0; + ti->width = transform(metrics.horiAdvance*1000 / fnt->units_per_em, + 0, fnt->efactor, fnt->slant); + + if (!quiet) + printf("%5d %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + i, ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + + if (j < 256) + { + fnt->inencptrs[j] = ti; + ti->incode = j; + } + else + break; + j++; + } + } + } + } + + /* Finally, we construct a `Germandbls' glyph if necessary */ + + if (!only_range) + { + if (NULL == findadobe("Germandbls", fnt->charlist) && + NULL != (Ti = findadobe("S", fnt->charlist))) + { + pcc *np, *nq; + + + ti = newchar(fnt); + ti->charcode = properties.num_Glyphs | 0x10000; + ti->glyphindex = properties.num_Glyphs; + ti->adobename = "Germandbls"; + ti->width = Ti->width << 1; + ti->llx = Ti->llx; + ti->lly = Ti->lly; + ti->urx = Ti->width + Ti->urx; + ti->ury = Ti->ury; + ti->kerns = Ti->kerns; + + np = newpcc(); + np->partname = "S"; + nq = newpcc(); + nq->partname = "S"; + nq->xoffset = Ti->width; + np->next = nq; + ti->pccs = np; + ti->constructed = True; + + if (!quiet) + printf("* %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", + ti->adobename, + ti->width, + ti->llx, ti->lly, ti->urx, ti->ury); + } + } + + /* kerning between subfonts isn't available */ + if (!only_range) + readttf_kern(fnt); +} + + +/* end */ diff --git a/contrib/ttf2pk/ttfaux.h b/contrib/ttf2pk/ttfaux.h new file mode 100644 index 0000000..5737c2f --- /dev/null +++ b/contrib/ttf2pk/ttfaux.h @@ -0,0 +1,21 @@ +/* + * ttfaux.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TTFAUX_H +#define TTFAUX_H + +#include "ttf2tfm.h" + +void readttf(Font *fnt, Boolean quiet, Boolean only_range); + +#endif /* TTFAUX_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ttfenc.c b/contrib/ttf2pk/ttfenc.c new file mode 100644 index 0000000..9362926 --- /dev/null +++ b/contrib/ttf2pk/ttfenc.c @@ -0,0 +1,1281 @@ +/* + * ttfenc.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + + +#include +#include +#include + +#include "newobj.h" +#include "ttf2tfm.h" +#include "ttfenc.h" +#include "errormsg.h" + +EncodingScheme current_encoding_scheme; + +struct encoding_table +{ + long code; + char *adobename; +}; + +struct encoding_table unicode_table[] = +{ + {-1, ".notdef"}, + + {0x0020, "space"}, + {0x0021, "exclam"}, + {0x0022, "quotedbl"}, + {0x0023, "numbersign"}, + {0x0024, "dollar"}, + {0x0025, "percent"}, + {0x0026, "ampersand"}, + {0x0027, "quotesingle"}, + {0x0028, "parenleft"}, + {0x0029, "parenright"}, + {0x002a, "asterisk"}, + {0x002b, "plus"}, + {0x002c, "comma"}, + {0x002d, "hyphen"}, /* cf "minus" */ + {0x002e, "period"}, + {0x002f, "slash"}, + + {0x0030, "zero"}, + {0x0031, "one"}, + {0x0032, "two"}, + {0x0033, "three"}, + {0x0034, "four"}, + {0x0035, "five"}, + {0x0036, "six"}, + {0x0037, "seven"}, + {0x0038, "eight"}, + {0x0039, "nine"}, + {0x003a, "colon"}, + {0x003b, "semicolon"}, + {0x003c, "less"}, + {0x003d, "equal"}, + {0x003e, "greater"}, + {0x003f, "question"}, + + {0x0040, "at"}, + {0x0041, "A"}, + {0x0042, "B"}, + {0x0043, "C"}, + {0x0044, "D"}, + {0x0045, "E"}, + {0x0046, "F"}, + {0x0047, "G"}, + {0x0048, "H"}, + {0x0049, "I"}, + {0x004a, "J"}, + {0x004b, "K"}, + {0x004c, "L"}, + {0x004d, "M"}, + {0x004e, "N"}, + {0x004f, "O"}, + + {0x0050, "P"}, + {0x0051, "Q"}, + {0x0052, "R"}, + {0x0053, "S"}, + {0x0054, "T"}, + {0x0055, "U"}, + {0x0056, "V"}, + {0x0057, "W"}, + {0x0058, "X"}, + {0x0059, "Y"}, + {0x005a, "Z"}, + {0x005b, "bracketleft"}, + {0x005c, "backslash"}, + {0x005d, "bracketright"}, + {0x005e, "asciicircum"}, + {0x005f, "underscore"}, + + {0x0060, "grave"}, + {0x0061, "a"}, + {0x0062, "b"}, + {0x0063, "c"}, + {0x0064, "d"}, + {0x0065, "e"}, + {0x0066, "f"}, + {0x0067, "g"}, + {0x0068, "h"}, + {0x0069, "i"}, + {0x006a, "j"}, + {0x006b, "k"}, + {0x006c, "l"}, + {0x006d, "m"}, + {0x006e, "n"}, + {0x006f, "o"}, + + {0x0070, "p"}, + {0x0071, "q"}, + {0x0072, "r"}, + {0x0073, "s"}, + {0x0074, "t"}, + {0x0075, "u"}, + {0x0076, "v"}, + {0x0077, "w"}, + {0x0078, "x"}, + {0x0079, "y"}, + {0x007a, "z"}, + {0x007b, "braceleft"}, + {0x007c, "bar"}, + {0x007d, "braceright"}, + {0x007e, "asciitilde"}, + + {0x00a0, "nbspace"}, /* cf "space" */ + {0x00a1, "exclamdown"}, + {0x00a2, "cent"}, + {0x00a3, "sterling"}, + {0x00a4, "currency"}, + {0x00a5, "yen"}, + {0x00a6, "brokenbar"}, + {0x00a7, "section"}, + {0x00a8, "dieresis"}, + {0x00a9, "copyright"}, /* "copyrightserif" "copyrightsans" */ + {0x00aa, "ordfeminine"}, + {0x00ab, "guillemotleft"}, + {0x00ac, "logicalnot"}, + {0x00ad, "sfthyphen"}, /* cf "hyphen" */ + {0x00ae, "registered"}, /* "registeredserif" "registeredsans" */ + {0x00af, "overscore"}, + + {0x00b0, "degree"}, + {0x00b1, "plusminus"}, + {0x00b2, "twosuperior"}, + {0x00b3, "threesuperior"}, + {0x00b4, "acute"}, + {0x00b5, "mu1"}, /* "micro" */ + {0x00b6, "paragraph"}, + {0x00b7, "middot"}, /* cf "periodcentered" */ + {0x00b8, "cedilla"}, + {0x00b9, "onesuperior"}, + {0x00ba, "ordmasculine"}, + {0x00bb, "guillemotright"}, + {0x00bc, "onequarter"}, + {0x00bd, "onehalf"}, + {0x00be, "threequarters"}, + {0x00bf, "questiondown"}, + + {0x00c0, "Agrave"}, + {0x00c1, "Aacute"}, + {0x00c2, "Acircumflex"}, + {0x00c3, "Atilde"}, + {0x00c4, "Adieresis"}, + {0x00c5, "Aring"}, + {0x00c6, "AE"}, + {0x00c7, "Ccedilla"}, + {0x00c8, "Egrave"}, + {0x00c9, "Eacute"}, + {0x00ca, "Ecircumflex"}, + {0x00cb, "Edieresis"}, + {0x00cc, "Igrave"}, + {0x00cd, "Iacute"}, + {0x00ce, "Icircumflex"}, + {0x00cf, "Idieresis"}, + + {0x00d0, "Eth"}, + {0x00d1, "Ntilde"}, + {0x00d2, "Ograve"}, + {0x00d3, "Oacute"}, + {0x00d4, "Ocircumflex"}, + {0x00d5, "Otilde"}, + {0x00d6, "Odieresis"}, + {0x00d7, "multiply"}, + {0x00d8, "Oslash"}, + {0x00d9, "Ugrave"}, + {0x00da, "Uacute"}, + {0x00db, "Ucircumflex"}, + {0x00dc, "Udieresis"}, + {0x00dd, "Yacute"}, + {0x00de, "Thorn"}, + {0x00df, "germandbls"}, + + {0x00e0, "agrave"}, + {0x00e1, "aacute"}, + {0x00e2, "acircumflex"}, + {0x00e3, "atilde"}, + {0x00e4, "adieresis"}, + {0x00e5, "aring"}, + {0x00e6, "ae"}, + {0x00e7, "ccedilla"}, + {0x00e8, "egrave"}, + {0x00e9, "eacute"}, + {0x00ea, "ecircumflex"}, + {0x00eb, "edieresis"}, + {0x00ec, "igrave"}, + {0x00ed, "iacute"}, + {0x00ee, "icircumflex"}, + {0x00ef, "idieresis"}, + + {0x00f0, "eth"}, + {0x00f1, "ntilde"}, + {0x00f2, "ograve"}, + {0x00f3, "oacute"}, + {0x00f4, "ocircumflex"}, + {0x00f5, "otilde"}, + {0x00f6, "odieresis"}, + {0x00f7, "divide"}, + {0x00f8, "oslash"}, + {0x00f9, "ugrave"}, + {0x00fa, "uacute"}, + {0x00fb, "ucircumflex"}, + {0x00fc, "udieresis"}, + {0x00fd, "yacute"}, + {0x00fe, "thorn"}, + {0x00ff, "ydieresis"}, + + {0x0100, "Amacron"}, + {0x0101, "amacron"}, + {0x0102, "Abreve"}, + {0x0103, "abreve"}, + {0x0104, "Aogonek"}, + {0x0105, "aogonek"}, + {0x0106, "Cacute"}, + {0x0107, "cacute"}, + {0x0108, "Ccircumflex"}, + {0x0109, "ccircumflex"}, + {0x010a, "Cdot"}, + {0x010b, "cdot"}, + {0x010c, "Ccaron"}, + {0x010d, "ccaron"}, + {0x010e, "Dcaron"}, + {0x010f, "dcaron"}, + + {0x0110, "Dslash"}, + {0x0111, "dmacron"}, + {0x0112, "Emacron"}, + {0x0113, "emacron"}, + {0x0114, "Ebreve"}, + {0x0115, "ebreve"}, + {0x0116, "Edot"}, + {0x0117, "edot"}, + {0x0118, "Eogonek"}, + {0x0119, "eogonek"}, + {0x011a, "Ecaron"}, + {0x011b, "ecaron"}, + {0x011c, "Gcircumflex"}, + {0x011d, "gcircumflex"}, + {0x011e, "Gbreve"}, + {0x011f, "gbreve"}, + + {0x0120, "Gdot"}, + {0x0121, "gdot"}, + {0x0122, "Gcedilla"}, + {0x0123, "gcedilla"}, + {0x0124, "Hcircumflex"}, + {0x0125, "hcircumflex"}, + {0x0126, "Hbar"}, + {0x0127, "hbar"}, + {0x0128, "Itilde"}, + {0x0129, "itilde"}, + {0x012a, "Imacron"}, + {0x012b, "imacron"}, + {0x012c, "Ibreve"}, + {0x012d, "ibreve"}, + {0x012e, "Iogonek"}, + {0x012f, "iogonek"}, + + {0x0130, "Idot"}, + {0x0131, "dotlessi"}, + {0x0132, "IJ"}, + {0x0133, "ij"}, + {0x0134, "Jcircumflex"}, + {0x0135, "jcircumflex"}, + {0x0136, "Kcedilla"}, + {0x0137, "kcedilla"}, + {0x0138, "kgreenlandic"}, + {0x0139, "Lacute"}, + {0x013a, "lacute"}, + {0x013b, "Lcedilla"}, + {0x013c, "lcedilla"}, + {0x013d, "Lcaron"}, + {0x013e, "lcaron"}, + {0x013f, "Ldot"}, + + {0x0140, "ldot"}, + {0x0141, "Lslash"}, + {0x0142, "lslash"}, + {0x0143, "Nacute"}, + {0x0144, "nacute"}, + {0x0145, "Ncedilla"}, + {0x0146, "ncedilla"}, + {0x0147, "Ncaron"}, + {0x0148, "ncaron"}, + {0x0149, "napostrophe"}, + {0x014a, "Eng"}, + {0x014b, "eng"}, + {0x014c, "Omacron"}, + {0x014d, "omacron"}, + {0x014e, "Obreve"}, + {0x014f, "obreve"}, + + {0x0150, "Odblacute"}, + {0x0151, "odblacute"}, + {0x0152, "OE"}, + {0x0153, "oe"}, + {0x0154, "Racute"}, + {0x0155, "racute"}, + {0x0156, "Rcedilla"}, + {0x0157, "rcedilla"}, + {0x0158, "Rcaron"}, + {0x0159, "rcaron"}, + {0x015a, "Sacute"}, + {0x015b, "sacute"}, + {0x015c, "Scircumflex"}, + {0x015d, "scircumflex"}, + {0x015e, "Scedilla"}, + {0x015f, "scedilla"}, + + {0x0160, "Scaron"}, + {0x0161, "scaron"}, + {0x0162, "Tcedilla"}, + {0x0163, "tcedilla"}, + {0x0164, "Tcaron"}, + {0x0165, "tcaron"}, + {0x0166, "Tbar"}, + {0x0167, "tbar"}, + {0x0168, "Utilde"}, + {0x0169, "utilde"}, + {0x016a, "Umacron"}, + {0x016b, "umacron"}, + {0x016c, "Ubreve"}, + {0x016d, "ubreve"}, + {0x016e, "Uring"}, + {0x016f, "uring"}, + + {0x0170, "Udblacute"}, + {0x0171, "udblacute"}, + {0x0172, "Uogonek"}, + {0x0173, "uogonek"}, + {0x0174, "Wcircumflex"}, + {0x0175, "wcircumflex"}, + {0x0176, "Ycircumflex"}, + {0x0177, "ycircumflex"}, + {0x0178, "Ydieresis"}, + {0x0179, "Zacute"}, + {0x017a, "zacute"}, + {0x017b, "Zdot"}, + {0x017c, "zdot"}, + {0x017d, "Zcaron"}, + {0x017e, "zcaron"}, + {0x017f, "longs"}, + + {0x0192, "florin"}, + + {0x01fa, "Aringacute"}, + {0x01fb, "aringacute"}, + {0x01fc, "AEacute"}, + {0x01fd, "aeacute"}, + {0x01fe, "Oslashacute"}, + {0x01ff, "oslashacute"}, + + {0x02c6, "circumflex"}, + {0x02c7, "caron"}, + {0x02c9, "macron"}, /* cf "overscore" */ + + {0x02d8, "breve"}, + {0x02d9, "dotaccent"}, + {0x02da, "ring"}, + {0x02db, "ogonek"}, + {0x02dc, "tilde"}, + {0x02dd, "hungarumlaut"}, + + {0x037e, "semicolon"}, + + {0x0384, "tonos"}, + {0x0385, "dieresistonos"}, + {0x0386, "Alphatonos"}, + {0x0387, "anoteleia"}, + {0x0388, "Epsilontonos"}, + {0x0389, "Etatonos"}, + {0x038a, "Iotatonos"}, + {0x038c, "Omicrontonos"}, + {0x038e, "Upsilontonos"}, + {0x038f, "Omegatonos"}, + + {0x0390, "iotadieresistonos"}, + {0x0391, "Alpha"}, + {0x0392, "Beta"}, + {0x0393, "Gamma"}, + {0x0394, "Delta"}, + {0x0395, "Epsilon"}, + {0x0396, "Zeta"}, + {0x0397, "Eta"}, + {0x0398, "Theta"}, + {0x0399, "Iota"}, + {0x039a, "Kappa"}, + {0x039b, "Lambda"}, + {0x039c, "Mu"}, + {0x039d, "Nu"}, + {0x039e, "Xi"}, + {0x039f, "Omicron"}, + + {0x03a0, "Pi"}, + {0x03a1, "Rho"}, + {0x03a2, "Sigma"}, + {0x03a3, "Tau"}, + {0x03a4, "Upsilon"}, + {0x03a5, "Phi"}, + {0x03a6, "Chi"}, + {0x03a7, "Psi"}, + {0x03a8, "Omega"}, /* cf "Ohm" */ + {0x03aa, "Iotadieresis"}, + {0x03ab, "Upsilondieresis"}, + {0x03ac, "alphatonos"}, + {0x03ad, "epsilontonos"}, + {0x03ae, "etatonos"}, + {0x03af, "iotatonos"}, + + {0x03b0, "upsilondieresistonos"}, + {0x03b1, "alpha"}, + {0x03b2, "beta"}, + {0x03b3, "gamma"}, + {0x03b4, "delta"}, + {0x03b5, "epsilon"}, + {0x03b6, "zeta"}, + {0x03b7, "eta"}, + {0x03b8, "theta"}, + {0x03b9, "iota"}, + {0x03ba, "kappa"}, + {0x03bb, "lambda"}, + {0x03bc, "mu"}, + {0x03bd, "nu"}, + {0x03be, "xi"}, + {0x03bf, "omicron"}, + + {0x03c0, "pi"}, + {0x03c1, "rho"}, + {0x03c2, "sigma1"}, + {0x03c3, "sigma"}, + {0x03c4, "tau"}, + {0x03c5, "upsilon"}, + {0x03c6, "phi"}, + {0x03c7, "chi"}, + {0x03c8, "psi"}, + {0x03c9, "omega"}, + {0x03ca, "iotadieresis"}, + {0x03cb, "upsilondieresis"}, + {0x03cc, "omicrontonos"}, + {0x03cd, "upsilontonos"}, + {0x03ce, "omegatonos"}, + + {0x0401, "afii10023"}, + {0x0402, "afii10051"}, + {0x0403, "afii10052"}, + {0x0404, "afii10053"}, + {0x0405, "afii10054"}, + {0x0406, "afii10055"}, + {0x0407, "afii10056"}, + {0x0408, "afii10057"}, + {0x0409, "afii10058"}, + {0x040a, "afii10059"}, + {0x040b, "afii10060"}, + {0x040c, "afii10061"}, + {0x040e, "afii10062"}, + {0x040f, "afii10145"}, + + {0x0410, "afii10017"}, + {0x0411, "afii10018"}, + {0x0412, "afii10019"}, + {0x0413, "afii10020"}, + {0x0414, "afii10021"}, + {0x0415, "afii10022"}, + {0x0416, "afii10024"}, + {0x0417, "afii10025"}, + {0x0418, "afii10026"}, + {0x0419, "afii10027"}, + {0x041a, "afii10028"}, + {0x041b, "afii10029"}, + {0x041c, "afii10030"}, + {0x041d, "afii10031"}, + {0x041e, "afii10032"}, + {0x041f, "afii10033"}, + + {0x0420, "afii10034"}, + {0x0421, "afii10035"}, + {0x0422, "afii10036"}, + {0x0423, "afii10037"}, + {0x0424, "afii10038"}, + {0x0425, "afii10039"}, + {0x0426, "afii10040"}, + {0x0427, "afii10041"}, + {0x0428, "afii10042"}, + {0x0429, "afii10043"}, + {0x042a, "afii10044"}, + {0x042b, "afii10045"}, + {0x042c, "afii10046"}, + {0x042d, "afii10047"}, + {0x042e, "afii10048"}, + {0x042f, "afii10049"}, + + {0x0430, "afii10065"}, + {0x0431, "afii10066"}, + {0x0432, "afii10067"}, + {0x0433, "afii10068"}, + {0x0434, "afii10069"}, + {0x0435, "afii10070"}, + {0x0436, "afii10072"}, + {0x0437, "afii10073"}, + {0x0438, "afii10074"}, + {0x0439, "afii10075"}, + {0x043a, "afii10076"}, + {0x043b, "afii10077"}, + {0x043c, "afii10078"}, + {0x043d, "afii10079"}, + {0x043e, "afii10080"}, + {0x043f, "afii10081"}, + + {0x0440, "afii10082"}, + {0x0441, "afii10083"}, + {0x0442, "afii10084"}, + {0x0443, "afii10085"}, + {0x0444, "afii10086"}, + {0x0445, "afii10087"}, + {0x0446, "afii10088"}, + {0x0447, "afii10089"}, + {0x0448, "afii10090"}, + {0x0449, "afii10091"}, + {0x044a, "afii10092"}, + {0x044b, "afii10093"}, + {0x044c, "afii10094"}, + {0x044d, "afii10095"}, + {0x044e, "afii10096"}, + {0x044f, "afii10097"}, + + {0x0451, "afii10071"}, + {0x0452, "afii10099"}, + {0x0453, "afii10100"}, + {0x0454, "afii10101"}, + {0x0455, "afii10102"}, + {0x0456, "afii10103"}, + {0x0457, "afii10104"}, + {0x0458, "afii10105"}, + {0x0459, "afii10106"}, + {0x045a, "afii10107"}, + {0x045b, "afii10108"}, + {0x045c, "afii10109"}, + {0x045e, "afii10110"}, + {0x045f, "afii10193"}, + + {0x0490, "afii10050"}, + {0x0491, "afii10098"}, + + {0x1e80, "Wgrave"}, + {0x1e81, "wgrave"}, + {0x1e82, "Wacute"}, + {0x1e83, "wacute"}, + {0x1e84, "Wdieresis"}, + {0x1e85, "wdieresis"}, + + {0x1ef2, "Ygrave"}, + {0x1ef3, "ygrave"}, + + {0x2013, "endash"}, + {0x2014, "emdash"}, + {0x2015, "afii00208"}, /* horizontal bar */ + {0x2017, "underscoredbl"}, + {0x2018, "quoteleft"}, + {0x2019, "quoteright"}, + {0x201a, "quotesinglbase"}, + {0x201b, "quotereversed"}, + {0x201c, "quotedblleft"}, + {0x201d, "quotedblright"}, + {0x201e, "quotedblbase"}, + + {0x2020, "dagger"}, + {0x2021, "daggerdbl"}, + {0x2022, "bullet"}, + {0x2026, "ellipsis"}, + {0x2030, "perthousand"}, + {0x2032, "minute"}, + {0x2033, "second"}, + {0x2039, "guilsinglleft"}, + {0x203a, "guilsinglright"}, + {0x203c, "exclamdbl"}, + {0x203e, "radicalex"}, + + {0x2044, "fraction"}, /* cf U+2215 */ + + {0x207f, "nsuperior"}, + + {0x20a3, "franc"}, + {0x20a4, "afii08941"}, /* lira sign */ + {0x20a7, "peseta"}, + + {0x2105, "afii61248"}, /* care of */ + + {0x2113, "afii61289"}, /* script small l */ + {0x2116, "afii61352"}, /* numero sign */ + + {0x2122, "trademark"}, + {0x2126, "Ohm"}, + {0x212e, "estimated"}, + + {0x215b, "oneeighth"}, + {0x215c, "threeeighths"}, + {0x215d, "fiveeighths"}, + {0x215e, "seveneighths"}, + + {0x2190, "arrowleft"}, + {0x2191, "arrowup"}, + {0x2192, "arrowright"}, + {0x2193, "arrowdown"}, + {0x2194, "arrowboth"}, + {0x2195, "arrowupdn"}, + + {0x21a8, "arrowupdnbse"}, + + {0x2202, "partialdiff"}, + {0x2206, "increment"}, + {0x220f, "product"}, + + {0x2211, "summation"}, + {0x2212, "minus"}, + {0x2215, "fraction"}, /* cf U+2044 */ + {0x2219, "periodcentered"}, + {0x221a, "radical"}, + {0x221e, "infinity"}, + {0x221f, "orthogonal"}, + + {0x2229, "intersection"}, + {0x222b, "integral"}, + + {0x2248, "approxequal"}, + + {0x2260, "notequal"}, + {0x2261, "equivalence"}, + {0x2264, "lessequal"}, + {0x2265, "greaterequal"}, + + {0x2302, "house"}, + + {0x2310, "revlogicalnot"}, + + {0x2320, "integraltp"}, + {0x2321, "integralbt"}, + + {0x2500, "SF100000"}, + {0x2502, "SF110000"}, + {0x250c, "SF010000"}, + + {0x2510, "SF030000"}, + {0x2514, "SF020000"}, + {0x2518, "SF040000"}, + {0x251c, "SF080000"}, + + {0x2524, "SF090000"}, + {0x252c, "SF060000"}, + + {0x2534, "SF070000"}, + {0x253c, "SF050000"}, + + {0x2550, "SF430000"}, + {0x2551, "SF240000"}, + {0x2552, "SF510000"}, + {0x2553, "SF520000"}, + {0x2554, "SF390000"}, + {0x2555, "SF220000"}, + {0x2556, "SF210000"}, + {0x2557, "SF250000"}, + {0x2558, "SF500000"}, + {0x2559, "SF490000"}, + {0x255a, "SF380000"}, + {0x255b, "SF280000"}, + {0x255c, "SF270000"}, + {0x255d, "SF260000"}, + {0x255e, "SF360000"}, + {0x255f, "SF370000"}, + + {0x2560, "SF420000"}, + {0x2561, "SF190000"}, + {0x2562, "SF200000"}, + {0x2563, "SF230000"}, + {0x2564, "SF470000"}, + {0x2565, "SF480000"}, + {0x2566, "SF410000"}, + {0x2567, "SF450000"}, + {0x2568, "SF460000"}, + {0x2569, "SF400000"}, + {0x256a, "SF540000"}, + {0x256b, "SF530000"}, + {0x256c, "SF440000"}, + + {0x2580, "upblock"}, + {0x2584, "dnblock"}, + {0x2588, "block"}, + {0x258c, "lfblock"}, + + {0x2590, "rtblock"}, + {0x2591, "ltshade"}, + {0x2592, "shade"}, + {0x2593, "dkshade"}, + + {0x25a0, "filledbox"}, + {0x25a1, "H22073"}, + {0x25aa, "H18543"}, + {0x25ab, "H18551"}, + {0x25ac, "filledrect"}, + + {0x25b2, "triagup"}, + {0x25ba, "triagrt"}, + {0x25bc, "triagdn"}, + + {0x25c4, "triaglf"}, + {0x25ca, "lozenge"}, + {0x25cb, "circle"}, + {0x25cf, "H18533"}, + + {0x25d8, "invbullet"}, + {0x25d9, "invcircle"}, + + {0x25e6, "openbullet"}, + + {0x263a, "smileface"}, + {0x263b, "invsmileface"}, + {0x263c, "sun"}, + + {0x2640, "female"}, + {0x2642, "male"}, + + {0x2660, "spade"}, + {0x2663, "club"}, + {0x2665, "heart"}, + {0x2666, "diamond"}, + {0x266a, "musicalnote"}, + {0x266b, "musicalnotedbl"}, + + {0xf000, "applelogo"}, + {0xf001, "fi"}, + {0xf002, "fl"}, + {0xf004, "commaaccent"}, + {0xf005, "undercommaaccent"}, + {0xfb01, "fi"}, + {0xfb02, "fl"}, +}; + +struct encoding_table mac_table[] = +{ + {-1, ".notdef"}, + {0x0000, ".notdef"}, /* null */ + {0x0008, ".notdef"}, /* backspace */ + {0x0009, ".notdef"}, /* horizontal tabulation */ + {0x000d, ".notdef"}, /* carriage return */ + {0x001d, ".notdef"}, /* group separator */ + {0x0020, "space"}, + {0x0021, "exclam"}, + {0x0022, "quotedbl"}, + {0x0023, "numbersign"}, + {0x0024, "dollar"}, + {0x0025, "percent"}, + {0x0026, "ampersand"}, + {0x0027, "quotesingle"}, + {0x0028, "parenleft"}, + {0x0029, "parenright"}, + {0x002a, "asterisk"}, + {0x002b, "plus"}, + {0x002c, "comma"}, + {0x002d, "hyphen"}, + {0x002e, "period"}, + {0x002f, "slash"}, + + {0x0030, "zero"}, + {0x0031, "one"}, + {0x0032, "two"}, + {0x0033, "three"}, + {0x0034, "four"}, + {0x0035, "five"}, + {0x0036, "six"}, + {0x0037, "seven"}, + {0x0038, "eight"}, + {0x0039, "nine"}, + {0x003a, "colon"}, + {0x003b, "semicolon"}, + {0x003c, "less"}, + {0x003d, "equal"}, + {0x003e, "greater"}, + {0x003f, "question"}, + + {0x0040, "at"}, + {0x0041, "A"}, + {0x0042, "B"}, + {0x0043, "C"}, + {0x0044, "D"}, + {0x0045, "E"}, + {0x0046, "F"}, + {0x0047, "G"}, + {0x0048, "H"}, + {0x0049, "I"}, + {0x004a, "J"}, + {0x004b, "K"}, + {0x004c, "L"}, + {0x004d, "M"}, + {0x004e, "N"}, + {0x004f, "O"}, + + {0x0050, "P"}, + {0x0051, "Q"}, + {0x0052, "R"}, + {0x0053, "S"}, + {0x0054, "T"}, + {0x0055, "U"}, + {0x0056, "V"}, + {0x0057, "W"}, + {0x0058, "X"}, + {0x0059, "Y"}, + {0x005a, "Z"}, + {0x005b, "bracketleft"}, + {0x005c, "backslash"}, + {0x005d, "bracketright"}, + {0x005e, "asciicircum"}, + {0x005f, "underscore"}, + + {0x0060, "grave"}, + {0x0061, "a"}, + {0x0062, "b"}, + {0x0063, "c"}, + {0x0064, "d"}, + {0x0065, "e"}, + {0x0066, "f"}, + {0x0067, "g"}, + {0x0068, "h"}, + {0x0069, "i"}, + {0x006a, "j"}, + {0x006b, "k"}, + {0x006c, "l"}, + {0x006d, "m"}, + {0x006e, "n"}, + {0x006f, "o"}, + + {0x0070, "p"}, + {0x0071, "q"}, + {0x0072, "r"}, + {0x0073, "s"}, + {0x0074, "t"}, + {0x0075, "u"}, + {0x0076, "v"}, + {0x0077, "w"}, + {0x0078, "x"}, + {0x0079, "y"}, + {0x007a, "z"}, + {0x007b, "braceleft"}, + {0x007c, "bar"}, + {0x007d, "braceright"}, + {0x007e, "asciitilde"}, + + {0x0080, "Adieresis"}, + {0x0081, "Aring"}, + {0x0082, "Ccedilla"}, + {0x0083, "Eacute"}, + {0x0084, "Ntilde"}, + {0x0085, "Odieresis"}, + {0x0086, "Udieresis"}, + {0x0087, "aacute"}, + {0x0088, "agrave"}, + {0x0089, "acircumflex"}, + {0x008a, "adieresis"}, + {0x008b, "atilde"}, + {0x008c, "aring"}, + {0x008d, "ccedilla"}, + {0x008e, "eacute"}, + {0x008f, "egrave"}, + + {0x0090, "ecircumflex"}, + {0x0091, "edieresis"}, + {0x0092, "iacute"}, + {0x0093, "igrave"}, + {0x0094, "icircumflex"}, + {0x0095, "idieresis"}, + {0x0096, "ntilde"}, + {0x0097, "oacute"}, + {0x0098, "ograve"}, + {0x0099, "ocircumflex"}, + {0x009a, "odieresis"}, + {0x009b, "otilde"}, + {0x009c, "uacute"}, + {0x009d, "ugrave"}, + {0x009e, "ucircumflex"}, + {0x009f, "udieresis"}, + + {0x00a0, "dagger"}, + {0x00a1, "degree"}, + {0x00a2, "cent"}, + {0x00a3, "sterling"}, + {0x00a4, "section"}, + {0x00a5, "bullet"}, + {0x00a6, "paragraph"}, + {0x00a7, "germandbls"}, + {0x00a8, "registered"}, + {0x00a9, "copyright"}, + {0x00aa, "trademark"}, + {0x00ab, "acute"}, + {0x00ac, "dieresis"}, + {0x00ad, "notequal"}, + {0x00ae, "AE"}, + {0x00af, "Oslash"}, + + {0x00b0, "infinity"}, + {0x00b1, "plusminus"}, + {0x00b2, "lessequal"}, + {0x00b3, "greaterequal"}, + {0x00b4, "yen"}, + {0x00b5, "mu"}, + {0x00b6, "partialdiff"}, + {0x00b7, "summation"}, + {0x00b8, "product"}, + {0x00b9, "pi"}, + {0x00ba, "integral"}, + {0x00bb, "ordfeminine"}, + {0x00bc, "ordmasculine"}, + {0x00bd, "Omega"}, + {0x00be, "ae"}, + {0x00bf, "oslash"}, + + {0x00c0, "questiondown"}, + {0x00c1, "exclamdown"}, + {0x00c2, "logicalnot"}, + {0x00c3, "radical"}, + {0x00c4, "florin"}, + {0x00c5, "approxequal"}, + {0x00c6, "Delta"}, + {0x00c7, "guillemotleft"}, + {0x00c8, "guillemotright"}, + {0x00c9, "ellipsis"}, + {0x00ca, "nbspace"}, + {0x00cb, "Agrave"}, + {0x00cc, "Atilde"}, + {0x00cd, "Otilde"}, + {0x00ce, "OE"}, + {0x00cf, "oe"}, + + {0x00d0, "endash"}, + {0x00d1, "emdash"}, + {0x00d2, "quotedblleft"}, + {0x00d3, "quotedblright"}, + {0x00d4, "quoteleft"}, + {0x00d5, "quoteright"}, + {0x00d6, "divide"}, + {0x00d7, "lozenge"}, + {0x00d8, "ydieresis"}, + {0x00d9, "Ydieresis"}, + {0x00da, "fraction"}, + {0x00db, "currency"}, + {0x00dc, "guilsinglleft"}, + {0x00dd, "guilsinglright"}, + {0x00de, "fi"}, + {0x00df, "fl"}, + + {0x00e0, "daggerdbl"}, + {0x00e1, "periodcentered"}, + {0x00e2, "quotesinglbase"}, + {0x00e3, "quotedblbase"}, + {0x00e4, "perthousand"}, + {0x00e5, "Acircumflex"}, + {0x00e6, "Ecircumflex"}, + {0x00e7, "Aacute"}, + {0x00e8, "Edieresis"}, + {0x00e9, "Egrave"}, + {0x00ea, "Iacute"}, + {0x00eb, "Icircumflex"}, + {0x00ec, "Idieresis"}, + {0x00ed, "Igrave"}, + {0x00ee, "Oacute"}, + {0x00ef, "Ocircumflex"}, + + {0x00f0, "apple"}, + {0x00f1, "Ograve"}, + {0x00f2, "Uacute"}, + {0x00f3, "Ucircumflex"}, + {0x00f4, "Ugrave"}, + {0x00f5, "dotlessi"}, + {0x00f6, "circumflex"}, + {0x00f7, "tilde"}, + {0x00f8, "macron"}, + {0x00f9, "breve"}, + {0x00fa, "dotaccent"}, + {0x00fb, "ring"}, + {0x00fc, "cedilla"}, + {0x00fd, "hungarumlaut"}, + {0x00fe, "ogonek"}, + {0x00ff, "caron"}, +}; + + +struct encoding_table *current_table; +size_t current_table_len; + + +void +set_encoding_scheme(EncodingScheme e, Font *fnt) +{ + current_encoding_scheme = e; + + switch (e) + { + case encUnicode: + current_table = unicode_table; + current_table_len = sizeof (unicode_table) / sizeof (unicode_table[0]); + break; + + case encMac: + current_table = mac_table; + current_table_len = sizeof (mac_table) / sizeof (mac_table[0]); + break; + + case encFontSpecific: + break; + } +} + + +/* + * We return ".c0x" + * if no name is found. + * + * We return ".g0x" + * if it's a glyph index (code >= 0x10000). + */ + +char * +code_to_adobename(long code) +{ + unsigned int n, n1 = 0, n2 = current_table_len - 1; + char *p; + + + if (current_encoding_scheme == encFontSpecific) + { + p = (char *)mymalloc(9); + sprintf(p, ".%c0x%x", (code >= 0x10000) ? 'g' : 'c', + (unsigned int)(code & 0xFFFF)); + return p; + } + + while (n1 <= n2) + { + n = (n1 + n2) / 2; + if (code < current_table[n].code) + n2 = n - 1; + else if (code > current_table[n].code) + n1 = n + 1; + else + return current_table[n].adobename; + } + + p = (char *)mymalloc(9); + sprintf(p, ".%c0x%x", (code >= 0x10000) ? 'g' : 'c', + (unsigned int)(code & 0xFFFF)); + return p; +} + + +/* + * The first of two identical entries will win. + */ + +long +adobename_to_code(char *s) +{ + size_t i; + long j; + char p; + + + if (s == NULL) + return -1; + + if (current_encoding_scheme == encFontSpecific) + { + if (*(s++) != '.') + return -1; + + p = *(s++); + if (!(p == 'c' || p == 'g')) + return -1; + + j = strtol(s, &s, 0); + if (*s == '\0') + return (p == 'g') ? (j | 0x10000) : j; + else + return -1; + } + + for (i = 0; i < current_table_len; i++) + { + if (strcmp(current_table[i].adobename, s) == 0) + return current_table[i].code; + } + + if (*(s++) != '.') + return -1; + + p = *(s++); + if (!(p == 'c' || p == 'g')) + return -1; + + j = strtol(s, &s, 0); + if (*s == '\0') + return (p == 'g') ? (j | 0x10000) : j; + else + return -1; +} + + +ttfinfo * +findglyph(unsigned short g, ttfinfo *p) +{ + register ttfinfo *ti; + + + if (!p) + return NULL; + + for (ti = p; ti; ti = ti->next) + if (g == ti->glyphindex) + return ti; + + return NULL; +} + + +ttfinfo * +findadobe(char *p, ttfinfo *ap) +{ + register ttfinfo *ti; + register long l = -1; + register char c = '\0', d = '\0'; + + + if (!p) + return NULL; + + if (p[0] == '.' && + (c = p[1]) && (c == 'c' || c == 'g') && + (d = p[2]) && '0' <= d && d <= '9') + l = strtol(p + 2, NULL, 0); + + for (ti = ap; ti; ti = ti->next) + { + if (l >= 0) + { + if (c == 'c') + { + if (ti->charcode == l) + return ti; + } + else + { + if (ti->glyphindex == l) + return ti; + } + } + else if (strcmp(p, ti->adobename) == 0) + return ti; + } + + return NULL; +} + + +ttfinfo * +findmappedadobe(char *p, ttfinfo **array) +{ + register int i; + register ttfinfo *ti; + register long l = -1; + register char c = '\0', d = '\0'; + + + if (!p) + return NULL; + + if (p[0] == '.' && + (c = p[1]) && (c == 'c' || c == 'g') && + (d = p[2]) && '0' <= d && d <= '9') + l = strtol(p + 2, NULL, 0); + + for (i = 0; i <= 0xFF; i++) + if ((ti = array[i])) + { + if (l >= 0) + { + if (c == 'c') + { + if (ti->charcode == l) + return ti; + } + else + { + if (ti->glyphindex == l) + return ti; + } + } + else if (strcmp(p, ti->adobename) == 0) + return ti; + } + + return NULL; +} + + +void +replace_glyphs(Font *fnt) +{ + stringlist *sl, *sl_old; + ttfinfo *ti; + + + for (sl = fnt->replacements, sl_old = NULL; sl; sl_old = sl, sl = sl->next) + { + if ((ti = findadobe(sl->old_name, fnt->charlist))) + ti->adobename = sl->new_name; + else + { + warning("Glyph name `%s' not found.", sl->old_name); + warning("Replacement glyph name `%s' thus ignored.", sl->new_name); + if (sl_old == NULL) + fnt->replacements = sl->next; + else + sl_old->next = sl->next; + } + } +} + + +/* the opposite of replace_glyph() */ + +void +restore_glyph(encoding *enc, Font *fnt) +{ + stringlist *sl; + int i; + + + for (sl = fnt->replacements; sl; sl = sl->next) + { + for (i = 0; i <= 0xFF; i++) + { + if (strcmp(enc->vec[i], sl->new_name) == 0) + { + enc->vec[i] = sl->old_name; + goto success; + } + } + warning("Glyph name `%s' not found in encoding.", sl->new_name); + warning("Replacement for glyph name `%s' thus ignored.", sl->old_name); + +success: + ; + } +} + + +/* end */ diff --git a/contrib/ttf2pk/ttfenc.h b/contrib/ttf2pk/ttfenc.h new file mode 100644 index 0000000..95a265b --- /dev/null +++ b/contrib/ttf2pk/ttfenc.h @@ -0,0 +1,41 @@ +/* + * ttfenc.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TTFENC_H +#define TTFENC_H + +#include "ttf2tfm.h" + + +enum _EncodingScheme +{ + encUnicode, + encMac, + encFontSpecific +}; +typedef enum _EncodingScheme EncodingScheme; + + +void set_encoding_scheme(EncodingScheme e, Font *fnt); + +char *code_to_adobename(long code); +long adobename_to_code(char *s); + +ttfinfo *findglyph(unsigned short g, ttfinfo *p); +ttfinfo *findadobe(char *p, ttfinfo *ap); +ttfinfo *findmappedadobe(char *p, ttfinfo **array); + +void replace_glyphs(Font *fnt); +void restore_glyph(encoding *enc, Font *fnt); + +#endif /* TTFENC_H */ + + +/* end */ diff --git a/contrib/ttf2pk/ttflib.c b/contrib/ttf2pk/ttflib.c new file mode 100644 index 0000000..3cadaa2 --- /dev/null +++ b/contrib/ttf2pk/ttflib.c @@ -0,0 +1,703 @@ +/* + * ttflib.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Loyer Frederic + * Werner Lemberg + */ + +#include +#include +#include +#include /* libc ANSI */ +#include + +#include "pklib.h" /* for the `byte' type */ +#include "freetype.h" +#include "ttfenc.h" +#include "ttflib.h" +#include "errormsg.h" +#include "newobj.h" +#include "ttf2tfm.h" + +#include "extend/ftxpost.h" +#include "extend/ftxopen.h" + + +#define Macintosh_platform 1 +#define Macintosh_encoding 0 + +#define Microsoft_platform 3 +#define Microsoft_Symbol_encoding 0 +#define Microsoft_Unicode_encoding 1 + +#define SCRIPT_kana MAKE_TT_TAG('k', 'a', 'n', 'a') +#define SCRIPT_hani MAKE_TT_TAG('h', 'a', 'n', 'i') +#define SCRIPT_hang MAKE_TT_TAG('h', 'a', 'n', 'g') + +#define LANGUAGE_JAN MAKE_TT_TAG('J', 'A', 'N', ' ') +#define LANGUAGE_CHN MAKE_TT_TAG('C', 'H', 'N', ' ') +#define LANGUAGE_KOR MAKE_TT_TAG('K', 'O', 'R', ' ') + +#define FEATURE_vert MAKE_TT_TAG('v', 'e', 'r', 't') + + +TT_Engine engine; +TT_Face face; +TT_Instance instance; +TT_Glyph glyph; +TT_CharMap char_map; + +TT_Outline outline; +TT_Face_Properties properties; +TT_BBox bbox; + +TT_Post post; + +TT_Raster_Map Bit, Bit2; +void *Bitp, *Bit2p; + +int dpi; +int ptsize; + +int x_offset, y_offset; +int ppem; + +TT_Big_Glyph_Metrics metrics; + +TT_Matrix matrix1, matrix2; + +TTO_GSUBHeader gsub_; +TTO_GSUBHeader *gsub; + +TT_UShort in_string[2]; +TTO_GSUB_String in, out; + +Boolean has_gsub; + + +static void +SetRasterArea(int quiet) +{ + int temp1_x, temp1_y, temp2_x, temp2_y; + + + temp1_x = bbox.xMin / 64; /* scaling F16.6 -> int */ + temp1_y = bbox.yMin / 64; + temp2_x = (bbox.xMax + 63) / 64; + temp2_y = (bbox.yMax + 63) / 64; + + x_offset = 5 - temp1_x; + y_offset = 5 - temp1_y; + + if (!quiet) + printf(" off = (%d, %d)", x_offset, y_offset); + +#if 0 + x_offset = y_offset = 0; +#endif + + if (!quiet) + printf(" bbox = (%d, %d) <-> (%d, %d)\n", + temp1_x, temp1_y, temp2_x, temp2_y); + + Bit.rows = temp2_y - temp1_y + 10; + Bit.width = temp2_x - temp1_x + 10; + + Bit.cols = (Bit.width + 7) / 8; /* convert to # of bytes */ + Bit.flow = TT_Flow_Up; + Bit.size = Bit.rows * Bit.cols; /* number of bytes in buffer */ + + /* + * We allocate one more row to have valid pointers for comparison + * purposes in pklib.c, making `gcc -fbounds-checking' happy. + */ + + if (Bitp) + free(Bitp); + Bitp = mymalloc(Bit.size + Bit.cols); + Bit.bitmap = Bitp; + + Bit2 = Bit; + + if (Bit2p) + free(Bit2p); + Bit2p = mymalloc(Bit.size + Bit.cols); + Bit2.bitmap = Bit2p; +} + + +static void +FlipBit(void) +{ + int y; + char *p1, *p2; + + p1 = (char *)Bit.bitmap; + p2 = (char *)Bit2.bitmap + Bit2.cols * (Bit2.rows - 1); + + for (y = 0; y < Bit.rows; y++) + { + memcpy(p2, p1, Bit.cols); + p1 += Bit.cols; + p2 -= Bit.cols; + } +} + + +#if 0 + +static void +Output(TT_Raster_Map Bit) +{ + int x; + int y; + int i; + + char *p, b; + + + p = Bit.bitmap; + printf("====\n"); + + for (y = 0; y < Bit.rows; y++) + { + printf("%3d:", y); + for (x = 0; x < Bit.cols; x++) + { + b = *p++; + for(i = 0x80; i; i >>= 1) + printf((b & i) ? "x" : "."); + } + printf("\n"); + } +} + +#endif /* 0 */ + + +void +TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize, Boolean quiet) +{ + unsigned short i, num_cmap; + unsigned short cmap_plat; + unsigned short cmap_enc; + TT_Error error; + + TT_UShort script_index, language_index, feature_index; + TT_UShort req_feature_index = 0xFFFF; + + + dpi = new_dpi; + ptsize = new_ptsize; + + if ((error = TT_Init_FreeType(&engine))) + oops("Cannot initialize FreeType engine (error code = 0x%x).", error); + + if (fnt->PSnames) + if ((error = TT_Init_Post_Extension(engine))) + oops("Cannot initialize PS name support (error code = 0x%x).", error); + + if (fnt->rotate) + if ((error = TT_Init_GSUB_Extension(engine))) + oops("Cannot initialize GSUB support (error code = 0x%x).", error); + + /* + * Load face. + */ + + error = TT_Open_Face(engine, filename, &face); + if (error) + oops("Cannot open `%s'.", filename); + + /* + * Get face properties and allocate preloaded arrays. + */ + + TT_Get_Face_Properties(face, &properties); + + /* + * Now we try to open the proper font in a collection. + */ + + if (fnt->fontindex != 0) + { + if (properties.num_Faces == 1) + warning("This isn't a TrueType collection.\n" + "Parameter `Fontindex' is ignored."); + else + { + TT_Close_Face(face); + if ((error = TT_Open_Collection(engine, filename, + fnt->fontindex, &face))) + oops("Cannot open font %lu in TrueType Collection `%s'.", + fnt->fontindex, filename); + } + } + + /* + * Create instance. + */ + + if ((error = TT_New_Instance(face, &instance))) + oops("Cannot create instance for `%s' (error code = 0x%x).", + filename, error); + + if ((error = TT_Set_Instance_Resolutions(instance, dpi, dpi))) + oops("Cannot set device resolutions (error code = 0x%x)."); + + if ((error = TT_Set_Instance_CharSize(instance, ptsize * 64))) + oops("Cannot set character size (error code = 0x%x).", error); + + ppem = (dpi * ptsize + 36) / 72; + + if (!quiet) + printf("dpi = %d, ptsize = %d, ppem = %d\n\n", dpi, ptsize, ppem); + + matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1<<16)/1024); + matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1<<16)/1024); + matrix1.yx = (TT_Fixed)0; + matrix1.yy = (TT_Fixed)(1<<16); + + if (fnt->rotate) + { + matrix2.xx = 0; + matrix2.yx = 1L << 16; + matrix2.xy = -matrix2.yx; + matrix2.yy = matrix2.xx; + } + + if ((error = TT_Set_Instance_Transform_Flags( + instance, + fnt->rotate ? 1 : 0, + fnt->efactor != 1.0 ? 1 : 0))) + oops("Cannot set transform flags (error code = 0x%x).", error); + + /* + * Create glyph container. + */ + + if ((error = TT_New_Glyph(face, &glyph))) + oops("Cannot create glyph container (error code = 0x%x)."); + + if (fnt->PSnames != Only) + { + num_cmap = properties.num_CharMaps; + for (i = 0; i < num_cmap; i++) + { + if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc))) + oops("Cannot query cmap (error code = 0x%x).", error); + if (cmap_plat == fnt->pid && cmap_enc == fnt->eid) + break; + } + if (i == num_cmap) + oops("Invalid platform and/or encoding ID."); + + if ((error = TT_Get_CharMap(face, i, &char_map))) + oops("Cannot load cmap (error code = 0x%x).", error); + } + + if (fnt->PSnames) + { + if ((error = TT_Load_PS_Names(face, &post))) + oops("Cannot load TrueType PS names (error code = 0x%x).", error); + } + else if (cmap_plat == Microsoft_platform && + cmap_enc == Microsoft_Unicode_encoding) + set_encoding_scheme(encUnicode, fnt); + else if (cmap_plat == Macintosh_platform && + cmap_enc == Macintosh_encoding) + set_encoding_scheme(encMac, fnt); + else + set_encoding_scheme(encFontSpecific, fnt); + + if (fnt->rotate) + { + gsub = &gsub_; + + error = TT_Load_GSUB_Table(face, gsub, NULL); + if (!error) + has_gsub = True; + else if (error != TT_Err_Table_Missing) + warning("Cannot load GSUB table (error code = 0x%x).", error); + else + warning("No GSUB data available " + "for vertical glyph presentation forms."); + + /* we check for the `vert' feature in Chinese, Japanese, and Korean */ + + error = TT_GSUB_Select_Script(gsub, + SCRIPT_kana, + &script_index); + if (error) + goto check_hani; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_JAN, + script_index, + &language_index, + &req_feature_index); + if (error) + goto check_hani; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + if (error) + goto check_hani; + else + goto Done; + } + else + goto Done; + + check_hani: + error = TT_GSUB_Select_Script(gsub, + SCRIPT_hani, + &script_index); + if (error) + goto check_hang; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_CHN, + script_index, + &language_index, + &req_feature_index); + if (error) + goto check_hang; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + if (error) + goto check_hang; + else + goto Done; + } + else + goto Done; + + check_hang: + error = TT_GSUB_Select_Script(gsub, + SCRIPT_hang, + &script_index); + if (error) + goto Done; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + 0xFFFF, + &feature_index); + if (error) + { + error = TT_GSUB_Select_Language(gsub, + LANGUAGE_KOR, + script_index, + &language_index, + &req_feature_index); + if (error) + goto Done; + error = TT_GSUB_Select_Feature(gsub, + FEATURE_vert, + script_index, + language_index, + &feature_index); + } + + Done: + if (error) + { + warning("There is no data for vertical typesetting in GSUB table."); + has_gsub = False; + } + + if (req_feature_index != 0xFFFF) + TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS); + TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS); + + in.length = 1; + in.pos = 0; + in.string = in_string; + in.properties = NULL; + + out.pos = 0; + out.allocated = 0; + out.string = NULL; + out.properties = NULL; + } +} + + +static TT_Error +LoadTrueTypeChar(Font *fnt, + int idx, + Boolean hint, + Boolean quiet) +{ + TT_Error error; + int flags; + + + flags = TTLOAD_SCALE_GLYPH; + if (hint) + flags |= TTLOAD_HINT_GLYPH; + + error = TT_Load_Glyph(instance, glyph, idx, flags); + if (!error) + error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); + if (!error) + error = TT_Get_Glyph_Outline(glyph, &outline); + if (!error) + { + if (fnt->efactor != 1.0 || fnt->slant != 0.0 ) + TT_Transform_Outline(&outline, &matrix1); + if (fnt->rotate) + TT_Transform_Outline(&outline, &matrix2); + } + if (!error) + error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non- + grid-fitted bbox */ + if (fnt->rotate) + TT_Translate_Outline(&outline, + metrics.vertBearingY - bbox.xMin, + -fnt->y_offset * ppem * 64); + if (!error) + error = TT_Get_Outline_BBox(&outline, &bbox); + if (!error) + SetRasterArea(quiet); + return error; +} + + +Boolean +TTFprocess(Font *fnt, + long Code, + byte **bitmap, + int *width, int *height, + int *hoff, int *voff, + Boolean hinting, + Boolean quiet) +{ + int Num; + TT_Error error; + + + if (!bitmap || !width || !height || !hoff || !voff) + oops("Invalid parameter in call to TTFprocess()"); + + if (Code >= 0x10000) + Num = Code & 0xFFFF; + else + { + Num = TT_Char_Index(char_map, Code); + if (has_gsub) + { + in_string[0] = Num; + error = TT_GSUB_Apply_String(gsub, &in, &out); + if (error && error != TTO_Err_Not_Covered) + warning("Cannot get the vertical glyph form for glyph index %d.", + Num); + else + Num = out.string[0]; + } + } + + if ((error = LoadTrueTypeChar(fnt, Num, hinting, quiet)) == TT_Err_Ok) + { + memset(Bit.bitmap, 0, Bit.size); + TT_Get_Glyph_Bitmap(glyph, &Bit, x_offset * 64, y_offset * 64); + + FlipBit(); + *bitmap = Bit2.bitmap; + *width = Bit2.width; + *height = Bit2.rows; + *hoff = x_offset; + *voff = y_offset; + /* *voff = Bit2.rows - y_offset; */ + /* printf("%D %d\n", *hoff, *voff); */ + /* Output(Bit2); */ + return True; + } + else + return False; +} + + +/* + * We collect first all glyphs addressed via the cmap. Then we fill the + * array up with glyphs not in the cmap. + * + * If PSnames is set to `Only', we get the first 256 glyphs which have + * names different from `.notdef', `.null', and `nonmarkingreturn'. + * + * For nicer output, we return the glyph names in an encoding array. + */ + +encoding * +TTFget_first_glyphs(Font *fnt, long *array) +{ + unsigned int i, j, Num; + unsigned int index_array[257]; /* we ignore glyph index 0 */ + char *n; + encoding *e = (encoding *)mymalloc(sizeof (encoding)); + + + if (!array) + oops("Invalid parameter in call to TTFget_first_glyphs()"); + + for (i = 0; i < 257; i++) + index_array[i] = 0; + + j = 0; + if (fnt->PSnames != Only) + { + for (i = 0; i <= 0xFFFF; i++) + { + Num = TT_Char_Index(char_map, i); + if (Num < 0) + oops("cmap mapping failure."); + if (Num == 0) + continue; + if (Num <= 256) + index_array[Num] = 1; + + if (fnt->PSnames) + (void)TT_Get_PS_Name(face, Num, &n); + else + n = code_to_adobename(i); + if (strcmp(n, ".notdef") == 0) + continue; + if (strcmp(n, ".null") == 0) + continue; + if (strcmp(n, "nonmarkingreturn") == 0) + continue; + + if (j < 256) + { + array[j] = i; + e->vec[j] = n; + } + else + return e; + j++; + } + + if (!fnt->PSnames) + { + for (i = 1; i < properties.num_Glyphs; i++) + { + if (index_array[i] == 0) + { + if (j < 256) + { + array[j] = i | 0x10000; + e->vec[j] = code_to_adobename(i | 0x10000); + } + else + return e; + j++; + } + } + } + } + else + { + for (i = 0; i < properties.num_Glyphs; i++) + { + char *n; + + + (void)TT_Get_PS_Name(face, i, &n); + + if (strcmp(n, ".notdef") == 0) + continue; + if (strcmp(n, ".null") == 0) + continue; + if (strcmp(n, "nonmarkingreturn") == 0) + continue; + + if (j < 256) + { + array[j] = i | 0x10000; + e->vec[j] = n; + } + else + return e; + j++; + } + } + + return NULL; /* never reached */ +} + + +/* + * This routine fills `array' with the subfont character codes; + * additionally, it tests for valid glyph indices. + */ + +void +TTFget_subfont(Font *fnt, long *array) +{ + int i, j, Num; + + + if (!fnt || !array) + oops("Invalid parameter in call to TTFget_subfont()"); + + for (i = 0; i <= 0xFF; i++) + { + j = fnt->sf_code[i]; + + if (j < 0) + array[i] = j; + else + { + Num = TT_Char_Index(char_map, j); + if (Num < 0) + oops("cmap mapping failure."); + else + array[i] = j; + } + } +} + + +long +TTFsearch_PS_name(char *name) +{ + unsigned int i; + char *n; + + + for (i = 0; i < properties.num_Glyphs; i++) + { + TT_Get_PS_Name(face, i, &n); + if (strcmp(name, n) == 0) + break; + } + + if (i == properties.num_Glyphs) + return -1L; + else + return (long)i; +} + + +/* end */ diff --git a/contrib/ttf2pk/ttflib.h b/contrib/ttf2pk/ttflib.h new file mode 100644 index 0000000..e218382 --- /dev/null +++ b/contrib/ttf2pk/ttflib.h @@ -0,0 +1,31 @@ +/* + * ttflib.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef TTFLIB_H +#define TTFLIB_H + +#include "pklib.h" /* for the `byte' type */ + +void TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize, + Boolean quiet); + +Boolean TTFprocess(Font *fnt, long Code, byte **bitmap, + int *width, int *height, int *hoff, int *voff, + Boolean hinting, Boolean quiet); + +encoding *TTFget_first_glyphs(Font *fnt, long *array); +void TTFget_subfont(Font *fnt, long *array); + +long TTFsearch_PS_name(char *name); + +#endif /* TTFLIB_H */ + + +/* end */ diff --git a/contrib/ttf2pk/vplaux.c b/contrib/ttf2pk/vplaux.c new file mode 100644 index 0000000..867c32f --- /dev/null +++ b/contrib/ttf2pk/vplaux.c @@ -0,0 +1,588 @@ +/* + * vplaux.c + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#include +#include +#include +#include + +#include "ttf2tfm.h" +#include "newobj.h" +#include "ttfenc.h" +#include "texenc.h" +#include "tfmaux.h" +#include "vplaux.h" +#include "errormsg.h" +#include "case.h" + + +#undef PI +#define PI 3.14159265358979323846264338327 + + +#define vout(s) fprintf(out, s) + +#define voutln(str) {fprintf(out, "%s\n", str); vlevout(level);} +#define voutln2(f, s) {fprintf(out, f, s); vlevnlout(level);} +#define voutln3(f, a, b) {fprintf(out, f, a, b); vlevnlout(level);} +#define voutln4(f, a, b, c) {fprintf(out, f, a, b, c); vlevnlout(level);} + + +static char vcharbuf[6]; +static char vnamebuf[100]; + +/* the depth of parenthesis nesting in VPL file being written */ +static int level; + + +static FILE *out; + + +static void +vlevout(register int l) +{ + while (l--) + vout(" "); +} + + +static void +vlevnlout(int level) +{ + vout("\n"); + vlevout(level); +} + + +static void +vleft(int *levelp) +{ + (*levelp)++; + vout("("); +} + + +static void +vright(int *levelp) +{ + (*levelp)--; + voutln(")"); +} + + +static char * +vchar(int c, + char *buf, + Boolean forceoctal) +{ + if (forceoctal == 0 && isalnum(c)) + (void)sprintf(buf, "C %c", c); + else + (void)sprintf(buf, "O %o", (unsigned)c); + return buf; +} + + +static char * +vname(int c, + char *buf, + ttfinfo **array, + Boolean forceoctal) +{ + if (!forceoctal && isalnum(c)) + buf[0] = '\0'; + else + sprintf(buf, " (comment %s)", array[c]->adobename); + return buf; +} + + +static int +texheight(register ttfinfo *ti, + ttfinfo *ac, + int xh) +{ + register char **p; + register ttfinfo *aci, *acci; + char buffer[200]; + + + if (xh <= 50 || *(ti->adobename + 1)) + return ti->ury; /* that was the simple case */ + + for (p = accents; *p; p++) /* otherwise we look for accented letters. */ + /* We even check glyphs not in any encoding */ + if (NULL != (aci = findadobe(*p, ac))) + { + strcpy(buffer, ti->adobename); + strcat(buffer, *p); + if (NULL != (acci = findadobe(buffer, ac))) + return acci->ury - aci->ury + xh; + } + return ti->ury; +} + + +/* + * Compute uppercase mapping, when making a small caps font. + */ + +void +upmap(Font *fnt) +{ + register ttfinfo *ti, *Ti; + register char *p, *q; + register pcc *np, *nq; + int i, j; + char lwr[50]; + + + for (Ti = fnt->charlist; Ti; Ti = Ti->next) + { + p = Ti->adobename; + if (isupper(*p)) + { + q = lwr; + for (; *p; p++) + *q++ = tolower(*p); + *q = '\0'; + + if (NULL != (ti = findmappedadobe(lwr, fnt->inencptrs))) + { + for (i = ti->outcode; i >= 0; i = fnt->nextout[i]) + fnt->uppercase[i] = Ti; + for (i = Ti->outcode; i >= 0; i = fnt->nextout[i]) + fnt->lowercase[i] = ti; + } + } + } + + /* + * Note that, contrary to the normal true/false conventions, + * uppercase[i] is NULL and lowercase[i] is non-NULL when `i' is the + * ASCII code of an uppercase letter; and vice versa for lowercase + * letters. + */ + + if (NULL != (ti = findmappedadobe("germandbls", fnt->inencptrs))) + if (NULL != (Ti = findmappedadobe("S", fnt->inencptrs))) + /* we also construct SS */ + { + for (i = ti->outcode; i >= 0; i = fnt->nextout[i]) + fnt->uppercase[i] = ti; + ti->incode = -1; + ti->width = Ti->width << 1; + ti->llx = Ti->llx; + ti->lly = Ti->lly; + ti->urx = Ti->width + Ti->urx; + ti->ury = Ti->ury; + ti->kerns = Ti->kerns; + + np = newpcc(); + np->partname = "S"; + nq = newpcc(); + nq->partname = "S"; + nq->xoffset = Ti->width; + np->next = nq; + ti->pccs = np; + ti->constructed = True; + } + + for (i = 0; casetable[i].upper; i++) + { + if ((ti = findmappedadobe(casetable[i].lower, fnt->inencptrs))) + for (j = ti->outcode; j >= 0; j = fnt->nextout[j]) + fnt->uppercase[j] = findmappedadobe(casetable[i].upper, + fnt->inencptrs); + } +} + +/* + * The logic above seems to work well enough, but it leaves useless + * characters like `fi' and `fl' in the font if they were present + * initially, and it omits characters like `dotlessj' if they are + * absent initially. + */ + + +void +writevpl(Font *fnt, char makevpl, Boolean forceoctal) +{ + register int i, j, k; + register ttfinfo *ti; + register lig *nlig; + register kern *nkern; + register pcc *npcc; + ttfinfo *asucc, *asub, *api; + ttfptr *kern_eq; + int xoff, yoff, ht; + int bc, ec; + char buf[200]; + char header[256]; + Boolean unlabeled; + float Slant; + + + out = fnt->vplout; + + header[0] = '\0'; + strncat(header, "Created by `", 12); + strncat(header, fnt->titlebuf, 255 - 12 - 1); + strncat(header, "'", 1); + + voutln2("(VTITLE %s)", header); + voutln("(COMMENT Please change VTITLE if you edit this file)"); + (void)sprintf(buf, "TeX-%s%s%s%s", + fnt->fullname, + (fnt->efactor == 1.0 ? "" : "-E"), + (fnt->slant == 0.0 ? "" : "-S"), + (makevpl == 1 ? "" : "-CSC")); + + if (strlen(buf) > 19) /* too long, will retain first 9 and last 10 chars */ + { + register char *p, *q; + + + for (p = &buf[9], q = &buf[strlen(buf)-10]; p < &buf[19]; + p++, q++) + *p = *q; + buf[19] = '\0'; + } + voutln2("(FAMILY %s)", buf); + + { + char tbuf[300]; + char *base_encoding = fnt->codingscheme; + + + if (strcmp(fnt->outencoding->name, base_encoding) == 0) + sprintf(tbuf, "%s", fnt->outencoding->name); + else + sprintf(tbuf, "%s + %s", base_encoding, fnt->outencoding->name); + + if (strlen(tbuf) > 39) + { + warning("Coding scheme too long; shortening to 39 characters"); + tbuf[39] = '\0'; + } + voutln2("(CODINGSCHEME %s)", tbuf); + } + + { + long t, sc; + char *s; + int n, pos; + + + s = header; + n = strlen(s); + t = ((long)n) << 24; + sc = 16; + pos = 18; + + voutln( + "(COMMENT The following `HEADER' lines are equivalent to the string)"); + voutln2("(COMMENT \"%s\")", header); + + while (n > 0) + { + t |= ((long)(*(unsigned char *)s++)) << sc; + sc -= 8; + if (sc < 0) + { + voutln3("(HEADER D %d O %lo)", pos, t); + t = 0; + sc = 24; + pos++; + } + n--; + } + if (t) + voutln3("(HEADER D %d O %lo)", pos, t); + } + + voutln("(DESIGNSIZE R 10.0)"); + voutln("(DESIGNUNITS R 1000)"); + voutln("(COMMENT DESIGNSIZE (1 em) IS IN POINTS)"); + voutln("(COMMENT OTHER DIMENSIONS ARE MULTIPLES OF DESIGNSIZE/1000)"); + +#if 0 + /* Let vptovf compute the checksum. */ + voutln2("(CHECKSUM O %lo)", cksum ^ 0xFFFFFFFF); +#endif + + if (fnt->boundarychar >= 0) + voutln2("(BOUNDARYCHAR O %lo)", (unsigned long)fnt->boundarychar); + + vleft(&level); + voutln("FONTDIMEN"); + + Slant = fnt->slant - fnt->efactor * tan(fnt->italicangle * (PI / 180.0)); + + if (Slant) + voutln2("(SLANT R %f)", Slant); + voutln2("(SPACE D %d)", fnt->fontspace); + if (!fnt->fixedpitch) + { + voutln2("(STRETCH D %d)", transform(200, 0, fnt->efactor, fnt->slant)); + voutln2("(SHRINK D %d)", transform(100, 0, fnt->efactor, fnt->slant)); + } + voutln2("(XHEIGHT D %d)", fnt->xheight); + voutln2("(QUAD D %d)", transform(1000, 0, fnt->efactor, fnt->slant)); + voutln2("(EXTRASPACE D %d)", + fnt->fixedpitch ? fnt->fontspace : + transform(111, 0, fnt->efactor, fnt->slant)); + vright(&level); + + vleft(&level); + voutln("MAPFONT D 0"); + voutln2("(FONTNAME %s)", fnt->fullname); +#if 0 + voutln2("(FONTCHECKSUM O %lo)", (unsigned long)cksum); +#endif + vright(&level); + + if (makevpl > 1) + { + vleft(&level); + voutln("MAPFONT D 1"); + voutln2("(FONTNAME %s)", fnt->fullname); + voutln2("(FONTAT D %d)", (int)(1000.0 * fnt->capheight + 0.5)); +#if 0 + voutln2("(FONTCHECKSUM O %lo)", (unsigned long)cksum); +#endif + vright(&level); + } + + for (i = 0; i <= 0xFF && fnt->outencptrs[i] == NULL; i++) + ; + bc = i; + for (i = 0xFF; i >= 0 && fnt->outencptrs[i] == NULL; i--) + ; + ec = i; + + vleft(&level); + voutln("LIGTABLE"); + ti = findadobe("||", fnt->charlist); + unlabeled = True; + for (nlig = ti->ligs; nlig; nlig = nlig->next) + if (NULL != (asucc = findmappedadobe(nlig->succ, fnt->inencptrs))) + { + if (NULL != (asub = findmappedadobe(nlig->sub, fnt->inencptrs))) + if (asucc->outcode >= 0) + if (asub->outcode >= 0) + { + if (unlabeled) + { + voutln("(LABEL BOUNDARYCHAR)"); + unlabeled = False; + } + for (j = asucc->outcode; j >= 0; j = fnt->nextout[j]) + voutln4("(%s %s O %o)", vplligops[nlig->op], + vchar(j, vcharbuf, forceoctal), + (unsigned)asub->outcode); + } + } + if (!unlabeled) + voutln("(STOP)"); + + for (i = bc; i <= ec; i++) + if ((ti = fnt->outencptrs[i]) && ti->outcode == i) + { + unlabeled = True; + if (fnt->uppercase[i] == NULL) + /* omit ligatures from smallcap lowercase */ + for (nlig = ti->ligs; nlig; nlig = nlig->next) + if (NULL != (asucc = findmappedadobe(nlig->succ, fnt->inencptrs))) + if (NULL != (asub = findmappedadobe(nlig->sub, fnt->inencptrs))) + if (asucc->outcode >= 0) + if (asub->outcode >= 0) + { + if (unlabeled) + { + for (j = ti->outcode; j >= 0; j = fnt->nextout[j]) + voutln3("(LABEL %s)%s", + vchar(j, vcharbuf, forceoctal), + vname(j, vnamebuf, + fnt->outencptrs, forceoctal)); + unlabeled = False; + } + for (j = asucc->outcode; j >= 0; j = fnt->nextout[j]) + { + voutln4("(%s %s O %o)", vplligops[nlig->op], + vchar(j, vcharbuf, forceoctal), + (unsigned)asub->outcode); + if (nlig->boundleft) + break; + } + } + + for (nkern = (fnt->uppercase[i] ? fnt->uppercase[i]->kerns : ti->kerns); + nkern; nkern=nkern->next) + if (NULL != (asucc = findmappedadobe(nkern->succ, fnt->inencptrs))) + for (j = asucc->outcode; j >= 0; j = fnt->nextout[j]) + { + if (fnt->uppercase[j] == NULL) + { + if (unlabeled) + { + for (k = ti->outcode; k >= 0; k = fnt->nextout[k]) + voutln3("(LABEL %s)%s", + vchar(k, vcharbuf, forceoctal), + vname(k, vnamebuf, fnt->outencptrs, forceoctal)); + unlabeled = False; + } + + /* + * If other characters have the same kerns as this + * one, output the label here. This makes the TFM + * file much smaller than if we output all the + * kerns again under a different label. + */ + + for (kern_eq = ti->kern_equivs; kern_eq; + kern_eq = kern_eq->next) + { + k = kern_eq->ch->outcode; + if (k >= 0 && k <= 0xFF) + voutln3("(LABEL %s)%s", + vchar(k, vcharbuf, forceoctal), + vname(k, vnamebuf, fnt->outencptrs, forceoctal)); + } + ti->kern_equivs = NULL; /* Only output those labels once. */ + + if (fnt->uppercase[i]) + { + if (fnt->lowercase[j]) + { + for (k = fnt->lowercase[j]->outcode; k >= 0; + k = fnt->nextout[k]) + voutln4("(KRN %s R %.1f)%s", + vchar(k, vcharbuf, forceoctal), + fnt->capheight * nkern->delta, + vname(k, vnamebuf, fnt->outencptrs, forceoctal)); + } + else + voutln4("(KRN %s R %.1f)%s", + vchar(j, vcharbuf, forceoctal), + fnt->capheight * nkern->delta, + vname(j, vnamebuf, fnt->outencptrs, forceoctal)); + } + else + { + voutln4("(KRN %s R %d)%s", + vchar(j, vcharbuf, forceoctal), + nkern->delta, + vname(j, vnamebuf, fnt->outencptrs, forceoctal)); + if (fnt->lowercase[j]) + for (k = fnt->lowercase[j]->outcode; k >= 0; + k = fnt->nextout[k]) + voutln4("(KRN %s R %.1f)%s", + vchar(k, vcharbuf, forceoctal), + fnt->capheight * nkern->delta, + vname(k, vnamebuf, fnt->outencptrs, forceoctal)); + } + } + } + if (!unlabeled) + voutln("(STOP)"); + } + vright(&level); + + for (i = bc; i <= ec; i++) + if (NULL != (ti = fnt->outencptrs[i])) + { + vleft(&level); + fprintf(out, "CHARACTER %s%s\n ", + vchar(i, vcharbuf, forceoctal), + vname(i, vnamebuf, fnt->outencptrs, forceoctal)); + + if (fnt->uppercase[i]) + { + ti = fnt->uppercase[i]; + voutln2("(CHARWD R %.1f)", fnt->capheight * (ti->width)); + if (0 != (ht = texheight(ti, fnt->charlist, fnt->xheight))) + voutln2("(CHARHT R %.1f)", fnt->capheight * ht); + if (ti->lly) + voutln2("(CHARDP R %.1f)", -fnt->capheight * ti->lly); + if (ti->urx > ti->width) + voutln2("(CHARIC R %.1f)", fnt->capheight * (ti->urx - ti->width)); + } + else + { + voutln2("(CHARWD R %d)", ti->width); + if (0 != (ht = texheight(ti, fnt->charlist, fnt->xheight))) + voutln2("(CHARHT R %d)", ht); + if (ti->lly) + voutln2("(CHARDP R %d)", -ti->lly); + if (ti->urx > ti->width) + voutln2("(CHARIC R %d)", ti->urx - ti->width); + } + + if (ti->incode != i || fnt->uppercase[i] || ti->constructed) + { + vleft(&level); + voutln("MAP"); + if (fnt->uppercase[i]) + voutln("(SELECTFONT D 1)"); + + if (ti->pccs && (ti->incode < 0 || ti->constructed)) + { + xoff = 0; + yoff = 0; + + for (npcc = ti->pccs; npcc; npcc = npcc->next) + if (NULL != (api = findmappedadobe(npcc->partname, + fnt->inencptrs))) + if (api->outcode >= 0) + { + if (npcc->xoffset != xoff) + { + if (fnt->uppercase[i]) + { + voutln2("(MOVERIGHT R %.1f)", + fnt->capheight * (npcc->xoffset - xoff)); + } + else + voutln2("(MOVERIGHT R %d)", npcc->xoffset - xoff); + + xoff = npcc->xoffset; + } + + if (npcc->yoffset != yoff) + { + if (fnt->uppercase[i]) + { + voutln2("(MOVEUP R %.1f)", + fnt->capheight * (npcc->yoffset - yoff)); + } + else + voutln2("(MOVEUP R %d)", npcc->yoffset - yoff); + + yoff = npcc->yoffset; + } + + voutln2("(SETCHAR O %o)", (unsigned)api->incode); + xoff += fnt->outencptrs[api->outcode]->width; + } + } + else + voutln2("(SETCHAR O %o)", (unsigned)ti->incode); + vright(&level); + } + vright(&level); + } + + if (level) + oops("I forgot to match the parentheses."); +} + + +/* end */ diff --git a/contrib/ttf2pk/vplaux.h b/contrib/ttf2pk/vplaux.h new file mode 100644 index 0000000..f6281d8 --- /dev/null +++ b/contrib/ttf2pk/vplaux.h @@ -0,0 +1,23 @@ +/* + * vplaux.h + * + * This file is part of the ttf2pk package. + * + * Copyright 1997-1999 by + * Frederic Loyer + * Werner Lemberg + */ + +#ifndef VPLAUX_H +#define VPLAUX_H + +#include "ttf2tfm.h" + + +void writevpl(Font *fnt, char makevpl, Boolean forceoctal); +void upmap(Font *fnt); + +#endif /* VPLAUX_H */ + + +/* end */ diff --git a/contrib/ttfbanner/.cvsignore b/contrib/ttfbanner/.cvsignore new file mode 100644 index 0000000..d0b8b54 --- /dev/null +++ b/contrib/ttfbanner/.cvsignore @@ -0,0 +1,2 @@ +ttfbanner +Makefile diff --git a/contrib/ttfbanner/Makefile.emx b/contrib/ttfbanner/Makefile.emx new file mode 100644 index 0000000..486e12d --- /dev/null +++ b/contrib/ttfbanner/Makefile.emx @@ -0,0 +1,9 @@ +# Makefile for ttfbanner + +all: ttfbanner.exe + +ttfbanner.exe: ttfbanner.o + gcc -O -o ttfbanner.exe ttfbanner.o -lttf + +ttfbanner.o: ttfbanner.c + gcc -O -c ttfbanner.c diff --git a/contrib/ttfbanner/Makefile.in b/contrib/ttfbanner/Makefile.in new file mode 100644 index 0000000..ef34d94 --- /dev/null +++ b/contrib/ttfbanner/Makefile.in @@ -0,0 +1,64 @@ +# Makefile for ttfbanner +# +# This Makefile assumes that you've already built and installed +# the FreeType library. + +VPATH = @srcdir@ +srcdir = @srcdir@ + +RM = @RM@ +RMF = @RM@ -f + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = ../../libtool +MKINSTALLDIRS = $(srcdir)/../../mkinstalldirs + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ + +CFLAGS = @CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ @DEFS@ +FT_CFLAGS = $(CFLAGS) $(CPPFLAGS) +LDFLAGS = @LDFLAGS@ @LIBS@ +LIBDIR = ../../lib + +SRC = ttfbanner.c + +default all: ttfbanner + +ttfbanner: ttfbanner.o $(LIBDIR)/libttf.la + $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o $@ $< \ + $(LIBDIR)/libttf.la $(LDFLAGS) + +clean: + $(RMF) *.o *BAK *CKP *~ a.out core + +realclean: clean + $(RMF) ttfbanner + $(RM) -rf .libs/ + +distclean: realclean + $(RMF) *~ *.orig core *.core + $(RMF) config.cache config.log config.status Makefile + +.c.o: + $(CC) -c $(FT_CFLAGS) $< + +install: ttfbanner + $(MKINSTALLDIRS) $(bindir) + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ttfbanner $(bindir)/ + +uninstall: + $(LIBTOOL) --mode=uninstall $(RM) $(bindir)/ttfbanner + +.PHONY: all clean realclean distclean install uninstall + +# end of Makefile diff --git a/contrib/ttfbanner/README b/contrib/ttfbanner/README new file mode 100644 index 0000000..62b260f --- /dev/null +++ b/contrib/ttfbanner/README @@ -0,0 +1,38 @@ +ttfbanner -- make posters using a TrueType font + +Installation +************ + +Say + + ./configure + make + make install + +It is assumed that you've built the FreeType library before. + +Usage +***** + +Just typing `ttfbanner' will provide you with some summary usage +instructions. + + +Limitations +*********** + +The program will not do any kerning. Incorrect UTF8 strings will not +always be detected. + + +Copying +******* + +This software is provided with no warranty whatsoever. You may do +whatever you wish with it as long as you don't ask me to maintain it. + + +Author +****** + +Juliusz Chroboczek diff --git a/contrib/ttfbanner/configure b/contrib/ttfbanner/configure new file mode 100644 index 0000000..c0e7f85 --- /dev/null +++ b/contrib/ttfbanner/configure @@ -0,0 +1,1372 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=../../lib/freetype.h + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:573: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:594: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:612: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:638: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:668: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:719: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:751: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 762 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:793: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:798: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:826: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:858: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:879: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:896: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +echo $ac_n "checking for TT_Init_FreeType in -lttf""... $ac_c" 1>&6 +echo "configure:942: checking for TT_Init_FreeType in -lttf" >&5 +ac_lib_var=`echo ttf'_'TT_Init_FreeType | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lttf $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LIBS="$LIBS -lttf" +else + echo "$ac_t""no" 1>&6 + + { echo "configure: error: Can't find ttf library! Compile FreeType first." 1>&2; exit 1; } +fi + +LIBS=$OLDLIBS + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -ansi -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1003: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RM"; then + ac_cv_prog_RM="$RM" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RM="rm" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RM="$ac_cv_prog_RM" +if test -n "$RM"; then + echo "$ac_t""$RM" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1041: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@XX_CFLAGS@%$XX_CFLAGS%g +s%@RM@%$RM%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + + diff --git a/contrib/ttfbanner/configure.in b/contrib/ttfbanner/configure.in new file mode 100644 index 0000000..7859e0d --- /dev/null +++ b/contrib/ttfbanner/configure.in @@ -0,0 +1,38 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(../../lib/freetype.h) + +AC_CANONICAL_SYSTEM + +AC_PROG_CC +AC_PROG_CPP + +OLDLIBS=$LIBS +LIBS="$LIBS -L../../lib/.libs" +CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS" +AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[ + AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])]) +LIBS=$OLDLIBS + +dnl get Compiler flags right. + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall -ansi -pedantic" +else + case "$host" in + alpha-dec-osf*) + XX_CFLAGS="-std1 -O2 -g3" + ;; + *) + XX_CFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) + +AC_CHECK_PROG(RM, rm, rm) +AC_PROG_INSTALL + +AC_OUTPUT(Makefile) + +dnl end of configure.in diff --git a/contrib/ttfbanner/ttfbanner.c b/contrib/ttfbanner/ttfbanner.c new file mode 100644 index 0000000..6d7bae4 --- /dev/null +++ b/contrib/ttfbanner/ttfbanner.c @@ -0,0 +1,320 @@ +/* This code was written by Juliusz Chroboczek . */ +/* It comes with no warranty whatsoever. */ +/* Feel free to use it as long as you don't ask me to maintain it. */ + +#include +#include +#include +#include +#include "freetype.h" +#include "ttfbanner.h" + +#define MAXIMIZE(x,xval) if((x)<(xval)) {x=(xval);} +#define MINIMIZE(x,xval) if((x)>(xval)) {x=(xval);} + +void +usage() +{ + fprintf(stderr, "Usage: ttfbanner [options] font.ttf string\n"); + fprintf(stderr, " where options include:\n"); + fprintf(stderr, " -e encoding: specify the encoding of the string (L1, L2 or UTF8, default L1)\n"); + fprintf(stderr, " -p pointsize: specify the point size to use (default 14)\n"); + fprintf(stderr, " -r resolution: specify x and y resolutions (default 72dpi)\n"); + fprintf(stderr, " -x resolution: specify x resolution\n"); + fprintf(stderr, " -y resolution: specify y resolution\n"); + exit(2); +} + +int +main(int argc, char **argv) +{ + int getopt(int argc, char * const argv[], const char *optstring); + extern char *optarg; + extern int optind; + int c; + + unsigned short *unicodeString=NULL; + enum {L1, L2, UTF8} encoding=L1; + double pointsize=14.0; + int xr=72, yr=72; + + TT_Raster_Map *raster; + + while((c=getopt(argc, argv, "s:e:p:r:x:y:"))!=EOF) { + switch(c) { + case 'e': + if(!strcmp(optarg,"L1")) + encoding=L1; + else if(!strcmp(optarg, "L2")) + encoding=L2; + else if(!strcmp(optarg, "UTF8")) + encoding=UTF8; + else { + fprintf(stderr, "Unknown encoding %s; defaulting to L1\n", optarg); + encoding=L1; + } + break; + case 'p': + pointsize=atof(optarg); + break; + case 'r': + xr=yr=atoi(optarg); + break; + case 'x': + xr=atoi(optarg); + break; + case 'y': + yr=atoi(optarg); + break; + default: + usage(); + } + } + + if(argc-optind!=2) + usage(); + + switch (encoding) + { + case L1: unicodeString=l1toUnicode(argv[optind+1]); + break; + case L2: unicodeString=l2toUnicode(argv[optind+1]); + break; + case UTF8: unicodeString=UTF8toUnicode(argv[optind+1]); + break; + default: Error("This cannot happen"); + } + + raster=makeBitmap(unicodeString, argv[optind], + pointsize, xr, yr); + writeBanner(raster); + + return 0; +} + +TT_Raster_Map * +makeBitmap(unsigned short *unicodeString, + char *ttf, double charsize, int xr, int yr) +{ + TT_Error error; + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_Glyph_Metrics metrics; + TT_Raster_Map *raster; + TT_CharMap cmap; + + long xMin, xMax, yMin, yMax; + int xpos, xoffset, yoffset; + unsigned short *p; + int first; + short index; + + if((error=TT_Init_FreeType(&engine))) + FTError("Coudn't initialise FreeType engine", error); + if((error=TT_Open_Face(engine, ttf, &face))) + FTError("Coudn't open font file", error); + if((error=TT_New_Instance(face, &instance))) + FTError("Couldn't create new instance", error); + if((error=TT_Set_Instance_Resolutions(instance, xr, yr))) + FTError("Couldn't set resolutions", error); + if((error=TT_Set_Instance_CharSize(instance, (TT_F26Dot6)(charsize*64.0)))) + FTError("Coudn't set point size", error); + if((error=TT_New_Glyph(face, &glyph))) + FTError("Coudn't create glyph", error); + + if((error=find_unicode_cmap(face, &cmap))) + Error("Couldn't find suitable Cmap"); + + /* Compute size */ + xMin=yMin= 100000l; + xMax=yMax= -100000l; + for(p=unicodeString, first=1, xpos=0; (*p)!=0xFFFF; p++, first=0) { + index=TT_Char_Index(cmap, *p); + if((error=TT_Load_Glyph(instance, glyph, index, TTLOAD_DEFAULT))) + FTError("Couldn't load glyph", error); + if((error=TT_Get_Glyph_Metrics(glyph, &metrics))) + FTError("Couldn't get glyph metrics", error); + + if(first) + xMin=metrics.bbox.xMin; + xMax=xpos*64+metrics.bbox.xMax; + xpos+=(metrics.advance+32)/64; + + MAXIMIZE(yMax, metrics.bbox.yMax); + MINIMIZE(yMin, metrics.bbox.yMin); + } + + xoffset=-(xMin-63)/64; + yoffset=-(yMin-63)/64; + + if((raster=malloc(sizeof(TT_Raster_Map)))==NULL) + Error("Couldn't allocate raster structure"); + raster->rows=(yMax+63)/64+yoffset; + raster->width=(xMax+63)/64+xoffset; + raster->cols=(raster->width+7)/8; + raster->flow=TT_Flow_Down; + if((raster->bitmap=calloc(raster->cols, raster->rows))==NULL) + Error("Couldn't allocate bitmap"); + raster->size=((long)raster->rows*raster->cols); + + + for(p=unicodeString, xpos=xoffset; *p!=0xFFFF; p++) { + index=TT_Char_Index(cmap, *p); + if((error=TT_Load_Glyph(instance, glyph, index, TTLOAD_DEFAULT))) + FTError("Couldn't load glyph", error); + if((error=TT_Get_Glyph_Metrics(glyph, &metrics))) + FTError("Couldn't get glyph metrics", error); + + if((error=TT_Get_Glyph_Bitmap(glyph, raster, xpos*64, yoffset*64))) + FTError("Couldn't typeset glyph", error); + xpos+=(metrics.advance+32)/64; + } + + return raster; +} + +int +find_unicode_cmap(TT_Face face, TT_CharMap *cmap) +{ + int i,n; + unsigned short p,e; + + n=TT_Get_CharMap_Count(face); + for(i=0; irows; i++) { + int j; + for(j=0; jwidth; j++) { + if(((((unsigned char*)raster->bitmap)+i*raster->cols)[j/8]&(1<<(7-j%8))) + != 0) + putchar('*'); + else + putchar(' '); + } + putchar('\n'); + } +} + +unsigned short * +l1toUnicode(char *string) +{ + unsigned short *r; + int n,i; + + n=strlen(string); + if((r=malloc(sizeof(unsigned short)*(n+1)))==NULL) + Error("Couldn't allocate string"); + + for(i=0; i +#include +#include +#include + +#include + +#include "freetype.h" +#include "gdriver.h" + +HANDLE evgetevent,evdriverdisplaybitmap,this_wnd,main_thread,listbox,bitmap; +TEvent evevent; +char message_32[256]; +char *ev_buffer; +jmp_buf Env; +long TTMemory_Allocated = 0; // just to have a clean link with ftdump +// save last rendered image Data +int save_lines,save_cols,exit_code; +char *save_buffer; +extern int vio_Width,vio_Height,vio_ScanLineWidth; +extern TT_Raster_Map Bit; +HDC hdc,memdc; +HBITMAP hbm,hbm1; + +//________________________________________________________________________________ +void Get_Event(TEvent *event) +{ + WaitForSingleObject(evgetevent,INFINITE); // wait for completion + *event=evevent; //set by message handler before posting waited upon event + return; +} + +int Driver_Set_Graphics( int mode ) +{ RECT rect; + GetClientRect(bitmap,&rect); + vio_Width=rect.right-rect.left; + vio_Height = rect.bottom-rect.top; + vio_ScanLineWidth=vio_Width; + return 1; + + } +int Driver_Restore_Mode() +{return 1;} + +int Driver_Display_Bitmap( char* buffer, int lines, int cols ) + { + long rc; + int i; + char *top,*bottom; + HANDLE rgdi; + RECT rect; + char *w_buffer; +// bitmap=listbox; + hdc=GetDC(bitmap); + memdc=CreateCompatibleDC(hdc); + GetClientRect(bitmap,&rect); + //hbm=CreateCompatibleBitmap(hdc,lines,cols); + // need to set upside down bitmap . + if (buffer != save_buffer) //new buffer + { + if (save_buffer!=NULL) + free(save_buffer); + save_buffer=(char *)malloc(Bit.size); + memcpy(save_buffer,buffer,Bit.size); + } + w_buffer=malloc(Bit.size); // hope it succeeds + top=buffer; + bottom=w_buffer+Bit.size-cols; + for(i=0;i diff --git a/contrib/win32/hack_ftdump.c b/contrib/win32/hack_ftdump.c new file mode 100644 index 0000000..4a673a2 --- /dev/null +++ b/contrib/win32/hack_ftdump.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) ftdump(A,B) +#include diff --git a/contrib/win32/hack_ftlint.c b/contrib/win32/hack_ftlint.c new file mode 100644 index 0000000..bee2d3f --- /dev/null +++ b/contrib/win32/hack_ftlint.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) ftlint(A,B) +#include diff --git a/contrib/win32/hack_ftstring.c b/contrib/win32/hack_ftstring.c new file mode 100644 index 0000000..ac248aa --- /dev/null +++ b/contrib/win32/hack_ftstring.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) ftstring(A,B) +#include diff --git a/contrib/win32/hack_fttimer.c b/contrib/win32/hack_fttimer.c new file mode 100644 index 0000000..d575d0c --- /dev/null +++ b/contrib/win32/hack_fttimer.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) fttimer(A,B) +#include diff --git a/contrib/win32/hack_ftview.c b/contrib/win32/hack_ftview.c new file mode 100644 index 0000000..17cd957 --- /dev/null +++ b/contrib/win32/hack_ftview.c @@ -0,0 +1,9 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +#define exit(code) force_exit(code) +#define main(A,B) ftview(A,B) +#include diff --git a/contrib/win32/readme.txt b/contrib/win32/readme.txt new file mode 100644 index 0000000..fb8ca9c --- /dev/null +++ b/contrib/win32/readme.txt @@ -0,0 +1,19 @@ +The purpose of this application is to serve as a running environment for +some of the freetype project test programs: +currently available programa aree ftdump,ftlint,,ftstring,ftview; +others may be convinced to run but you may need to change the source +code to avoid duplicate problems with the linker. +This work has been based on a large amount of guesswork +and a small amount of my (little) spare time; +however it seems to be working pretty well as far as I can tell +( -g -r options are not working but I don't care 'bout them). +It can be compiled both under MS VC++ Version 4.X and Version 5. +and has been tested under Windows 95 & NT 4.0 . + +Have Fun . + Giancarlo Ramat + (gcramat@radiostudio.it) + +[Please note that all files are archived in Unix LF format (except +testw32.mdp which is a binary file). If necessary, use e.g. unzip's `-a' +flag to convert to MSDOS CR/LF convention.] diff --git a/contrib/win32/res/testw32.ico b/contrib/win32/res/testw32.ico new file mode 100644 index 0000000000000000000000000000000000000000..7eef0bcbe6580a6f464d688906172c2d9de44262 GIT binary patch literal 1078 zcmc&zF>b>!3}jLb9s)T}@Kod(893@u8ajANzT`op9^o+)S?=nU(FD@%0s)Sg^oyC8{H z9myetc;MEP)59v(LMa~xK8Yu^jIR*H22uCFiq5%C{s7(PJi>o15i^bmX4(vPxWAio z9ryY#AU_jfnd047-@`)XzL?%iS$gQyFP{44kS9X)fN{{QoL~hO-&=q&20Zr*cxFAt PkaNE{wR~2C$NfnjhSXWT literal 0 HcmV?d00001 diff --git a/contrib/win32/res/testw32.rc2 b/contrib/win32/res/testw32.rc2 new file mode 100644 index 0000000..c81f594 --- /dev/null +++ b/contrib/win32/res/testw32.rc2 @@ -0,0 +1,13 @@ +// +// TESTW32.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/contrib/win32/resource.h b/contrib/win32/resource.h new file mode 100644 index 0000000..1c284d7 --- /dev/null +++ b/contrib/win32/resource.h @@ -0,0 +1,24 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by testw32.rc +// +#define IDD_TESTW32_DIALOG 102 +#define IDR_MAINFRAME 128 +#define IDC_FONT_NAME 1000 +#define IDC_BITMAP 1001 +#define IDC_LIST_BOX 1002 +#define IDC_SELECT_ACTION 1003 +#define IDC_ACTION 1004 +#define IDC_TEST_PROGRAM 1005 +#define IDC_OPTIONS 1007 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 130 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1008 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/contrib/win32/stdafx.cpp b/contrib/win32/stdafx.cpp new file mode 100644 index 0000000..06d180b --- /dev/null +++ b/contrib/win32/stdafx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// testw32.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/contrib/win32/stdafx.h b/contrib/win32/stdafx.h new file mode 100644 index 0000000..80d2b6f --- /dev/null +++ b/contrib/win32/stdafx.h @@ -0,0 +1,25 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__70F52CAD_06A4_11D2_9AC4_0060978849F3__INCLUDED_) +#define AFX_STDAFX_H__70F52CAD_06A4_11D2_9AC4_0060978849F3__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__70F52CAD_06A4_11D2_9AC4_0060978849F3__INCLUDED_) diff --git a/contrib/win32/testw32.cpp b/contrib/win32/testw32.cpp new file mode 100644 index 0000000..4b1ddde --- /dev/null +++ b/contrib/win32/testw32.cpp @@ -0,0 +1,79 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +// testw32.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "testw32.h" +#include "testw32dlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTestw32App + +BEGIN_MESSAGE_MAP(CTestw32App, CWinApp) + //{{AFX_MSG_MAP(CTestw32App) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG + ON_COMMAND(ID_HELP, CWinApp::OnHelp) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTestw32App construction + +CTestw32App::CTestw32App() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CTestw32App object + +CTestw32App theApp; + +///////////////////////////////////////////////////////////////////////////// +// CTestw32App initialization + +BOOL CTestw32App::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + CTestw32Dlg dlg; + m_pMainWnd = &dlg; + int nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: Place code here to handle when the dialog is + // dismissed with OK + } + else if (nResponse == IDCANCEL) + { + // TODO: Place code here to handle when the dialog is + // dismissed with Cancel + } + + // Since the dialog has been closed, return FALSE so that we exit the + // application, rather than start the application's message pump. + return FALSE; +} + +BOOL CTestw32App::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) +{ + // TODO: Add your specialized code here and/or call the base class + + return CWinApp::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); +} diff --git a/contrib/win32/testw32.dsp b/contrib/win32/testw32.dsp new file mode 100644 index 0000000..b1cafb6 --- /dev/null +++ b/contrib/win32/testw32.dsp @@ -0,0 +1,190 @@ +# Microsoft Developer Studio Project File - Name="testw32" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=testw32 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "testw32.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "testw32.mak" CFG="testw32 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "testw32 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "testw32 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "testw32 - Win32 Release" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 +# ADD LINK32 /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /G5 /MDd /W3 /Gm /Zi /Od /I "../../../LIB" /I "../" /I "../../../lib/arch/win32" /I "../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "WIN32_GR_TEST" /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 freetype.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\lib\arch\win32\release" /libpath:"..\..\..\lib\arch\win32\debug" /FORCE:MULTIPLE /FORCE:UNRESOLVED +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "testw32 - Win32 Release" +# Name "testw32 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\display.c +# End Source File +# Begin Source File + +SOURCE=.\driver32.c +# End Source File +# Begin Source File + +SOURCE=..\..\gmain.c +# End Source File +# Begin Source File + +SOURCE=.\hack_common.c +# End Source File +# Begin Source File + +SOURCE=.\hack_ftdump.c +# End Source File +# Begin Source File + +SOURCE=.\hack_ftlint.c +# End Source File +# Begin Source File + +SOURCE=.\hack_ftstring.c +# End Source File +# Begin Source File + +SOURCE=.\hack_fttimer.c +# End Source File +# Begin Source File + +SOURCE=.\hack_ftview.c +# End Source File +# Begin Source File + +SOURCE=.\stdafx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\testw32.cpp +# End Source File +# Begin Source File + +SOURCE=.\testw32.rc + +!IF "$(CFG)" == "testw32 - Win32 Release" + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\testw32dlg.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\Resource.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\testw32.h +# End Source File +# Begin Source File + +SOURCE=.\testw32Dlg.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\testw32.ico +# End Source File +# Begin Source File + +SOURCE=.\res\testw32.rc2 +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/contrib/win32/testw32.dsw b/contrib/win32/testw32.dsw new file mode 100644 index 0000000..d2774c4 --- /dev/null +++ b/contrib/win32/testw32.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "testw32"=.\testw32.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/win32/testw32.h b/contrib/win32/testw32.h new file mode 100644 index 0000000..727b11f --- /dev/null +++ b/contrib/win32/testw32.h @@ -0,0 +1,50 @@ +// testw32.h : main header file for the TESTW32 application +// + +#if !defined(AFX_TESTW32_H__70F52CA9_06A4_11D2_9AC4_0060978849F3__INCLUDED_) +#define AFX_TESTW32_H__70F52CA9_06A4_11D2_9AC4_0060978849F3__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CTestw32App: +// See testw32.cpp for the implementation of this class +// + +class CTestw32App : public CWinApp +{ +public: + CTestw32App(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTestw32App) + public: + virtual BOOL InitInstance(); + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CTestw32App) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TESTW32_H__70F52CA9_06A4_11D2_9AC4_0060978849F3__INCLUDED_) diff --git a/contrib/win32/testw32.mak b/contrib/win32/testw32.mak new file mode 100644 index 0000000..636caa2 --- /dev/null +++ b/contrib/win32/testw32.mak @@ -0,0 +1,533 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +!IF "$(CFG)" == "" +CFG=testw32 - Win32 Debug +!MESSAGE No configuration specified. Defaulting to testw32 - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "testw32 - Win32 Release" && "$(CFG)" !=\ + "testw32 - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "testw32.mak" CFG="testw32 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "testw32 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "testw32 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "testw32 - Win32 Debug" +MTL=mktyplib.exe +RSC=rc.exe +CPP=cl.exe + +!IF "$(CFG)" == "testw32 - Win32 Release" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\testw32.exe" "$(OUTDIR)\testw32.pch" + +CLEAN : + -@erase ".\Release\testw32.pch" + -@erase ".\Release\testw32.exe" + -@erase ".\Release\hack_ftview.obj" + -@erase ".\Release\testw32.obj" + -@erase ".\Release\hack_fttimer.obj" + -@erase ".\Release\hack_common.obj" + -@erase ".\Release\driver32.obj" + -@erase ".\Release\stdafx.obj" + -@erase ".\Release\hack_ftlint.obj" + -@erase ".\Release\testw32dlg.obj" + -@erase ".\Release\gmain.obj" + -@erase ".\Release\hack_ftdump.obj" + -@erase ".\Release\hack_ftstring.obj" + -@erase ".\Release\display.obj" + -@erase ".\Release\testw32.res" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\lib" /I "..\..\" /I "..\..\..\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /YX"stdafx.h" /c +CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "..\..\..\lib" /I "..\..\" /I "..\..\..\"\ + /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS"\ + /Fp"$(INTDIR)/testw32.pch" /YX"stdafx.h" /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "NDEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x410 /fo"$(INTDIR)/testw32.res" /d "NDEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/testw32.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 +# ADD LINK32 freetype.lib /nologo /subsystem:windows /machine:I386 +LINK32_FLAGS=freetype.lib /nologo /subsystem:windows /incremental:no\ + /pdb:"$(OUTDIR)/testw32.pdb" /machine:I386 /out:"$(OUTDIR)/testw32.exe" +LINK32_OBJS= \ + "$(INTDIR)/hack_ftview.obj" \ + "$(INTDIR)/testw32.obj" \ + "$(INTDIR)/hack_fttimer.obj" \ + "$(INTDIR)/hack_common.obj" \ + "$(INTDIR)/driver32.obj" \ + "$(INTDIR)/stdafx.obj" \ + "$(INTDIR)/hack_ftlint.obj" \ + "$(INTDIR)/testw32dlg.obj" \ + "$(INTDIR)/gmain.obj" \ + "$(INTDIR)/hack_ftdump.obj" \ + "$(INTDIR)/hack_ftstring.obj" \ + "$(INTDIR)/display.obj" \ + "$(INTDIR)/testw32.res" + +"$(OUTDIR)\testw32.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +# PROP BASE Use_MFC 6 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 6 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\testw32.exe" "$(OUTDIR)\testw32.pch" + +CLEAN : + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + -@erase ".\Debug\testw32.pch" + -@erase ".\Debug\testw32.exe" + -@erase ".\Debug\stdafx.obj" + -@erase ".\Debug\display.obj" + -@erase ".\Debug\hack_ftlint.obj" + -@erase ".\Debug\hack_fttimer.obj" + -@erase ".\Debug\hack_ftdump.obj" + -@erase ".\Debug\driver32.obj" + -@erase ".\Debug\hack_ftview.obj" + -@erase ".\Debug\testw32dlg.obj" + -@erase ".\Debug\testw32.obj" + -@erase ".\Debug\gmain.obj" + -@erase ".\Debug\hack_ftstring.obj" + -@erase ".\Debug\hack_common.obj" + -@erase ".\Debug\testw32.res" + -@erase ".\Debug\testw32.ilk" + -@erase ".\Debug\testw32.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "c:\winlib\freetype.orig\test" /I "..\..\..\lib" /I "..\..\..\lib\arch\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /YX"stdafx.h" /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "c:\winlib\freetype.orig\test" /I\ + "..\..\..\lib" /I "..\..\..\lib\arch\win32" /D "WIN32" /D "_DEBUG" /D\ + "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/testw32.pch" /YX"stdafx.h"\ + /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +# ADD RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL" +RSC_PROJ=/l 0x410 /fo"$(INTDIR)/testw32.res" /d "_DEBUG" /d "_AFXDLL" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/testw32.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 ..\..\..\lib\arch\win32\debug\freetype.lib /nologo /subsystem:windows /debug /machine:I386 +LINK32_FLAGS=..\..\..\lib\arch\win32\debug\freetype.lib /nologo\ + /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)/testw32.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/testw32.exe" +LINK32_OBJS= \ + "$(INTDIR)/stdafx.obj" \ + "$(INTDIR)/display.obj" \ + "$(INTDIR)/hack_ftlint.obj" \ + "$(INTDIR)/hack_fttimer.obj" \ + "$(INTDIR)/hack_ftdump.obj" \ + "$(INTDIR)/driver32.obj" \ + "$(INTDIR)/hack_ftview.obj" \ + "$(INTDIR)/testw32dlg.obj" \ + "$(INTDIR)/testw32.obj" \ + "$(INTDIR)/gmain.obj" \ + "$(INTDIR)/hack_ftstring.obj" \ + "$(INTDIR)/hack_common.obj" \ + "$(INTDIR)/testw32.res" + +"$(OUTDIR)\testw32.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "testw32 - Win32 Release" +# Name "testw32 - Win32 Debug" + +!IF "$(CFG)" == "testw32 - Win32 Release" + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\ReadMe.txt + +!IF "$(CFG)" == "testw32 - Win32 Release" + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\testw32.cpp +DEP_CPP_TESTW=\ + ".\stdafx.h"\ + ".\testw32.h"\ + ".\testw32dlg.h"\ + + +"$(INTDIR)\testw32.obj" : $(SOURCE) $(DEP_CPP_TESTW) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\testw32dlg.cpp +DEP_CPP_TESTW3=\ + ".\stdafx.h"\ + ".\testw32.h"\ + ".\testw32dlg.h"\ + ".\..\..\gdriver.h"\ + ".\..\..\gevents.h"\ + + +"$(INTDIR)\testw32dlg.obj" : $(SOURCE) $(DEP_CPP_TESTW3) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\stdafx.cpp +DEP_CPP_STDAF=\ + ".\stdafx.h"\ + + +!IF "$(CFG)" == "testw32 - Win32 Release" + +# ADD CPP /Yc"stdafx.h" + +BuildCmds= \ + $(CPP) /nologo /MD /W3 /GX /O2 /I "..\..\..\lib" /I "..\..\" /I "..\..\..\" /D\ + "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS"\ + /Fp"$(INTDIR)/testw32.pch" /Yc"stdafx.h" /Fo"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\stdafx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\testw32.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +# ADD CPP /Yc"stdafx.h" + +BuildCmds= \ + $(CPP) /nologo /MDd /W3 /Gm /GX /Zi /Od /I "c:\winlib\freetype.orig\test" /I\ + "..\..\..\lib" /I "..\..\..\lib\arch\win32" /D "WIN32" /D "_DEBUG" /D\ + "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/testw32.pch" /Yc"stdafx.h"\ + /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \ + + +"$(INTDIR)\stdafx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +"$(INTDIR)\testw32.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)" + $(BuildCmds) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\testw32.rc +DEP_RSC_TESTW32=\ + ".\res\testw32.ico"\ + ".\res\testw32.rc2"\ + + +"$(INTDIR)\testw32.res" : $(SOURCE) $(DEP_RSC_TESTW32) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_ftview.c +DEP_CPP_HACK_=\ + ".\..\..\ftview.c"\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\common.h"\ + ".\..\..\gmain.h"\ + ".\..\..\gevents.h"\ + ".\..\..\gdriver.h"\ + ".\..\..\display.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + +NODEP_CPP_HACK_=\ + ".\..\..\std.h"\ + ".\..\..\graflink.h"\ + ".\..\..\armsup.c"\ + + +"$(INTDIR)\hack_ftview.obj" : $(SOURCE) $(DEP_CPP_HACK_) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_common.c +DEP_CPP_HACK_C=\ + ".\..\..\common.c"\ + ".\..\..\common.h"\ + + +"$(INTDIR)\hack_common.obj" : $(SOURCE) $(DEP_CPP_HACK_C) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_ftdump.c + +!IF "$(CFG)" == "testw32 - Win32 Release" + +DEP_CPP_HACK_F=\ + ".\..\..\ftdump.c"\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\common.h"\ + ".\..\..\..\lib\ttobjs.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + ".\..\..\..\lib\ttconfig.h"\ + ".\..\..\..\lib\ttengine.h"\ + ".\..\..\..\lib\ttmutex.h"\ + ".\..\..\..\lib\ttcache.h"\ + ".\..\..\..\lib\tttables.h"\ + ".\..\..\..\lib\ttcmap.h"\ + ".\..\..\..\lib\tttypes.h"\ + +NODEP_CPP_HACK_F=\ + ".\..\..\std.h"\ + ".\..\..\graflink.h"\ + ".\..\..\armsup.c"\ + ".\..\..\ftxerr18.h"\ + ".\..\..\..\lib\ft_conf.h"\ + + +"$(INTDIR)\hack_ftdump.obj" : $(SOURCE) $(DEP_CPP_HACK_F) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "testw32 - Win32 Debug" + +DEP_CPP_HACK_F=\ + ".\..\..\ftdump.c"\ + + +"$(INTDIR)\hack_ftdump.obj" : $(SOURCE) $(DEP_CPP_HACK_F) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_ftlint.c +DEP_CPP_HACK_FT=\ + ".\..\..\ftlint.c"\ + ".\..\..\..\lib\freetype.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + +NODEP_CPP_HACK_FT=\ + ".\..\..\std.h"\ + ".\..\..\graflink.h"\ + ".\..\..\armsup.c"\ + ".\..\..\ftxerr18.h"\ + + +"$(INTDIR)\hack_ftlint.obj" : $(SOURCE) $(DEP_CPP_HACK_FT) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_ftstring.c +DEP_CPP_HACK_FTS=\ + ".\..\..\ftstring.c"\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\common.h"\ + ".\..\..\gmain.h"\ + ".\..\..\gevents.h"\ + ".\..\..\gdriver.h"\ + ".\..\..\display.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + +NODEP_CPP_HACK_FTS=\ + ".\..\..\std.h"\ + ".\..\..\graflink.h"\ + ".\..\..\armsup.c"\ + + +"$(INTDIR)\hack_ftstring.obj" : $(SOURCE) $(DEP_CPP_HACK_FTS) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\hack_fttimer.c +DEP_CPP_HACK_FTT=\ + ".\..\..\fttimer.c"\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\common.h"\ + ".\..\..\gmain.h"\ + ".\..\..\gdriver.h"\ + ".\..\..\gevents.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + + +"$(INTDIR)\hack_fttimer.obj" : $(SOURCE) $(DEP_CPP_HACK_FTT) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\driver32.c +DEP_CPP_DRIVE=\ + ".\..\..\gdriver.h"\ + ".\..\..\..\lib\freetype.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + + +"$(INTDIR)\driver32.obj" : $(SOURCE) $(DEP_CPP_DRIVE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\winlib\freetype.orig\test\gmain.c +DEP_CPP_GMAIN=\ + ".\..\..\gmain.h"\ + ".\..\..\gdriver.h"\ + + +"$(INTDIR)\gmain.obj" : $(SOURCE) $(DEP_CPP_GMAIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=\winlib\freetype.orig\test\display.c +DEP_CPP_DISPL=\ + ".\..\..\..\lib\freetype.h"\ + ".\..\..\gmain.h"\ + ".\..\..\display.h"\ + "..\..\..\lib\fterrid.h"\ + "..\..\..\lib\ftnameid.h"\ + + +"$(INTDIR)\display.obj" : $(SOURCE) $(DEP_CPP_DISPL) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/contrib/win32/testw32.mdp b/contrib/win32/testw32.mdp new file mode 100644 index 0000000000000000000000000000000000000000..51d051996fde824bf8f108e8531e3f2381f334cc GIT binary patch literal 43008 zcmeHQO>7&-6@IcTTa^Fg_%CUGx>X&=sT)$394A)NRuU=MaztB^l*l#MCadL0+JxLC zmMdE-id1Qmq6PZn{$Jd}#~ga-!H2>*REOT;gIgqkQ3Qb+7|jm?G>4$QByiu`omo=! za?N$+#I@c)%XvHV-pqX8%noN~-%>}%4tF-gS{Mgd0~}Tz16Mh$Y6g~8HF^f$2M@s* zd>QTp;$pM+$*im%1}a~8AFUqHj5J_iEv$zPPpA8z7(39J%s$<}`>)@w3<;K)0cL<1 zUrP}@ z^w8^k%X4c^#(erkm})tyJ*NgxT0PFzVICc%LkBhC>i6)YDztafqq*f_Dc?1cyXe3h z$N|}}#iKB$CQRe7S{O(`vwsy4 zU>YsF|F>GYo^dh*%m6dM3@`)C05iZ0Fayj0Gr$b2Dh7D}Z*}kgZGm>!3U|OZ*bX~j zC+u2Pqkpx7P2lctGm=1Ce>+@Jc29SAX%A@=riF1vOwLXdL$7~}K4tLsl)cSzGW5nv z3pDj6(zfL~cHyBkrIJ!BrfyQH{f^L|S2<|Cup^_px;tMITGlM<1#{Xe3d~hPIgY-(Q1nB|gPHmmc0 zjQKnI97mtm`t4aOU-pU+d68Gm_z7z494y$ni_BWKQ^eLBF9}Dt0+pYl%66$@o-*@7 zo1E893ddGu{H&rdWQjT5aJ5lUo-G8#ok4|NehEXev0fe3P5n9QZ1#1IpAybg!9K0Z z{{?1k^|QuY-FRM0&j{mrmHSJ~-QwpyW#yM!{tEMU4q2|477p?g*7#qeO1o02t@$@( zKjNSv_LInm_0y-Qve|D|t#yABEZ&tF9!4|l73`z$cq2v|)UmjLUZY%G+Lbj8$1dAb zu9n`n@7jK*F-p%<)=lWHF|%I@T}tRy!U2E_sCNOf!$*h7iUTvi3@`)C05iZ0Fayj0 zGr$Zm1Iz$3zzi@0wLxJI27PB$vAqAw`@g*Z zOIHK$|Ef8GV`hLEUEmQ*%i=8?>bo$@z+GXbAc405UctsNHKEWgkivw9dH$`#ZJNlqyDg&n6vF#uD>Y zW+ba-qVat}*~(NkbFyr7Q1QR7W~z#pT%J5~EBqplT2NSdcCtKQc15uVo0+#ym$j5> z8IB;gTD{OSFEF8$pX{lnCQp6g6|AL-x-nx~qGzc4(Susbo^@-r#hmESy3#$liLkCF z9JxN~M$GQ+%8d#=pA|`W&h2j0M6qa;N=;1%V_Ibj(@D>;;TDd$`92&EWON&ibEC0w z-Y`q5QyinI>ETBEWCq=bpP6z`nc{RZww+-Yi?$WtZpzKi7E3o`S1>J?>>i1U5537v z3x{2d(JGm7&7yF~u;G5lpnJ4%y1U3|cVs&c7j@I4Z%?Ee`LP%Dc`6Tf)qVkt4h#?U zjSYBT0T+U4CYzDp066;}?~0t)abCgigba~+Sxp) zHJHsGTQ-|3<6zLM`8+VJna?Xzu-&1IX(q&1DUxbN|8DS|7-!D5@GIAwvTKXQM8p;{ zTh}Vy*7NnPJt%7@VbwL>pltY(4@MzgqCEA=b%mTjZ=0zXfB38J!}q3LatH*kWyyg= zEBkP(4Qlo&>iFtTE2Kvp`#E8_;o9-bra|=|DdDK8=~2il z&9AxwL+ag<%q?H&MCb&Inh2d>0TZbs7b_t;TZ8rlS4W5zQd+YJ2~k2ys}>v~3LO!5 z0crsfVzxWNtg;{pF>KBYT&8b_bVif}zJF#J^YnTlu5^SW`>RzBf|(}RQmsdWPO2nS zheqgZlsYuvBGeMod2dA)ts_q19auR^XM<{zY2cfF^%@>%IYw7~t=3@4UALgNU@;Pb ztyPZJ2$l8I-YPRfBaxR2%qX2fS2&KDk0PjT(6#iUh*nZ9HX_N9_Xl;!X?0zD^0~ac(0NL3?fa|9`mI^>X>l05iZ0Faw`2 z14&3hC+vqV=!OIEFdT$O;88dPJ@6Pj4qt<>!#AM!^KBy6e$yD(hQGAfgunf%HJ?~> z2e`}XNvH4!^573|FTg$jDZ-yHrqKKD3-A{ypZnVaT$1t<%5O<|1mpLleCh8C@bTN8 zX`PRTpM_T*@Lj#yj?Ws!oSU(YaZyAc7FR&vx=K$b)&IBt1ceXr*o|rU6OQl+X70sf zYbe-@Z}?y@V@!d-UP0M&Ttv@}k5E<~EuU1$t#4ww^lsVy=I_w*RnNW>%TstD(jTX? zZyq1vNvwkY16LP5o+X6sp$Pjc-h-ZZCOQ4&`bN`7a-O?o@GRCb@BthK`qx}^s3%mI z4j;csIbL>EOlcH4BN0}42dYPP@u42UYUn2yH3@Y~DAWg2L8C<(u!Aly0QJ#cj45== znB>P%?xh3eBNz|kL9RyQmnnBWePB?re+IC>QK;k69cU&#)`M8tAv`uqteZozuH03s zFsfK#JLBe6MdKo!^HF!jLgY0B7D=@C-^QpOtbif_hcTBPgGj^0TP3 zDCKqpeDNJJRX|nj6^9@3rYz-^79Vf*ltp;g)Wv)5w=cn&D+^u&7g0VdO zc^S^D^x>CbQOZjwU%Ubs6iyXW8ij^mVN#2IbZ3o^wtD?bXq!UOhF!3JD=QahV;Ar` zX{KUTO2fmsYPo+yfUCQgZd>tIQ? zW#r0^k?Sj!igtdsKz_;fJ8}&c(2PgzhJ(VjL<$}*RTIa|05iZ0Fayj0Gr$Zm1Iz$3 zzzi@0%)n>Q0Q>)a_MG2JHTFXqGB5yxa2Srj5FCXk@Y#A6j=^ylfhS?~R%$G_WrZ2o G3jYPv{gnLx literal 0 HcmV?d00001 diff --git a/contrib/win32/testw32.rc b/contrib/win32/testw32.rc new file mode 100644 index 0000000..5d6cd03 --- /dev/null +++ b/contrib/win32/testw32.rc @@ -0,0 +1,202 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Italian (Italy) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA) +#ifdef _WIN32 +LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 16, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif\r\n" + "#include ""res\\testw32.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""l.ita\\afxres.rc"" // Standard components\r\n" + "#endif\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON DISCARDABLE "res\\testw32.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_TESTW32_DIALOG DIALOGEX 0, 0, 331, 274 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_APPWINDOW +CAPTION "testw32" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "Run",IDOK,105,100,28,14 + PUSHBUTTON "Exit",IDCANCEL,105,116,28,14 + CONTROL "",IDC_BITMAP,"Static",SS_BLACKRECT,146,47,178,120 + LISTBOX IDC_LIST_BOX,7,171,317,97,LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_HSCROLL | WS_TABSTOP + PUSHBUTTON "<-Select Action (q to quit test pgm)",IDC_SELECT_ACTION, + 34,56,110,15 + EDITTEXT IDC_ACTION,23,56,9,12,ES_AUTOHSCROLL + COMBOBOX IDC_TEST_PROGRAM,13,12,90,64,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Test Program",IDC_STATIC,13,1,60,8 + EDITTEXT IDC_OPTIONS,111,12,204,12,ES_AUTOHSCROLL + LTEXT "Options/Arguments",IDC_STATIC,109,2,73,8 + LTEXT "Show Window",IDC_STATIC,146,37,70,8 +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041004B0" + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "testw32 Applicazione MFC\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "testw32\0" + VALUE "LegalCopyright", "Copyright (C) 1998\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "testw32.EXE\0" + VALUE "ProductName", "testw32 Applicazione\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x410, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_TESTW32_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 324 + BOTTOMMARGIN, 268 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_TESTW32_DIALOG DLGINIT +BEGIN + IDC_TEST_PROGRAM, 0x403, 7, 0 +0x5446, 0x4956, 0x5745, "\000" + IDC_TEST_PROGRAM, 0x403, 7, 0 +0x5446, 0x5544, 0x504d, "\000" + IDC_TEST_PROGRAM, 0x403, 9, 0 +0x5446, 0x5453, 0x4952, 0x474e, "\000" + IDC_TEST_PROGRAM, 0x403, 7, 0 +0x5446, 0x494c, 0x544e, "\000" + 0 +END + +#endif // Italian (Italy) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA) +#ifdef _WIN32 +LANGUAGE 16, 1 +#pragma code_page(1252) +#endif +#include "res\testw32.rc2" // non-Microsoft Visual C++ edited resources +#include "l.ita\afxres.rc" // Standard components +#endif +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/contrib/win32/testw32dlg.cpp b/contrib/win32/testw32dlg.cpp new file mode 100644 index 0000000..c3f4660 --- /dev/null +++ b/contrib/win32/testw32dlg.cpp @@ -0,0 +1,358 @@ +/*********************************************************/ +/* Test program driver for freetype on Win32 Platform */ +/* CopyRight(left) G. Ramat 1998 (gcramat@radiostudio.it)*/ +/* */ +/*********************************************************/ + +// testw32Dlg.cpp : implementation file +// + +#include "stdafx.h" +#include "testw32.h" +#include "testw32dlg.h" +#include "gdriver.h" +#include "gevents.h" +#include +#include +#include +CWnd *button_OK,*button_Cancel; +DWORD thrd_spool; // output spooler +HANDLE spool_thread; + +//Sync data: +extern "C" { + HANDLE evgetevent,evdriverdisplaybitmap,this_cwnd,main_thread,listbox,bitmap; + TEvent evevent; + char *ev_buffer; + int ev_lines,ev_columns; + char *save_buffer; + int save_lines,save_cols,exit_code; + int ftview(int,char**); + int ftdump(int,char**); + int ftlint(int,char**); + int ftstring(int,char**); + int ftstrpnm(int,char**); + int ftzoom(int,char**); + int call_test_program(int (*)(int,char**),int,char **); + +} +//pipe handling variables +int pipe_std[2]={2*0},pipe_err[2]={2*0},error; +int old_std,old_err; +//end of pipe handling variables + + +#define TEST_PROG_N 4 +//Sync data end +char ProgramName[16]; +char fontname[16]; +char fullfont[MAX_PATH]; +char *argv[255]; +int argc; +DWORD WINAPI ThreadHead(LPVOID ); +DWORD WINAPI ThreadSpool(LPVOID ); +void readpipe(int); + + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif +extern main(int,char **); +extern int X_Link; + +///////////////////////////////////////////////////////////////////////////// +// CTestw32Dlg dialog + +CTestw32Dlg::CTestw32Dlg(CWnd* pParent /*=NULL*/) + : CDialog(CTestw32Dlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CTestw32Dlg) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT + // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CTestw32Dlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CTestw32Dlg) + // NOTE: the ClassWizard will add DDX and DDV calls here + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CTestw32Dlg, CDialog) + //{{AFX_MSG_MAP(CTestw32Dlg) + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_BN_CLICKED(IDC_SELECT_ACTION, OnSelectAction) + ON_WM_DESTROY() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTestw32Dlg message handlers + +BOOL CTestw32Dlg::OnInitDialog() +{ int error; + FILE *retf; + CDialog::OnInitDialog(); + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + // TODO: Add extra initialization here + //save CWnd objects for utility fns; + evgetevent=CreateEvent(NULL,FALSE,FALSE,"Get_Event"); + evdriverdisplaybitmap=CreateEvent(NULL,FALSE,FALSE,"Driver_Display_Bitmap"); + listbox=(GetDlgItem(IDC_LIST_BOX))->m_hWnd; + bitmap=(GetDlgItem(IDC_BITMAP))->m_hWnd; + button_OK=GetDlgItem(IDOK); + button_Cancel=GetDlgItem(IDCANCEL); + error=_pipe(pipe_std,1024,_O_TEXT); +// error=_pipe(pipe_err,1024,_O_TEXT); + // enable piping + if(-1==_fileno(stdout)) + {retf=freopen("throwaway_stdout.tmp","wt",stdout); + } + if(-1==_fileno(stderr)) + {retf=freopen("throwaway_stderr.tmp","wt",stderr); + } + old_std=dup(_fileno(stdout)); + old_err=dup(_fileno(stderr)); + error=dup2(pipe_std[1],_fileno(stdout)); + error=dup2(pipe_std[1],_fileno(stderr)); //error=dup2(pipe_err[1],_fileno(stderr)); + save_buffer=NULL; +// error=write(pipe_std[1],"Pipe_test:Write\n",16); +// error=fprintf(stdout,"Pipe_test:fprintf"); +// error=fflush(stdout); +// activate spooler + spool_thread=CreateThread(NULL,0,ThreadSpool,NULL,0,&thrd_spool); + + + return TRUE; // return TRUE unless you set the focus to a control +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CTestw32Dlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// The system calls this to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CTestw32Dlg::OnQueryDragIcon() +{ + return (HCURSOR) m_hIcon; +} + +void CTestw32Dlg::OnOK() +{ + DWORD thrd_id; + char Options[256]; + char *p,*pb,*pe; + int i; + // TODO: Add extra validation here + GetDlgItemText(IDC_TEST_PROGRAM,ProgramName,sizeof(ProgramName)-1); + GetDlgItemText(IDC_OPTIONS,Options,sizeof(Options)-1); + argv[0]=ProgramName; + p=Options; + i=1; + while (*p!=0) + { + while (*p==' ') p++; + pb=p; + while (*p>' ') p++; + pe=p; + if (pe>pb) + { + argv[i]=new char[1+pe-pb]; + strncpy(argv[i],pb,pe-pb); + argv[i][pe-pb]=0; + i++; + } + } + argv[0]=ProgramName; + argc=i; + main_thread=CreateThread(NULL,0,ThreadHead,NULL,0,&thrd_id); + +// CDialog::OnOK(); +} + +DWORD WINAPI ThreadHead(LPVOID Parm) +{ int i,rc; + +struct { + char pname[16]; + int (*program)(int,char**); +} tab[TEST_PROG_N]= +{ + {"FTVIEW",&ftview}, + {"FTDUMP",&ftdump}, + {"FTLINT",&ftlint}, + {"FTSTRING",&ftstring} +// {"FTSTRPNM",&ftstrpnm}, +// {"FTZOOM",&ftzoom} +}; +//disable Ok button + rc=button_OK->EnableWindow(FALSE); + rc=button_Cancel->EnableWindow(FALSE); + + for (i=0;(i< TEST_PROG_N) &&strcmp(tab[i].pname,ProgramName);i++); + if (i>= TEST_PROG_N) + { + MessageBox(NULL,"Please select a valid Test Program Name","FreeType Test ",MB_ICONQUESTION); + } + else + call_test_program(tab[i].program,argc,(char **)&argv); + //enable buttons again + rc=button_OK->EnableWindow(TRUE); + rc=button_Cancel->EnableWindow(TRUE); + rc=fflush(stdout); + rc=fflush(stderr); + ExitThread(1); + return 1; +} + + + +void translate_command(char nChar) +{ int rc,i; + // TODO: Add your message handler code here and/or call default + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[ NUM_Translators] = + { + { 'q', event_Quit, 0 }, + { (char)27, event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( nChar == trans[i].key ) + { + evevent.what = trans[i].event_class; + evevent.info = trans[i].event_info; + break; + } + } + if (i>= NUM_Translators) + { + evevent.what=event_Keyboard; + evevent.what=nChar; + } + rc=SetEvent(evgetevent); +} + +void CTestw32Dlg::OnSelectAction() +{ + char c[2]; + GetDlgItemText(IDC_ACTION,c,2); + translate_command(c[0]); +} + + +DWORD WINAPI ThreadSpool(LPVOID Parm) +{ + while(1) + { + if (pipe_std[0]) readpipe(pipe_std[0]); // will never get out of there !!!! +// if (pipe_err[0]) readpipe(pipe_err[0]); + Sleep(1000); + } + return 1; +} + +void readpipe(int h) + { int i,j,rc; + + char buffer[1024],line[1024]; + rc=1; + while(rc) + { + rc=read(h,buffer,sizeof(buffer)); + if (rc) + { j=0; + for(i=0;i= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +///////////////////////////////////////////////////////////////////////////// +// CTestw32Dlg dialog + +class CTestw32Dlg : public CDialog +{ +// Construction +public: + CTestw32Dlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CTestw32Dlg) + enum { IDD = IDD_TESTW32_DIALOG }; + // NOTE: the ClassWizard will add data members here + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTestw32Dlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + HICON m_hIcon; + + // Generated message map functions + //{{AFX_MSG(CTestw32Dlg) + virtual BOOL OnInitDialog(); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + virtual void OnOK(); + afx_msg void OnSelectAction(); + afx_msg void OnDestroy(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TESTW32DLG_H__70F52CAB_06A4_11D2_9AC4_0060978849F3__INCLUDED_) diff --git a/docs/FAQ b/docs/FAQ new file mode 100644 index 0000000..c567ec3 --- /dev/null +++ b/docs/FAQ @@ -0,0 +1,799 @@ + FreeType User FAQ + +-------------------------------------------------------------------- + + + Table of contents + + +1. How do I compile the test programs? + +2. What are the test programs? + +3. How do I use them? + +4. How do I only compile the FreeType library? + +5. The library compiles fine on my system, unfortunately it seems + the test programs won't. What can I do? + +6. What is FreeType, and what is it not? + +7. Can FreeType be ported to other platforms? + +8. My TrueType font only works on a Mac/in Windows. Will I be able + to use it with FreeType? + +9. What are the most common character mappings? + +10. How do I render text with FreeType? + +11. How do I render rotated/slanted text with FreeType? + +12. How do I compute a glyph bitmap's dimensions? + +13. Why is text rendering so slow? Does FreeType cache glyphs? + +14. Do you always render the same glyphs as Windows or the Mac? + +15. The program `ftlint' reports errors with one of my fonts, though + it works perfectly under Windows. What does this mean? + +16. What does the `fttimer' test program benchmarks? + +17. Is it possible to perform styling (like oblique, italic, bold, + underline, etc.) with FreeType? + +18. When does glyph hinting takes place? Is it when the glyph is + loaded, or when it is converted to a bitmap/pixmap? + +19. Which is the best, caching outlines or bitmaps? + +20. Can I open OpenType and/or TrueType GX fonts with FreeType? + +21. How can I access additional TrueType tables that FreeType + doesn't support? + +22. When will I be able to use FreeType to display TrueType fonts in + X11, Wine, or OS/2, or even other systems? + +23. What does the `free' in FreeType really means? + +24. Does FreeType support threads? Is it re-entrant? + +25. Does FreeType support `foreign languages'? + +26. I'm using fractional char sizes, but the glyphs stay at the same + integer size. Why? + +27. Hinting doesn't work at very small sizes. Why? + +-------------------------------------------------------------------- + +1. How do I compile the test programs? + + Detailed compilation steps are given in the `freetype/HOWTO.txt' + file, as well as system and compiler specific hints in the + `freetype/howto' directory. What follows is a _very_ simple + guide: + + For Unix: + + Do the following on the prompt while in the base directory of + the FreeType package: + + % ./configure + % make + % make install + + This will build and install the library (shared, if supported) + together with the test programs. Say `./configure --help' to + see the available configuring options. + + This should work with any ANSI C compiler. + + For other platforms: + + Go to the `test' directory. Look at one of the makefiles + located in the `arch/' directory, and use the + appropriate makefile from there. + + For example: + + make -f arch/msdos/makefile.gcc (DJGPP or emx) + wmake -f=arch\msdos\makefile.wat (Watcom DOS) + nmake -f arch\os2\makefile.icc (Visual Age OS/2) + make -f arch/amigaos/makefile.gcc (GCC Amiga) + + This will compile both the library and the test programs. + + +-------------------------------------------------------------------- + +2. What are the test programs? + + The test programs are simple sources that `show off' the FreeType + library. They are located in the `test' directory. They make use + of a small graphics sub-system which is able to display bitmaps + and pixmaps on a variety of platforms through the use of + system-specific `drivers'. + + The test programs are: + + ftdump: A simple TTF information dumper. Also prints the + memory used by each opened font file with FreeType. + Doesn't use the graphics sub-system. + + ftlint: A simple TrueType bytecode verifier. It simply hints + all glyphs of one or more font files at a given size + and reports errors. Doesn't use the graphics + sub-system. + + ftview: A simple font viewer. Displays all glyphs in a font + file in a window. + + ftstring: Renders a simple string to the screen. Demonstrates + how to produce text with FreeType. + + fttimer: A simple benchmark, used to profile the scan-line + conversion routines (and only them). Supports also + display. + + ftstrpnm: A version of `ftstring' which saves a bit/pixmap to a + PNM file rather than to the screen. No graphics + sub-system needed. + + ftzoom: A simple glyph viewer, useful to view, zoom and rotate + individual glyphs in a font file. + + fterror: This program demonstrates how to use the ftxerr18 + extension. Note that internationalized strings will + be available on some platforms only (e.g. Linux). + + ftmetric: A simple metric/glyph dumper. No graphics sub-system + needed. + + ftsbit: Displays data about embedded bitmaps in a TrueType + font. + + ftstrtto: Renders a string to screen, using TrueType Open + features. + + NOTE: The file `ftdebug.c' isn't part of the test suite. It is + used only by the developers team to debug the engine at a + higher level. It won't work with a standard library + compile. + + + The tiny graphics subsystem is defined in the following files: + + gmain.h/gmain.c: The subsystem's main body/interface. + + gevents.h: The definition of events defined for the + subsystem + + gdriver.h: The generic interface of all system-specific + drivers. + + System-specific drivers are in the `test/arch/' + directories, like: + + test/arch/msdos/gfs_dos.c Full-Screen DOS driver + test/arch/os2/gpm_os2.c PM (Windowed) OS/2 driver + test/arch/unix/gwin_x11.c X11 Windowed driver + + etc. + + +-------------------------------------------------------------------- + +3. How do I use them? + + Please read the file freetype/README for a full description. + + +-------------------------------------------------------------------- + +4. How do I only compile the FreeType library? + + For Unix: + + Do a `configure' run as described in section 1. Then change to + the lib subdirectory and say `make' and `make install'. + + For other platforms: + + Go to the `lib' directory. Look at one of the makefiles located + in the `arch/' directory, and use it from `lib'. + + For example: + + make -f arch/msdos/makefile.gcc (DJGPP or emx) + wmake -f=arch\msdos\makefile.wat (Watcom DOS) + nmake -f arch\os2\makefile.icc (Visual Age OS/2) + make -f arch/amigaos/makefile.gcc (GCC Amiga) + + The library is pure ANSI C and doesn't depend on any + system-specific package. You need not gcc to compile it. + + +-------------------------------------------------------------------- + +5. The library compiles fine on my system, unfortunately it seems + the test programs won't. What can I do? + + As said before, the test programs rely on a small graphics + sub-system to display the bitmaps and pixmaps produced by the + library. The following systems are currently supported: + + DOS Full-Screen + Amiga Full-Screen Note that the windowed graphics + Amiga Windowed driver are very 'basic', they do + OS/2 Full-Screen not provide menus, dialog boxes, + OS/2 Windowed etc. Rather, they provide one + X11 Windowed windowed bitmap/pixmap and translate + Win32 Windowed events to the ones defined in + `test/gevents'. + + If you want to add support to your system, you should write a new + graphics driver. To do that, read the file `test/gdriver.h' which + contains the driver generic interface, then browse the drivers + that are already provided. + + The graphics drivers are located in the `test/arch/' + directories. They're not part of the library proper. + + IMPORTANT NOTE: + + You can also directly link the library to your own application + and render glyphs directly into your own bitmaps with very few + efforts. + + +-------------------------------------------------------------------- + +6. What is FreeType, and what is it not? + + FreeType is a rather low-level font engine. It has been designed + primarily to be the basis of several font servers, for very + different systems which all have their own metrics and graphics + models. This means that it focuses on the following points: + + - Opening and loading font files in memory. + + - Giving access to most important font properties and TrueType + tables. + + - Providing a simple way to translate system-specific character + codes into glyph indexes, according to the TrueType `cmap' + specification. + + - Loading and rendering _individual_ glyphs as nicely as possible + (either in outlines, bitmaps, or pixmaps), and performing + excellent hinting. + + It isn't a high-level text rendering library, and many tasks will + have to be performed by higher level layers like: + + - glyph caching (outlines and/or maps) + - text rendering + - justification, kerning + - font mapping + - rotated/slanted text + + However, its API provides many functions that ease these + operations considerably: + + - Glyph outlines can be copied and transformed easily with the API + functions, then rendered to bitmaps or pixmaps with FreeType's + scan-line converter, which is very fast. + + - The glyph loader places the outlines in order to ease the + process of text rendering. See the documentation file named + `glyphs.htm' (resp. `glyphs.txt') or `ftstring's source for more + details. + + - The engine gives you access to several TrueType tables that can + be processed by your application to provide more powerful + rendering (e.g. kerning). + + - It is possible, and rather simple, to write separately + compilable extensions to the engine to access other TrueType + tables that are not supported by the engine in this release. + This can be handy if one wants to access data in TrueType GX or + OpenType fonts (as these formats comply to the TrueType `sfnt' + file storage format, they can be opened by the FreeType engine + as a normal TrueType file). + + +-------------------------------------------------------------------- + +7. Can FreeType be ported to other platforms? + + FreeType is written in pure ANSI C and should compile well on all + 16, 32, and 64 bits processors. Note, however, that the 16-bit + port requires a large memory model, as some tables found in + TrueType programs could exceed 64kByte (this is really true for + CJK and Unicode fonts. Nearly all others should work fine with + it). + + It doesn't support some very exotic platforms though, like a + 32-bit only processor (where the only word size is 32-bit, even + for chars and shorts). However, nothing prevents you to test it + by yourself... + + The memory management and file access routines have been gathered + in two components, namely `ttmemory' and `ttfile', which can be + specialized for a specific system. Their standard version, found + in the `lib' directory, uses simply the ANSI libc. However, + examples are given of alternative file components for OS/2 and + Unix in: + + lib/arch/os2/ttfile.c + (accessing the low-level OS/2 file API directly) + + lib/arch/unix/ttmmap.c + (using memory-mapped files for improved access) + + You would certainly need to rewrite these components if you intend + to use FreeType in an embedded system. + + +-------------------------------------------------------------------- + +8. My TrueType font only works on a Mac/in Windows. Will I be able + to use it with FreeType? + + Short Answer: YES, but be cautious! + + If you have read section 9 or 25, you know that a font file might + have different charMaps entries, used to translate character codes + to glyph indexes. The problem of most `system-specific' TrueType + fonts (sigh) is that they only contain one single mapping, like + Apple Roman, or Windows Glyph List, making it usable only on the + platform it was `designed' for. + + The test program `ftdump' can be used to display the character + encodings supported in a font file. Most fonts come with Apple + Roman and Windows Unicode. + + FreeType can use every charmap found in a font file, so it is up + to your application to choose the one that fits its task best. If + you use a font which only provides an Apple Roman charcode, you'll + probably have a hard time rendering Unicode strings without an + additional translation. + + Note that the tool `ttf_edit' can actually add missing cmaps to a + TrueType font file. More info on this can be found at: + + http://www.truetex.com + + Another possibility is to use Just van Rossum's TTX compiler + (still beta) which can convert a TrueType font into an XML + description and vice versa; it can be found at + + http://www.letterror.com/ttx/ + +-------------------------------------------------------------------- + +9. What are the most common character mappings? + + If you don't want to read the TrueType specification, here is some + information about the most used char maps. Each map is designed + by a `platform ID', followed by a platform-specific `encoding ID': + + Examples: + + 0, 0 : Apple Unicode + 1, 0 : Apple Roman + 3, 0 : Windows Symbol + 3, 1 : Windows Unicode + + Windows and Apple Unicode charmaps differ only in internal storage + layout. Both can be used transparently with FreeType. + + Many fonts come also with both Apple Roman and Windows Unicode. + + +-------------------------------------------------------------------- + +10. How do I render text with FreeType? + + This is explained with great detail in the glyphs documentation + file available in both text (glyphs.txt) and HTML (glyphs.htm, + including schematics). + + Text rendering isn't difficult. One can also look at the code for + `ftstring' or `ftstrtto' to see how it is done. + + +-------------------------------------------------------------------- + +11. How do I render rotated/slanted text with FreeType? + + It is possible to transform the outlines returned by the glyph + loader, hence producing rotated or slanted text. Please read the + `glyphs' documentation file, which explains this in great detail, + as well as some other important things. + + +-------------------------------------------------------------------- + +12. How do I compute a glyph bitmap's dimensions? + + You should grid-fit its bounding box, then compute its width and + height. This is explained in the `bitmaps.txt' documentation + file. + + +-------------------------------------------------------------------- + +13. Why is text rendering so slow? + Does FreeType cache glyphs? + + The FreeType engine doesn't cache anything, be it outlines or + bitmaps. Hence, a program that renders text by calling the glyph + loader on each letter is slow. + + Because caching cannot be performed in both an _easy_ and + _portable_ way it is left to the application. Moreover, some + graphics systems already provide some sort of caching, and it is + better to take advantage of it rather than re-implementing it. + + The `how's and `when's of caching are explained in the `glyphs' + documentation file. The `bitmaps' documentation file is also a + good source of information if you intend to render individual + glyph bitmaps. + + +-------------------------------------------------------------------- + +14. Do you always render the same glyphs as Windows or the Mac? + + Short answer: No for rare cases. + + There are a lot of technical details, too numerous and lengthy to + be put here, that prevents the FreeType library from matching 100% + the glyphs produced by the Windows or Macintosh rasterizers. + + This engine is a clean-room implementation, and most of the + reasons why its development took so much time is the largely + deficient TrueType specification published by Apple and Microsoft. + A number of key technical aspects are missing, and we found many + `undocumented' features in the TrueType bytecode, after several + months of testing and trying. We are now very satisfied with the + current quality, though still try to improve it. + + The glyph metrics (bearings and advances) also match significantly + those computed by Windows, or found in the TrueType pre-calc + tables. + + As hinting glyphs also makes use of several rounding operations, + we will be unable to provide a perfect clone unless we implement + the exact same computations _and_ rounding errors -- this is + very unlikely... + + +-------------------------------------------------------------------- + +15. The program `ftlint' reports errors with one of my fonts, though + it works perfectly under Windows. What does this mean? + + Associated to each glyph is a small `program', written in a + specific bytecode language, which is in charge of hinting the + glyph's outline to make it perfect on screen as on paper. Some of + these programs can be broken (e.g., accessing invalid areas of + memory, performing a divide by zero, etc.), and these are the + errors that are reported by `ftlint'. + + They can also mean a bug in the TrueType bytecode interpreter (or + more likely an `undocumented' feature we haven't discovered yet), + but should now be extremely rare. + + Surprisingly, even largely distributed fonts can contain broken + glyph programs. For example: + + - antqua.ttf, glyph 163 (MS Office 4.2): + + The program tries to access point number 0x127, which is too + much. + + - timesbs, arialbs, courbs (MS Office International): + + The back-slanted versions of the MS core fonts produce stack + overflows in many glyphs, and other oddities. It seems their + `maximum profile' table is invalid. + + - a ton of `free' fonts, apparently designed with mediocre tools. + + It seems the Windows TrueType engine doesn't check its arguments + often, and let all overflows run, possibly writing to critical + portions of memory. Please, don't ask us what this could do to + NT 4 :-) + + The FreeType engine performs checks on every opcode. We cannot + guarantee that it is bullet proof, of course, but it seems to work + well and catch font bugs accordingly. + + We also have artificially `enlarged' some allocated tables to make + the engine work with the back-slanted fonts without compromising + security, but it's clearly a hack we would have preferred to + avoid! + + +-------------------------------------------------------------------- + +16. What does the `fttimer' test program benchmarks? + + This test program is only dedicated to profiling FreeType's + scan-line converter, a component also called `rasterizer', which + is in charge of converting a vectorial outline into a bitmap, or a + pixmap. + + It simply loads all glyphs of a font file (by slices of 512 at + once), then converts them. Only the conversion is actually + benchmarked. + + The glyphs are rendered at size 400pt at a resolution of 96dpi + (this is about 500 pixels high!). As you'll see by running + `fttimer', the rasterizer is very fast. + + +-------------------------------------------------------------------- + +17. Is it possible to perform styling (like oblique, italic, bold, + underline, etc.) with FreeType? + + Actually, these refer to very different things: + + - Italic and Bold styles usually mean many variations from the + `Regular' font. This is why you normally need a proper font + file for each of these. For example, the MS core font Times + comes in the following TrueType files: + + TIMES.TTF Times New Roman Regular + TIMESI.TTF Times New Roman Italic + TIMESB.TTF Times New Roman Bold + TIMESBI.TTF Times New Roman Bold Italic + (sometimes named TIMESZ.TTF) + + With FreeType, you simply need the required font file to use it. + + - Oblique style refers to a transformation that is applied to a + regular font in order to make it `slanted', likes italics do. + However, an italic font very frequently contains small but + important variations that cannot be produced by this method and + make the font more appealing. + + Slanting can easily be done with a transformation under + FreeType, with the exact same process as rendering rotated text. + Please read the `glyphs' documentation file where it is + explained in details. + + Usually, Windows or the Macintosh produce oblique versions of a + regular font if the corresponding italic TrueType file isn't + available. They also stretch regular fonts horizontally if the + bold one isn't available. All of this can be done with trivial + transformations. + + - Underlining and stroking are not really part of the glyphs. + They're simply lines that are printed on the glyph after it has + been rendered. Each TrueType file provides, in its OS/2 table + (which is accessible through the face object properties in + FreeType), several values that define the position and width of + those lines, in notional font units. + + If you want to use them, you'll have to scale these values to + your current instance/point size, then draw the lines yourself. + + +-------------------------------------------------------------------- + +18. When does glyph hinting takes place? Is it when the glyph is + loaded, or when it is converted to a bitmap/pixmap? + + The glyph loader returns fitted outlines by default (it can be + asked to return a non-fitted one, or simply the original outline + in notional coordinates too). + + This is important to have a glyph's correct metrics, even if it is + not to be rendered immediately, like when caching outlines for + rotated text. + + +-------------------------------------------------------------------- + +19. Which is the best, caching outlines or bitmaps? + + It depends on your application, and what it does with text. + + Usually, if all you need is render some simple text at specific + point sizes, then simply cache the bitmaps or pixmaps. + + However, if you want to do more advanced things, like rotated + text, which require sub-pixel placement to look good, you should + then only cache the outlines, and transform/place them as needed + before sending them to the scan-line converter. + + It's always possible to produce a bitmap from an outline, and the + scan-converter is very fast. It's up to you then... + + +-------------------------------------------------------------------- + +20. Can I open OpenType and/or TrueType GX fonts with FreeType? + + TrueType GX fonts are normal TrueType fonts with enhanced tables + and capabilities. They can always be opened by a normal TrueType + engine (like Windows, the Mac, or FreeType), but their improved + features won't be available. + + On the contrary, OpenType fonts may vary. While some may contain + legal TrueType glyphs, an `otf' file may only contain glyphs + encoded in the Type 2 format. You won't be able to produce any + glyphs from such a font file without a dedicated font engine (like + the ones promised in NT 5 and Java 2D). + + FreeType is a TrueType glyph engine and doesn't support Type 2 + fonts. Supporting them would require a very different philosophy + and a different core engine (even though they could share an API). + + Note that you can write extensions to the engine to access + supplemental tables defined in these formats (see next question). + + Note that FreeType version 2 (which is in alpha stage currently) + already includes a PostScript Type 1 interpreter... + + +-------------------------------------------------------------------- + +21. How can I access additional TrueType tables that FreeType + doesn't support? + + You can write an `engine extension'. This is a separately + compilable component which can enhance the base library's + functionalities, without recompiling it. Some important + extensions are provided in the `lib/extend' directory. + + You'll need of course to know the TrueType specification + precisely, as well as some of the conventions used to access + tables and to manage memory. Read the documentation files for + more details, or contact the developers at: + + devel@freetype.org + + +-------------------------------------------------------------------- + +22. When will I be able to use FreeType to display TrueType fonts in + X11, Wine or OS/2, or even other systems? + + Actually, an OS/2 replacement for TRUETYPE.DLL based on FreeType + is part of this package (to be found in contrib/ftos2). Thanks go + to Michal Mecasek (mike@mendelu.cz) for his excellent work! + + At least three X11 TrueType font servers are available; two of + them (xfsft and xtt) are based on FreeType, whereas the third + (xfstt) uses a separately developed TrueType engine. + + More information about these servers is available at the FreeType + homepage (http://www.freetype.org). + + Don't hesitate to contact us if you plan to use or port the engine + to exotic platforms, we're always interested in helping out. + + +-------------------------------------------------------------------- + +23. What does the `free' in FreeType really means? + + The previous releases of FreeType (alphas and beta) were placed + under the LGPL. FreeType 1.0, and later releases, come with an an + alternate license, inspired from the BSD, Artistic, and IJG's + (Independent JPEG Group) ones. In short: + + - You are encouraged to use and distribute this program in all + kinds of products, including commercial ones. + + - You don't have to pay us anything for it (royalty-free). + + - You may not pretend you wrote it, or part of it that you may use + in one of your product, and you have to state clearly that you + use the FreeType code if you distribute products based on it, or + parts of it (credits clause). + + - This source code is provided AS IS, with no warranty whatsoever, + and we cannot promise support for it. + + The exact and legal terms are in the file `license.txt'. + + Enjoy ;-) + + +-------------------------------------------------------------------- + +24. Does FreeType support threads? Is it re-entrant? + + Short answer: Basically yes, but not fully tested. + + We have changed some code since FreeType 1.0 in order to support + multi-threaded environments. However, these have not been tested + yet. Apparently, the thread-safe and reentrant builds now work + well perfectly once compiled; however, no serious concurrency + testing has been performed (of course, a serious lock analysis was + done in order to modify the source). + + Right now, the mutex management functions are all gathered in the + component `ttmutex', which has to be specialized for your own + system if a thread build will be necessary. + + +-------------------------------------------------------------------- + +25. Does FreeType support `foreign languages'? + + Short Answer: YES, it does! + + From a TrueType font file point of view, there are several parts + to the file, one of them being the `glyphs', i.e., picture + representations of the symbols. + + Another part is the mapping table, also called `charMap'. + + For example, glyph #1 could be letter `A', and glyph #2 could be + letter `Z'. Glyphs can be stored in any order in a font file. + + The mapping tables contain at least one char-map entry. For + example, you could have an ASCII-map that maps character code 0x41 + to glyph #1, and code 0x5A to glyph #2, etc. FreeType provides a + `charMap' object class to access and use this information easily. + + There are several character encodings recognized and defined by + the TrueType specification, like Latin-1, Unicode, Apple Scripts, + WGL, etc., but a font file might only contain one or two of them. + + When using a more `exotic' character encoding like EBCDIC (this is + IBM mainframe stuff!), you would need to translate it to one of + the available formats (or to add a charmap table to the font). + Cf. section 8. + + +-------------------------------------------------------------------- + +26. I'm using fractional char sizes, but the glyphs stay at the same + integer size. Why? + + Because hinting only works well with integer pixel sizes. There + is a flag that can be set in a TrueType font file to force integer + pixel size scaling, even if you ask for fractional sizes with an + API function like TT_Set_Instance_CharSize(). Needless to say, + nearly all fonts have the flag set. So this is normal. + + Also, notice that when giving a charsize in fractional points, + this will be converted to integer pixels with the formula: + + pixel_size = char_size * y_resolution / 72 + + For example, using a resolution of 96 dpi, we would have: + + 9.5 pts => 12.666 pixels => 13 pixels + 10.0 pts => 13.333 pixels => 13 pixels, i.e. same size + 10.5 pts => 14 pixels => 14 pixels + 11.0 pts => 14.666 pixels => 15 pixels + 11.5 pts => 15.333 pixels => 15 pixels, i.e. same size + + If you want to control the exact size in pixels of your glyphs, + simply use a resolution of 72dpi, where char_size = pixel_size. + + +-------------------------------------------------------------------- + +27. Hinting doesn't work at very small sizes. Why? + + This is normal. There are very good technical reasons why hinting + doesn't work well at sizes under 7 ppem, usually meaning the + appearance of ugly spikes and glyph distortions. This is why the + engine disables hinting by default at such low sizes. + + +--- end of FAQ --- diff --git a/docs/TODO b/docs/TODO new file mode 100644 index 0000000..2472cce --- /dev/null +++ b/docs/TODO @@ -0,0 +1,23 @@ +FreeType TODO list + +. Handle various PostScript glyph names in ftxpost.c: + + Omega vs. Ohm + Delta vs. increment + macron vs. overscore + my vs. mu1 + periodcentered vs. middot + + with a new flag. + + +. Adaption of FreeType for non-ANSI compilers (wow, I'm heretic :-) + + +. More 16bit stuff to support _cdecl etc. Maybe something like this + may be used in place of the current EXPORT_DEF/EXPORT_FUNC: + + NEW_EXPORT_DEF( TT_Error ) + Cache_Create( PEngine_Instance engine, ... ) + +--- end of TODO --- diff --git a/docs/apiref.txt b/docs/apiref.txt new file mode 100644 index 0000000..47b0307 --- /dev/null +++ b/docs/apiref.txt @@ -0,0 +1,1867 @@ + The FreeType Engine + + Core Library Reference + + + ----------------------------------- + + + Table of Contents: + + Introduction + + I. Types + + II. Functions + + III. Error codes + + + -------------------- + + +Introduction +============ + + This reference presents the types, functions, and error codes + defined in the high-level API header file `freetype.h'. Note that + all symbols defined in this file are prefixed by `TT_', to avoid + name conflicts with other packages at link time. + + The reference for extensions of the FreeType library can be found + in the file apirefx.txt. + + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +I. Types +======== + + Here is the list of all the types defined in the core FreeType + API. Their exact definition can be found in the file `freetype.h' + which should be included by every client application. + + + TT_Bool + + Can be either non-zero (true) or zero (false). + + .................................................................. + + TT_Fixed + + A signed 16.16 fixed float integer type used to specify + transform coefficients and other important data. + + .................................................................. + + TT_FWord + + A signed 16-bit type used to express a distance measured in the + font's original EM units. These are also called `FUnits' in the + TrueType specification. + + .................................................................. + + TT_UFWord + + An unsigned 16-bit type. + + .................................................................. + + TT_String + TT_Char + TT_Byte + + These types represent various 8-bit integer values (for strings, + signed, and unsigned values, respectively). + + .................................................................. + + TT_Short + TT_UShort + TT_Long + TT_ULong + + These four types are aliases for 16-bit integer (signed and + unsigned) and 32-bit integer types (signed and unsigned). + + .................................................................. + + TT_F2Dot14 + + A 2.14 fixed float integer type used for unary vectors and some + scaling coefficients. Its layout is: + + s : 1 -- sign bit + m : 1 -- mantissa bit + f : 14 -- unsigned fractional value + + where `s:m' is the 2-bit signed integer value to which the + always positive fractional part `f' should be added. + + .................................................................. + + TT_F26Dot6 + + A 26.6 fixed float integer format used to define fractional + pixel coordinates. Here, 1 unit = 1/64 pixel. + + .................................................................. + + TT_Pos + + This type is used to store point coordinates, either in + fractional pixels (26.6 fixed floats) or in EM units (simple + integers). + + The meaning of the value depends on the context. For example, + all distances relative to a scaled glyph are expressed in + fractional pixels (including bearings, advances, etc). However, + the same distances are in notional font units when the glyph was + loaded unscaled. + + .................................................................. + + TT_UnitVector + + A simple structure used to store a unit vector. The vector's + coordinates are expressed in fixed float format (2.14). + + struct + { + TT_F2Dot14 x; + TT_F2Dot14 y; + } + + .................................................................. + + TT_Vector + + A simple structure used to store a single vector. Its + coordinates are expressed in fixed float format (26.6). + + struct + { + TT_F26Dot6 x; + TT_F26Dot6 y; + } + + .................................................................. + + TT_Matrix + + A simple structure used to store a single 2x2 matrix. Its + coefficients are expressed in 16.16 fixed float format. This + matrix is used to perform linear transformations on the glyph + outline, such as slanting or rotation. + + struct + { + TT_Fixed xx, xy; + TT_Fixed yx, yy; + }; + + The computation performed is: + + x' = xx * x + xy * y + y' = yx * x + yy * y + + .................................................................. + + TT_BBox + + A simple type to hold a glyph's bounding box. Used by the + TT_Get_Outline_BBox() API. + + struct + { + TT_Pos xMin, yMin; + TT_Pos xMax, yMax; + } + + .................................................................. + + TT_Outline + + Outlines are now full-class citizens, with their own API. + + This structure is used to describe a vectorial glyph + representation to the rasterizer. It is made of several fields + described below. Note however that: + + ***** THIS STRUCTURE MAY CHANGE IN THE FUTURE. We thus + ***** encourage you to use the outlines APIs described below to + ***** process your outlines, i.e., create/copy/translate/ + ***** transform them as well as rendering bitmaps and pixmaps. + + ***** THE STRUCTURE CHANGED BETWEEN 1.0 and 1.1! + + Now that you have been warned, the fields are: + + - An array of points: + + The `n_points' field gives the number of points in the + outline, while their coordinates are found in the single + vector array `points'. The `flag' array holds for each point + a flag indicating its type. + + Currently, only the first bit (bit 0, the least significant + bit) of each byte is meaningful to the rasterizer. If set, it + indicates that the point is _on_ the curve. If not set, the + point is said to be _off_ the curve. It is then a Bezier + control point. + + For more information about point states, read the TrueType + specification or the scan-line documentation `raster.txt'. + + - An array of contours' end-point indexes: + + The `n_contours' field gives the number of contours, while the + `contours' array holds the indexes of each contour's last + point. Note that the first contour always begin at point 0. + + Hence, contours[0] holds the index of the last point of the + first contour. The second contour starting at point number + `contours[0]+1' and ending a point number `contours[1]'. + + ** IMPORTANT NOTE: ** + ********************* + + The last table entry _must_ always give the total number of + points used to draw the contours, i.e.: + + contours[n_contours - 1] == n_points + + If this value is bigger than `n_points' when calling the + scan-line converter, the component will immediately return + an error (TT_Err_Too_Many_Points). If the value is smaller, + only the points contained in the described contours will be + used in the conversion process. + + - An owner field: + + This flag should **NEVER** be changed by the user. It + indicates whether the pointer fields own the arrays they refer + to (when the flag is set), or if they simply alias them (flag + unset). + + - A high precision flag: + + If this boolean is set (i.e. not zero), the scan-line + converter uses a higher precision to compute segment and + Bezier coordinates (more precisely, it uses 1/1024 precision, + instead of the normal 1/64). This is of course slower but can + be important for glyphs rendered at small sizes. + + - A second pass flag: + + If this boolean is set, the scan-line converter performs a + second sweep on the bitmap/pixmap to detect vertical drop-out. + Only horizontal drop-outs are detected in the first pass. + This is slower, but important for glyphs rendered at small + sizes. + + - A dropout mode: + + Used to specify the method to apply for drop-out control (also + called `continuity testing' in other environments). The mode + value must be one of the values defined by the TrueType + specification. + + The recent modes 4 and 5 introduced in the newest TrueType + specification (Version 1.66) are fully supported. + + An invalid value (i.e., not 0, 1, 2, 4, or 5) is taken as no + dropout control (equivalent to mode 0). + + NOTE 1: + + The outline returned by TT_Get_Glyph_Outline() only alias the + data that is part of a glyph container (see below). However, + it is possible to create and process your own outlines with + the new API functions TT_New_Outline(), TT_Done_Outline(), + TT_Copy_Outline(), TT_Translate_Outline(), etc. + + TT_Done_Outline() will only discard an outline's array if it + owns them. + + NOTE 2: + + The outlines created by TT_New_Outline() are _not_ released by + the engine on TT_Done_FreeType(), they must be discarded + explicitly by the user who has created them! + + NOTE 3: + + The glyph loader sets the fields `high_precision', + `dropout_mode' and `second_pass' automatically. + + NOTE 4: + + This structure was called TT_Glyph_Outline in beta versions of + FreeType. + + .................................................................. + + TT_Glyph_Metrics + + A structure used to return simple glyph metrics, usable for + either horizontal or vertical layout. The values are expressed + in fractional pixels (26.6 format) if scaling was active, and in + FUnits otherwise. + + The main idea was to accomodate vertical text layouts by getting + rid of the two explicit `leftSideBearing' and `advanceWidth' + names. + + The meaning of the fields varies with the text layout: + + bearingX: Also known as the `left side bearing'. For + horizontal metrics, this value gives the horizontal + distance from the pen position to the glyph's bbox + xmin, otherwise it specifies the vertical distance. + + bearingY: Also known as the `top side bearing', this is the + vertical distance from the baseline to the glyph's + bbox ymax for horizontal metrics, the horizontal + distance otherwise. + + struct + { + TT_BBox bbox; /* the glyph's bbox */ + + TT_Pos bearingX; /* left-side bearing */ + TT_Pos bearingY; /* top-side bearing */ + + TT_Pos advance; /* advance width or height */ + }; + + ** IMPORTANT NOTE ** + + Because of the convention used by the TrueType engine, the + outlines generated at glyph-load time are all placed so that + the pen is at position (0,0). This means that you don't need + to increase the pen position by `bearingX' and/or `bearingY' + before writing a glyph. Text output can be performed with + simple lines like: + + for (glyphs in text) + { + TT_Load_Glyph( ... ); + TT_Get_Glyph_Outline( glyph, &outline ); + TT_Translate_Outline( outline, + cur_pos_x * 64, cur_pos_y * 64 ); + + TT_Get_Outline_Bitmap( outline, bitmap ); + /* blit bitmap to surface */ + + cur_pos_x += (metrics.advance + 32) / 64 + } + + See the file `test/ftstring.c' for an example. + + NOTE 2: + + This structure has changed from the beta version of FreeType. + + NOTE 3: + + FreeType implements only TT_Get_Glyph_Metrics() to return + horizontal metrics. For extracting vertical metrics you + should use TT_Get_Glyph_Big_Metrics(). + + .................................................................. + + TT_Big_Glyph_Metrics + + This structure is used to return the metrics of a glyph for both + horizontal and vertical layout. + + The `linearXXX' fields represent unhinted scaled metrics values. + They can be useful for applications which need to compute device + independent placement of glyphs. Applying these metrics to + hinted glyphs will in most cases ruin the grid fitting performed + by the bytecode interpreter. + + struct + { + TT_BBox bbox; /* the glyph's bounding box */ + + TT_Pos horiBearingX; /* horizontal left-side bearing */ + TT_Pos horiBearingY; /* horizontal top-side bearing */ + + TT_Pos vertBearingX; /* vertical left-side bearing */ + TT_Pos vertBearingY; /* vertical top-side bearing */ + + TT_Pos horiAdvance; /* horizontal advance */ + TT_Pos vertAdvance; /* vertical advance */ + + TT_Pos linearHoriBearingX; /* lin. scaled hor. lsb. */ + TT_Pos linearHoriAdvance; /* lin. scaled hor. adv. */ + + TT_Pos linearVertBearingY; /* lin. scaled vert. tsb. */ + TT_Pos linearVertAdvance; /* lin. scaled vert. adv. */ + } + + .................................................................. + + TT_Instance_Metrics + + A structure used to return instance (point size) metrics. + + struct + { + int pointSize; + /* point size in points (1 point = 1/72 inch) */ + + TT_UShort x_ppem; /* horizontal pixels per EM square */ + TT_UShort y_ppem; /* vertical pixels per EM square */ + + TT_Fixed x_scale; /* 16.16 scale for EM -> frac pixels */ + TT_Fixed y_scale; /* 16.16 scale for EM -> frac pixels */ + + TT_UShort x_resolution; /* device hor. res. in dpi */ + TT_UShort y_resolution; /* device vert. res. in dpi */ + }; + + The fields `x_scale' and `y_scale' can be used by clients to + convert from notional units (in funits) to fractional + pixels (in 26.6 fixed float format), e.g.: + + TT_FUnit em_distance; + TT_F26Dot6 frac_distance; + TT_Fixed x_scale; + + frac_distance = (em_distance * x_scale) / 0x10000; + + .................................................................. + + TT_Raster_Map + + This structure is used to describe a target bitmap (or pixmap) + to the scan-line converter. It _must_ be set up by the client + application. + + - The `rows' field contains the total number of rows in the + bitmap. + + - The `width' field gives the number of pixels per row (a bit or + a byte, depending on the map's nature). + + - The `cols' field gives the number of columns, i.e. bytes, + taken by each row in the map buffer. + + ** IMPORTANT: ** The `cols' field must be a multiple of 4 for + pixmaps! + + Typically, its value should be `(width+7)/8' for bitmaps, and + `(width+3) & -4' for pixmaps. + + - The `flow' field gives the map's vertical orientation. + + If the first bytes of the bitmap buffer pertain to its upper + row, the flow is said to be going `down', and the field should + take the value `TT_Flow_Down'. If these bytes pertain to its + lowest row, the flow is going `up', and the value is + `TT_Flow_Up'. + + As an example, the PC video modes use a `down' flow, where the + first VRAM byte corresponds to the upper and leftmost corner + of the screen. + + - The `bitmap' field is a typeless pointer to the map's buffer. + + - The `size' field contains the buffer's size in bytes. It is + usually computed as follows: + + size = rows * cols; + + NOTE 1: + + For bitmaps, the leftmost-pixel is related to the highest + (i.e. most significant) bit of its byte. There is currently + no support for the opposite convention found in some systems. + + (It can be easily added if you really need it, just ask the + development team.) + + struct + { + int rows; /* number of rows */ + int cols; /* number of columns (bytes) per row */ + int width; /* number of pixels per line */ + int flow; /* bitmap orientation */ + + void* bitmap; /* bit/pixmap buffer */ + long size; /* bit/pixmap size in bytes */ + } TT_Raster_Map; + + NOTE 2: + + TT_Get_Outline_Bitmap() resp. TT_Get_Glyph_Bitmap() are used + to render bitmaps into a TT_Raster_Map. The convention used + is 0 for the background, and 1 for the foreground. The glyph + is simply `or-ed' to the bitmap buffer. + + NOTE 3: + + TT_Get_Outline_Pixmap() and TT_Get_Glyph_Pixmap() are used to + render pixmaps into a TT_Raster_Map. Note that pixels are + drawn in spans of 4 successive bytes, only if needed. This + means that you must ALWAYS pass a clean pixmap buffer to these + functions. Otherwise, garbage could accumulate! + + .................................................................. + + TT_Header + + This structure is used to hold the font's header. Its layout + and meaning are defined in the TrueType specification, in the + `head' section. + + .................................................................. + + TT_Horizontal_Header + + This structure is used to hold the font's horizontal header. + Its layout and meaning are defined in the TrueType + specification, in the `hhead' section. + + .................................................................. + + TT_OS2 + + This structure is used to hold the font's OS/2 table. Its + layout and meaning are defined in the TrueType specification, in + the `OS/2' section. + + Note that since FreeType 1.3, we support fonts without an OS/2 + table (mainly old but popular Mac fonts). In this case, the + table's `version' field will be set to 0xFFFF by the loader, and + all other fields will be zeroed. + + .................................................................. + + TT_Postscript + + This structure is used to hold the font's PostScript table. Its + layout and meaning are defined in the TrueType specification, in + the `post' section. + + .................................................................. + + TT_Face_Properties + + This structure is used to return an opened face's properties. + These are: + + - The total number of glyphs in the font, given by the field + `num_Glyphs'. + + - The maximum number of points for the font's glyphs. This + value is used to allocate the points tables of a glyph + container's outline. It can be fairly large (like 256 points + for Roman fonts). + + - The maximum number of contours for the font's glyphs. This + value is used to allocate the contours tables of a glyph + container's outline. It can be fairly large (over 16, even in + Roman fonts). + + - The number of character mappings and name records within the + font. These values can still be retrieved through the APIs + TT_Get_CharMapCount() and TT_Get_Num_Names(), though these + have been _seriously_ deprecated. + + - The number of associated faces. This number is always 1 for a + normal TrueType font file. However, when the face object was + opened from a TrueType collection, it contains the total + number of embedded fonts. + + - Pointers to the face's header, horizontal header, OS/2, and + PostScript tables. + + struct + { + TT_UShort num_Glyphs; /* number of glyphs in face */ + TT_UShort max_Points; /* max. numb. of points in a glyph */ + TT_Short max_Contours; + /* maximum number of contours in a glyph */ + + TT_ULong num_Faces; + /* 1 for normal TrueType files resp. */ + /* the number of embedded faces for TT */ + /* collections */ + + TT_Header* header; /* TrueType header table */ + TT_Horizontal_Header* horizontal; + /* TrueType horizontal header */ + TT_Vertical_Header* vertical; + /* TrueType vertical header */ + TT_OS2* os2; /* TrueType OS/2 table */ + TT_Postscript* postscript; + /* TrueType PostScript table */ + } TT_Face_Properties; + + - Note that the `vertical' field is set to NULL if the font file + does not contain any vertical metrics. + + - Note also that since version 1.3 we support font files without + an OS/2 table. See the definition of TT_OS2 for more details. + + .................................................................. + + TT_Stream + + This handle type defines a stream used to access a font file's + data. A client application should never deal with streams + directly, but some engine extensions need it to support more + advanced features like sbit support. + + .................................................................. + + TT_Face + + This type defines a handle used to reference a face object. The + objects are never accessed directly by a client application; it + can only obtain handles to new objects, and use them to query + specific information or processes. + + See also: + + TT_Open_Face(), TT_Open_Collection(), TT_Close_Face(), + TT_Get_Face_Properties(), etc. + + .................................................................. + + TT_Instance + + This type defines a handle used to reference an instance object + (also called a `pointsize' in other type engines). An instance + is always created from a valid face object, and is destroyed + with it by the engine. + + See also: + + TT_New_Instance(), TT_Close_Instance(), + TT_Set_Instance_Pointsize(), TT_Set_Instance_Resolutions(), + etc. + + .................................................................. + + TT_Glyph + + This type defines a handle used to reference a glyph container + object. A glyph container is an object owning tables sized to + the font's maximum profile to hold any glyph of a given font + file. + + It contains an outline, some metrics, as well as some data + related to the way it should be processed by the scan-line + converter. + + Note that a glyph container doesn't contain any bitmap or + pixmap! + + See also: + + TT_New_Glyph(), TT_Close_Glyph(), TT_Get_Glyph_Metrics(), + TT_Get_Glyph_Big_Metrics(), TT_New_Outline(), + TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap(), + TT_Get_Glyph_Pixmap() + + .................................................................. + + TT_Error + + This is the type of all error codes returned by the API. Nearly + all functions return an error code, set to 0 in case of success. + + A list of all error codes is given in section III. + + .................................................................. + + TT_Engine + + For the sake of re-entrancy it is possible to distinguish + `engines' to separate several running instances of the library. + For example, it could be used as a DLL shared by several client + applications. + + Each client program must begin by creating its own engine, + through a call to TT_Init_FreeType(). The engine must also be + passed as the first argument of the following functions: + + TT_Open_Face() + TT_Open_Collection() + TT_Set_Raster_Gray_Palette() + TT_Get_Outline_Bitmap() + TT_Get_Outline_Pixmap() + TT_Done_FreeType() + + Note that any FreeType object pertains to one single engine + (there is no sharing). Closing an engine with + TT_Done_FreeType() will delete all the objects that have been + allocated within its instance. + + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +II. Functions +============= + + Here is a list of the core library's API. + + NOTE: + + A function's default result is an error code of type TT_Error; a + list of error codes is given in section III below. + + Some functions return other types, in which case the result type + is documented with its description. + + .................................................................. + + TT_FreeType_Version( int* major, int* minor ); + + Queries the major and minor version of the library. + + .................................................................. + + TT_Init_FreeType( TT_Engine* engine ); + + Creates and initializes a new engine. Returns a handle to the + engine in the `*engine' variable. + + This call must be performed before any other function of + FreeType is invoked. The engine handle must be passed to the + following functions: + + TT_Open_Face() + TT_Open_Collection() + TT_Set_Raster_Gray_Palette() + TT_Done_FreeType() + + .................................................................. + + TT_Done_FreeType( TT_Engine engine ); + + Finalizes and destroys an engine. This call destroys _all_ + objects that were previously created and used with the engine. + + .................................................................. + + TT_Open_Face( TT_Engine engine, + TT_Text* fontPathName, + TT_face* face ); + + This call opens a font file, located by `fontPathName', and + returns a handle to the newly corresponding face object in the + handle `*face'. The object is part of the `engine' instance. + + Example: + + error = TT_Open_Face( engine, "c:\ttf\wingding.ttf", &face ); + if ( error ) + fprintf( stderr, "Could not open face.\n" ); + + NOTE 1: + + The font file can be a TrueType collection; in this case, the + engine will always open the first embedded font found in the + file. + + NOTE 2: + + `TT_Text' is usually defined as `char' by a typedef + declaration. It may be a 16-bit quantity (or even wider) for + some operating systems; see ttconfig.h for details. + + .................................................................. + + TT_Open_Collection( TT_Engine engine, + TT_Text* collectionPathName, + TT_ULong fontIndex, + TT_Face* face ); + + This call opens one of the fonts found in a TrueType collection. + The font is selected through the `fontIndex' argument. The + first font has index 0. + + Note that to know a collection's number of embedded fonts, + you will have to: + + 1 - open the first collection font with TT_Open_Face(). + + 2 - query the face's properties through + TT_Get_Face_Properties(). + + The number of embedded faces is then `properties->num_Faces'. + + Example: + + TT_Face face; + TT_Face_Properties properties; + + + /* Open first embedded collection font */ + error = TT_Open_Face( engine, "c:\ttf\sample.ttc", &face ); + if ( error ) { ...error... } + + /* Get face properties */ + error = TT_Get_Face_Properties( face, &properties ); + if ( error ) { ...error... } + + printf( "There are %d fonts in this collection.\n", + properties->num_Faces ); + + TT_Close_Face( face ); + + /* Open second font in collection */ + error = TT_Open_Collection( engine, "c:\ttf\sample.ttc", 1, + &face ); + if ( error ) { ...error... } + + NOTE 1: + + If the file isn't a collection, `fontIndex' must be zero. + Otherwise, an error will be returned. + + NOTE 2: + + `TT_Text' is usually defined as `char' by a typedef + declaration. It may be a 16-bit quantity (or even wider) for + some operating systems; see ttconfig.h for details. + + .................................................................. + + TT_Set_Raster_Gray_Palette( TT_Engine engine, + TT_Byte* palette ); + + Sets the gray-level palette for an engine. The palette is used + to create pixmaps through the TT_Get_Glyph_Pixmap() function. + It is an array of five bytes, following the convention: + + palette[0] = background (white) + palette[1] = light + palette[2] = medium + palette[3] = dark + palette[4] = foreground (black) + + .................................................................. + + TT_Get_Face_Properties( TT_Face face, + TT_Face_Properties* properties ); + + Returns the `face' object's `*properties'. This structure + contains various data like the total number of glyphs and + pointers to some mandatory TrueType tables. + + See the definition of TT_Face_Properties in section I for more + details. + + Note that since version 1.3, FreeType supports fonts with no + OS/2 table, like many old Mac fonts. See the definition of + TT_OS2 for more details. + + .................................................................. + + TT_Get_Face_Metrics( TT_Face face, + TT_UShort firstGlyph, + TT_UShort lastGlyph, + TT_Short* leftBearings, + TT_UShort* widths, + TT_Short* topBearings, + TT_UShort* heights ); + + This function returns the original horizontal AND vertical + metrics for a given face `face' and a given glyph range specified + by `firstGlyph' and `lastGlyph' as found in the `hmtx' and `vmtx' + tables. These are the glyphs' left-side bearings (in + `leftBearings') and horizontal advance widths (in `widths'), as + well as top-side bearings (in `topBearings') and vertical advance + heights (in `heights'). If you aren't interested in any of the + metrics fields, simply set its value to NULL. + + All are expressed in font units, a.k.a. EM units. + + The metrics arrays must be allocated by the client program. + + IMPORTANT NOTE: + + As vertical metrics are optional in a TrueType font, this + function will return an error (TT_Err_No_Vertical_Data) if this + function is called on such a face with non-NULL `topBearings' + or `heights' arguments. + + If a font has no vertical data, the `vertical' field in its + properties structure is set to NULL. + + .................................................................. + + TT_Set_Face_Pointer( TT_Face face, + void* data ); + + For convenience purposes, each face object has a `generic' + pointer which value is unused by the engine, but that can be set + freely by client applications through this function. + + Do what you want with it; it is here to give you a chance to + link a face object to your own structures and data. + + .................................................................. + + void* TT_Get_Face_Pointer( TT_Face face ); + ^^^^ + Returns a face object's generic pointer. See + TT_Set_Face_Pointer() above. + + .................................................................. + + TT_Flush_Face( TT_Face face ); + + Closes a given face object's file handler or descriptor. This + is useful to save system resources if your application opens + dozens or even hundreds of fonts. The face object is still + valid, and its file will be re-opened automatically on the next + request which requires disk access. + + .................................................................. + + TT_Close_Face( TT_Face face ); + + Closes a given `face' object. This function will also destroy + all the face's child instances. The face's glyphs will not be + destroyed, however. + + .................................................................. + + TT_New_Instance( TT_Face face, + TT_Instance* instance ); + + Creates a new instance object related to the `face' object. A + handle to the newly created instance is returned in `instance'. + + The default instance resolution is 96dpi in both vertical and + horizontal direction; the default point size is 10pt. + + .................................................................. + + TT_Set_Instance_Resolutions( TT_Instance instance, + TT_UShort xResolution, + TT_UShort yResolution ); + + Sets the target device resolutions for a given instance. The + values are expressed in dots per inch (dpi). A value of 96dpi + is typical for an SVGA display, 72dpi for a Macintosh one, and + 300 to 6000dpi for printers. Default value (before a call to + this function) is 96dpi. + + .................................................................. + + TT_Set_Instance_CharSize( TT_Instance instance, + TT_F26Dot6 charsize ); + + Sets the point size for a given instance. The size is expressed + in fractional (26.6) `points', where 1 point = 1/72 inch. The + default value is 10pt (before a call to this function). + + For example, to use a char size of 12pt, call the function with: + + TT_Set_Instance_CharSize( instance, 12 * 64 ); + + Fractional point sizes are thus possible. + + .................................................................. + + TT_Set_Instance_CharSizes( TT_Instance instance, + TT_F26Dot6 charWidth, + TT_F26Dot6 charHeight ); + + Sets an instance's glyph width and height independently in + fractional (26.6) points. Similar to Set_Instance_CharSize() + with the exception that the horizontal and vertical glyph + dimensions can differ. + + .................................................................. + + TT_Set_Instance_PixelSizes( TT_Instance instance, + TT_UShort pixelWidth, + TT_UShort pixelHeight, + TT_F26Dot6 pointSize ); + + This function can be used to specify directly the pixel sizes + and point size of a given instance, independently of device + resolutions. This is not the recommended way to do it, but can + be used for debugging or simplicity in some special cases. + + Note that you _must_ provide a point size! + + .................................................................. + + TT_Set_Instance_Transform_Flags( TT_Instance instance, + TT_Bool rotated, + TT_Bool stretched ); + + Sets the transform flags for a given instance. These flags are + passed to the interpreter each time a glyph is loaded within the + instance. Their role is to notify the glyph hinting mechanism + that the resulting glyph will be transformed in a special way. + Setting one of these flags to true usually disables hinting, + though this behaviour varies with each font file. + + NOTE: + + The glyph loader doesn't perform the rotation or the + stretching automatically; this must be done explicitly by the + client application. Use the function TT_Transform_Outline() + for that purpose. + + .................................................................. + + TT_Get_Instance_Metrics( TT_Instance instance, + TT_Instance_Metrics* imetrics ); + + This call returns a given instance's current metrics. They are + returned in the `imetrics' structure, which contains, among + other things, the current point size, ppem, and device + resolution (horizontal and vertical). + + .................................................................. + + TT_Set_Instance_Pointer( TT_Instance instance, + void* data ); + + For convenience purposes, each instance object has a `generic' + pointer which value is unused by the engine, but that can be set + freely by client applications through this function. + + Do what you want with it, it is here to give you a chance to + link a face object to your own structures and data. + + .................................................................. + + void* TT_Get_Instance_Pointer( TT_Instance instance ) + ^^^^ + + This function returns an instance object's generic pointer set + through TT_Set_Instance_Pointer(). + + .................................................................. + + TT_Done_Instance( TT_Instance instance ); + + Closes a given instance object, destroying its associated data. + Note that this is performed automatically when a face is closed + on all its child instances. However, explicit deallocation can + help in freeing the memory used by the application earlier. + + .................................................................. + + TT_New_Glyph( TT_Face face, + TT_Glyph* glyph ); + + Creates a new glyph container for the glyphs of the font + described by the `face' handle. A pointer to the container is + returned in `glyph'. The face is said to be the glyph's parent. + + NOTE: + + A glyph is destroyed with its parent face object. However, it + is possible to delete it explicitly with TT_Done_Glyph(). + + .................................................................. + + TT_Done_Glyph( TT_Glyph glyph ); + + Discards a glyph container. This is also done automatically for + all glyphs when closing its parent face object. + + .................................................................. + + TT_Load_Glyph( TT_Instance instance, + TT_Glyph glyph, + TT_UShort glyphIndex, + TT_UShort loadFlags ); + + Loads and processes (scales and/or hints) a glyph at a given + `instance' into the `glyph' container. + + Note that `glyph' and `instance' must have the _same_ parent + face object, otherwise an error message will be returned. + + `glyph_index' is the glyph's index as found in the TrueType + font. It is _not_ a character code (see the charmap functions + below). + + `load_flags' is an integer that specifies which operations are + to be performed on the loaded glyph. The following values/bits + are used: + + TTLOAD_SCALE_GLYPH + + Indicates that the glyph must be scaled to the instance's + resolution. The pixel coordinates returned in the glyph + outline structure (see below) are then expressed in + fractional pixels represented in the 26.6 fixed point + floating format (F26Dot6). + + If scaling is disabled, the coordinates returned in the + outline structure are integer font units, also called + `FUnits' by the TrueType specification. + + TTLOAD_HINT_GLYPH + + This flag is only valid when scaling is on. It informs the + loader that the glyph must be hinted (i.e., grid-fitted for + optimal display). Note that hinting will occur only if the + instance's transformations and metrics allow it (for + example, most font programs disable hinting automatically in + case of rotation or stretching). + + When loading a hinted glyph, the metrics computed by the + loader, including the bounding box, will also be + grid-fitted. + + TTLOAD_PEDANTIC + + Starting with FreeType version 1.3, the bytecode interpreter + can ignore even more errors (like out-of-bound array + accesses). Using this flag it is possible to force TrueType + compliant interpretation of font programs. + + TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH + + A flag to handle monospaced fonts with an incorrect global + advance width in the `hhea' table. If set, the actual + advance width value of a particular glyph will be used; if + unset, the advance widths for all glyphs are forced to be + equal to the global value. + + + NOTE: + + You can also use the constant TTLOAD_DEFAULT, which is simply + the union of TTLOAD_SCALE_GLYPH and TTLOAD_HINT_GLYPH for most + `typical' loads. + + .................................................................. + + TT_Get_Glyph_Outline( TT_Glyph glyph, + TT_Outline* outline ); + + This call returns the glyph's `outline'. This is a simple + structure which contains pointers to the data used to describe + an outline to the rasterizer. See the definition of + TT_Outline in section I. + + .................................................................. + + TT_Get_Glyph_Metrics( TT_Glyph glyph, + TT_Glyph_Metrics* metrics ); + + Extracts the glyph's metrics and copies them to the `*metrics' + structure. Its format is described in section I. + + If the glyph has been loaded without scaling, the values are + expressed in FUnits (integers relative to the original font grid + called the EM Square). + + If the glyph has been loaded _with_ scaling, which is the + default, the values are expressed in fractional pixels in 26.6 + fixed point float format (F26Dot6; 1 unit = 1/64th of a pixel). + + If the glyph has been loaded with hinting, the metrics are also + grid-fitted, including the bounding box. To get the un-fitted + bbox, call TT_Get_Outline_BBox() on the glyph's outline. + + NOTE: + + BBox fitting occurs according to the following scheme: + + #define FLOOR( x ) ( (x) & -64 ) + #define CEILING( x ) ( ( (x) + 63 ) & -64 ) + + xMin = FLOOR( xMin ); + yMin = FLOOR( yMin ); + xMax = CEILING( xMax ); + yMax = CEILING( yMax ); + + This means that the outline's width and height in pixels can be + computed simply from the fitted bbox, namely + + (xMax-xMin)/64 and (yMax-yMin)/64 + + .................................................................. + + TT_Get_Glyph_Big_Metrics( TT_Glyph glyph, + TT_Big_Glyph_Metrics* metrics ); + + Extracts the glyph's big metrics and copies them to the + `*metrics' structure. Its format is described in section I. + + If the glyph has been loaded without scaling, the values are + expressed in FUnits (integers relative to the original font grid + called the EM Square). + + If the glyph has been loaded _with_ scaling, which is the + default, the values are expressed in fractional pixels in 26.6 + fixed point float format (F26Dot6; 1 unit = 1/64th of a pixel). + + If the glyph has been loaded with hinting, the metrics are also + grid-fitted, including the bounding box. To get the un-fitted + bbox, just call TT_Get_Outline_BBox() on the glyph's outline. + + NOTE 1: + + BBox fitting occurs according to the following scheme: + + #define FLOOR( x ) ( (x) & -64 ) + #define CEILING( x ) ( ( (x) + 63 ) & -64 ) + + xMin = FLOOR( xMin ); + yMin = FLOOR( yMin ); + xMax = CEILING( xMax ); + yMax = CEILING( yMax ); + + This means that the outline's width and height in pixels can be + computed simply from the fitted bounding box, namely + + (xMax-xMin)/64 and (yMax-yMin)/64 + + NOTE 2: + + The vertBearingX value in `metrics' cannot be extracted for + outline glyphs -- it is defined for embedded bitmaps only. + Instead, it is set to (xMin-xMax)/2; this will center the + bounding box on the vertical `baseline'. + + .................................................................. + + TT_Get_Glyph_Bitmap( TT_Glyph glyph, + TT_Raster_Map* bitmap, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + This call converts the vectorial glyph representation contained + in the object handled by `glyph' into a bitmap. + + The target bitmap is described by the `bitmap' pointer. + Clipping will be done if necessary. You can also specify an + offset to be applied before the scan-line conversion; `xOffset' + and `yOffset' must be expressed in fractional pixels (where + 1 unit = 1/64th pixel). + + NOTE 1: + + Choosing non integer pixel offsets, i.e., values of `xOffset' + and `yOffset' that are not multiples of 64, will ruin the + hinting performed by the interpreter, and result in bad + rendering at small sizes. + + NOTE 2: + + The glyph's point coordinates must be scaled before calling + this function. Never call this function with a glyph that + were loaded with no scaling! + + NOTE 3: + + FreeType always shifts the glyph horizontally so that the left + side bearing is equal to the left side of the bounding box. + + .................................................................. + + TT_Get_Glyph_Pixmap( TT_Glyph glyph, + TT_Raster_Map* pixmap, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + This call converts the vectorial glyph representation contained + in the object handled by `glyph' into a pixmap (i.e., an + 8-bit/pixel map). The result is an anti-aliased version of the + glyph (`anti-aliasing' is also known as `font-smoothing'). + + The target pixmap is described by the `pixmap' pointer. Note + that its width _must_ be a multiple of 4. For the definition + and description of a pixmap see Section I. + + As with TT_Get_Glyph_Bitmap(), you can specify offsets to be + applied before the rendering (`xOffset' and `yOffset' must be + expressed in fractional pixel coordinates). + + NOTE 1: + + You don't need to supply a temporary bitmap for the + anti-aliaser. The rasterizer uses its own scheme to optimize + memory usage. + + NOTE 2: + + The glyph's point coordinates must be scaled before calling + this function. This means that you should never call it with + a glyph which has been loaded without scaling! + + NOTE 3: + + The pixmap passed to this function should always be EMPTY + (i.e., filled with zero bytes) before the call. If not, + garbage will accumulate! + + NOTE 4: + + FreeType always shifts the glyph horizontally so that the left + side bearing is equal to the left side of the bounding box. + + .................................................................. + + TT_New_Outline( TT_UShort numPoints, + TT_UShort numContours, + TT_Outline* outline ); + + Creates a new outline object. This function creates the arrays + necessary to hold `numPoints' points and `numContours' contours, + and set `outline's pointers to them. + + The new outline owns the arrays, and they will be destroyed with + it through TT_Done_Outline(). + + NOTE 1: + + Outlines created with this function are called `user' + outlines, in contrast with the outlines returned by + TT_Get_Glyph_Outline(), which fields refer to the data + contained within a glyph object (i.e., these outlines do not + own the arrays they refer to). + + NOTE 2: + + User outlines aren't tracked by the engine, which means they + are not destroyed by a TT_Done_FreeType(). You have to + explicitly discard them through TT_Done_Outline() to avoid + memory leaks. + + .................................................................. + + TT_Done_Outline( TT_Outline* outline ); + + Deletes an outline's data. Note that you need not destroy the + outlines returned by TT_Get_Glyph_Outline(), only those created + by TT_New_Outline(). + + .................................................................. + + TT_Copy_Outline( TT_Outline* source, + TT_Outline* target ); + + Copies the content of the `source' outline into the content of + the `target' outline. The two outlines must have been created + with the same dimensions (num_points and num_contours), + otherwise this function will return an error code. + + .................................................................. + + void TT_Transform_Outline( TT_Glyph_Outline* outline, + ^^^^ TT_Matrix* matrix ); + + Applies a simple transformation matrix on a given outline. This + will multiply each point coordinate vector by a 2x2 matrix, + which coefficients are given in the 16.16 fixed float format. + + Rotation can be performed with this function. + + NOTE: + + This function takes an outline, and not a glyph handle, as a + parameter. This `feature' lets you apply transformations on + your own copies of glyphs. + + .................................................................. + + void TT_Translate_Outline( TT_Glyph_Outline* outline, + ^^^^ TT_Pos xOffset, + TT_Pos yOffset ); + + Applies a simple translation on a given outline. + + NOTE: + + This function takes an outline, and not a glyph handle, as a + parameter. This `feature' lets you apply translation to your + own copies of glyphs. + + .................................................................. + + TT_Get_Outline_Bitmap( TT_Outline* outline, + TT_Raster_Map* bitmap ); + + Renders an outline into a bitmap. The latter must be setup by + the user before the call (i.e., it is not created by this + function, instead it must be provided by the user). + + .................................................................. + + TT_Get_Outline_Pixmap( TT_Outline* outline, + TT_Raster_Map* pixmap ); + + Renders an outline into a pixmap. The latter must be setup by + the user before the call (i.e., it is not created by this + function, instead it must be provided by the user). + + NOTE: + + The pixmap passed to this function must always be EMPTY (i.e., + filled with zero bytes) before the call. Otherwise, garbage may + accumulate! + + .................................................................. + + TT_Get_Outline_BBox( TT_Outline* outline, + TT_BBox* bbox ); + + Returns an outline's bounding box in the `bbox' structure. Note + that the returned coordinates are not grid fitted! + + NOTE: + + The current release of FreeType (1.x) does compute the bounding + box for the outline's control points, and not the `exact' box + based on Bezier arcs extrema. Hence, the bbox returned by this + function may be slightly larger than necessary if the glyph + doesn't have control points at its extrema, or if it has been + rotated. + + .................................................................. + + void TT_Transform_Vector( TT_Pos* x, + ^^^^ TT_Pos* y, + TT_Matrix* matrix ); + + Applies a 2x2 matrix to a vector. + + .................................................................. + + int TT_Get_CharMapCount( TT_Face face ); + ^^^ + + Gets the number of character mappings present in the TrueType + file described by the `face' handle. Returns -1 if the handle + is invalid. + + IMPORTANT NOTE: ******** + + This function is deprecated. Get the number of character maps + from the `num_CharMaps' field in the structure returned by + TT_Get_Face_Property() instead. + + .................................................................. + + TT_Get_CharMap_ID( TT_Face face, + TT_UShort charmapIndex, + TT_UShort* platformID, + TT_UShort* encodingID ); + + Returns the platform ID and platform-specific encoding ID for + the charmap numbered `charmapIndex' in the `face' object. The + total number of character mapping tables can be found in the + `num_CharMaps' field in the structure returned by + TT_Get_Face_Property(). + + .................................................................. + + TT_Get_CharMap( TT_Face face, + TT_UShort charmapIndex, + TT_CharMap* charMap ); + + Returns a handle for the character map number `charmapIndex' of + `face'. The handle is placed in `*charMap' and can be used + later for fast lookup with the TT_Char_Index() API function. + + Charmap objects are automatically destroyed when their face + object is destroyed. + + .................................................................. + + TT_UShort TT_Char_Index( TT_CharMap charMap, + ^^^^^^^^^ TT_UShort charCode ); + + Applies a charMap to translate `charCode' into a glyph index + that can be used to load and address a glyph in the TrueType + file. In case of error, the undefined glyph (index 0) is + returned. + + The charmap handle can be obtained with TT_Get_CharMap(). + + .................................................................. + + int TT_Get_Name_Count( TT_Face face ); + ^^^ + + Gets the number of name strings found in a face's name table. + This function will return -1 if the face handle is invalid. + + IMPORTANT NOTE: ******** + + This function is deprecated. Get the number of name strings + from the `num_Names' field in the structure returned by + TT_Get_Face_Property() instead. + + .................................................................. + + TT_Get_Name_ID( TT_Face face, + TT_UShort nameIndex, + TT_UShort* platformID, + TT_UShort* encodingID, + TT_UShort* languageID, + TT_UShort* nameID ); + + Returns the ID of a given name string, indexed by the number + `nameIndex' in a given face. The name index ranges from 0 to + `num_names' minus one; this value can be found in the structure + returned by TT_Get_Face_Property(). + + Each string has a `platformID', `encodingID', `languageID' and + `nameID', as defined by the TrueType specification. + + The platformID is typically in the range [0,3]. Some font files + have unusual name table entries; these can be detected from + their platformID which is larger than 3. + + .................................................................. + + TT_Get_Name_String( TT_Face face, + TT_UShort nameIndex, + TT_String** stringPtr, + TT_UShort* length ); + + Returns a name string's address and length. Note that an + invalid name table entry always returns NULL for `stringPtr' and + zero for `length'. + + NOTE 1: + + The string belongs to the face object and should not be + written to or freed by the client application. + + NOTE 2: + + The library does not care about endianess here! If you are + using a little-endian machine and you have to interpret the + string bytes as 16-bit-wide characters (e.g. Unicode encoded), + you must byte-swap the data because 16-bit data is stored as + big-endian in TrueType fonts, and FreeType reads in the whole + name table bytewise. + + .................................................................. + + TT_Get_Font_Data( TT_face face, + TT_Long tag, + TT_Long offset, + void* buffer, + TT_Long* length ); + + Gets font or table data. Similar to the GetFontData() API of + the Windows world. You can use the macro MAKE_TT_TAG() to + generate TrueType table tags from character descriptions, like + + MAKE_TT_TAG( 'e', 'b', 'l', 'c' ) + + Use the value 0 instead for `tag' if you want to access the + whole font file. `offset' specifies the starting offset in the + table (or the offset in the file if tag == 0), `buffer' the + address of target buffer. + + Depending on the value of length, various actions are performed. + If `length' is NULL, the whole table will be loaded. An error + will be returned if `offset' is not 0. If `*length' is zero, + TT_Get_Font_Data() exits immediately, returning only the length + of the given table (in the variable `length'), or of the font + file, depending on the value of `tag'. Finally, if `*length' is + not zero, the next `length' bytes of the table (resp. the font) + are loaded into an array pointed to by `buffer', starting at + offset `offset'. Note that the `buffer' array must be large + enough to hold `length' bytes. + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +III. Error Messages +=================== + + Most functions return an error code, typed to TT_Error. A return + value of zero indicates no error. The error values are defined in + the file `freetype.h'. In the following table, the prefix + `TT_Err_' is omitted, e.g. `Ok' -> `TT_Err_Ok'. + + + Error Unprefixed Error + Code Macro Name Description + ------------------------------------------------------------------ + + 0x0000 Ok Successful function call. + Always 0! + + ----------------- high-level API error codes --------------------- + + The following error codes are returned by the high-level API to + indicate an invalid client request. + + 0x0001 Invalid_Face_Handle An invalid face object handle was + passed to an API function. + + 0x0002 Invalid_Instance_Handle An invalid instance object handle + was passed to an API function. + + 0x0003 Invalid_Glyph_Handle An invalid glyph container handle + was passed to an API function. + + 0x0004 Invalid_CharMap_Handle An invalid charmap handle was + passed to an API function. + + 0x0005 Invalid_Result_Address An output parameter (a result) + was given a NULL address in an + API call. + + 0x0006 Invalid_Glyph_Index An invalid glyph index was passed + to an API function. + + 0x0007 Invalid_Argument An invalid argument was passed to + an API function. Usually, this + means a simple out-of-bounds + error. + + 0x0008 Could_Not_Open_File The pathname passed doesn't point + to an existing or accessible + file. + + 0x0009 File_Is_Not_Collection Returned by TT_Open_Collection + while trying to open a file which + isn't a collection. + + 0x000A Table_Missing The requested TrueType table is + missing in the font file. + + 0x000B Invalid_Horiz_Metrics The font's HMTX table is invalid. + Denotes a broken font. + + 0x000C Invalid_CharMap_Format A font's charmap entry has an + invalid format. Some other + entries may be valid though. + + 0x000D Invalid_PPem Invalid PPem values specified, + i.e., you are accessing a scaled + glyph without having called + TT_Set_Instance_CharSize() or + TT_Set_Instance_PixelSizes(). + + 0x0010 Invalid_File_Format The file isn't a TrueType font or + collection. + + 0x0020 Invalid_Engine An invalid engine handle was + passed to one of the API + functions. + + 0x0021 Too_Many_Extensions The client application is trying + to initialize too many + extensions. The default max + extensions number is 8 (this + value can be changed at compile + time). + + 0x0022 Extensions_Unsupported This build of the engine doesn't + support extensions. + + 0x0023 Invalid_Extension_Id This error indicates that the + client application is trying to + use an extension that has not + been initialized yet. + + 0x0080 Max_Profile_Missing The max profile table is missing. + => broken font file + + 0x0081 Header_Table_Missing The font header table is missing. + => broken font file + + 0x0082 Horiz_Header_Missing The horizontal header is missing. + => broken font file + + 0x0083 Locations_Missing The locations table is missing. + => broken font file + + 0x0084 Name_Table_Missing The name table is missing. + => broken font file + + 0x0085 CMap_Table_Missing The character encoding tables are + missing. + => broken font file + + 0x0086 Hmtx_Table_Missing The hmtx table is missing. + => broken font file + + 0x0087 OS2_Table_Missing The OS/2 table is missing. + Mac fonts doesn't have it. + + 0x0088 Post_Table_Missing The PostScript table is missing. + => broken font file + + 0x0089 Glyf_Table_Missing The glyph table is missing. + => broken font file + + ----------------- memory component error codes ------------------- + + 0x0100 Out_Of_Memory An operation couldn't be + performed due to memory + exhaustion. + + ----------------- file component error codes --------------------- + + 0x0200 Invalid_File_Offset Trying to seek to an invalid + portion of the font file. + Denotes a broken file. + + 0x0201 Invalid_File_Read Trying to read an invalid portion + of the font file. Denotes a + broken file. + + 0x0202 Invalid_Frame_Access Trying to frame an invalid + portion of the font file. + Denotes a broken file. + + ----------------- glyph loader error codes ----------------------- + + These errors are produced by the glyph loader. They denote an + invalid glyph record within the font file. + + 0x0300 Too_Many_Points The glyph has too many points to + be valid for its font file. + + 0x0301 Too_Many_Contours The glyph has too many contours + to be valid for its font file. + + 0x0302 Invalid_Composite_Glyph A composite glyph's description + is broken. + + 0x0303 Too_Many_Ins The glyph has too many + instructions to be valid for its + font file. + + ----------------- byte-code interpreter error codes -------------- + + These error codes are produced by the TrueType byte-code + interpreter. They usually indicate a broken font file or a broken + glyph within a font. + + 0x0400 Invalid_Opcode Found an invalid opcode in a + TrueType byte-code stream. + + 0x0401 Too_Few_Arguments An opcode was invoked with too + few arguments on the stack. + + 0x0402 Stack_Overflow The interpreter's stack has been + filled up and operations can't + continue. + + 0x0403 Code_Overflow The byte-code stream runs out of + its valid bounds. + + 0x0404 Bad_Argument A function received an invalid + argument. + + 0x0405 Divide_By_Zero A division by 0 operation was + queried by the interpreter + program. + + 0x0406 Storage_Overflow The program tried to access data + outside of its storage area. + + 0x0407 Cvt_Overflow The program tried to access data + outside of its control value + table. + + 0x0408 Invalid_Reference The program tried to reference an + invalid point, zone, or contour. + + 0x0409 Invalid_Distance The program tried to use an + invalid distance. + + 0x040A Interpolate_Twilight The program tried to interpolate + twilight points. + + 0x040B Debug_Opcode The now invalid `debug' opcode + was found in the byte-code + stream. + + 0x040C ENDF_In_Exec_Stream A misplaced ENDF was encountered + in the byte-code stream. + + 0x040D Out_Of_CodeRanges The program tried to allocate too + much code ranges (this is really + an engine internal error that + should never happen). + + 0x040E Nested_DEFS Nested function definitions + encountered. + + 0x040F Invalid_CodeRange The program tried to access an + invalid code range. + + 0x0410 Invalid_Displacement The program tried to use an + invalid displacement. + + 0x0411 Execution_Too_Long In order to get rid of `poison' + fonts, the interpreter produces + this error if more than one + million opcodes have been + interpreted in a single glyph + program. This detects infinite + loops softly. + + ----------------- internal failure error codes ------------------- + + These error codes are produced if an incoherent library state has + been detected. All of these reflect a severe bug in the engine + (or a severe memory corruption due to massive overwrites by your + application into the library's data)! + + If you do encounter a font that makes one of the test programs + produce such an error, please report it! + + 0x0500 Nested_Frame_Access + 0x0501 Invalid_Cache_List + 0x0502 Could_Not_Find_Context + 0x0503 Unlisted_Object + + ----------------- scan-line converter error codes ---------------- + + These error codes are produced by the raster component. They + indicate that an outline structure was incoherently set up, or + that you are trying to render a horribly complex glyph. + + They should be _extremely_ rare, however. + + 0x0600 Raster_Pool_Overflow Render pool overflow. This should + never happen in this release. + + 0x0601 Raster_Negative_Height A negative height was produced. + + 0x0602 Raster_Invalid_Value The outline data wasn't set + properly. Check that: + points >= endContours[contours] + + 0x0603 Raster_Not_Initialized You did not call + TT_Init_FreeType()! + + +--- end of apiref.txt --- diff --git a/docs/apirefx.txt b/docs/apirefx.txt new file mode 100644 index 0000000..c2d1f44 --- /dev/null +++ b/docs/apirefx.txt @@ -0,0 +1,864 @@ + The FreeType Engine + + Extension Library Reference + + + ----------------------------------- + + + Table of Contents: + + I. Engine extensions + 1. kerning (ftxkern) + 2. PostScript names (ftxpost) + 3. TrueType Open (ftxopen) + a. The `BASE' table (baseline data) + b. The `GDEF' table (glyph definitions) + c. The `GPOS' table (glyph positions) + d. The `GSUB' table (glyph substitions) + e. The `JSTF' table (justification data) + f. auxiliary functions + 4. embedded bitmaps (ftxsbit) + + II. API extensions + 1. cmap iteration (ftxcmap) + 2. internationalized error messages (ftxerr18) + 3. access to the `gasp' table (ftxgasp) + 4. fast retrieval of glyph widths and heights (ftxwidth) + + III. Error codes + + + -------------------- + + +Please read the file `user.txt' for an introduction into FreeType's +extension mechanism and the difference between engine and API +extensions. + + +I. Engine extensions +==================== + +To use engine extensions you have to compile the library with the +macro TT_CONFIG_OPTION_EXTEND_ENGINE. By default, this macro is set +and all engine extensions are linked to the FreeType library. + + + 1. kerning (ftxkern) + -------------------- + + TT_Init_Kerning_Extension( TT_Engine engine ) + + Initializes the kerning extension for a given engine. This must + be called just after the engine creation, and before any face + object allocation. Example: + + TT_Init_FreeType( &engine ); + TT_Init_Kerning_Extension( engine ); + + .................................................................. + + TT_Get_Kerning_Directory( TT_Face face, + TT_Kerning* directory ) + + Queries the kerning directory found in a face object. If no + kerning table is found in the TrueType file, the error + TT_Err_Table_Is_Missing will be returned. + + You can access the subtables through the pointers of the + directory. However, by default, the directory is only loaded if + a face object is created. You must load the subtables that + interest you with a call to TT_Load_Kerning_Table(). + + The layout of all kerning structures is defined in the file + `lib/extend/ftxkern.h'. Formats 0 and 2 (as defined in the + Microsoft TrueType specification) are exposed by this API. + + NOTE: + + This function must be called after the kerning extension has + been initialized. + + .................................................................. + + TT_Load_Kerning_Table( TT_Face face, + TT_UShort kernIndex ) + + Loads the kerning subtable number `kern_index' into memory. The + subtable can be accessed through the pointers provided by the + kerning directory, obtained from a call to the function + TT_Get_Kerning_Directory(). + + Note that the interpretation of the kerning data is left to the + client application. Read the TrueType specification for more + information on kerning encoding. + + NOTE 1: + + This function must be called after the kerning extension were + initialized. + + NOTE 2: + + An example can be found in the file `test/ftstrtto.c'. + + +==================================================================== + + + 2. PostScript names (ftxpost) + ----------------------------- + + TT_Init_Post_Extension( TT_Engine engine ) + + Initializes the PostScript name extension to load the PostScript + glyph names given in the `post' table. This must be called just + after creation of the engine, and before any face object + allocation. See description of TT_Get_PS_Name() for an example. + + .................................................................. + + TT_Load_PS_Names( TT_Face face, + TT_Post* post ) + + Loads the PostScript glyph names into memory. This must be done + before TT_Get_PS_Name() is called. In case of error, either + TT_Err_Invalid_Post_Table or TT_Err_Invalid_Post_Table_Format is + returned. See description of TT_Get_PS_Name() for an example. + + .................................................................. + + TT_Get_PS_Name( TT_Face face, + TT_UShort index, + TT_String** PSname ) + + Get the PostScript glyph name for a given glyph index. A + pointer to the name is returned in `PSname'. Example: + + ... + TT_Post post; + char* PSname; + + ... + TT_Init_Post_Extension( engine ); + TT_Load_PS_Names( face, &post ); + + ... + TT_Get_PS_Name( face, index, &PSname ); + + + NOTE: + + You must not alter the PostScript glyph name string returned + in `PSname'. + + +==================================================================== + + + 3. TrueType Open (ftxopen) + -------------------------- + + Please note that TrueType Open specific error codes have the + prefix `TTO_Err_' instead of `TT_Err_'. + + a. The `BASE' table (baseline data) + + Not yet supported. + + b. The `GDEF' table (glyph definitions) + + TT_Init_GDEF_Extension( TT_Engine engine ) + + Initializes the GDEF extension to load the glyph definition + data given in the `GDEF' table. This must be called just + after creation of the engine, and before any face object + allocation. See the file `ftstrtto.c' for an example. + + ................................................................ + + TT_Load_GDEF_Table( TT_Face face, + TTO_GDEFHeader* gdef ) + + Loads the GDEF table into `gdef' for a given face `face'. + This must be done before any queries about glyph properties + with TT_GSUB_Get_Property(). Returns TT_Err_Table_Missing if + there is no GDEF table in the font. + + ................................................................ + + TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef, + TT_UShort glyphID, + TT_UShort* property ) + + Use this function to get glyph properties in the variable + `property' for the glyph with index `glyphID' stored in the + `gdef' table. This data is essential for many fonts to + correctly apply contextual substitution (both GSUB and GPOS). + As a special case, zero is assigned to `property' if `gdef' is + NULL or the glyph has no special glyph property assigned to + it. The other return values of `property' are TTO_BASE, + TTO_LIGATURE, TTO_MARK, and TTO_COMPONENT; you can directly + apply the `LookupFlag' mask to check for certain properties: + + TTO_GDEFHeader* gdef; + TTO_Lookup* lo; + TT_UShort glyph_ID; + TT_UShort p; + + + TT_GDEF_Get_Property( gdef, glyph_ID, &p ); + + if ( p & lo->LookupFlag ) + return TTO_Err_Not_Covered; + + Usually, you don't need to take care of glyph properties by + yourself since TT_GSUB_Apply_String() will do this for you by + calling TT_GDEF_Get_Property(). + + Some fonts need GDEF-like data even if no GDEF table is + provided (for example, the Arabic script needs information + which glyphs are base glyphs and which are mark glyphs). In + such cases, you should use TT_GDEF_Build_ClassDefinition() to + build the necessary structures so that TT_GDEF_Get_Property() + returns meaningful values. + + See also TT_Load_GSUB_Table() and TT_Load_GPOS_Table(). + + ................................................................ + + TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef, + TT_UShort num_glyphs, + TT_UShort glyph_count, + TT_UShort* glyph_array, + TT_UShort* class_array ) + + Fills a `gdef' structure with data to make + TT_GDEF_Get_Property() work in case no GDEF table is + available. `num_glyphs' is the number of glyphs in the font. + + `glyph_count' is the number of glyphs resp. class values (as + specified in the GDEF specification) given in the arrays + `glyph_array' and `class_array', respectively. The glyph + indices in `glyph_array' must be all different and sorted in + ascending order; the function expects that glyph index + `glyph_array[n]' has its class value in `class_array[n]'. + + Note that mark attach classes as defined in OpenType 1.2 are + not supported for constructed GDEF tables. + + See `arabic.c' for an example. + + + c. The `GPOS' table (glyph positions) + + Not yet supported. + + + d. The `GSUB' table (glyph substitions) + + For glyph substitution, a string object of type TTO_GSUB_String + is used. The field `length' holds the length of the string, + `pos' points to the actual position in the glyph string `string' + (for input strings) resp. the position where the substituted + glyphs should be placed at (for output strings). + + Within the `properties' array (which must always have the same + length as `string' if set), you can define properties for glyphs + -- `string[n]' is associated with `properties[n]'. The idea is + that some features apply to specific glyphs only. As an + example, the `fina' feature for Arabic applies only to glyphs + which appear at the end of a word (strictly speaking, this + feature is used only for glyphs which have a `final' property; + such glyphs can occur in the middle of a word also under certain + circumstances which is dependent on Arabic script rules). The + relationship between properties and features can be set up with + the function TT_GSUB_Add_Feature(). If `properties' is set to + NULL, all selected features apply to all glyphs in the given + string object. If `properties' is non-NULL, the elements of the + array are treated as bit fields. A set flag means that the + corresponding feature (as set with the TT_GSUB_Add_Feature() + function) should not be applied to the particular glyph. As a + consequence, a zero value for these 16 bits means that all + features should be applied, and a value of 0xFFFF implies that + no feature at all should be used for the glyph. + + The field `allocated' is for internal use only and must not be + modified. If its value is larger than zero, you should use + free() to deallocate the memory used by `string' (and + `properties' if set) in case you want to destroy a + TTO_GSUB_String object (memory for `string' and `properties' is + allocated automatically e.g. by TT_GSUB_Apply_String() for + output string objects). + + struct TTO_GSUB_String_ + { + TT_ULong length; + TT_ULong pos; + TT_ULong allocated; + TT_UShort* string; + TT_UShort* properties; + }; + + typedef struct TTO_GSUB_String_ TTO_GSUB_String; + + Note that the `string' field must contain glyph indices, not + character codes. + + For initializing an input string object, you should set the + `length', `string', and `properties' fields (the last one only + if necessary) to appropriate values. `pos' has to be set to the + position where the substitution lookups should start (usually + zero). The `allocated' field will be ignored. + + For initializing an output string object, all fields (except + `length' which will be ignored) must be set to zero. If you + want to reuse the object, set `pos' to the position where the + substituted glyphs should be placed at (usually zero), but don't + touch the `allocated', `string', and `properties' fields. + + ................................................................ + + TT_Init_GSUB_Extension( TT_Engine engine ) + + Initializes the GSUB extension to load the glyph substitution + data given in the `GSUB' table. This must be called just + after creation of the engine, and before any face object + allocation. See the files `ftstrtto.c' and `ftdump.c' for + detailed examples. + + ................................................................ + + TT_Load_GSUB_Table( TT_Face face, + TTO_GSUBHeader* gsub, + TTO_GDEFHeader* gdef ) + + Loads the GSUB table into `gsub' for a given face `face'. + This must be done before any queries about or selection of + scripts, languages, and features. Returns + TT_Err_Table_Missing if there is no GSUB table in the font. + + `gdef' should contain a pointer to an associated GDEF table, + either a native one loaded with TT_Load_GDEF_Table() or + emulated with TT_GDEF_Build_ClassDefinition(). If `gdef' is + set to NULL, no GDEF data will be used. + + ................................................................ + + TT_GSUB_Select_Script( TTO_GSUBHeader* gsub, + TT_ULong script_tag, + TT_UShort* script_index ) + + This function sets the script index of a given script tag + `script_tag' in the variable `script_index' for the GSUB table + `gsub'. Returns TTO_Err_Not_Covered if the script tag cannot + be found. The available script tags can be queried with the + function TT_GSUB_Query_Scripts(). + + ................................................................ + + TT_GSUB_Select_Language( TTO_GSUBHeader* gsub, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ) + + This function sets the language index of a given language tag + `language_tag' and script index `script_index' in the variable + `language_index' for the GSUB table `gsub'. Returns + TTO_Err_Not_Covered if the language tag cannot be found. The + available language tags can be queried with the function + TT_GSUB_Query_Languages(). + + Additionally, the index of the required feature for this + language system is returned in `req_feature_index'; it must be + later registered for use with TT_GSUB_Add_Feature(). + + ................................................................ + + TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ) + + This function sets the feature index of a feature tag + `feature_tag', script index `script_index', and language index + `language_index' in the variable `feature_index' for the GSUB + table `gsub'. Returns TTO_Err_Not_Covered if the feature tag + cannot be found. The available feature tags can be queried + with the function TT_GSUB_Query_Features(). Setting + language_index to 0xFFFF selects the default language system. + + ................................................................ + + TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub, + TT_ULong** script_tag_list ) + + Returns the available script tags for a given GSUB table + `gsub' in the array `script_tag_list'. The array can be later + deallocated with free(). + + ................................................................ + + TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_ULong** language_tag_list ) + + Returns the available language tags for a given GSUB table + `gsub' and script index `script_index' in the array + `language_tag_list'. The array can be later deallocated with + free(). + + ................................................................ + + TT_GSUB_Query_Features( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ) + + Returns the available feature tags for a given GSUB table + `gsub', script index `script_index', and language index + `language_index' in the array `feature_tag_list'. If language + index is set to 0xFFFF, the values for the default language + system are returned. The array can be later deallocated with + free(). + + ................................................................ + + TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub, + TT_UShort feature_index, + TT_UShort property ) + + To prepare a call to TT_GSUB_Apply_String() which should + process a given feature with index `feature_index' and the + property `property', you must use this function. Its task is + to mark the lookup tables used by the feature for further + processing. + + `property' defines a relationship between the input string + object and the specific feature. The client must handle this + variable as a bit field, i.e., up to 16 user properties can be + defined. If `property' is set to ALL_GLYPHS (0xFFFF, the only + predefined value), or if the input string object has no set + bits in the `properties' field, the feature applies to all + glyphs. If bit `x' is set in `property', the feature applies + only to glyphs which have bit `x' not set in glyph's + `properties' field in the input string object. See + TT_GSUB_Apply_String() for an example. + + Returns TT_Err_Invalid_Argument in case of error. + + ................................................................ + + TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub ) + + Clears the list of used features and properties. No lookup + tables will be processed. + + ................................................................ + + TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub, + TTO_AltFunction alt, + void* data ) + + Installs a callback function to handle alternate + substitutions. `data' is a generic pointer to a user-defined + structure which will be completely ignored by the ftxopen + extension. `alt' is a function pointer defined as + + typedef TT_UShort + (*TTO_AltFunction)(TT_ULong pos, + TT_UShort glyphID, + TT_UShort num_alternates, + TT_UShort* alternates, + void* data ); + + If TT_GSUB_Apply_String() encounters an alternate lookup while + processing the input string, it will call the function `alt' + to find out which alternate glyph it should use. `pos' gives + the position in the string, `glyphID' the glyph ID of the + glyph to be replaced with an alternate glyph, and + `num_alternates' the number of alternate glyphs in the + `alternates' array. A pointer to the user-defined `data' + structure is also available. `alt' must return an index into + `alternates'. + + If `alt' is NULL or if this function isn't called at all, + TT_GSUB_Apply_String() will always use the first alternate + glyph. + + Please note that theoretically an alternate lookup can happen + during any other lookup! For example, a lookup chain like + + single subst -> alternate subst -> ligature subst + + *is* possible (albeit rather unlikely). Thus be warned that + `pos' does not necessarily reflect the position of a glyph to + be displayed at all, nor does `glyphID' specifies a glyph + which will be in the final output string. + + ................................................................ + + TT_GSUB_Apply_String( TTO_GSUBHeader* gsub, + TTO_GSUB_String* in, + TTO_GSUB_String* out ) + + This is the very function which handles glyph substitution + according to the features set up with TT_GSUB_Add_Feature(), + using both GSUB and GDEF data (if defined). Two + TTO_GSUB_String objects `in' and `out' (as described above) + are taken for input and output; after successful excecution, + the converted glyph string can been found in `out', and + `out.length' gives the actual length of the output string + (counted from the begin of the array). + + Example: + + /* We assume that the feature `xxxx' has index 5, and */ + /* feature `yyyy' has index 8, applying only to glyphs */ + /* with the property `FINAL_GLYPHS' set (0x1000 is an */ + /* ad-hoc value just for this example). */ + + /* The order of calls to TT_GSUB_Add_Feature() is not */ + /* significant. */ + + #define FINAL_GLYPHS 0x1000 + + TT_GSUB_Clear_Features( &gsub ); + TT_GSUB_Add_Feature( &gsub, 8, FINAL_GLYPHS ); + TT_GSUB_Add_Feature( &gsub, 5, ALL_GLYPHS ); + + TT_GSUB_Apply_String( &gsub, &in, &out ); + + You must initialize both `in' and `out' structures; allocation + necessary for the `out' object will be handled automatically. + + In case you don't register a function to handle alternate + substitutions (GSUB lookup 3), always the first alternate + glyph will be used. See TT_GSUB_Register_Alternate_Function() + above for more details. + + + e. The `JSTF' table (justification data) + + Not yet supported. + + + f. auxiliary functions + + TT_GSUB_Add_String( TTO_GSUB_String* in, + TT_UShort num_in, + TTO_GSUB_String* out, + TT_UShort num_out, + TT_UShort* data ) + + This function copies `num_out' elements from `data' to `out', + advancing the array pointer `in.pos' by `num_in' elements and + `out.pos' by `num_out' elements. If the string (resp. the + properties) array in `out' is empty or too small, it allocates + resp. reallocates the string (and properties) array. + Finally, it sets `out.length' equal to `out.pos'. + + The properties for all replaced glyphs are taken from the + glyph at position `in->pos'. + + TT_GSUB_Add_String() is normally used in + TT_GSUB_Apply_String(); you will need it for the special case + to skip some glyphs (i.e., copy glyphs directly from the `in' + to the `out' object), bypassing a possible GSUB substitution. + + Here an example which copies one glyph: + + TT_GSUB_Add_String( in, 1, + out, 1, + &in->string[in->pos] ); + + +==================================================================== + + + 4. embedded bitmaps (ftxsbit) + ----------------------------- + + TT_Init_SBit_Extension( TT_Engine engine ) + + Initializes the embedded bitmap extension to load the bitmap + glyphs given in the various sbit tables: `EBLC', `bloc', `EBDT', + and `bdat' (`bloc' and `bdat' tables are only in Apple fonts; + the former is equivalent to `EBLC', the latter equivalent to + `EBDT'). This must be called just after creation of the engine, + and before any face object allocation. See description of + TT_Load_Glyph_Bitmap() for an example. + + .................................................................. + + TT_Get_Face_Bitmaps( TT_Face face, + TT_EBLC* eblc_table ) + + Loads the `EBLC' (resp. `bloc') table from a font file into the + `eblc_table' structure. Use this function for testing whether + embedded bitmaps are available or not. + + This function returns TT_Err_Table_Missing if the font contains + no embedded bitmaps. All fields in `eblc_table' will then be + set to 0. + + .................................................................. + + TT_New_SBit_Image( TT_SBit_Image** image ) + + Allocates a new embedded bitmap container, pointed to by + `image'. + + .................................................................. + + void TT_Done_SBit_Image( TT_SBit_Image* image ) + ^^^^ + + Releases the embedded bitmap container `image'. + + .................................................................. + + TT_Get_SBit_Strike( TT_Face face, + TT_Instance instance, + TT_SBit_Strike* strike ) + + Loads a suitable strike (i.e. bitmap sizetable) for the given + instance. Will return TT_Err_Invalid_PPem if there is no strike + for the current x_ppem and y_ppem values. + + .................................................................. + + TT_Load_Glyph_Bitmap( TT_Face face, + TT_Instance instance, + TT_UShort glyph_index, + TT_SBit_Image* bitmap ); + + Loads a glyph bitmap for a given glyph index `glyph_index' (in + face `face' and instance `instance') into `bitmap'. It calls + TT_Get_SBit_Strike() internally for checking the current x_ppem + and y_ppem values. + + This function returns an error if there is no embedded bitmap + for the glyph at the given instance. + + Example (omitting the error handling): + + ... + TT_SBit_Image* bitmap; + + ... + TT_Init_SBit_Extension( engine ); + TT_New_SBit_Image( &bitmap ); + ... + TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); + + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +II. API extensions +================== + +To use API extensions, simply compile the specific extension file +and link it to the library or your program. By default, all +extensions described below are linked to the library. + + + 1. cmap iteration (ftxcmap) + --------------------------- + + TT_Long TT_CharMap_First( TT_CharMap charMap, + ^^^^^^^ TT_UShort* glyph_index ) + + + Returns the first valid character code in a given character map + `charMap'. Also returns the corresponding glyph index (in the + parameter `*glyph_index'). In case of failure, -1 is returned, + and `*glyph_index' is undefined. + + .................................................................. + + TT_Long TT_CharMap_Next( TT_CharMap charMap, + ^^^^^^^ TT_UShort last_char, + TT_UShort* glyph_index ) + + Returns the next valid character code in a given character map + `charMap' which follows `last_char'. Also returns the + corresponding glyph index (in the parameter `*glyph_index'). In + case of failure, -1 is returned, and `glyph_index' is undefined. + + .................................................................. + + TT_Long TT_CharMap_Last( TT_CharMap charMap, + ^^^^^^^ TT_UShort* glyph_index ) + + + Returns the last valid character code in a given character map + `charMap'. Also returns the corresponding glyph index (in the + parameter `*glyph_index'). In case of failure, -1 is returned, + and `*glyph_index' is undefined. + + +==================================================================== + + + 2. internationalized error messages (ftxerr18) + ---------------------------------------------- + + This extension provides internationalized error strings from the + various error messages. It uses the `gettext' package if + available or returns English/American message strings if not. + Currently, the gettext package is only available on UNIX-like + systems like Linux; this means that for other platforms only + English error strings are returned. + + If the gettext package is found on your system, the configure + script automatically includes it by default. In case you don't + want to use it, or if you encounter some problems compiling this + file, try to disable nls support by configuring FreeType with + `./configure --disable-nls'. + + Please read the gettext info files for more information how to set + up your system for internationalized messages. A short + introduction is also given in the file `i18n.txt'. + + + TT_String* TT_ErrToString18( TT_Error i ) + ^^^^^^^^^^ + + This function returns an error string for a given error code + `i'. The type `TT_String' usually defaults to `char'; see + apiref.txt for more details. + + An example how to use this function (in connection with the + gettext interface) is given e.g. in test/ftdump.c. + + +==================================================================== + + + 3. access to the `gasp' table (ftxgasp) + --------------------------------------- + + The `gasp' table is currently loaded by the core engine, but the + standard API doesn't give access to it. + + + TT_Get_Face_Gasp_Flags( TT_Face face, + TT_UShort point_size, + TT_Bool* grid_fit, + TT_Bool* smooth_font ) + + This function returns for a given `point_size' the values of the + gasp flags `grid_fit' and `smooth_font'. The returned values + are booleans (where 0 = NO, and 1 = YES). + + Note that this function will return TT_Err_Table_Missing if the + font file doesn't contain any gasp table. + + +==================================================================== + + + 4. fast retrieval of glyph widths and heights (ftxwidth) + -------------------------------------------------------- + + This extension is used to parse the `glyf' table of a TrueType + file in order to extract the bounding box of a given range of + glyphs. + + The bounding box is then used to build font unit widths and + heights that are returned in two parallel arrays. + + This extension is needed by the FreeType/2 OS/2 Font Driver. + + + TT_Get_Face_Widths( TT_Face face, + TT_UShort first_glyph, + TT_UShort last_glyph, + TT_UShort* widths, + TT_UShort* heights ) + + Returns the widths (in array `widths') and heights (in array + `heights') of a glyph range which starts at `first_glyph' and + ends at `last_glyph'. All returned values are returned in font + units. If either `widths' or `heights' is set to a NULL + pointer, no data will be returned for that particular array. + + Note: TT_Get_Face_Widths() does *not* allocate the two arrays! + + + +-------------------------------------------------------------------- +-------------------------------------------------------------------- + + + +III. Error Messages +=================== + + Most functions return an error code, typed to TT_Error. A return + value of zero indicates no error. The error values are defined in + the various extension header files (e.g. ftxkern.h). In the + following table, the prefix `TT_Err_' is omitted, e.g. `Ok' -> + `TT_Err_Ok'. + + + Error Unprefixed Error + Code Macro Name Description + ------------------------------------------------------------------ + + 0x0A00 Invalid_Kerning_Table_Format + An invalid kerning subtable + format was found in this font. + + 0x0A01 Invalid_Kerning_Table A kerning table contains illegal + glyph indices. + + 0x0B00 Invalid_Post_Table_Format + The post table format specified + in the font is invalid. + + 0x0B01 Invalid_Post_Table The post table contains illegal + entries. + + + Here the TrueType Open error codes. In the following table, the + prefix `TTO_Err_' is omitted. + + + Error Unprefixed Error + Code Macro Name Description + ------------------------------------------------------------------ + 0x1000 Invalid_SubTable_Format The TrueType Open subtable format + specified in the font is invalid. + + 0x1001 Invalid_SubTable A TrueType Open subtable contains + illegal entries. + + 0x1002 Not_Covered The requested feature, glyph, + etc. isn't covered by the actual + function. + + 0x1010 Invalid_GSUB_SubTable_Format + The GSUB subtable format + specified in the font is invalid. + + 0x1011 Invalid_GSUB_SubTable The GSUB subtable contains + illegal entries. + + 0x1020 Invalid_GPOS_SubTable_Format + The GPOS subtable format + specified in the font is invalid. + + 0x1021 Invalid_GPOS_SubTable The GPOS subtable contains + illegal entries. + + +--- end of apirefx.txt --- diff --git a/docs/bitmaps.txt b/docs/bitmaps.txt new file mode 100644 index 0000000..847befe --- /dev/null +++ b/docs/bitmaps.txt @@ -0,0 +1,771 @@ + + Bitmap and Pixmap generation with FreeType + ------------------------------------------ + + Table of Contents + + + Introduction + + I. The rasterizer component + + II. Bitmap & pixmap descriptors + + III. Rendering an outline + + IV. Anti-aliasing palette and other concerns + + Conclusion + + + +Introduction +------------ + + This document describes the steps that are needed to render a + glyph outline into a bitmap or a pixmap with the FreeType library. + It contains several important details needed to generate bitmaps + correctly in all situations, including if an outline has been + transformed or translated. + + +-------------------------------------------------------------------- + + +I. The rasterizer component +--------------------------- + + In FreeType, the component in charge of performing bitmap and + pixmap rendering is called the `rasterizer'. Generation is + performed through a traditional process called `scan-line + conversion', but exhibits certain properties: + + - The rasterizer doesn't allocate bitmaps: + + In fact, it is only able to render an outline into an existing + bitmap or pixmap, which is passed to one of its rendering + functions. This means that the target bitmap/pixmap must be set + up correctly by the caller to achieve desired results. Setting + up bitmap and pixmap descriptors is explained in section II. + + - It is able to render anti-aliased pixmaps directly: + + This is unlike other graphics packages, which render to a + `large' bitmap which is then filtered down. Putting the + anti-aliasing logic within the rasterizer improves performance + and reduces memory usage, as well as lets us use better + algorithms which couldn't work in a `two-phase' process. + + The rasterizer is located in the files `ttraster.h' and + `ttraster.c' (or `ttraster.pas' for the Pascal version -- + unfortunately, this is severely out of date). + + The format of outlines isn't important for most developers and + won't be discussed here. However, a few conventions must be + explained regarding the vector outlines: + + + 1. Units + + All point coordinates within an outline are stored in 32-bit + fractional pixel values, using the 26.6 fixed float format + (which uses 26 bits for the integer part, and 6 bits for the + fractional part). The following table gives some examples of + real versus 26.6 coordinates: + + ----------------------------------------- + real real coord 26.6 coord + coord. * 2^6 + ----------------------------------------- + 0 0*64 = 0.0 0 + 2.4 2.4*64 = 153.6 154 + 3 3*64 = 192.0 192 + -1.7 -1.7*64 = -108.8 -109 + + As you can see, conversion is relatively simple -- basically a + multiplication by 64. + + In order to differentiate coordinates expressed in real or 26.6 + systems, we'll use in the following lines brackets (`[' and `]') + for real coordinates, and simple parentheses (`(' and `)') for + fractional coordinates so that + + [1.0,2.5] equals (64,160) + + [0,0] equals (0,0) + + [-2,3] equals (-128,192) + + + 2. Orientation + + The rasterizer uses the traditional convention of an X axis + oriented from left to right, and of a Y axis oriented from + bottom to top. + + ^ Y + | + | + | + -*-----> X + | + + You've probably already used it at school when doing math :-) + + Though the orientation of bitmap lines has the opposite + direction on nearly all graphics systems, the former convention + is the _right_ one when it comes to vector graphics. The reason + is simply that for managing angles and vector cross-products + resp. orientations in complex algorithms, a single convention, + used in math as well as computing alike solves many headaches. + + And due to education, most people expect a 45 degrees angle to + be in the top right quadrant, at coordinate (1,1). + + + 3. Pixels and the grid + + In a vector outline, a point is immaterial and has no size or + width, just like in usual geometry. A `pixel' is an element of + a computer image called a `map' (like a bitmap or a pixmap). + + The FreeType rasterizer follows the convention defined by the + TrueType specification regarding pixel placement: + + - The map can be seen as a `grid' placed in the vector plane. + The grid lines are set on integer real coordinates (i.e., on + multiples of 64 in 26.6 fractional notation). + + Each pixel is one `cell' of the grid, and can be `lit' with + any color. Hence, each pixel has a width and a height of + [1.0] units, (i.e., 64 fixed float units). + + ^ Y + | + | The pixel grid with two + | points (not pixels!) + +-----+-----+-----+-----+-----+ at coordinates [0,0] + | | | | | | and [2,2]. + | | | | | | + | | | | |[2,2]| + +-----+-----+-----+-----@-----+ The pixels are the + | | |11111|22222| | grid's cells, and this + | | |11111|22222| | example show the four + | | |11111|22222| | pixels enclosed within + +-----+-----+-----+-----+-----+ the rectangle delimited + | | |33333|44444| | by these two points. + | | |33333|44444| | + | | |33333|44444| | + --+-----+-----@-----+-----+-----+----> X + | | |[0,0]| | | + | | | | | | Note that the numbering + | | | | | | of pixels isn't + +-----+-----+-----+-----+-----+ meaningful here, it's + | | | | | | only used to distinguish + | | | | | | them. + | | | | | | + +-----+-----+-----+-----+-----+ + | + | + + - The `center' of each pixel is always located on a + `half-integer' coordinate, i.e., at -1.5, -0.5, 0.5, 1.5, etc. + + - When drawing a shape, the rasterizer only `lits' a pixel when + its center is placed _within_ the shape. This is important + because an outline point may not be necessarily be on a grid + line. + + - When a pixel center falls on the shape, the pixel is lit too. + + For example, the following graphics show the `lit' pixels + corresponding to the rectangle enclosed by the points: + + [-0.2, 0] and [2.4, 2.7] + + + ^ Y As one can see, the + | newest pixels `1' + | and `2' are now lit, + | because its centers + +-----+-----+-----+-----+--[2.4,2.7] are located at + | | |11111|22222| @ | coordinates + | . | . |11.11|22.22| . | [0.5,2.5] and + | | |11111|22222| | [1.5,2.5], + +-----+-----+-----+-----+-----+ respectively. + | | |33333|44444| | + | . | . |33.33|44.44| . | Note that pixel + | | |33333|44444| | centers are + +-----+-----+-----+-----+-----+ represented with a + | | |55555|66666| | dot in the graphics. + | . | . |55.55|66.66| . | + | | |55555|66666| | + --+-----+----@+-----+-----+-----+----> X + | | [-0.2,0] | | | + | . | . | . | . | . | + | | | | | | Note also that pixel + +-----+-----+-----+-----+-----+ numbering is still + | | | | | | meaningless there. + | . | . | . | . | . | + | | | | | | + +-----+-----+-----+-----+-----+ + | + | + + + 4. Drop-out control + + Sometimes, a stroke is too thin to even contain a single pixel + center. This results in `lost continuity' in the resulting + bitmap, i.e., some unpleasant `holes' or `breaks' in the + rendered shape, which are called a `drop-out'. + + Because a glyph representation uses curves (Bezier arcs), this + case is not easily controllable during the `hinting' of glyph + outlines by the font driver, which means that the rasterizer + must be able to correct these `artefacts'. + + This processing is called `drop-out control', and can be + performed in several modes, defined by the TrueType + specification, and which details do not belong to this document. + However, the important idea is that, in _some_ cases, a pixel + may be lit even if its center isn't part of the shape. + + This case is relatively rare, but is mentioned because it has + consequences of the rendering of maps. More precisely, in the + way an outline's extent is computed (see below). + + +-------------------------------------------------------------------- + + +II. Bitmap and pixmap descriptors +--------------------------------- + + The Freetype rasterizer only supports bitmaps and 8-bit pixmaps. + In order to render an outline, a map descriptor must be sent to + its rendering functions, along with a vectorial outline. + + + 1. Bitmap properties + + This section explains how to set up a bitmap descriptor, and how + vector coordinates in the outline plane relate to pixel + positions within the bitmap buffer. + + A bitmap's `raw data' is made of a simple bit buffer where each + bit corresponds to a monochrome pixel. For the sake of + simplicity, the FreeType rasterizer uses the following + conventions to store bitmaps in a buffer: + + - The value 0 is used for `unlit' pixels, usually the + `background' when rendering text. Hence 1 is used for `lit'. + + - Lines are padded to 8 bits, i.e. bytes. A bitmap row thus + takes an integral number of bytes in its buffer. No further + alignment is required. + + (Some systems compress bitmaps by _not_ padding bit rows to + byte boundaries. It is not possible to render into such a + bitmap buffer with FreeType.) + + - In a bitmap buffer byte, the left-most pixel is represented by + the most significant bit (i.e., 0x80). + + The opposite convention is not supported by the FreeType + rasterizer, though it may possibly be implemented too if this + ever comes useful (ask the developers -- for now, nobody did). + + - Increasing offsets within a row correspond to right-most + positions in the bitmap (i.e., byte 1 contains the + 8 bits/pixels that are located on the right of the + 8 bits/pixels of byte 0). + + - A bitmap can be oriented in two ways: + + o If increasing row addresses within the buffer correspond to + lower vertical lines, the bitmap is said to go `down'. This + is, for example, the case of nearly all video RAMs. + + o If increasing row addresses within the buffer correspond to + higher vertical lines, the bitmap is said to go `up'. This + is the case, for example, for OS/2 bitmaps. + + The `direction' of a bitmap is called `flow' to avoid any + confusion. In both cases, the rasterizer ALWAYS matches the + vector coordinate (0,0) with the lower-left corner of the + *lower-left* pixel in the bitmap. + + The following graphics illustrate these ideas: + + + + Y ^ + | A `down-flow' bitmap. + +--+--+--+--+--+--+--+--+ On the left is each + | | | | | | | | | row's number and its + 0: 0 | | | | | | | | | offset in the bitmap + +--+--+--+--+--+--+--+--+ buffer (where `w' is + | | | | | | | | | the width, in bytes, + 1: w | | | | | | | | | of a single bitmap + +--+--+--+--+--+--+--+--+ row). Note that the + | | | | | | | | | origin is located at + 2: 2*w | | | | | | | | | the lower left, i.e., + +--+--+--+--+--+--+--+--+ near the leftmost bit + | | | | | | | | | of the last bitmap + 3: 3*w | | | | | | | | | row. + -@--+--+--+--+--+--+--+-----> X + |[0,0] + + + + Y ^ + | An `up-flow' bitmap. + +--+--+--+--+--+--+--+--+ On the left is each + | | | | | | | | | row's number and its + 3: 3*w | | | | | | | | | offset in the bitmap + +--+--+--+--+--+--+--+--+ buffer (where `w' is + | | | | | | | | | the width, in bytes, + 2: 2*w | | | | | | | | | of a single bitmap + +--+--+--+--+--+--+--+--+ row). Note that the + | | | | | | | | | origin is located at + 1: w | | | | | | | | | the lower left, i.e., + +--+--+--+--+--+--+--+--+ near the first bit in + | | | | | | | | | the buffer. + 0: 0 | | | | | | | | | The first buffer bit + -@--+--+--+--+--+--+--+-----> X corresponds to the + |[0,0] rectangle [0,0]-[1,1] + in the vector plane. + + + 2. Bitmap descriptors + + Now that you understand all these details, a bitmap can be + described to the rasterizer engine through a map, which + structure must be set up by client application: + + struct TT_Raster_Map_ + { + int rows; /* number of rows */ + int cols; /* number of columns (bytes) per row */ + int width; /* number of pixels per line */ + int flow; /* bitmap orientation */ + + void* bitmap; /* bit/pixmap buffer */ + long size; /* bit/pixmap size in bytes */ + }; + typedef struct TT_Raster_Map_ TT_Raster_Map; + + where the fields stand for: + + rows: + The number of rows within the bitmap buffer. + + cols: + The number of columns, i.e. bytes per row within the + buffer. It corresponds to the `w' value used in the above + graphics. + + width: + The number of pixels (i.e. bits) per row in the buffer. The + rasterizer always clips its rendering to the bit width + specified in this field, even if the `cols' fields + corresponds to a larger width. + + flow: + The bitmap flow. Use the constants TT_Flow_Up and + TT_Flow_Down exclusively for this field. + + bitmap: + A typeless pointer to the bit buffer. + + size: + The total size of the bit buffer in bytes. This is not used + directly by the rasterizer, so applications can use it. + + Note that the `cols' field should always be bigger than the + value of `width' multiplied by 8. The rasterizer clips the + generated bitmap to the `width' first bits in a row. + + Note also that it is of course allowed to create, for example, a + Windows or X11 bitmap through a normal system-specific API call, + using a TT_Raster_Map that describes it to the rasterizer. It + is thus possible to draw directly into such OS specific + structures. + + + IMPORTANT: ***************************************************** + + When rendering a bitmap, the rasterizer always OR-es the shape + on the target bitmap. It is thus possible to draw several + shapes into a single surface which successive calls to the + render functions. + + **************************************************************** + + + 3. Pixmap properties + + The rasterizer only supports 8-bit pixmaps, where one pixel is + represented by a single byte. They must conform to the + following rules: + + - A 5-entries palette is used to generate an outline's pixmap in + the buffer. They correspond to: + + palette[0] -> background + palette[1] -> `light' + palette[2] -> `medium' + palette[3] -> `dark' + palette[4] -> foreground + + where the terms `light', `medium', and `dark' correspond to + intermediate values between the first (background) and last + (foreground) entry. + + The upcoming FreeType 2.0 will feature an additional + anti-aliasing logic with a 17-entries palette. + + - Lines are padded to 32 bits, i.e. 4 bytes. A pixmap row thus + takes a multiple of 4 bytes in its buffer. + + - Increasing offsets within a row correspond to right-most + positions in the bitmap (i.e., byte/pixel 1 is to the right of + byte/pixel 0). + + - A pixmap can be oriented in two ways, following the same rules + as a bitmap regarding its flow. + + + IMPORTANT: ***************************************************** + + In order to improve performance when rendering large outlines + with anti-aliasing, the rasterizer draws pixels in runs of + 4-bytes ONLY when at least one of their `colour' isn't 0 + (background). + + This means that you should ALWAYS CLEAR the pixmap buffer before + calling the rendering function, you may otherwise experience + ugly artefacts, which are possibly left from a previous + rendering! + + In general, it is not possible to do colour compositing with the + FreeType rasterizer (compositing is if you want to superpose a + transparent coloured layer on top of an image). This is mainly + due to the fact that: + + - There are too many pixel formats to support. + + - There is not a single portable way to do it anyway. + + - It really is a graphics processing question, not one that + should be solved by a text rendering engine. + + **************************************************************** + + + 4. Pixmap descriptors + + Pixmaps use the same descriptor structure as bitmaps, with a few + differences in interpretation: + + - The `cols' field is used to indicate the number of _bytes_ in + a pixmap row. It must thus be a multiple of 4! + + - The rasterizer clips the outline to the first `width' + pixels/width within each buffer row. + + As usual, it should be possible to use a system-specific pixmap + and render directly into it, as long as you set up a descriptor + for it. + + +------------------------------------------------------------------------- + + +III. Rendering an outline +------------------------- + + Now that you understand how the rasterizer sees the target bitmaps + and pixmaps it renders to, this section will explain how the + rendering eventually happen. + + + 1. Outline coordinates and extents + + Let's first consider the case where we're rendering text + directly into a huge single bitmap. To do that, we simply + translate each glyph outline before calling the rasterizer. + Here the roadmap: + + - Vectorial coordinates [0,0] are mapped to the lower left + `corner' (in the grid) of the lower left pixel in the bitmap + (whatever its flow is). + + - When the glyph loader returns an outline, the latter is placed + so that the coordinate [0,0] corresponds to the current cursor + position. + + This means that: + + - If we use our own cursor (cx,cy) within the bitmap during text + rendering, we must translate the outline to its position + before rendering it, e.g. with + + TT_Translate_Outline( outline, cx, cy ) + + (and the cursor position must be incremented after rendering + each glyph). + + - Before translation (i.e., when it is returned by the glyph + loader), the glyph outline doesn't necessarily lie on any of + the coordinate axes, nor is it limited to the first quadrant + (i.e., x>0 and y>0 is not true in general). + + Its extent can be computed with the function + TT_Get_Outline_BBox(), which returns the minimum and maximum + values of its X and Y point coordinates (in 26.6 format, of + course). + + + 2. Computing an outline's dimensions in pixels + + In many cases, however, it is much better to render individual + glyph bitmaps, then cache them with appropriate metrics in order + to render text much more quickly at a given point size. + + To be able to render the smallest possible bitmap, the exact + outline's extent dimensions in pixel are required. Again a + roadmap: + + - Get the outline's bounding box in vector coordinates: + + Simply call the TT_Get_Outline_BBox() function which will + return the values of xMin, yMin, xMax, and yMax in vector + (i.e. fractional) coordinates. + + - Grid-fit the bounding box: + + Because of the way pixels are lit in the bitmaps relative to + the position of their `centers' within the shape (see + section I), it is necessary to align the values of xMin, xMax, + yMin, and yMax to the pixel grid in order to compute the width + and height of the resulting bitmap. This can be done with: + + xMin = FLOOR ( xMin ); with FLOOR(x) == (x & -64) + xMax = CEILING( xMax ); CEILING(x) == ((x+63) & -64) + yMin = FLOOR ( yMin ); + yMax = CEILING( yMax ); + + The extents in pixels can then be simply computed as: + + pixel_width = (xMax - xMin) / 64; + pixel_height = (yMax - yMin) / 64; + + Note that because of drop-out control, and because the + bounding box computed currently includes all Bezier control + points from the outline, the bitmap may be slightly larger + than necessary in some cases. + + Some improvements are planned for FreeType 2.0; for now, you + should consider that finding the `exact' bitmap bounding box + requires to scan all `borders' to detect null columns or rows. + However, the values are right in most cases. + + NOTE: It seems that in some *rare* cases, which relate to + weird drop-out control situations, the above dimensions + are not enough to store all bits from the outline (there + are one or more bits `cut' on the edge). + + This being hard to study (it only appears in very poorly + hinted fonts), we leave this problem to FreeType 2.0. + + - Create/setup a bitmap with the computed dimensions. DON'T + FORGET TO CLEAR ITS BUFFER TOO! + + - Translate the outline to stick within the bitmap space. This + is done easily by translating it by (-xMin,-yMin), where you + should ALWAYS USE THE GRID-FITTED VALUES computed above for + xMin and yMin: + + TT_Translate_Outline( outline, -xMin, -yMin ); + + + IMPORTANT: *************************************************** + + For technical reasons, you should never translate a HINTED + outline by a non-integer vector (i.e., a vector which + coordinates aren't multiples of 64)! This would CERTAINLY + completely RUIN the delicate HINTING of the glyph, and will + result probably in pure GARBAGE at small point sizes. + + Of course, if you're not interested in hinting, like when + displaying rotated text, you can ignore this rule and + translate to any position freely. + + ************************************************************** + + - Render the bitmap (or pixmap). + + DON'T FORGET TO STORE THE GRID-FITTED xMin and yMin WITH THE + BITMAP! This will allow you later to place it correctly + relative to your cursor position. + + + Here's some example pseudo code: + + { + ... load the glyph ... + + TT_Outline outline; + TT_BBox bbox; + TT_Raster_Map bitmap; + + + /* get the outline */ + TT_Get_Glyph_Outline( glyph, &outline ); + + /* compute its extent */ + TT_Get_Outline_BBox( &outline, &bbox ); + + /* Grid-fit it */ + bbox.xMin &= -64; + bbox.xMax = ( bbox.xMax + 63 ) & -64; + bbox.yMin &= -64; + bbox.yMax = ( bbox.yMax + 63 ) & -64; + + /* compute pixel dimensions */ + width = (bbox.xMax - bbox.xMin) / 64; + height = (bbox.yMax - bbox.yMin) / 64; + + /* set up bitmap */ + bitmap.rows = height; + bitmap.width = width; + bitmap.cols = (width + 7) / 8; + bitmap.size = bitmap.rows * bitmap.cols; + bitmap.bitmap = malloc( bitmap.size ); + if ( !bitmap.bitmap ) + return error_memory... + + /* clear the bitmap buffer! */ + memset( bitmap.bitmap, 0, bitmap.size ); + + /* translate outline */ + TT_Translate_Outline( &outline, -bbox.xMin, -bbox.yMin ); + + /* render it within the bitmap */ + TT_Get_Outline_Bitmap( engine, &outline, &bitmap ); + + /* We're done; don't forget to save bbox.xMin and */ + /* bbox.yMin to adjust the bitmap position when */ + /* rendering text with it */ + + ... + } + + + 3. The case of transformed/rotated glyphs: + + You may want to apply a transformation other than a translation + to your glyph outlines before rendering them. For example, a + simple slant to synthesize italics, or a slight rotation. + + In all cases, it is possible to render individual glyph bitmaps. + Just make sure to follow the same process AFTER you have + transformed you outline! + + DON'T FORGET THAT YOU NEED TO RE-COMPUTE THE BBOX TO GET THE + CORRECT PIXEL DIMENSIONS AFTER A TRANSFORMATION. + + +-------------------------------------------------------------------- + + +IV. Anti-aliasing palette and other concerns + + When rendering pixmaps, using the TT_Get_Outline_Pixmap() or + TT_Get_Glyph_Pixmap() functions, the rasterizer uses a 5-entries + palette of 8-bit deep `colors'. + + By default, this palette is set to ( 0, 1, 2, 3, 4 ), but one can + change it to suit your needs with TT_Set_Raster_Palette(). + + While in bitmap mode, it simply OR-es the pixel values to the + target bitmap that has been passed to TT_Get_Outline_Bitmap(). + + For pixmaps it simply writes directly the palette entries + corresponding to the `color' of the `lit' pixels it has computed. + This means that it is NOT POSSIBLE to render text in a single + pixmap with multiple calls to TT_Get_Outline_Pixmaps() within the + same target! + + The reason is that `gray' pixels of two distinct outlines are not + `added' when they overlap (the operation called 'compositing'), as + it could be expected by applications. + + The following graphic shows this effect when rendering two + overlapping anti-aliased shapes: + + + *** *** + .** .** + ** **. **. ** + .*. .*.. .*..*. + .*. + .*. = ---> ..*. + .*. ** | .*. ** + ** | ** + **. | **. + *** | *** + | + + missing black pixel after second + rendering... + + + There is no simple way to perform a composition within the + rasterizer. This would not be portable; moreover, it would be + extremely slow if it is too general. This operation is thus left + to client applications which can use their own system-specific API + for transparently blitting the glyph pixmaps into a surface to + form text. + + NOTE: + + If your system doesn't support transparent/alpha blits, you can + still have a look at the source file `freetype/test/display.c'. + It uses a large pixmap, with a special palette trick to render all + text quickly, then convert everything to `real' colors for + display. + + +-------------------------------------------------------------------- + + +Conclusion +---------- + + We've seen how the FreeType rasterizer sees bitmaps through + descriptors, as well as the mapping which exists between the + vector coordinate space and the pixel position space. + + You should now be able to render outlines into bitmaps and pixmaps + while applying transformations like translation, slanting, or + rotation. Don't forget a few rules, however: + + - Always clear the bitmap/pixmap buffer before rendering (unless + you want to render several glyphs in a single _bitmap_; it won't + work on a pixmap). + + - A pixmap `cols' field, i.e. the size in bytes of each rows, must + be a multiple of 4. + + - Never translate a hinted outline by a non-integer vector if you + want to preserve the hints (i.e., the vector's coordinates must + be multiples of 64). + + - Finally, don't expect the rasterizer to composite transparent + `grays' for you in a single target pixmap through multiple + calls. + + +--- end of bitmaps.txt --- diff --git a/docs/changes.txt b/docs/changes.txt new file mode 100644 index 0000000..95daad8 --- /dev/null +++ b/docs/changes.txt @@ -0,0 +1,851 @@ +Changes between FreeType version 1.3 and version 1.3.1 +====================================================== + + Bug fixes. + +Changes between FreeType version 1.2 and version 1.3 +==================================================== + + +Documentation +------------- + + Improved installation instructions. + + + Complete revision of almost all documentation files. + +** +** Added the file apirefx.txt to document all extensions to the +** FreeType library. Consequently, errstr.txt has been removed. +** + + Added the file optimize.txt, explaining how to improve FreeType + on a given architecture. + +** +** Documentation about possible patent restrictions added. +** + + Added howto/mac.txt (stating basically that the FreeType team + can't support the Macintosh platform because of lack of + knowledge). + + + Added howto/msdos.txt, documenting compilation for various 16bit + and 32bit compilers. + + +API functions +------------- + + TT_Load_Kerning_Table() now returns TT_Err_Invalid_Argument + instead of TT_Err_Bad_Argument (which is used for an internal + error only) for an invalid argument. The same holds for + TT_Get_Face_Widths() and TT_Get_Glyph_Big_Metrics(). + + + If the glyf table is missing, the new error code + TT_Err_Glyf_Table_Missing is returned instead of + TT_Err_Table_Missing. This affects TT_Get_Face_Widths(), + TT_Load_Glyph(), and TT_Open_Face(). + +** +** New function TT_FreeType_Version() to get the major and minor +** version dynamically. +** + + TT_Load_Glyph() has now two additional flags. TTLOAD_PEDANTIC + will force pedantic handling of the glyph instructions, and + TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH is needed for some fonts + which have correct advance width values for the glyphs but an + incorrect global advance width value. + + + TT_Get_Glyph_Big_Metrics() now returns correct vertical bearing + values (both linear and pixel values). + + + New error code TT_Err_Glyf_Table_Missing (0x89) used to indicate + a missing `glyf' table. + + + The following macros have been shortened to stay within the + limit of 32 characters (the longer macro names are still + available if HAVE_LIMITS_ON_IDENTS is not defined). + + TT_UCR_ARABIC_PRESENTATION_FORMS_A -> + TT_UCR_ARABIC_PRESENTATIONS_A + TT_UCR_ARABIC_PRESENTATION_FORMS_B -> + TT_UCR_ARABIC_PRESENTATIONS_B + + TT_UCR_COMBINING_DIACRITICAL_MARKS -> + TT_UCR_COMBINING_DIACRITICS + TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB -> + TT_UCR_COMBINING_DIACRITICS_SYMB + + + freetype.h: + + TT_Bool is now typedef'ed as `typedef int'. + + New typedefs: TT_Int and TT_UInt. + + Declarations of TT_Matrix_Multiply() and TT_Matrix_Invert() + have been removed since these functions were never + implemented. + + +Architectures +------------- + + Added `ansi' directory to the supported architectures -- any + ANSI C compiler should compile FreeType with these files. + + + Added `debugger' directory to the architectures. Use this to + build a special version of FreeType for bytecode debugging + (tested with OS/2 and Unix). + + + Added more files to the `mac' architecture directory to make + basic support complete. + + + Support for VMS added (to compile the library only). + Contributed by Jouk Jansen . + + + Added `win16' architecture directory for older Windows versions. + A graphics driver (gw_win16.c) for the example programs is + available also. + +** +** Antoine Leca contributed support for many MS-DOS and Windows +** compilers (including library fixes to make it 16bit compliant): +** + Borland C++ for MS-DOS (tested with v. 3.1, 4.02, 5.0), + Microsoft C for MS-DOS, + Turbo C (versions 1.5 and 2.0 -- version 1.0 is too old), + Borland C++ 4.0 and 5.0 for Windows (both 16bit and 32bit + versions), + gcc under Win32 (Cygwin32 or MinGW32), + Microsoft Visual C++ 2.x, 4.x, 5.0, and 6.0 for Windows + + + Support for the gettext package with DJGPP compiler has been + added. + + + Since many older compilers on both MS-DOS and Windows platforms + have problems to build dependency files automatically, scripts + for gcc under Unix have been added to do this. Similarly, a + script to produce a DLL definition file is now included in the + distribution. + + + Moved old win32 support to contrib/win32, replacing all CR/LF + with LF, and using only lowercase file names for consistency. + Additionally, some missing files in the FreeType 1.2 + distribution have been added. Antoine Leca has written a new, + light-weight graphics driver (gw_win32.c) which fits better into + the current scheme. + + + Small additions have been made to the Amiga graphics driver. + + + The use of the ARM macro (intended for this architecture) has + been completely removed due to lack of support. + + + Checks for endianness have been removed completely since + FreeType isn't dependent on it. + + +Global compilation macros +------------------------- + + The TT_HUGE_PTR macro has been added to support fonts with more + than 16000 characters or so with 16bit MS-DOS compilers. + Consequently, the files hugefile.c and hugemem.c have been added + which provide special versions for these compilers. + + + HAVE_LIMITS_ON_IDENTS has been introduced to overcome + restrictions with old compilers which can't digest identifiers + longer than 32 characters. + +** +** Added option TT_CONFIG_OPTION_NO_INTERPRETER to desactivate the +** bytecode interpreter completely. This option is off by default. +** + + Added options TT_CONFIG_OPTION_STATIC_RASTER and + TT_CONFIG_OPTION_STATIC_INTERPRETER to build static versions of + the respective components. Off by default. (It was formerly + called TT_STATIC_RASTER.) + + Better debugging support (see ttconfig.h for details): + DEBUG_LEVEL_TRACE, DEBUG_LEVEL_ERROR, DEBUG_INTERPRETER, + DEBUG_MEMORY, DEBUG_FILE. + + Added TT_MAX_EXTENSIONS to define the maximal number of + extensions (currently set to 8 -- this macro was previously in + ttextend.c). + + +Extensions +---------- +** +** Full support for TrueType Open resp. OpenType GSUB tables has +** been implemented. It uses a GDEF table if available; otherwise, +** a method to construct an artificial GDEF table has been added +** (note that GDEF parts not related to GSUB are loaded but not +** further handled). An example how to use it can be found in the +** new test program ftstrtto. +** + + Rudimentary GPOS support -- currently, you can load the GPOS + subtables but nothing more. + +** +** Documentation for all extensions can be found in the file +** apirefx.txt. +** + + Fixed a bug in TT_Load_PS_Names() which returned a local, thus + invalid pointer. + +** +** Support for embedded bitmaps has been added (thanks to +** YAMANO'UCHI Hidetoshi who has contributed +** a lot of the code). It can handle `bloc', `bdat', `EBLC', and +** `EBDT' tables. [TrueType embedded bitmaps are also called +** `sbits' (for `scaler bitmaps').] +** + +Test programs +------------- +** +** A new test program called ftstrtto has been added to test +** TrueType Open features. Almost all available FreeType +** extensions are used in this program -- it displays a UTF 8 +** encoded string on screen, allowing to toggle kerning, embedded +** bitmaps, GSUB support, and hinting. Additionally, it has a +** special module to handle the Arabic script properly (in +** arabic.c), i.e., it treats initial, medial, final, and isolated +** glyphs correctly. +** + + The new module `blitter.c' provides the blitting function + Blit_Bitmap() for bitmaps of various depth. + + + The debugging program `fdebug' has been rewritten to provide a + better user interface. + + + ftdump has been extended to show information about embedded + bitmaps and GSUB data. It will now also show the PostScript + name of the font. + + + The new test program ftmetric can dump metrics and glyphs -- it + uses the gettext package for i18n support. + + + Another new test program is ftsbit to dump embedded bitmaps + contained in a font. + + + A small bug has been fixed in ftstring to compute the right + bounding box of the string. + + + ftview has been extended to display embedded bitmaps also + (switch `-B'). + + + The maximal point size of glyphs in ftview has been increased to + 5000pt -- this has shown some clipping bugs in the engine which + has been fixed meanwhile. As a demonstration, it also activates + tracing of the raster and gload component if DEBUG_LEVEL_TRACE + (see above) is defined. + + +Miscellaneous +------------- + + The library has been updated to use autoconf 2.13 and libtool + 1.3.3 throughout. + +** +** FreeType will now install its header files in +** /freetype/... since the number of files has grown again. +** + + Added a lot of EXPORT_FUNC/EXPORT_DEF macros to functions for + correct exporting in DLLs. + +** +** FreeType can now successfully load Mac fonts which don't have an +** `OS/2' table. +** + + Fixed a bug in handling composite glyphs where the composite + elements use attached points. + + + Better debugging support for instructions. + + + Various workarounds have been implemented to support slightly + broken fonts (or rather, fonts not following exactly the + TrueType specifications). + + +Contributed programs +-------------------- + + ttf2bdf: +** +** Swapped all the columns in the mapping files. +** + + Changed the mapping table loader to index on the second column + instead of the first. + + + Changed the includes to deal with compilation on Windows. + + + Added some new mapping tables. + + + Fixed an incorrect parameter for Traditional C compilers. + + + Added generation of the _XFREE86_GLYPH_RANGES properties. + + + Change all CRLF's, CR's, or LF's in copyright strings to + double spaces. + + + Changed it so gcc 2.8.1 likes the return type of main() again. + + + Changed Makefile.in a bit to make installation more + consistent. + + + Changed the lower limit for the vertical and horizontal + resolutions to be 10dpi instead of 50dpi. + + + ttf2pfb: + + Has now rudimentary support for mapping tables (switch `-m') + and better PostScript name support for ordinary Type 1 fonts + -- nevertheless, it is far from finished, and there are some + plans to merge it with ttf2pt1. + + configure script added. + + Option `-k' added to keep output file in case of error. + + `-v' is now really verbose. + + ttf2pk: +** +** Support for MiKTeX's file searching mechanism added (ttf2pk +** and ttf2tfm are now part of the MiKTeX). +** +** +** Support for rotated glyphs added (only for subfonts; switches +** `-x' and `-y' to activate rotation resp. controlling the y +** offset). If a GSUB table with the `vert' feature is available +** in the font, vertical glyph presentation forms are used. +** + + Added warning message to the configure script in case the + kpathsea library isn't used. + + + Fixed an omission in Bg5.sfd. + +** +** Added UBg5plus.sfd for mapping Unicode to Bg5+ encoding. +** Similar SFD files now available: UBg5.sfd, UGB.sfd, UGBK.sfd, +** UJIS.sfd, UKS.sfd. +** + + Added documentation for dvidrv.btm. + + + Will now compile with kpathsea version 3.3 or newer also. + + + Subfont ligature support added as needed in the HLaTeX package + for Korean (switch `-l'). + +** +** Since ttf2pk support has been added to teTeX version 1.0 and +** newer, no patch are necessary. +** + + Fixed a string initialization bug in buildtfm() (file + tfmaux.c). + + + Added more documentation about file searching and a full + example how to use ttf2tfm. + + + Fixed a small bug in ttf2tfm.c which printed `(null)' instead + of nothing for the ttfonts.map entry if the font name prefix + string was empty. + + + ttf2tfm will now use the first type 0 kerning table only + (instead of the first kerning table only). + + + Both ttf2pk and ttf2tfm will now apply stretching and slanting + directly to the outline. This usually yields smaller bounding + boxes. + + + ttf2tfm will now output a comment string to the VPL file to + illustrate the meaning of the `HEADER' lines. + + + ttfbanner: + + Added Makefile for emx+gcc compiler. + + + Added autoconf support. + + + Fixed a lot of compilation warnings. + + +Pascal source code +------------------ + + The Pascal source code has been seriously updated since 1.2. + Here are the most important changes. + +** +** A. Support for charmaps and the name table +** +** +** The Charmap functions were not correctly implemented before +** 1.3. They are now available in the Pascal API. +** +** +** Similarly, the `name' table was not loaded, and the +** TT_Get_Name function wasn't implemented before 1.3. It is now +** done. +** +** +** The Pascal engine is now feature-complete, except that it +** provides no extensions like the C source code. +** + + B. Improvements in the glyph loader and the interpreter + + + Several changes were made in order to be able to load more + broken fonts, as well as old Apple fonts which happened to use + some very rarely-used aspects of the specification. + + + Note that the Pascal bytecode interpreter, contrary to the C + version, is not able to silently accept broken glyphs yet, or + even use the flag TTLOAD_PEDANTIC. Implementing this in + Pascal would require some serious work (unlike to C, where + this feature was introduced easily with the use of a few + macros to minimize source changes). So TT_Load_Glyph might + return an error with the Pascal engine while the C one accept + the same request successfully. + + + C. Ports to Delphi and Free Pascal + + This release has been compiled on the following compilers: + + - Free Pascal 0.9 (Dos,Linux,Win32,OS/2) + - Virtual Pascal 1.1 and 2.0 (Win32 and OS/2) + - Turbo Pascal 6.0 and Borland Pascal 7.0 (Dos) + - Delphi 1, 2, and 3. It should work with D4 and D5 also. + (Windows) + + Note that most of the test programs will not compile on + anything except MS-DOS or OS/2. The debugger also needs the + Turbo Vision library. The library, however, should compile + fine with all tools cited above. + + + +Changes between FreeType 1.1 and 1.2 +==================================== + +Mostly bug fixes and build fixes. + + + +Changes between FreeType 1.0 and 1.1 +==================================== + +There were various changes since the 1.0 release. Here they are +summarized: + +- Added vertical layout support + + The engine now loads the vertical header and metrics if available + and makes them visible through the new `vertical' field of the + face properties (it is set to NULL if no vertical data was found + in the font file). + + The glyph loader now loads all metrics (horizontal and vertical), + but still returns the horizontal ones only with the API + TT_Get_Glyph_Metrics(). However, TT_Get_Glyph_Bit_Metrics() has + been added to extract them from a glyph container. + + +- Serialization of coordinates arrays in TT_Outline() + + As announced in the previous API reference, the structure of + TT_Outline changed slightly, as well as the naming of its fields. + The points are now stored in a single array of TT_Vector, instead + of two parallel arrays (one for the Xs, the other for the Ys). + + +- New API function TT_Get_Face_Metrics() + + Useful to access unscaled metrics like left side bearings, advance + widths, top side bearings, and advance height, for a given range + of glyphs. + + +- New extension: ftxcmap.c + + Used by some applications to enumerate and parse the charmap + tables in an easier way. + + +- New extension: ftxpost.c + + With this extension you can access the PostScript glyph names + given in the `post' table. + + +- New extension: ftxwidth.c + + This extension is used to parse the `glyf' table to extract the + bounding boxes of a given range of glyphs. This is much faster + than loading individual glyphs. + + +- The FreeType engine is now THREAD-SAFE and REENTRANT + + However, the implementation of ttmutex must be refined for your + system -- the default one is a dummy and doesn't do anything! + Beware! THIS IS STILL IN BETA. + + The thread-safe and reentrant builds now compile and seem to run + well when used with a single thread. Some efforts have been spent + to check the coherency of the lock contentions within the engine, + but we haven't tested multi-threading heavily. + + +- Large internal re-organization + + Too technical to explain shortly, but results in a much better + memory footprint and smaller code, especially when opening + multiple faces. + + +- Fixes/enhancements to the interpreter + + The infamous Monotype.com bug (a new free font released by + Microsoft Typography a few days after the FreeType 1.0 release!) + is fixed, of course, as well as few other little and unpleasant + artifacts... + + The interpreter was also seriously re-organized to allow the use + of a very large `switch' statement, instead of a jump table, which + results in smaller and faster code on some systems (depending of + the compiler too). Users of the library can experiment with the + TT_CONFIG_OPTION_INTERPRETER_SWITCH configuration macro to test + this. + + +- Single object compilation mode + + The core engine can now be compiled into a single object file. + This allows optimizing compilers to do more global optimizations, + and get rid of many of the `intermediate' internal symbols used to + link internal engine components together. + + The engine now takes only 48kByte of stripped Intel object code! + + +- DLL compilation mode + + In order to allow the compilation of the library as a DLL, the + keyword EXPORT has been added as a prefix to all high-level API + functions found in `freetype.h'. Define it to the value you need + before `#include "freetype.h"' when building the DLL (if undefined + it will default to nothing within this header file). + + (Apparently, this is only useful on Win32, maybe on OS/2.) + + +- Renamed configuration macros + + These were renamed to forms of TT_CONFIG_OPTION_XXXXX_YYYYY. + They're located in ttconfig.h and can be defined/undefined + manually by developers who want to tune the compilation of the + engine: + + TT_CONFIG_OPTION_EXTEND_ENGINE + + Allows extensions to be linked with the single object engine. + If you don't need any of them, you may save one or more + kilobytes by undefining it. + + + TT_CONFIG_OPTION_GRAY_SCALING + + Allows the compilation of the gray-scaling (font smoothing) + code in ttraster. If undefined, some APIs won't be available: + + TT_Set_Raster_Palette(), + TT_Get_Glyph_Pixmap(), + TT_Get_Outline_Pixmap() + + + TT_CONFIG_OPTION_INTERPRETER_SWITCH + + Uses a large `switch' statement in the bytecode interpreter + instead of a constant call-table. Depending on your processor + and compiler, this can lead to significant reduction of code + size and/or increase of performance. + + + TT_CONFIG_OPTION_THREAD_SAFE + + When defined, a thread-safe version of the engine is built. A + thread-safe version is a bit bigger, probably not slower, than + a non-threaded build. ATTENTION: You must redefine the file + `lib/ttmutex.c' for your own platform to get it to work + correctly. + + + Some more options may come in the future... + + +- New API functions TT_MulDiv() and TT_MulFix()" + + To help you compute `a*b/c' with 64-bit intermediate precision, or + `a*b/0x10000' with the same one... + + These are not necessarily the fastest functions but they are + clearly portable and overflow-safe. Your runtime/compiler may + provide better replacements, though... + + + +Changes between FreeType Beta and 1.0 +===================================== + +There were a number of changes since the public beta: + + +I. Bug fixes +------------ + + The following bugs have been fixed in this release: + + + - Incorrect advance width and left side bearings + + The glyph loader has been re-designed to match the values found + in the pre-calc tables... + + + - Problems when opening multiple fonts + + Fixed. A stupid bug in the i/o component. + + + - Problems with some Georgian fonts + + Fixed. Discovered some new undocumented opcodes behaviour... + + + - Buglets in the test programs which made them return invalid + error codes + + Fixed. + + + - Memory leaks when trying to open broken some font files + + Fixed. Waiting for more broken fonts to test... + + + - Non-square resolutions don't work or display correctly + + They now work very well! + + + - The scan-line converter, while in font-smoothing mode, doesn't + perform horizontal drop-out control + + This wasn't really bug, but the feature has been correctly + added. + + +The remaining `features' persist, as they're not essential yet: + + - The `rotated' and `stretched' flags do not work (glyph loading + will then return errors). However, it is still possible to + rotate or transform any outline without setting these flags. + + - We always use drop-out mode number 2, as some of the values + returned by some `cvt programs' seem invalid for now... + + +Note also that an `event hook/callback' has been introduced in this +release, but is still under alpha (not even beta; it is commented +out currently). You should not rely on this... + + +II. Code changes +---------------- + + 1. API Changes + + A few API changes were necessary in order to support important + features, or future improvements which will come in later + releases. + + + - TT_Set_Instance_Resolution() was renamed to + TT_Set_Instance_Resolutions(). + + + - TT_Set_Instance_PointSize() has disappeared. Instead, the + following APIs have been defined: + + TT_Set_Instance_CharSize() + TT_Set_Instance_CharSizes() + TT_Set_Instance_PixelSizes() + + + - The TT_Engine class has been introduced. It models one + instance of the library, and is used to allow re-entrance and + shared library code. The functions which now depend on a + TT_Engine parameter are: + + TT_Init_FreeType() + TT_Done_FreeType() + TT_Open_Face() + TT_Open_Collection() + TT_Set_Raster_Palette() + TT_Get_Outline_Bitmap() + TT_Get_Outline_Pixmap() + + Note that there is _no_ sharing of objects between distinct + engines. + + + - Each face and instance object have an inside pointer which use + is reserved to client application. Several functions are + defined to set and read it: + + TT_Set_Face_Pointer() / TT_Get_Face_Pointer() + TT_Set_Instance_Pointer() / TT_Get_Instance_Pointer() + + + - TT_Apply_Outline_Matrix() has been renamed to + TT_Transform_Outline(). + TT_Apply_Outline_Translation() has been renamed to + TT_Translate_Outline() + TT_Apply_Vector_Matrix() has been renamed to + TT_Transform_Vector() + + all for the sake of clarity. + + + 2. Structural changes + + Some structures have evolved. + + + - The instance metrics have now two new fields which are + `x_scale' and `y_scale'. Each one is a scaling factor, + expressed in the 16.16 fixed float format (TT_Fixed), used to + convert one distance expressed in font units into the same + distance in fractional (26.6) pixels. + + + - A new structure TT_BBox has been defined to describe an + outline's bounding box. + + + - The outlines are now full-class citizen. It is possible to + create new outlines, copy, clone, transform, translate and + render them through specific methods of the TT_Outline class + (previously called TT_Glyph_Outline). Read the API reference + for a complete listing. + + + - The glyph metrics have a new structure: they contain a TT_BBox + field, a TT_Outline field, as well as three metrics values, + which are `bearingX', `bearingY', and `advance'. Read the + file `glyphs.txt' for more information about their definitions + and uses. + + + 3. Small but IMPORTANT changes + + + - The `max_Faces' field of a face's properties has disappeared. + It is replaced by `num_Faces' which gives the total number of + fonts embedded in a collection (the previous field gave the + total minus one). + + + - TT_Load_Glyph() now returns correctly placed outlines, and + computes advance widths which match the pre-calc values in the + "hdmx" table in nearly all cases. + + + - TT_Get_Glyph_Metrics() returns grid-fitted metrics for hinted + glyphs (i.e., loaded with the TTLOAD_HINT_GLYPH, or + TTLOAD_DEFAULT, flags). This includes the bounding box. To + get the exact bounding box of a hinted glyph, you should + extract its outline, then call TT_Get_Outline_BBox(). + + + - Some improvements in the glyph loader, which improves + drastically the placement of glyphs (especially composite + ones) which previously caused trouble for some fonts + (e.g. goudy.ttf). + + + - Several minor improvements in the interpreter to improve + rendering and bounds checking... + + + - Up-to-date Pascal source code, with output equivalent to the C + tree... + + +--- END --- diff --git a/docs/convntns.txt b/docs/convntns.txt new file mode 100644 index 0000000..0117785 --- /dev/null +++ b/docs/convntns.txt @@ -0,0 +1,970 @@ + + Conventions and Design in the FreeType library + ---------------------------------------------- + + +Table of Contents + +Introduction + +I. Style and Formatting + + 1. Naming + 2. Declarations & Statements + 3. Blocks + 4. Macros + +II. Design conventions + + 1. Modularity and Components Layout + 2. Configuration and Debugging + +III. Usage conventions + + 1. Error handling + 2. Font File I/O + 3. Memory management (due to change soon) + 4. Support for threaded environments + 5. Object Management + + +Introduction +============ + +This text introduces the many conventions used within the FreeType +library code. Please read it before trying any modifications or +extensions of the source code. + + + +I. Style and Formatting +======================= + +The following coding rules are extremely important to keep the +library's source code homogeneously. Keep in mind the following +points: + + - `Humans read source code, not machines' (Donald Knuth) + + The library source code should be as readable as possible, even + by non-C experts. With `readable', two things are meant: First, + the source code should be pleasant to the eye, with sufficient + whitespace and newlines, to not look like a boring stack of + characters stuck to each other. Second, the source should be + _expressive_ enough about its goals. This convention contains + rules that can help the source focus on its purpose, not on a + particular implementation. + + - `Paper is the _ultimate_ debugger' (David Turner :-) + + There is nothing like sheets of paper (and a large floor) to + help you understand the design of a library you're new to, or to + debug it. The formatting style presented here is targeted at + printing. For example, it is more than highly recommended to + never produce a source line that is wider than 78 columns. More + on this below. + + +1. Naming +--------- + + a. Components + + A unit of the library is called a `component'. Each component + has at least an interface, and often a body. The library comes + in two language flavors, C and Pascal (the latter severely out + of date unfortunately). A component in C is defined by two + files, one `.h' header and one `.c' body, while a Pascal + component is contained in a single `.pas' file. + + All component source file names begin with the `tt' prefix, with + the exception of the `FreeType' component. For example, the + file component is implemented by the files `ttfile.h', + `ttfile.c', and `ttfile.pas'. Only lowercase letters should be + used, following the 8+3 naming convention to allow compilation + under DOS. + + In the C version, a single component can have multiple bodies. + For example, `ttfile.c' provides stream i/o through standard + ANSI libc calls, while `ttfile2.c' implements the same thing + using a Unix memory-mapping API. + + The FreeType component is an interface-only component. + + b. Long and expressive labels + + Never hesitate to use long labels for your types, variables, + etc.! Except maybe for things like very trivial types, the + longest is the best, as it increases the source's + _expressiveness_. Never forget that the role of a label is to + express the `function' of the entity it represents, not its + implementation! + + NOTE: Hungarian notation is NOT expressive, as it sticks the + `type' of a variable to its name. A label like `usFoo' + rarely tells the use of the variable it represents. + + And the state of a variable (global, static, dynamic) + isn't helpful anymore. + + Avoid Hungarian Notation like the *plague*! + + + When forging a name with several nouns + (e.g. `number-of-points'), use an uppercase letter for the first + letter of each word (except the first), like: + + numberOfPoints + + You are also welcomed to introduce underscores `_' in your + labels, especially when sticking large nouns together, as it + `airs' the code greatly. E.g.: + + `numberOfPoints' or `number_Of_Points' + + `IncredibleFunction' or `Incredible_Function' + + And finally, always put a capital letter after an underscore, + except in variable labels that are all lowercase: + + `number_of_points' is OK for a variable (_all_ lowercase label) + + `incredible_function' is NOT for a function! + ^ ^ + + `Microsoft_windows' is a *shame*! + ^ ^ + + `Microsoft_Windows' isn't really better, but at least its a + ^ ^ correct function label within this + convention ;-) + + c. Types + + All types that are defined for use by FreeType client + applications are defined in the FreeType component. All types + defined there have a label beginning with `TT_'. Examples: + + TT_Face, TT_F26Dot6, etc. + + However, the library uses a lot more of internal types that are + defined in the Types, Tables, and Objs components (`tttypes' & + `tttables' files). + + By convention, all internal types, except the simplest ones like + integers, have their name beginning with a capital `T', like in + 'TFoo'. Note that the first letter of `foo' is also + capitalized. The corresponding pointer type uses a capital `P' + instead, i.e. (TFoo*) is simply named 'PFoo'. Examples: + + typedef struct _TTableDir + { + TT_Fixed version; /* should be 0x10000 */ + UShort numTables; /* Tables number */ + + UShort searchRange; /* These parameters are only used */ + UShort entrySelector;/* for a dichotomy search in the */ + UShort rangeShift; /* directory. We ignore them. */ + } TTableDir; + + typedef TTableDir* PTableDir; + + Note that we _always_ define a typedef for structures. The + original struct label starts with `_T'. + + This convention is a famous one from the Pascal world. + + Try to use C or Pascal types to the very least! Rely on + internally defined equivalent types instead. For example, not + all compilers agree on the sign of `char'; the size of `int' is + platform-specific, etc. + + There are equivalents to the most common types in the `Types' + components, like `Short', `UShort', etc. Using the internal + types will guarantee that you won't need to replace every + occurence of `short' or wathever when compiling on a weird + platform or with a weird compiler, and there are many more than + you could think of... + + d. Functions + + The name of a function should always begin with a capital + letter, as lowercase first letters are reserved for variables. + The name of a function should be, again, _expressive_! Never + hesitate to put long function names in your code: It will make + the code much more readable. + + Expressiveness doesn't necessarily imply lengthiness though; for + instance, reading shorts from a file stream is performed using + the following functions defined in the `File' component: + + Get_Byte, Get_Short, Get_UShort, Get_Long, etc. + + Which is somewhat more readable than: + + cget, sget, usget, lget, etc. + + e. Variables + + Variable names should always begin with a lowercase letter. + Lowercase first letters are reserved for variables in this + convention, as it has been already explained above. You're + still welcome to use long and expressive variable names. + + Something like `numP' can express a number of pixels, porks, + pancakes, and much more... Something like `num_points' won't. + + Today, we are still using short variable labels in some parts of + the library. We're working on removing them however... + + As a side note, a field name of a structure counts as a variable + name too. There are exceptions to the first-lowercase-letter + rule, but these are only related to fields within the structure + defined by the TrueType specification (well, at least it + _should_ be that way). + + +2. Declarations & Statements +---------------------------- + + a. Columning + + Try to align declarations and assignments in columns, if it + proves logical. For example (taken from `ttraster.c'): + + struct _TProfile + { + Int flow; /* Profile orientation : Asc/Descending */ + Int height; /* profile's height in scanlines */ + Int start; /* profile's start scanline */ + ULong offset; /* offset of profile's data in render pool */ + PProfile link; /* link to next profile */ + Int index; /* index of profile's entry in trace table */ + Int count_lines; /* count of lines having to be drawn */ + Int start_line; /* lines to be rendered before this profile */ + PTraceRec trace; /* pointer to profile's current trace table */ + }; + + instead of + + struct _TProfile { + Int flow; /* Profile orientation : Asc/Descending */ + Int height; /* profile's height in scanlines */ + Int start; /* profile's start scanline */ + ULong offset; /* offset of profile's data in render pool */ + PProfile link; /* link to next profile */ + Int index; /* index of profile's entry in trace table */ + Int count_lines; /* count of lines having to be drawn */ + Int start_line; /* lines to be rendered before this profile */ + PTraceRec trace; /* pointer to profile's current trace table */ + }; + + This comes from the fact that you're more interested by the + field and its function than by its type. + + Or: + + x = i + 1; + y += j; + min = 100; + + instead of + + x=i+1; + y+=j; + min=100; + + And don't hesitate to separate blocks of declarations with + newlines to `distinguish' logical sections. + + E.g., taken from an old source file, in the declarations of the CMap + loader: + + long n, num_SH; + unsigned short u; + long off; + unsigned short l; + long num_Seg; + unsigned short* glArray; + long table_start; + int limit, i; + + TCMapDir cmap_dir; + TCMapDirEntry entry_; + PCMapTable Plcmt; + PCMap2SubHeader Plcmsub; + PCMap4 Plcm4; + PCMap4Segment segments; + + instead of + + long n, num_SH; + unsigned short u; + long off; + unsigned short l; + long num_Seg; + unsigned short *glArray; + long table_start; + int limit, i; + TCMapDir cmap_dir; + TCMapDirEntry entry_; + PCMapTable Plcmt; + PCMap2SubHeader Plcmsub; + PCMap4 Plcm4; + PCMap4Segment segments; + + b. Aliases and the `with' clause + + The Pascal language comes with a very handy `with' clause that + is often used when dealing with the fields of a same record. + The following Pascal source extract + + with table[incredibly_long_index] do + begin + x := some_x; + y := some_y; + z := wathever_the_hell; + end; + + is usually translated to: + + table[incredibly_long_index].x = some_x; + table[incredibly_long_index].y = some_y; + table[incredibly_long_index].z = wathever_the_hell; + + When a lot of fields are involved, it is usually helpful to + define an `alias' for the record, like in: + + alias = table + incredibly_long_index; + + alias->x = some_x; + alias->y = some_y; + alias->z = wathever_the_hell; + + which gives cleaner source code, and eases the compiler's + optimization work. + + Though the use of aliases is currently not fixed in the current + library source, it is useful to follow one of these rules: + + - Avoid an alias with a stupid, or cryptic name, something like: + + TFooRecord tfr; + .... + [lots of lines snipped] + .... + + tfr = weird_table + weird_index; + + ... + + tfr->num = n; + + It doesn't really help to guess what 'tfr' stands for several + lines after its declaration, even if it's an extreme + contraction of one particular type. + + Something like `cur_record' or `alias_cmap' is better. The + current source also uses a prefix of `Pl' for such aliases + (like Pointer to Local alias), but this use is _not_ + encouraged. If you want to use prefixes, use `loc_', `cur_', + or `al_' at the very least, with a descriptive name following. + + - Or simply use a local variable with a semi-expressive name: + + { + THorizontalHeader hheader; + TVerticalHeader vheader; + + + hheader = instance->fontRes->horizontalHeader; + vheader = instance->fontRes->verticalHeader; + + hheader->foo = bar; + vheader->foo = bar2; + ... + } + + which is much better than + + { + THorizontalHeader Plhhead; + TVerticalHeader Plvhead; + + Plhhead = instance->fontRes->horizontalHeader; + Plvhead = instance->fontRes->verticalHeader; + + Plhhead->foo = bar; + Plvhead->foo = bar2; + ... + } + + +3. Blocks +--------- + + Block separation is done with `{' and `}'. We do not use the K&R + convention which becomes only useful with an extensive use of + tabs. The `{' and its corresponding `}' should always be on the + same column. It makes it easier to separate a block from the rest + of the source, and it helps your _brain_ associates the accolades + easily (ask any Lisp programmer on the topic!). + + Use two spaces for the next indentation level. + + Never use tabs in your code, their widths may vary with editors + and systems. + + Example: + + if (condition_test) { + waow mamma; + I'm doing K&R format; + just like the Linux kernel; + } else { + This test failed poorly; + } + + is _OUT_! + + if ( condition_test ) + { + This code isn't stuck to the condition; + read it on paper, you'll find it more; + pleasant to the eye; + } + else + { + Of course, this is a matter of taste; + That's just the way it is in this convention; + and you should follow it to be homogenous with; + the rest of the FreeType code; + } + + is _IN_! + + +4. Macros +--------- + + Macros should be made of uppercase letters. When a macro label is + forged from several words, it is possible to only uppercasify the + first word, using an underscore to separate the nouns. This is + used in ttload.c, ttgload.c and ttfile.c with macros like + + ACCESS_Frame, GET_UShort, CUR_Stream + + The role of the macros used throughout the engine is explained + later in this document. + + + +II. Design Conventions +====================== + + +1. Modularity and Components Layout +----------------------------------- + + The FreeType engine has been designed with portability in mind. + This implies the ability to compile and run it on a great variety + of systems and weird environments, unlike many packages where the + word strictly means `runs on a bunch of Unix-like systems'. We + have thus decided to stick to the following restrictions: + + - The C version is written in ANSI C. The Pascal version compiles + and run under Turbo Pascal 5.0 and compatible compilers. + + - The library, if compiled with gcc, doesn't produce any warning + with the `-ansi -pedantic' flags. Other compilers with better + checks may produce ANSI warnings that we'd be happy to now + about. + + (NOTE: It can of course be compiled by an `average' C compiler, + and even by a C++ one.) + + - It only requires in its simplest form an ANSI libc to compile, + and no utilities other than a C pre-processor, compiler, and + linker. + + - It is written in a modular fashion. Each module is called a + `component' and is made of two files in the C version (an + interface with suffix `.h' and body with suffix `.c' ) and one + file in the Pascal one. + + - The very low-level components can be easily replaced by + system-specific ones that do not rely on the standard libc. + These components deal mainly with i/o, memory, and mutex + operations. + + - A client application must only include one interface file named + `freetype.h' resp. `freetype.pas' to use the engine. All other + components should never be used or accessed by client + applications, and their name always begin with a `tt' prefix: + + ttmemory, ttobjs, ttinterp, ttapi, etc. + + - All configuration options are gathered in two files. One + contains the processor and OS specific configuration options, + while the other treats options that may be enabled or disabled + by the developer to test specific features (like assertions, + debugging, etc). + + IMPORTANT NOTES: + + These restrictions only apply to the core engine. The package + that comes with it contains several test programs sources that + are much less portable, even if they present a modular model + inspired from the engine's layout. + + The components currently found in the `lib' directory are: + + -------- high-level interface ---------------------------------- + + freetype.h High-level API, to be used by client applications. + + ttapi.c Implementation of the api found in `freetype.h'. + + -------- configuration ----------------------------------------- + + ttconfig.h Engine configuration options. These are commented + and switched by hand by the developer. See + section 2 below for more info. + + ft-conf.h Included by ttconfig.h, this file isn't part of + the `lib' directory, but depends on the target + environment. See section 2 blow for more info. + + -------- definitions ------------------------------------------- + + tttypes.h The engine's internal types definitions. + tttables.h The TrueType tables definitions, per se the Specs. + tttags.h The TrueType table tags definitions. + tterror.[ch] The error and debugging component. + + ttdebug.[ch] Only used by the debugger, should not be linked + into a release build. + + ttcalc.[ch] Math component used to perform some computations + with an intermediate 64-bit precision. + + -------- replaceable components -------------------------------- + + ttmemory.[ch] Memory component. This version uses the ANSI libc + but can be replaced easily by your own version. + + ttfile.[ch] Stream i/o component. This version uses the ANSI + libc but can be replaced easily by your own + version. Compiled only if file memory mapping + isn't available on your system. + + ttfile2.[ch] Unix-specific file memory mapping version of the + file component. It won't compile on other + systems. Usually results in much faster file + access (about 2x on a SCSI P166 system) + + ttmutex.[ch] Generic mutex component. This version is a dummy + and should only be used for a single-thread build. + You _need_ to replace this component's body with + your own implementation to be able to build a + threaded version of the engine. + + -------- data management --------------------------------------- + + ttengine.h The engine instance record definition, root of all + engine data. + + ttlists.[ch] Generic lists manager. + ttcache.[ch] Generic cache manager. + + ttobjs.[ch] The engine's object definitions and + implementations module contains structures, + constructors, destructors and methods for the + following objects: + + face, instance, glyph, execution_context + + ttload.[c] The TrueType tables loader. + + ttgload.[ch] The glyph loader. A component in itself, due to + the task's complexity. + + ttindex.[ch] The character mapping to glyph index conversion + routines. Implements functions defined in + `freetype.h'. + + ttinterp.[ch] The TrueType instructions interpreter. Probably + the nicest source in this engine. Apparently, + many have failed to produce a comparable one due + to the very poorly written specification! It took + David Turner three months of his spare time to get + it working correctly! :-) + + ttraster.[ch] The engine's second best piece. This is the + scan-line converter. Performs gray-level + rendering (also known as font-smoothing) as well + as dropout-control. + + +2. Configuration and Debugging +------------------------------ + + As stated above, configuration depends on two files: + + The environment configuration file `ft-conf.h': + + This file contains the definitions of many configuration options + that are processor and OS-dependent. On Unix systems, this file + is generated automatically by the `configure' script that comes + with the released package. + + On other environments, it is located in one of the architecture + directories found in `arch' (e.g. `arch/os2/ft-conf.h'). + + The path to this file should be passed to the compiler when + compiling _each_ component. (typically with an -I option). + + The engine configuration file `ttconfig.h': + + This file contains many configuration options that the developer + can turn on or off to experiment with some `features' of the + engine that are not part of its `simplest' form. The options + are commented. + + Note that the makefiles are compiler-specific. + + It is possible to enable the dumping of debugging information by + compiling the components with the various debug macros. Please + consult the file `ttconfig.h' for details. + + If you want to port the engine to another environment, you will + need to + + - Write a new `ft-conf.h' file for it. Just copy one of those + available and change the flags accordingly (they're all + commented). + + - Replace the memory, file, and mutex components with yours, + presenting the same interface and behaviour. + + - Eventually add some code in ttapi.c to initialize + system-specific data with the engine. + + + +III. Usage conventions +====================== + + +1. Error Handling +----------------- + + Error handling has been refined to allow reentrant builds of the + library, available only in the C version. We thus have now two + different conventions. + + In Pascal: + + A global error variable is used to report errors when they are + detected. All functions return a boolean that indicates success + or failure of the call. If an error occurs within a given + function, the latter must set the error variable and return + `false' (which means failure). + + It is then possible to make several calls in a single `if' + statement like: + + if not Perform_Action_1( parms_of_1 ) or + not Perform_Action_2( parms_of_2 ) or + not Perform_Action_3( parms_of_3 ) then goto Fail; + + where execution will jump to the `Fail' label whenever an error + occurs in the sequence of actions invoked in the condition. + + In C: + + Global errors are forbidden in re-entrant builds. Each function + thus returns directly an error code. A return value of 0 means + that no error occured, while a non-zero other value indicates a + failure of any kind. + + This convention is more constraining than the one used in the + Pascal source. The above Pascal statement should be translated + into the following C fragment: + + rc = Perform_Action_1( parms_of_1 ); + if ( rc ) + goto Fail; + + rc = Perform_Action_2( parms_of_2 ); + if ( rc ) + goto Fail; + + rc = Perform_Action_3( parms_of_3 ); + if ( rc ) + goto Fail; + + which, while being equivalent, isn't as pleasantly readable. + + One `simple' way to match the original fragment would be to + write: + + if ( (rc = Perform_Action_1( parms_of_1 )) || + (rc = Perform_Action_2( parms_of_2 )) || + (rc = Perform_Action_3( parms_of_3 )) ) + goto Fail; + + which is better but uses assignments within expressions, which + are always delicate to manipulate in C (the risk of writing `==' + exists, and would go unnoticed by a compiler). Moreover, the + assignments are a bit redundant and don't express much things + about the actions performed (they only speak of the error + management issue). + + That is why some macros have been defined for the most + frequently used functions. They relate to low-level routines + that are called very often (mainly i/o, mutex, and memory + handling functions). Each macro produces an implicit assignment + to a variable called `error' and can be used instead as a simple + function call. Example: + + if ( PERFORM_Action_1( parms_of_1 ) || + PERFORM_Action_2( parms_of_2 ) || + PERFORM_Action_3( parms_of_3 ) ) + goto Fail; + + with + + #define PERFORM_Action_1( parms_1 ) \ + ( error = Perform_Action_1( parms_1 ) ) + #define PERFORM_Action_2( parms_1 ) \ + ( error = Perform_Action_2( parms_1 ) ) + #define PERFORM_Action_3( parms_1 ) \ + ( error = Perform_Action_3( parms_1 ) ) + + defined at the beginning of the file. + + There, the developer only needs to define a local `error' + variable and use the macros directly in the code, without caring + about the actual error handling performed. Examples of such a + usage can be found in `ttload.c' and `ttgload.c'. Moreover, the + structure of the source files remain very similar, even though + the error handling is very different. + + This convention is very close to the use of exceptions in + languages like C++, Pascal, Java, etc. where the developer + focuses on the actions to perform, and not on every little error + checking. + + +2. Font File I/O +---------------- + + a. Streams + + The engine uses `streams' to access the font files. A stream is + a structure defined in the `File' component containing + information used to access files through a system-specific i/o + library. + + The current implementation of the File component uses the ANSI + libc i/o functions. However, for the sake of embedding in light + systems and independence of a complete libc, it is possible to + re-implement the component for a specific system or OS, letting + it use system calls. + + A stream is of type `TStream' defined in the `TTObjs' interface. + The type is `(void*)' but actually points to a structure defined + within the File component. + + A stream is created, managed and closed through the interface of + the `File' component. Several implementations of the same + component can co-exist, each taking advantage of specific system + features (the file `ttfile2.c' uses memory-mapped files for + instance) as long as it respects the interface. + + b. Frames + + TrueType is tied to the big-endian format, which implies that + reading shorts or longs from the font file may need conversions + depending on the target processor. To be able to easily detect + read errors and allow simple conversion calls or macros, the + engine is able to access a font file using `frames'. + + A frame is simply a sequence of successive bytes taken from the + input file at the current position. A frame is pre-loaded into + memory by a `TT_Access_Frame()' call of the `File' component. + + It is then possible to read all sizes of data through the + `Get_xxx()' functions, like Get_Byte(), Get_Short(), + Get_UShort(), etc. + + When all important data is read, the frame can be released by a + call to `TT_Forget_Frame()'. + + The benefits of frames are various. Consider these two + approaches at extracting values: + + if ( (error = Read_Short( &var1 )) || + (error = Read_Long ( &var2 )) || + (error = Read_Long ( &var3 )) || + (error = Read_Short( &var4 )) ) + + return FAILURE; + + and + + /* Read the next 16 bytes */ + if ( (error = TT_Access_Frame( 16L )) ) + return error; /* The Frame could not be read */ + + var1 = Get_Short(); /* extract values from the frame */ + var2 = Get_Long(); + var3 = Get_Long(); + var4 = Get_Short(); + + TT_Forget_Frame(); /* release the frame */ + + In the first case, there are four error assignments with four + checks of the file read. This unnecessarily increases the size + of the generated code. Moreover, you must be sure that `var1' + and `var4' are short variables, `var2' and `var3' long ones, if + you want to avoid bugs and/or compiler warnings. + + In the second case, you perform only one check for the read, and + exit immediately on failure. Then the values are extracted from + the frame, as the result of function calls. This means that you + can use automatic type conversion; there is no problem if + e.g. `var1' and `var4' are longs, unlike previously. + + On big-endian machines, the `Get_xxx()' functions could also be + simple macros that merely peek the values directly from the + frame, which speeds up and simplifies the generated code! + + And finally, frames are ideal when you are using memory-mapped + files, as the frame is not really `pre-loaded' and never uses + any `heap' space. + + IMPORTANT: You CANNOT nest several frame accesses. There is + only one frame available at a time for a specific + instance. + + It is also the programmer's responsibility to never + extract more data than was pre-loaded in the frame! + (But you usually know how many values you want to + extract from the file before doing so). + + +3. Memory Management +-------------------- + + The library now uses a component which interface is similar to + malloc()/free(). It defines only two functions. + + * Alloc() + + To be used like malloc(), except that it returns an error code, + not an address. Its arguments are the size of the requested + block and the address of the target pointer to the `fresh' + block. An error code is returned in case of failure (and this + will also set the target pointer to NULL), 0 in case of success. + + Alloc() should always respect the following rules: + + - Requesting a block of size 0 should set the target pointer to + NULL and return no error code (i.e., return 0). + + - The returned block is always zeroed. This is an important + assumption of other parts of the library. + + If you wish to replace the memory component with your own, + please respect this behaviour, or your engine won't work + correctly. + + * Free() + + As you may have already guessed, Free() is Alloc()'s + counterpart. It takes as argument the _target pointer's + address_! You should _never_ pass the block's address directly, + i.e. the pointer, to Free(). + + Free should always respect the following rules: + + - Calling it with a NULL argument, or the address of a NULL + pointer is valid, and should return success. + + - The pointer is always set to NULL after the block's + deallocation. This is also an important assumption of many + other parts of the library. + + If you wish to replace the memory component with your own, + please respect this behaviour, or your engine won't work + correctly. + + As the pointers addresses needed as arguments are typed `void**', + the component's interface also provides in the C version some + macros to help use them more easily, these are: + + MEM_Alloc A version of Alloc that casts the argument pointer + to (void**). + + ALLOC Same as MEM_Alloc, but with an assignment to a + variable called `error'. See the section `error + handling' above for more info on this. + + FREE A version of Free() that casts the argument + pointer to (void**). There is currently no error + handling by with this macro. + + MEM_Set An alias for `memset()', which can be easily + changed to anything else if you wish to use a + different memory manager than the functions + provided by the ANSI libc. + + MEM_Copy An alias of `memcpy()' or `bcopy()' used to move + blocks of memory. You may change it to something + different if you wish to use something else that + your standard libc. + + +4. Support for threaded environments +------------------------------------ + + Support for threaded environments have been added to the C + sources, and only to these. It is now theorically possible to + build three distinct versions of the library: + + single-thread build: + + The default build. This one doesn't known about different + threads. Hence, no code is generated to perform coherent data + sharing and locking. + + thread-safe build: + + With this build, several threads can use the library at the + same time. However, some key components can only be used by + one single thread at a time, and use a mutex to synchronize + access to their functions. These are mainly the file, raster + and interpreter components. + + re-entrant build: + + A re-entrant version is able to perform certain actions in + parallel that a thread-safe one cannot. This includes + accessing file(s) in parallel, interpreting different + instruction streams in parallel, or even scan-line converting + distinct glyphs at the same time. + + Note that most of the latest changes in the engine are making the + distinction between the thread-safe and re-entrant builds thinner + than ever. + + There is a `ttmutex' component that presents a generic interface + to mutex operations. It should be re-implemented for each + platform. + + + + +--- end of convntns.txt --- diff --git a/docs/credits b/docs/credits new file mode 100644 index 0000000..9d6c6bd --- /dev/null +++ b/docs/credits @@ -0,0 +1,94 @@ + +NOTE: This list is far from being complete. Please send a mail if + you want to be included. + + +David TURNER (david.turner@freetype.org) + + Main engine design and coding. Pascal source maintainer. + + +Robert WILHELM (robert.wilhelm@freetype.org) + + Web, FTP and CVS wizard & administrator. C source maintainer. + Incredible bug and spell fixer! + + +Werner LEMBERG (werner.lemberg@freetype.org) + + Internationalization and CJK guru. ttf2pk author. + + +Antoine LECA (antoine.leca@renault.fr) + + 16bit support for various compilersamd platforms. + + +Mark LEISHER (mleisher@crl.nmsu.edu) + + Internationalization. X11 font server prototype author. ttf2bdf + author. + + +Pavel KANKOVSKY (peak@argo.troja.mff.cuni.cz) + + Old logo, internationalization, on-line demo, humor, and + remarkable bug hunter! + + +Erwin DIETERICH (erwin.dieterich.ed@bayer-ag.de) + + *Real* internationalization :-) Author of the ftxerr18 and gettext + support. + + +Michal NECASEK (mike@mendelu.cz) + + Author and maintainer of the OS/2 font driver based on FreeType. + + +Munagala V. S. RAMANATH, CurveSoft, Inc. (ram@curvesoft.com) + + Contributor of many bug fixes and code improvements. + + +Williss, Dave (dwilliss@tnt.microimages.com) + + GSUB support. Author of the Mac port. + + +Yamano-uchi, Hidetoshi + + embedded bitmap support + + + +The following people have also contributed to the development of +FreeType: + + Beebe, Nelson H. F.: Tested FreeType on many platforms. + Benett, Kendall + Choi, Junho + Chong, Chin Soon + Chroboczek, Juliusz: Author of the xfsft Truetype font server. + Cohen, Marc L. + Davis, Jack + Demaille, Akim + Ellis, Duane + Feinberg, Matthew + Furr, Anthony + Hoo, Dave: 16bit support + Jamme, Thibault + Lewis, Kevin + Long, Jeff + Marukawa, Kazushi + Nijtmans, Jan + Olson, Eric + Paterson-Jones, Roland + Pommnitz, Joerg + Quigley, Ian + Steger, Helmut + Taggart, Scott + + +--- end of credits --- diff --git a/docs/freetype.lsm b/docs/freetype.lsm new file mode 100644 index 0000000..c8c15e3 --- /dev/null +++ b/docs/freetype.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: freetype +Version: 1.3 +Entered-date: 01SEP99 +Description: truetype font rasterizer +Keywords: font truetype rasterizer +Author: David Turner , + Werner Lemberg + Robert Wilhelm +Maintained-by: Robert Wilhelm +Primary-site: ftp://sunsite.unc.edu/pub/Linux/X11/fonts/ +Alternate-site: +Original-site: ftp://ftp.freetype.org/pub/freetype +Platforms: Linux, OS/2, MSDOS, Amiga OS, Unix, Mac, Windows +Copying-policy: BSD-like +End diff --git a/docs/glyphs.htm b/docs/glyphs.htm new file mode 100644 index 0000000..d6f0b54 --- /dev/null +++ b/docs/glyphs.htm @@ -0,0 +1,1257 @@ + + +An introduction to glyphs + + + + + + + + +http://www.freetype.org

+ +

+ Glyph Hell

+ + An introduction to glyphs, as used and defined in + the FreeType engine

+

+ +

+ +Introduction

+ +This article discusses in great detail the definition +of glyph metrics, per se the TrueType specification, and the way they +are managed and used by the FreeType engine. This information is +crucial when it comes to rendering text strings, either in a +conventional (i.e. Roman) layout, or with vertical or right-to-left +ones. Some aspects like glyph rotation and transformation are +explained too.

+ +Comments and corrections are highly welcome, and can be sent to the +FreeType developers list.

+ +


+ + +I. An overview of font files

+ +In TrueType, a single font file is used to contain +information related to classification, modeling and rendering of text +using a given typeface. This data is located in various independent +`tables', which can be sorted in four simple classes, as described +below:

+ +

    + +
  • Face Data

    + + We call face data the amount of information related to a + given typeface, independently of any particular scaling, + transformation, and/or glyph index. This usually means some + typeface-global metrics and attributes, like family and styles, + PANOSE number, typographic ascenders and descenders, as well as + some very TrueType specific items like the font `programs' found + in the fpgm and prep tables, the gasp table, + character mappings, etc.

    + + In FreeType, a face object is used to model a font file's + face data.

    + +

  • Instance Data

    + + We call instance a given pointsize/transformation, at a + given device resolution (e.g. 8pt at 96x96dpi, or 12pt at + 300x600dpi, etc). Some tables found in the font files are used to + produce instance-specific data, like the cvt table, or the + prep program. Though they are often part of the face data, + their processing results in information called instance + data.

    + + In FreeType, it is modeled through an instance object, + which is always created from an existing face object.

    + +

  • Glyph Data

    + + We call glyph data the piece of information related to + specific glyphs. This includes the following things that are + described in more details in the next sections:

    + +

      + +
    • The glyph's vectorial representation, also called its + outline.

      + +

    • Various metrics, like the glyph's bounding box, its + bearings and advance values.

      + +

    • TrueType specifies a specific instruction bytecode, + used to associate each glyph with a small program, + called the glyph code. Its purpose is to grid-fit the + outline to any target instance, in order to produce excellent + output at small pixel sizes. + +

    + + The FreeType engine doesn't map each glyph to a single structure, + as this would waste memory for no good reason. Rather, a glyph + object is a container, created from any active face, + which can be used to load and/or process any font glyph at any + instance (or even no instance at all). Of course, the glyph + properties (outline, metrics, bitmaps, etc.) can be extracted + independently from an object once it has been loaded or + processed.

    + +

  • Text and Layout Data

    + + Finally, there is a last class of data that doesn't really fit in + all others, and that can be called text data. It comprises + information related to the grouping of glyphs together to form + text. Simple examples are the kerning table, which + controls the spacing between adjacent glyphs, as well as some of + the extensions introduced in TrueType Open, + OpenType, and TrueType GX like glyph substitution + (ligatures, vertical representations), baseline management, + justification, etc.

    + + This article focuses on the basic TrueType tables, and hence, will + only talk about kerning, as FreeType doesn't support OpenType nor + GX (yet). [Support for TrueType Open is already partially + available.] + +

+ +


+ + +II. Glyph Outlines

+ +TrueType is a scalable font format; it is thus +possible to render glyphs at any scale, and under any affine +transform, from a single source representation. However, simply +scaling vectorial shapes exhibits at small sizes (where `small' refers +here to anything smaller than at least 150 pixels) a collection +of un-harmonious artifacts, like widths and/or heights +degradations.

+ +Because of this, the format also provides a complete programming +language used to design small programs associated to each glyph. Its +role is to align the point positions on the pixel grid after the +scaling. This operation is hence called grid-fitting, or even +hinting.

+ +

    + +
  1. Vectorial representation

    + + The source format of outlines is a collection of closed paths + called contours. Each contour delimits an outer or inner + region of the glyph, and can be made of either line segments + and/or second-order beziers (also called conic beziers or + quadratics).

    + + It is described internally as a series of successive points, with + each point having an associated flag indicating whether it is `on' + or `off' the curve. These rules are applied to decompose the + contour:

    + +

      + +
    • Two successive `on' points indicate a line segment joining + them.

      + +

    • One `off' point amidst two `on' points indicates a conic + bezier, the `off' point being the control point, and the `on' + ones the start and end points.

      + +

    • Finally, two successive `off' points forces the rasterizer + to create (only during bitmap rendering) a virtual `on' point + amidst them, at their exact middle. This greatly facilitates + the definition of successive Bezier arcs. + +

    + +

    +                                  *              # on
    +                                                 * off
    +                               __---__
    +  #-__                      _--       -_
    +      --__                _-            -
    +          --__           #               \
    +              --__                        #
    +                  -#
    +                           Two `on' points
    +   Two `on' points       and one `off' point
    +                            between them
    +
    +
    +
    +                *
    +  #            __      Two `on' points with two `off'
    +   \          -  -     points between them.  The point
    +    \        /    \    marked `0' is the middle of the
    +     -      0      \   `off' points, and is a `virtual
    +      -_  _-       #   on' point where the curve passes.
    +        --             It does not appear in the point
    +                       list.
    +        *
    +
    + + + + Each glyph's original outline points are located on a grid of + indivisible units. The points are stored in the font file as + 16-bit integer grid coordinates, with the grid origin's being at + (0,0); they thus range from -16384 to 16383.

    + + In creating the glyph outlines, a type designer uses an imaginary + square called the EM square. Typically, the EM square + encloses the capital letter `M' and most other letters of a + typical roman alphabet. The square's size, i.e., the number of + grid units on its sides, is very important for two reasons:

    + +

      + +
    • It is the reference used to scale the outlines to a given + instance. For example, a size of 12pt at 300x300dpi + corresponds to 12*300/72 = 50 pixels. This is the + size the EM square would appear on the output device if it was + rendered directly. In other words, scaling from grid units to + pixels uses the formula

      + +

      + pixel_size = point_size * + resolution / 72 +

      + +

      + pixel_coordinate = grid_coordinate * + pixel_size / EM_size +

      + +

    • The greater the EM size is, the larger resolution the + designer can use when digitizing outlines. For example, in + the extreme example of an EM size of 4 units, there are + only 25 point positions available within the EM square + which is clearly not enough. Typical TrueType fonts use an EM + size of 2048 units (note: with Type 1 PostScript + fonts, the EM size is fixed to 1000 grid units. However, + point coordinates can be expressed in floating values). + +

    + + Note that glyphs can freely extend beyond the EM square if the + font designer wants this. The EM is used as a convenience, and is + a valuable convenience from traditional typography.

    + +

    + + Grid units are very often called font units or EM + units. + +

    + +


    + IMPORTANT NOTE:

    + + Under FreeType, scaled pixel positions are all expressed in the + 26.6 fixed float format (made of a 26-bit integer mantissa, and a + 6-bit fractional part). In other words, all coordinates are + multiplied by 64. The grid lines along the integer pixel + positions, are multiples of 64, like (0,0), (64,0), (0,64), + (128,128), etc., while the pixel centers lie at middle coordinates + (32 modulo 64) like (32,32), (96,32), etc. +


    + +

  2. Hinting and Bitmap rendering

    + + As said before, simply scaling outlines to a specific instance + always creates undesirable artifacts, like stems of different + widths or heights in letters like `E' or `H'. Proper glyph + rendering needs that the scaled points are aligned along the pixel + grid (hence the name grid-fitting), and that important + widths and heights are respected throughout the whole font (for + example, it is very often desirable that the letters `I' and `T' + have their central vertical line of the same pixel width).

    + + Type 1 PostScript font files include with each glyph a small + series of distances called hints, which are later used by + the type manager to try grid-fitting the outlines as cleverly as + possible. On one hand, it has the consequence that upgrading your + font engine can enhance the visual aspects of all fonts of your + system; on the other hand, the quality of even the best version of + Adobe's Type Manager isn't always very pleasing at small sizes + (notwithstanding font smoothing).

    + + TrueType takes a radically different approach: Each glyph has an + associated `program', designed in a specific geometrical language, + which is used to align explicitly each outline point to the pixel + grid, preserving important distances and metrics. A stack-based + low-level bytecode is used to store it in the font file, and is + interpreted later when rendering the scaled glyphs.

    + + This means that even very complex glyphs can be rendered perfectly + at very small sizes, as long as the corresponding glyph code is + designed correctly. Moreover, a glyph can loose some of its + details, like serifs, at small sizes to become more readable, + because the bytecode provides interesting features.

    + + However, this also have the sad implication that an ill-designed + glyph code will always render junk, whatever the font engine's + version, and that it's very difficult to produce quality glyph + code. There are about 200 TrueType opcodes, and no known + `high-level language' for it. Most type artists aren't + programmers at all and the only tools able to produce quality code + from vectorial representation have been distributed to only a few + font foundries, while tools available to the public, e.g. + Fontographer, are usually expensive though generating average to + mediocre glyph code.

    + + All this explains why an enormous number of broken or ugly `free' + fonts have appeared on the TrueType scene, and that this format is + now mistakenly thought as `crap' by many people. Funnily, these + are often the same who stare at the `beauty' of the classic `Times + New Roman' and `Arial/Helvetica' at 8 points.

    + + Once a glyph's code has been executed, the scan-line converter + converts the fitted outline into a bitmap (or a pixmap with + font-smoothing). + +

+ + +


+ +III. Glyph metrics

+ +

    + +
  1. Baseline, Pens and Layouts

    + + The baseline is an imaginary line that is used to `guide' glyphs + when rendering text. It can be horizontal (e.g. Roman, Cyrillic, + Arabic, etc.) or vertical (e.g. Chinese, Japanese, etc). + Moreover, to render text, a virtual point, located on the + baseline, called the pen position, is used to locate + glyphs.

    + + Each layout uses a different convention for glyph placement:

    + +

      + +
    • With horizontal layout, glyphs simply `rest' on the + baseline. Text is rendered by incrementing the pen position, + either to the right or to the left.

      + +

      +

      +

      + + The distance between two successive pen positions is + glyph-specific and is called the advance width. Note + that its value is always positive, even for + right-to-left oriented alphabets, like Arabic. This + introduces some differences in the way text is rendered.

      + +


      + IMPORTANT NOTE:

      + + The pen position is always placed on the baseline in + TrueType, unlike the convention used by some graphics + systems, like Windows, to always put the pen above the line, + at the ascender's position. +


      + +

    • With vertical layout, glyphs are centered around the + baseline:

      + +

      + +
      + +

    + +

  2. Typographic metrics and bounding + boxes

    + + A various number of face metrics are defined for all glyphs in + a given font. Three of them have a rather curious status in + the TrueType specification; they only apply to horizontal + layouts:

    + +

      + +
    • The ascent

      + + This is the distance from the baseline to the highest/upper + grid coordinate used to place an outline point. It is a + positive value, due to the grid's orientation with the + y axis upwards.

      + +

    • The descent

      + + The distance from the baseline to the lowest grid coordinate + used to place an outline point. This is a negative value, + due to the grid's orientation.

      + +

    • The linegap

      + + The distance that must be placed between two lines of text. + The baseline-to-baseline distance should be computed as

      + +

      + ascent - descent + linegap +

      + + if you use the typographic values. + +

    + + The problem with these metrics is that they appear three times + in a single font file, each version having a slightly different + meaning:

    + +

      + +
    1. The font's horizontal header provides the ascent, descent + and linegap fields, which are used to express the designer's + intents, rather than the real values that may be computed + from all glyphs in the outline. These are used by the + Macintosh font engine to perform font mapping (i.e. font + substitution).

      + +

    2. The OS/2 table provides the usWinAscent and + usWinDescent fields. These values are computed for + glyphs of the Windows ANSI charset only, which means that + they are wrong for any other glyph. Note that + usWinDescent is always positive (i.e. looks like + `-descent').

      + +

    3. The OS/2 table provides the typoAscender, + typoDescender and typoLinegap values, which + hopefully concern the whole font file. These are the + correct system-independent values! + +

    + + All metrics are expressed in font units. If you want to use any + of the two first versions of these metrics, the TrueType + specification contains some considerations and computing tips + that might help you.

    + + Other, simpler metrics are:

    + +

      + +
    • The glyph's bounding box, also called bbox

      + + This is an imaginary box that encloses any glyph (usually as + tightly as possible). It is represented by four fields, + namely xMin, yMin, xMax, and + yMax, that can be computed for any outline. In + FreeType, their values can be in font units (if measured in + the original outline) or in 26.6 pixel units (if + measured on scaled outlines).

      + + Note that if it wasn't for grid-fitting, you wouldn't need + to know a box's complete values, but only its dimensions to + know how big is a glyph outline/bitmapa. However, correct + rendering of hinted glyphs needs the preservation of + important grid alignment on each glyph translation/placement + on the baseline, which is why FreeType always returns the + complete glyph outline.

      + + Note also that the font's header contains a global font + bounding box in font units which should enclose all glyphs + in a font. This can be used to pre-compute the maximum + dimensions of any glyph at a given instance.

      + +

    • The internal leading

      + + This concept comes directly from the world of traditional + typography. It represents the amount of space within the + `leading' which is reserved for glyph features that lay + outside of the EM square (like accentuation). It usually + can be computed as

      + +

      + internal_leading = ascent - descent - + EM_size +

      + +

    • The external leading

      + + This is another name for the linegap. + +

    + +

  3. Bearings and Advances

    + + Each glyph has also distances called bearings and + advances. Their definition is constant, but their values + depend on the layout, as the same glyph can be used to render + text either horizontally or vertically.

    + +

      +
    1. The left side bearing: a.k.a. bearingX

      + + This is the horizontal distance from the current pen + position to the glyph's left bounding box edge. It is + positive for horizontal layouts, and most generally negative + for vertical one.

      + +

    2. The top side bearing: a.k.a. bearingY

      + + This is the vertical distance from the baseline to the top + of the glyph's bounding box. It is usually positive for + horizontal layouts, and negative for vertical ones

      + +

    3. The advance width: a.k.a. advanceX

      + + This is the horizontal distance the pen position must be + incremented (for left-to-right writing) or decremented (for + right-to-left writing) by after each glyph is rendered when + processing text. It is always positive for horizontal + layouts, and null for vertical ones.

      + +

    4. The advance height: a.k.a. advanceY

      + + This is the vertical distance the pen position must be + decremented by after each glyph is rendered. It is always + null for horizontal layouts, and positive for vertical + layouts.

      + +

    5. The glyph width

      + + The glyph's horizontal extent. More simply, it is + (bbox.xMax - bbox.xMin) for unscaled font coordinates. + For scaled glyphs, its computation requests specific care, + described in the grid-fitting chapter below.

      + +

    6. The glyph height

      + + The glyph's vertical extent. More simply, it is + (bbox.yMax - bbox.yMin) for unscaled font coordinates. + For scaled glyphs, its computation requests specific care, + described in the grid-fitting chapter below.

      + +

    7. The right side bearing

      + + Only used for horizontal layouts to describe the distance + from the bbox's right edge to the advance width. It is in + most cases a non-negative number. The FreeType library + doesn't provide this metric directly, as it isn't really + part of the TrueType specification. It can be computed + simply as

      + +

      + advance_width - left_side_bearing - (xMax-xMin) +
      + +

    + +

    +

    + + +

    + + Finally, if you use `ABC widths' under Windows and OS/2, the + following relations apply: + +

    +  A = left side bearing
    +  B = width
    +  C = right side bearing
    +
    +  A+B+C = advance width
    +
    + +
  4. The effects of grid-fitting

    + + All these metrics are stored in font units in the font file. + They must be scaled and grid-fitted properly to be used at a + specific instance. This implies several things:

    + +

      + +
    • First, a glyph program not only aligns the outline along + the grid pixel, it also processes the left side bearing and + the advance width. Other grid-fitted metrics are usually + available in optional TrueType tables if you need them.

      + +

    • A glyph program may decide to extend or stretch any of + these two metrics if it has a need for it. This means that + you cannot assume that the fitted metrics are simply equal + to the scaled one plus or minus a liberal distance + < 1 pixel (i.e., less than 64 fractional + pixel units). For example, it is often necessary to stretch + the letter `m' horizontally at small pixel sizes to make all + vertical stems visible, while the same glyph can be + perfectly `square' at larger sizes.

      + +

    • Querying the fitted metrics of all glyphs at a given + instance is very slow, as it needs to load and process each + glyph independently. For this reason, some optional + TrueType tables are defined in the specification, containing + pre-computed metrics for specific instances (the most + commonly used, like 8, 9, 10, 11, 12, and 14 points at + 96dpi, for example). These tables aren't always present in + a TrueType font.

      + + If you don't need the exact fitted value, it's much faster + to query the metrics in font units, then scale them to the + instance's dimensions. + +

    + +


    + IMPORTANT NOTE:

    + + Another very important consequence of grid-fitting is the fact + that moving a fitted outline by a non-integer pixel distance + will simply ruin the hinter's work, as alignments won't be + preserved. The translated glyph will then look `ugly' when + converted to a bitmap!

    + + In other words, each time you want to translate a fitted glyph + outline, you must take care of only using integer pixel + distances (the x and y offsets must be multiples + of 64, which equals to 1.0 in the 26.6 fixed float + format). + + If you don't care about grid-fitting (typically when rendering + rotated text), you can use any offset you want and use sub-pixel + glyph placement. +


    + +

+ +

+ + +IV. Text processing

+ +This section demonstrates how to use the concepts previously defined +to render text, whatever the layout you use.

+ +

    + +
  1. Writing simple text strings

    + + We will start by generating a simple string with a Roman alphabet. + The layout is thus horizontal, left to right.

    + + For now, we will assume all glyphs are rendered in a single target + bitmap. The case of generating individual glyph bitmaps, then + placing them on demand on a device is presented in a later chapter + of this section.

    + + Rendering the string needs to place each glyph on the baseline; + this process looks like the following:

    + +

      + +
    1. Place the pen to the cursor position. The pen is always + located on the baseline. Its coordinates must be grid-fitted + (i.e. multiples of 64)!

      + +

      +  pen_x = cursor_x;
      +  pen_y = cursor_y;
      +
      + +
    2. Load the glyph outline and its metrics. Using the flag + TTLOAD_DEFAULT will scale and hint the glyph: + +
      +  TT_Load_Glyph( instance,
      +                 glyph,
      +                 glyph_index,
      +                 TTLOAD_DEFAULT );
      +
      +  TT_Get_Glyph_Metrics( glyph, &metrics );
      +  TT_Get_Glyph_Outline( glyph, &outline );
      +
      + +
    3. The loader always places the glyph outline relative to the + imaginary pen position (0,0). You thus simply need to + translate the outline by the vector: + +
      +  ( pen_x, pen_y )
      +
      + + To place it on its correct position, you can use the call + +
      +  TT_Translate_Outline( outline, pen_x, pen_y );
      +
      + +
    4. Render the outline in the target bitmap, the glyph will be + surimposed on it with a binary `or' operation (FreeType never + creates glyph bitmaps by itself, it simply renders glyphs in + the arrays you pass to it. See the API reference for a + complete description of bitmaps and pixmaps). + +
      +  TT_Get_Outline_Bitmap( outline, &target_bitmap );
      +
      + +
      + IMPORTANT NOTE:

      + + If you don't want to access the outline in your code, you can + also use the API function TT_Get_Glyph_Bitmap() which does the + same as the previous lines: + +

      +  TT_Get_Glyph_Outline( glyph, &outline );
      +  TT_Translate_Outline( outline, x_offset, y_offset );
      +  TT_Get_Outline_Bitmap( outline, &target_bitmap );
      +  TT_Translate_Outline( outline, -x_offset, -y_offset );
      +
      + + is equivalent to: + +
      +  TT_Get_Glyph_Bitmap( glyph,
      +                       x_offset,
      +                       y_offset,
      +                       &target_bitmap );
      +
      +

      + +

    5. Now advance the pen to its next position. The advance is + always grid-fitted when the glyph was hinted:

      + +

      +  pen_x += metrics.advance;
      +
      + + The advance being grid-fitted, the pen position remains + aligned on the grid.

      + +

    6. Start over on item 2 until string completion. That's + it! + +

    + +

  2. Writing right-to-left and vertical text

    + + Generating strings for different layouts is very similar. Here + are the most important differences.

    + +

      + +
    • For right-to-left text (like Arabic)

      + + The main difference here is that, as the advance width and + left side bearings are oriented against the flow of text, the + pen position must be decremented by the advance width, + before placing and rendering the glyph. Other than + that, the rest is strictly similar.

      + +

    • For vertical text (like Chinese or Japanese)

      + + In this case, the baseline is vertical, which means that the + pen position must be shifted in the vertical direction. You + need the vertical glyph metrics to do that (using the + TT_Get_Big_Glyph_Metrics() function).

      + + Once you get these, the rest of the process is very similar. + The glyph outline is placed relative to an imaginary origin of + (0,0), and you should translate it to the pen position before + rendering it.

      + + The big difference is that you must decrement pen_y, rather + than increment pen_x (this is for the TrueType convention of y + oriented upwards). + +

      +  pen_y -= metrics.advance;
      +
      + +

    + +

  3. Generating individual glyph bitmaps and using + them to render text

    + + Loading each glyph when rendering text is slow, and it's much + more efficient to render each one in a standalone bitmap to place + it in a cache. Text can then be rendered fast by applying simple + blit operations on the target device.

    + + To be able to render text correctly with the bitmaps, you must + record and associate with them its fitted bearings and advances. + Hence the following process:

    + +

      + +
    1. Generate the bitmaps.

      + +

        + +
      • Load the glyph and get its metrics. + +
        +  TT_Load_Glyph( instance,
        +                 glyph,
        +                 glyph_index,
        +                 TTLOAD_DEFAULT );
        +
        +  TT_Get_Glyph_Metrics( glyph, &metrics );
        +
        + + The bbox is always fitted when calling + TT_Get_Glyph_Metrics() on a hinted glyph. You can then + easily compute the glyph's dimension in pixels as: + +
        +  width  = (bbox.xMax - bbox.xMin) / 64;
        +  height = (bbox.yMax - bbox.yMin) / 64;
        +
        + + NOTE 1:
        + The fitted bounding box always contains all the dropouts + that may be produced by the scan-line converter. This + width and height are thus valid for all kinds of + glyphs).

        + + NOTE 2:
        + If you want to compute the dimensions of a rotated + outline's bitmap, compute its bounding box with + TT_Get_Outline_BBox(), then grid-fit the bbox manually: + +

        +  #define  FLOOR(x)    ((x) & -64)
        +  #define  CEILING(x)  (((x)+63) & -64)
        +
        +  xMin = FLOOR(xMin);
        +  yMin = FLOOR(yMin);
        +  yMin = CEILING(xMax);
        +  yMax = CEILING(yMax);
        +
        + + then compute width and height as above.

        + +

      • Create a bitmap of the given dimension, e.g.: + +
        +  bitmap.width  = width;
        +  bitmap.cols   = (width+7) & -8;
        +  bitmap.rows   = height;
        +  bitmap.flow   = TT_Flow_Up;
        +  bitmap.size   = bitmap.cols * bitmap.rows;
        +  bitmap.buffer = malloc( bitmap.size );
        +
        + +
      • Render the glyph into the bitmap.

        + + Don't forget to shift it by (-xMin, -yMin) to fit it in + the bitmap: + +

        +  /* Note that the offsets must be grid-fitted to */
        +  /* preserve hinting!                            */
        +  TT_Get_Glyph_Bitmap( glyph,
        +                       &bitmap,
        +                       -bbox.xMin,
        +                       -bbox.yMin );
        +
        + +
      + +
    2. Store the bitmap with the following values: + +
      +  bearingX / 64 = left side bearing in pixels
      +  advance / 64  = advance width/height in pixels
      +
      + + When your cache is set up, you can then render text using a + scheme similar to the ones describe in 1. and 2., + with the exception that now pen positions and metrics are + expressed in pixel values. We are done! + +
      +  pen_x = cursor_x;
      +  pen_y = cursor_y;
      +
      +  while ( glyph_to_render )
      +  {
      +    access_cache( glyph_index, metrics, bitmap );
      +
      +    blit_bitmap_to_position
      +     ( pen_x + bearingX,
      +       pen_y (+ bearingY depending on orientation ) );
      +
      +    pen_x += advance;
      +  }
      +
      + +
    + +
  4. Device-independent text rendering

    + + The previously described rendering processes all align glyphs on + the baseline according to metrics fitted for the display's + distance. In some cases, the display isn't the final output, and + placing the glyphs in a device-independent way is more important + than anything.

    + + A typical case is a word processor which displays text as it + should appear on paper when printed. As you've probably noticed, + the glyphs aren't always spaced uniformly on the screen as you + type them, sometimes the space between an `m' and a `t' is too + small, some other it is too large, etc.

    + + These differences are simply due to the fact that the word + processor aligns glyphs in an device-independent way, using + original metrics in font units to do it, then scale them as it + can to display text on screen, usually at a very smaller + resolution than your printer's one.

    + + Device-independence is a crucial part of document portability, + and it is very saddening to see that most professional word + processors don't do it correctly. For example, MS Word uses + the fitted metrics of the printer's resolution, rather than the + originals in font units.

    + + This is great to get sure that your text prints very well on your + printer, but it also implies that someone printing the exact same + document on a device with different output resolutions (e.g. + bubble-jet vs. laser printers) may encounter trouble.

    + + As the differences in advances accumulate on one line, they can + sum to the width of one or more glyphs in extreme cases, which is + enough to `overflow' the automatic justification algorithm. This + may add additional lines of printed text, or even remove some. + Moreover, supplemental lines can produce unexpected page breaks + and `blank' pages. This can be extremely painful when working + with large documents, as this `feature' may require you to + redesign completely your formatting to re-print it.

    + + In conclusion, if you want portable document rendering, never + hesitate to use and apply device-independent terms! For example, + a simple way to produce text would be:

    + +

      + +
    1. Get a scale to convert from your device-independent units + to 26.6 pixels.

      + +

    2. Get another scale to convert from original font units to + device-independent units.

      + +

    3. Perform pen placement and advances in device-independent + units.

      + +

    4. To render each glyph, compute the pen's rounded position, + as well as the rounded glyph left side bearing, both + expressed in 26.6 pixels (don't use the fitted metrics). You + will then be able to place the glyph and/or blit its bitmap. + +

    + +

  5. Kerning glyphs

    + + An interesting effect that most people appreciate is + kerning. It consists of modifying the spacing between two + successive glyphs according to their outlines. For example, the + letters `T' and a `y' can be easily moved closer, as the top of + the `y' fits nicely under the `T's upper right bar.

    + + To perform kerning, the TrueType specification provides a + specific table (its tag being `kern'), with several storage + formats. This section doesn't explain how to access this + information; however, you can have a look at the standard + extension called `ttkern.h' which comes with FreeType.

    + + The kerning distance between two glyphs is a value + expressed in font units which indicates whether their outline can + be moved together or apart when one follows the other. The + distance isn't reflexive, which means that the kerning for the + glyph pair (`T',`y') isn't the same as the one for (`y',`T').

    + + The value is positive when the glyphs must be moved apart, and + negative when they must be moved closer. You can implement + kerning simply by adding its scaled and rounded value to the + advance width when moving the pen position. Here an example for + horizontal kerning: + +

    +  #define ROUND( x )  ( (x + 32) & -64 )
    +
    +  scaled_kerning = kerning * imetrics.x_scale / 0x10000;
    +
    +  pen_x += metrics.advance + ROUND( scaled_kerning );
    +
    + +
  6. Rotated and stretched/slanted text

    + + In order to produce rotated glyphs with FreeType, one must + understand a few things:

    + +

      + +
    • The engine doesn't apply specific transformations to the + glyphs it loads and processes (other than the simpler + resolution-base scaling and grid-fitting). If you want to + rotate glyphs, you will have to load their outline, then apply + the geometric transformations that please you (a number of + APIs are there to help you to do it easily).

      + +

    • Even if the glyph loader hints `straight' glyphs, it is + possible to inform the font and glyph programs that you're + going to later transform the resulting outlines. Two flags + can be passed to the bytecode interpreter:

      + +

        + +
      • The `rotated' flag indicates that you are going to + rotate the glyphs in a non-trivial direction (i.e., on + neither of the two coordinate axis). You are advised not + to set it when writing 90 degrees-rotated text for + example.

        + +

      • The `stretched' flag indicates that you are going to + apply a transformation that will distort distances. While + rotations and symmetries keep distances constant, slanting + and stretching do modify them. + +
      + +

    + + These flags can be interpreted by the glyph code to toggle certain + processings which vary from one font to the other. However, most + of the TrueType fonts that were tested with FreeType, if not all + of them, simply change the dropout-mode when any of these flags is + set, and/or disable hinting when rotation is detected. We advise + you to never set these flags, even when rotating text. For what + it's worth, hinted rotated text is no uglier than un-hinted + one.

    + + You can use the function TT_Set_Instance_Transform_Flags() to set + them. Then, rendering can be done with the following calls: + +

    +  /* set the flags */
    +  TT_Set_Instance_Transforms( instance, 
    +                              rotated,
    +                              stretched );
    +
    +  /* load a given glyph */
    +  TT_Get_Glyph_Outline( instance,
    +                        glyph,
    +                        index,
    +                        TTLOAD_DEFAULT );
    +
    +  /* access its outline */
    +  TT_Get_Glyph_Outline( instance, &outline );
    +
    +  /* in order to transform it */
    +  TT_Transform_Outline( outline, &matrix );
    +  /* and/or */
    +  TT_Translate_Outline( outline,
    +                        x_offset, y_offset );
    +
    +  /* to render it */
    +  TT_Get_Outline_Bitmap( outline, &bitmap );
    +
    + + Here is an example, assuming that the following variables + +
    +  TT_Matrix  matrix;        /* 2x2 matrix */
    +  TT_Pos     x_off, y_off;  /* corrective offsets */
    +
    + + define a transformation that can be correctly applied to a glyph + outline which have been previously placed relative to the + imaginary point position (0,0) with bearings preserved. Rendering + text can now be done as follows:

    + +

      + +
    1. Initialize the pen position; when rotating, it is extremely + well advised to use sub-pixel placement as you don't care + about hinting. + +
      +  pen_x = cursor_x;
      +  pen_y = cursor_y;
      +
      + +
    2. Transform the glyph as needed, then translate it to the + current pen position: + +
      +  TT_Transform_Outline( outline, &matrix );
      +  TT_Translate_Outline( outline,
      +                        pen_x + x_off,
      +                        pen_y + y_off );
      +
      + + (Note that the transformation offsets have been included in + the translation.)

      + +

    3. Render the bitmap, as it has now been placed correctly.

      + +

    4. To change the pen position, transform the vector (0,advance) + with your matrix, and add it: + +
      +  vec_x = metrics.advance;
      +  vec_y = 0;
      +  TT_Transform_Vector( &vec_x, &vec_y, &matrix );
      +  pen_x += vec_x;
      +  pen_y += vec_y;
      +
      + +
    5. Start over at 2. until completion. + +

    + +


    + IMPORTANT NOTE:

    + + Do not grid-fit the pen position before rendering your glyph when + rendering rotated text. If you do, your transformed baseline + won't be preserved on each glyph, and the text will look like it's + `hopping' randomly. This is particularly visible at small + sizes.

    + + Sub-pixel precision placement is very important for clean + rotated text. +


    + +

  7. Font-smoothing, a.k.a. gray-levels + rendering

    + + The FreeType engine's scan-line converter (the component also + called the rasterizer) is able to convert a vectorial glyph + outline into either a normal bitmap, or an 8-bit pixmap (a.k.a. + colored bitmaps on some systems). This last feature is + called gray-level rendering or font-smoothing, + because it uses a user-supplied palette to produce anti-aliased + versions of the glyphs.

    + + Its principle is to render a bitmap which is twice as large than + the target pixmap, then simply filtering it using a 2x2 + summation.

    + +


    + NOTE:

    + + FreeType's scan-line converter doesn't use or need an intermediate + second bitmap. Rather, filtering is performed in a single pass + during the sweep (see the file `raster.txt' for more information + about it). +


    + + You'll notice that, as with Windows 95, FreeType's rasterizer + only grays those parts of the glyph which need it, i.e., diagonals + and curves, while keeping horizontal and vertical stems straight + `black'. This greatly improves the legibility of text, while + avoiding the `blurry' look anti-aliased fonts typically found with + Adobe's Type Manager or Acrobat.

    + + There are thus five available gray-levels, ranging from 0 + to 4, where level 0 and level 4 are the background + and foreground colors, respectively, and where levels 1, + 2, 3 are intermediate. For example, to render black text on + a white background, one can use a palette like:

    + +

      + + palette[0] = white (background)
      + palette[1] = light gray
      + palette[2] = medium gray
      + palette[3] = dark gray
      + palette[4] = black (foreground)
      + +

    + + To set the engine's gray-level palette, simply use the API + function TT_Set_Raster_Palette() after initialization. It expects + an array of 5 chars which will be used to render the + pixmaps.

    + + Note that the rasterizer doesn't create bitmaps or pixmaps. + Rather, it simply renders glyphs in the arrays you pass to it. + The generated glyph bitmaps are simply `or'-ed to the target (with + 0 being the background as a convention); in the case of pixmaps, + pixels are simply written to the buffer, in spans of four aligned + bytes.

    + +


    + NOTE:

    + + The raster isn't able to superpose `transparent' glyphs on the + target pixmap. This means that you should always call the API + functions TT_Get_Glyph_Pixmap() and TT_Get_Outline_Pixmap() with + an empty map, and perform the superposition yourself.

    + + This can be more or less tricky, depending on the palette you are + using and your target graphics resolution. One of the components + found in the test directory, called `display.c', has large + comments on the way it implements it for the test programs. You + are encouraged to read the test program sources to understand how + one can take advantage of font smoothing.

    + + Pixmap surimposition is too system-specific a feature to be part + of the FreeType engine. Moreover, not everybody needs it! +


    + + Finally, the question of sur-imposing anti-aliased colored text on + any texture, since being even more tricky, is left as an exercise + to the reader ;-) If this topic really interests you, the + FreeType mailing list may host some helpful enthusiasts ready to + answer your questions. Who knows :-)

    + +

  8. Other interesting text processes

    + +

      + +
    • Glyph substitution

      + + Substitution is used to replace one glyph by another when some + specific condition is met in the text string. Its most common + examples are ligatures (like replacing the `f' followed by `i' + by the single glyph `fi' if available in the font), as well as + positional selection as performed in the Arabic script (for + those not aware of this, each letter of the Arabic alphabet + can be written differently according to its position on words: + starting, ending, intermediate, or isolated).

      + + The base TrueType format doesn't define any table for glyph + substitution. However, GX, TrueType Open, and OpenType + provide (incompatible) extensions to perform it. Of course, + it isn't supported by the engine, but an extension could be + easily written to access the required tables.

      + + [Support for TrueType Open is already partially available.]

      + +

    • Justification

      + + ... + +

    + +
+ +To be continued... + + + diff --git a/docs/glyphs.txt b/docs/glyphs.txt new file mode 100644 index 0000000..239686a --- /dev/null +++ b/docs/glyphs.txt @@ -0,0 +1,999 @@ +http://www.freetype.org + + Glyph Hell + + An introduction to glyphs, as used and defined in the FreeType engine + + ------------------------------------------------------------------------ + +Introduction + +This article discusses in great detail the definition of glyph metrics, per +se the TrueType specification, and the way they are managed and used by the +FreeType engine. This information is crucial when it comes to rendering text +strings, either in a conventional (i.e. Roman) layout, or with vertical or +right-to-left ones. Some aspects like glyph rotation and transformation are +explained too. + +Comments and corrections are highly welcome, and can be sent to the FreeType +developers list. + + ------------------------------------------------------------------------ + +I. An overview of font files + +In TrueType, a single font file is used to contain information related to +classification, modeling and rendering of text using a given typeface. This +data is located in various independent `tables', which can be sorted in four +simple classes, as described below: + + * Face Data + + We call face data the amount of information related to a given + typeface, independently of any particular scaling, transformation, + and/or glyph index. This usually means some typeface-global metrics and + attributes, like family and styles, PANOSE number, typographic + ascenders and descenders, as well as some very TrueType specific items + like the font `programs' found in the fpgm and prep tables, the gasp + table, character mappings, etc. + + In FreeType, a face object is used to model a font file's face data. + + * Instance Data + + We call instance a given pointsize/transformation, at a given device + resolution (e.g. 8pt at 96x96dpi, or 12pt at 300x600dpi, etc). Some + tables found in the font files are used to produce instance-specific + data, like the cvt table, or the prep program. Though they are often + part of the face data, their processing results in information called + instance data. + + In FreeType, it is modeled through an instance object, which is always + created from an existing face object. + + * Glyph Data + + We call glyph data the piece of information related to specific glyphs. + This includes the following things that are described in more details + in the next sections: + + o The glyph's vectorial representation, also called its outline. + + o Various metrics, like the glyph's bounding box, its bearings and + advance values. + + o TrueType specifies a specific instruction bytecode, used to + associate each glyph with a small program, called the glyph code. + Its purpose is to grid-fit the outline to any target instance, in + order to produce excellent output at small pixel sizes. + + The FreeType engine doesn't map each glyph to a single structure, as + this would waste memory for no good reason. Rather, a glyph object is a + container, created from any active face, which can be used to load + and/or process any font glyph at any instance (or even no instance at + all). Of course, the glyph properties (outline, metrics, bitmaps, etc.) + can be extracted independently from an object once it has been loaded + or processed. + + * Text and Layout Data + + Finally, there is a last class of data that doesn't really fit in all + others, and that can be called text data. It comprises information + related to the grouping of glyphs together to form text. Simple + examples are the kerning table, which controls the spacing between + adjacent glyphs, as well as some of the extensions introduced in + TrueType Open, OpenType, and TrueType GX like glyph substitution + (ligatures, vertical representations), baseline management, + justification, etc. + + This article focuses on the basic TrueType tables, and hence, will only + talk about kerning, as FreeType doesn't support OpenType nor GX (yet). + [Support for TrueType Open is already partially available.] + + ------------------------------------------------------------------------ + +II. Glyph Outlines + +TrueType is a scalable font format; it is thus possible to render glyphs at +any scale, and under any affine transform, from a single source +representation. However, simply scaling vectorial shapes exhibits at small +sizes (where `small' refers here to anything smaller than at least +150 pixels) a collection of un-harmonious artifacts, like widths and/or +heights degradations. + +Because of this, the format also provides a complete programming language +used to design small programs associated to each glyph. Its role is to align +the point positions on the pixel grid after the scaling. This operation is +hence called grid-fitting, or even hinting. + + 1. Vectorial representation + + The source format of outlines is a collection of closed paths called + contours. Each contour delimits an outer or inner region of the glyph, + and can be made of either line segments and/or second-order beziers + (also called conic beziers or quadratics). + + It is described internally as a series of successive points, with each + point having an associated flag indicating whether it is `on' or `off' + the curve. These rules are applied to decompose the contour: + + o Two successive `on' points indicate a line segment joining them. + + o One `off' point amidst two `on' points indicates a conic bezier, + the `off' point being the control point, and the `on' ones the + start and end points. + + o Finally, two successive `off' points forces the rasterizer to + create (only during bitmap rendering) a virtual `on' point amidst + them, at their exact middle. This greatly facilitates the + definition of successive Bezier arcs. + + * # on + * off + __---__ + #-__ _-- -_ + --__ _- - + --__ # \ + --__ # + -# + Two `on' points + Two `on' points and one `off' point + between them + + * + # __ Two `on' points with two `off' + \ - - points between them. The point + \ / \ marked `0' is the middle of the + - 0 \ `off' points, and is a `virtual + -_ _- # on' point where the curve passes. + -- It does not appear in the point + list. + * + + Each glyph's original outline points are located on a grid of + indivisible units. The points are stored in the font file as + 16-bit integer grid coordinates, with the grid origin's being at (0,0); + they thus range from -16384 to 16383. + + In creating the glyph outlines, a type designer uses an imaginary + square called the EM square. Typically, the EM square encloses the + capital letter `M' and most other letters of a typical roman alphabet. + The square's size, i.e., the number of grid units on its sides, is very + important for two reasons: + + o It is the reference used to scale the outlines to a given + instance. For example, a size of 12pt at 300x300dpi corresponds to + 12*300/72 = 50 pixels. This is the size the EM square would appear + on the output device if it was rendered directly. In other words, + scaling from grid units to pixels uses the formula + + pixel_size = point_size * resolution / 72 + + pixel_coordinate = grid_coordinate * pixel_size / EM_size + + o The greater the EM size is, the larger resolution the designer can + use when digitizing outlines. For example, in the extreme example + of an EM size of 4 units, there are only 25 point positions + available within the EM square which is clearly not enough. + Typical TrueType fonts use an EM size of 2048 units (note: with + Type 1 PostScript fonts, the EM size is fixed to 1000 grid units. + However, point coordinates can be expressed in floating values). + + Note that glyphs can freely extend beyond the EM square if the font + designer wants this. The EM is used as a convenience, and is a valuable + convenience from traditional typography. + + Grid units are very often called font units or EM units. + + ----------------------------------------------------------------------- + IMPORTANT NOTE: + + Under FreeType, scaled pixel positions are all expressed in the 26.6 + fixed float format (made of a 26-bit integer mantissa, and a 6-bit + fractional part). In other words, all coordinates are multiplied by 64. + The grid lines along the integer pixel positions, are multiples of 64, + like (0,0), (64,0), (0,64), (128,128), etc., while the pixel centers + lie at middle coordinates (32 modulo 64) like (32,32), (96,32), etc. + ----------------------------------------------------------------------- + + 2. Hinting and Bitmap rendering + + As said before, simply scaling outlines to a specific instance always + creates undesirable artifacts, like stems of different widths or + heights in letters like `E' or `H'. Proper glyph rendering needs that + the scaled points are aligned along the pixel grid (hence the name + grid-fitting), and that important widths and heights are respected + throughout the whole font (for example, it is very often desirable that + the letters `I' and `T' have their central vertical line of the same + pixel width). + + Type 1 PostScript font files include with each glyph a small series of + distances called hints, which are later used by the type manager to try + grid-fitting the outlines as cleverly as possible. On one hand, it has + the consequence that upgrading your font engine can enhance the visual + aspects of all fonts of your system; on the other hand, the quality of + even the best version of Adobe's Type Manager isn't always very + pleasing at small sizes (notwithstanding font smoothing). + + TrueType takes a radically different approach: Each glyph has an + associated `program', designed in a specific geometrical language, + which is used to align explicitly each outline point to the pixel grid, + preserving important distances and metrics. A stack-based low-level + bytecode is used to store it in the font file, and is interpreted later + when rendering the scaled glyphs. + + This means that even very complex glyphs can be rendered perfectly at + very small sizes, as long as the corresponding glyph code is designed + correctly. Moreover, a glyph can loose some of its details, like + serifs, at small sizes to become more readable, because the bytecode + provides interesting features. + + However, this also have the sad implication that an ill-designed glyph + code will always render junk, whatever the font engine's version, and + that it's very difficult to produce quality glyph code. There are about + 200 TrueType opcodes, and no known `high-level language' for it. Most + type artists aren't programmers at all and the only tools able to + produce quality code from vectorial representation have been + distributed to only a few font foundries, while tools available to the + public, e.g. Fontographer, are usually expensive though generating + average to mediocre glyph code. + + All this explains why an enormous number of broken or ugly `free' fonts + have appeared on the TrueType scene, and that this format is now + mistakenly thought as `crap' by many people. Funnily, these are often + the same who stare at the `beauty' of the classic `Times New Roman' and + `Arial/Helvetica' at 8 points. + + Once a glyph's code has been executed, the scan-line converter converts + the fitted outline into a bitmap (or a pixmap with font-smoothing). + + ------------------------------------------------------------------------ + +III. Glyph metrics + + 1. Baseline, Pens and Layouts + + The baseline is an imaginary line that is used to `guide' glyphs when + rendering text. It can be horizontal (e.g. Roman, Cyrillic, Arabic, + etc.) or vertical (e.g. Chinese, Japanese, etc). Moreover, to render + text, a virtual point, located on the baseline, called the pen + position, is used to locate glyphs. + + Each layout uses a different convention for glyph placement: + + o With horizontal layout, glyphs simply `rest' on the baseline. Text + is rendered by incrementing the pen position, either to the right + or to the left. + + [Image] + + The distance between two successive pen positions is + glyph-specific and is called the advance width. Note that its + value is always positive, even for right-to-left oriented + alphabets, like Arabic. This introduces some differences in the + way text is rendered. + + ------------------------------------------------------------------ + IMPORTANT NOTE: + + The pen position is always placed on the baseline in TrueType, + unlike the convention used by some graphics systems, like Windows, + to always put the pen above the line, at the ascender's position. + ------------------------------------------------------------------ + + o With vertical layout, glyphs are centered around the baseline: + + [Image] + + 2. Typographic metrics and bounding boxes + + A various number of face metrics are defined for all glyphs in a given + font. Three of them have a rather curious status in the TrueType + specification; they only apply to horizontal layouts: + + o The ascent + + This is the distance from the baseline to the highest/upper grid + coordinate used to place an outline point. It is a positive value, + due to the grid's orientation with the y axis upwards. + + o The descent + + The distance from the baseline to the lowest grid coordinate used + to place an outline point. This is a negative value, due to the + grid's orientation. + + o The linegap + + The distance that must be placed between two lines of text. The + baseline-to-baseline distance should be computed as + + ascent - descent + linegap + + if you use the typographic values. + + The problem with these metrics is that they appear three times in a + single font file, each version having a slightly different meaning: + + 1. The font's horizontal header provides the ascent, descent and + linegap fields, which are used to express the designer's intents, + rather than the real values that may be computed from all glyphs + in the outline. These are used by the Macintosh font engine to + perform font mapping (i.e. font substitution). + + 2. The OS/2 table provides the usWinAscent and usWinDescent fields. + These values are computed for glyphs of the Windows ANSI charset + only, which means that they are wrong for any other glyph. Note + that usWinDescent is always positive (i.e. looks like `-descent'). + + 3. The OS/2 table provides the typoAscender, typoDescender and + typoLinegap values, which hopefully concern the whole font file. + These are the correct system-independent values! + + All metrics are expressed in font units. If you want to use any of the + two first versions of these metrics, the TrueType specification + contains some considerations and computing tips that might help you. + + Other, simpler metrics are: + + o The glyph's bounding box, also called bbox + + This is an imaginary box that encloses any glyph (usually as + tightly as possible). It is represented by four fields, namely + xMin, yMin, xMax, and yMax, that can be computed for any outline. + In FreeType, their values can be in font units (if measured in the + original outline) or in 26.6 pixel units (if measured on scaled + outlines). + + Note that if it wasn't for grid-fitting, you wouldn't need to know + a box's complete values, but only its dimensions to know how big + is a glyph outline/bitmapa. However, correct rendering of hinted + glyphs needs the preservation of important grid alignment on each + glyph translation/placement on the baseline, which is why FreeType + always returns the complete glyph outline. + + Note also that the font's header contains a global font bounding + box in font units which should enclose all glyphs in a font. This + can be used to pre-compute the maximum dimensions of any glyph at + a given instance. + + o The internal leading + + This concept comes directly from the world of traditional + typography. It represents the amount of space within the `leading' + which is reserved for glyph features that lay outside of the EM + square (like accentuation). It usually can be computed as + + internal_leading = ascent - descent - EM_size + + o The external leading + + This is another name for the linegap. + + 3. Bearings and Advances + + Each glyph has also distances called bearings and advances. Their + definition is constant, but their values depend on the layout, as the + same glyph can be used to render text either horizontally or + vertically. + + 1. The left side bearing: a.k.a. bearingX + + This is the horizontal distance from the current pen position to + the glyph's left bounding box edge. It is positive for horizontal + layouts, and most generally negative for vertical one. + + 2. The top side bearing: a.k.a. bearingY + + This is the vertical distance from the baseline to the top of the + glyph's bounding box. It is usually positive for horizontal + layouts, and negative for vertical ones + + 3. The advance width: a.k.a. advanceX + + This is the horizontal distance the pen position must be + incremented (for left-to-right writing) or decremented (for + right-to-left writing) by after each glyph is rendered when + processing text. It is always positive for horizontal layouts, and + null for vertical ones. + + 4. The advance height: a.k.a. advanceY + + This is the vertical distance the pen position must be decremented + by after each glyph is rendered. It is always null for horizontal + layouts, and positive for vertical layouts. + + 5. The glyph width + + The glyph's horizontal extent. More simply, it is (bbox.xMax - + bbox.xMin) for unscaled font coordinates. For scaled glyphs, its + computation requests specific care, described in the grid-fitting + chapter below. + + 6. The glyph height + + The glyph's vertical extent. More simply, it is (bbox.yMax - + bbox.yMin) for unscaled font coordinates. For scaled glyphs, its + computation requests specific care, described in the grid-fitting + chapter below. + + 7. The right side bearing + + Only used for horizontal layouts to describe the distance from the + bbox's right edge to the advance width. It is in most cases a + non-negative number. The FreeType library doesn't provide this + metric directly, as it isn't really part of the TrueType + specification. It can be computed simply as + + advance_width - left_side_bearing - (xMax-xMin) + + [Image] + + [Image] + + Finally, if you use `ABC widths' under Windows and OS/2, the following + relations apply: + + A = left side bearing + B = width + C = right side bearing + + A+B+C = advance width + + 4. The effects of grid-fitting + + All these metrics are stored in font units in the font file. They must + be scaled and grid-fitted properly to be used at a specific instance. + This implies several things: + + o First, a glyph program not only aligns the outline along the grid + pixel, it also processes the left side bearing and the advance + width. Other grid-fitted metrics are usually available in optional + TrueType tables if you need them. + + o A glyph program may decide to extend or stretch any of these two + metrics if it has a need for it. This means that you cannot assume + that the fitted metrics are simply equal to the scaled one plus or + minus a liberal distance < 1 pixel (i.e., less than 64 fractional + pixel units). For example, it is often necessary to stretch the + letter `m' horizontally at small pixel sizes to make all vertical + stems visible, while the same glyph can be perfectly `square' at + larger sizes. + + o Querying the fitted metrics of all glyphs at a given instance is + very slow, as it needs to load and process each glyph + independently. For this reason, some optional TrueType tables are + defined in the specification, containing pre-computed metrics for + specific instances (the most commonly used, like 8, 9, 10, 11, 12, + and 14 points at 96dpi, for example). These tables aren't always + present in a TrueType font. + + If you don't need the exact fitted value, it's much faster to + query the metrics in font units, then scale them to the instance's + dimensions. + + ----------------------------------------------------------------------- + IMPORTANT NOTE: + + Another very important consequence of grid-fitting is the fact that + moving a fitted outline by a non-integer pixel distance will simply + ruin the hinter's work, as alignments won't be preserved. The + translated glyph will then look `ugly' when converted to a bitmap! + + In other words, each time you want to translate a fitted glyph outline, + you must take care of only using integer pixel distances (the x and + y offsets must be multiples of 64, which equals to 1.0 in the 26.6 + fixed float format). If you don't care about grid-fitting (typically + when rendering rotated text), you can use any offset you want and use + sub-pixel glyph placement. + ----------------------------------------------------------------------- + + ------------------------------------------------------------------------ + +IV. Text processing + +This section demonstrates how to use the concepts previously defined to +render text, whatever the layout you use. + + 1. Writing simple text strings + + We will start by generating a simple string with a Roman alphabet. The + layout is thus horizontal, left to right. + + For now, we will assume all glyphs are rendered in a single target + bitmap. The case of generating individual glyph bitmaps, then placing + them on demand on a device is presented in a later chapter of this + section. + + Rendering the string needs to place each glyph on the baseline; this + process looks like the following: + + 1. Place the pen to the cursor position. The pen is always located on + the baseline. Its coordinates must be grid-fitted (i.e. multiples + of 64)! + + pen_x = cursor_x; + pen_y = cursor_y; + + 2. Load the glyph outline and its metrics. Using the flag + TTLOAD_DEFAULT will scale and hint the glyph: + + TT_Load_Glyph( instance, + glyph, + glyph_index, + TTLOAD_DEFAULT ); + + TT_Get_Glyph_Metrics( glyph, &metrics ); + TT_Get_Glyph_Outline( glyph, &outline ); + + 3. The loader always places the glyph outline relative to the + imaginary pen position (0,0). You thus simply need to translate + the outline by the vector: + + ( pen_x, pen_y ) + + To place it on its correct position, you can use the call + + TT_Translate_Outline( outline, pen_x, pen_y ); + + 4. Render the outline in the target bitmap, the glyph will be + surimposed on it with a binary `or' operation (FreeType never + creates glyph bitmaps by itself, it simply renders glyphs in the + arrays you pass to it. See the API reference for a complete + description of bitmaps and pixmaps). + + TT_Get_Outline_Bitmap( outline, &target_bitmap ); + + ------------------------------------------------------------------ + IMPORTANT NOTE: + + If you don't want to access the outline in your code, you can also + use the API function TT_Get_Glyph_Bitmap() which does the same as + the previous lines: + + TT_Get_Glyph_Outline( glyph, &outline ); + TT_Translate_Outline( outline, x_offset, y_offset ); + TT_Get_Outline_Bitmap( outline, &target_bitmap ); + TT_Translate_Outline( outline, -x_offset, -y_offset ); + + is equivalent to: + + TT_Get_Glyph_Bitmap( glyph, + x_offset, + y_offset, + &target_bitmap ); + + ------------------------------------------------------------------ + + 5. Now advance the pen to its next position. The advance is always + grid-fitted when the glyph was hinted: + + pen_x += metrics.advance; + + The advance being grid-fitted, the pen position remains aligned on + the grid. + + 6. Start over on item 2 until string completion. That's it! + + 2. Writing right-to-left and vertical text + + Generating strings for different layouts is very similar. Here are the + most important differences. + + o For right-to-left text (like Arabic) + + The main difference here is that, as the advance width and left + side bearings are oriented against the flow of text, the pen + position must be decremented by the advance width, before placing + and rendering the glyph. Other than that, the rest is strictly + similar. + + o For vertical text (like Chinese or Japanese) + + In this case, the baseline is vertical, which means that the pen + position must be shifted in the vertical direction. You need the + vertical glyph metrics to do that (using the + TT_Get_Big_Glyph_Metrics() function). + + Once you get these, the rest of the process is very similar. The + glyph outline is placed relative to an imaginary origin of (0,0), + and you should translate it to the pen position before rendering + it. + + The big difference is that you must decrement pen_y, rather than + increment pen_x (this is for the TrueType convention of y oriented + upwards). + + pen_y -= metrics.advance; + + 3. Generating individual glyph bitmaps and using them to render text + + Loading each glyph when rendering text is slow, and it's much more + efficient to render each one in a standalone bitmap to place it in a + cache. Text can then be rendered fast by applying simple blit + operations on the target device. + + To be able to render text correctly with the bitmaps, you must record + and associate with them its fitted bearings and advances. Hence the + following process: + + 1. Generate the bitmaps. + + + Load the glyph and get its metrics. + + TT_Load_Glyph( instance, + glyph, + glyph_index, + TTLOAD_DEFAULT ); + + TT_Get_Glyph_Metrics( glyph, &metrics ); + + The bbox is always fitted when calling TT_Get_Glyph_Metrics() + on a hinted glyph. You can then easily compute the glyph's + dimension in pixels as: + + width = (bbox.xMax - bbox.xMin) / 64; + height = (bbox.yMax - bbox.yMin) / 64; + + NOTE 1: + The fitted bounding box always contains all the dropouts that + may be produced by the scan-line converter. This width and + height are thus valid for all kinds of glyphs). + + NOTE 2: + If you want to compute the dimensions of a rotated outline's + bitmap, compute its bounding box with TT_Get_Outline_BBox(), + then grid-fit the bbox manually: + + #define FLOOR(x) ((x) & -64) + #define CEILING(x) (((x)+63) & -64) + + xMin = FLOOR(xMin); + yMin = FLOOR(yMin); + yMin = CEILING(xMax); + yMax = CEILING(yMax); + + then compute width and height as above. + + + Create a bitmap of the given dimension, e.g.: + + bitmap.width = width; + bitmap.cols = (width+7) & -8; + bitmap.rows = height; + bitmap.flow = TT_Flow_Up; + bitmap.size = bitmap.cols * bitmap.rows; + bitmap.buffer = malloc( bitmap.size ); + + + Render the glyph into the bitmap. + + Don't forget to shift it by (-xMin, -yMin) to fit it in the + bitmap: + + /* Note that the offsets must be grid-fitted to */ + /* preserve hinting! */ + TT_Get_Glyph_Bitmap( glyph, + &bitmap, + -bbox.xMin, + -bbox.yMin ); + + 2. Store the bitmap with the following values: + + bearingX / 64 = left side bearing in pixels + advance / 64 = advance width/height in pixels + + When your cache is set up, you can then render text using a scheme + similar to the ones describe in 1. and 2., with the exception that + now pen positions and metrics are expressed in pixel values. We + are done! + + pen_x = cursor_x; + pen_y = cursor_y; + + while ( glyph_to_render ) + { + access_cache( glyph_index, metrics, bitmap ); + + blit_bitmap_to_position + ( pen_x + bearingX, + pen_y (+ bearingY depending on orientation ) ); + + pen_x += advance; + } + + 4. Device-independent text rendering + + The previously described rendering processes all align glyphs on the + baseline according to metrics fitted for the display's distance. In + some cases, the display isn't the final output, and placing the glyphs + in a device-independent way is more important than anything. + + A typical case is a word processor which displays text as it should + appear on paper when printed. As you've probably noticed, the glyphs + aren't always spaced uniformly on the screen as you type them, + sometimes the space between an `m' and a `t' is too small, some other + it is too large, etc. + + These differences are simply due to the fact that the word processor + aligns glyphs in an device-independent way, using original metrics in + font units to do it, then scale them as it can to display text on + screen, usually at a very smaller resolution than your printer's one. + + Device-independence is a crucial part of document portability, and it + is very saddening to see that most professional word processors don't + do it correctly. For example, MS Word uses the fitted metrics of the + printer's resolution, rather than the originals in font units. + + This is great to get sure that your text prints very well on your + printer, but it also implies that someone printing the exact same + document on a device with different output resolutions (e.g. bubble-jet + vs. laser printers) may encounter trouble. + + As the differences in advances accumulate on one line, they can sum to + the width of one or more glyphs in extreme cases, which is enough to + `overflow' the automatic justification algorithm. This may add + additional lines of printed text, or even remove some. Moreover, + supplemental lines can produce unexpected page breaks and `blank' + pages. This can be extremely painful when working with large documents, + as this `feature' may require you to redesign completely your + formatting to re-print it. + + In conclusion, if you want portable document rendering, never hesitate + to use and apply device-independent terms! For example, a simple way to + produce text would be: + + 1. Get a scale to convert from your device-independent units to 26.6 + pixels. + + 2. Get another scale to convert from original font units to + device-independent units. + + 3. Perform pen placement and advances in device-independent units. + + 4. To render each glyph, compute the pen's rounded position, as well + as the rounded glyph left side bearing, both expressed in 26.6 + pixels (don't use the fitted metrics). You will then be able to + place the glyph and/or blit its bitmap. + + 5. Kerning glyphs + + An interesting effect that most people appreciate is kerning. It + consists of modifying the spacing between two successive glyphs + according to their outlines. For example, the letters `T' and a `y' can + be easily moved closer, as the top of the `y' fits nicely under the + `T's upper right bar. + + To perform kerning, the TrueType specification provides a specific + table (its tag being `kern'), with several storage formats. This + section doesn't explain how to access this information; however, you + can have a look at the standard extension called `ttkern.h' which comes + with FreeType. + + The kerning distance between two glyphs is a value expressed in font + units which indicates whether their outline can be moved together or + apart when one follows the other. The distance isn't reflexive, which + means that the kerning for the glyph pair (`T',`y') isn't the same as + the one for (`y',`T'). + + The value is positive when the glyphs must be moved apart, and negative + when they must be moved closer. You can implement kerning simply by + adding its scaled and rounded value to the advance width when moving + the pen position. Here an example for horizontal kerning: + + #define ROUND( x ) ( (x + 32) & -64 ) + + scaled_kerning = kerning * imetrics.x_scale / 0x10000; + + pen_x += metrics.advance + ROUND( scaled_kerning ); + + 6. Rotated and stretched/slanted text + + In order to produce rotated glyphs with FreeType, one must understand a + few things: + + o The engine doesn't apply specific transformations to the glyphs it + loads and processes (other than the simpler resolution-base + scaling and grid-fitting). If you want to rotate glyphs, you will + have to load their outline, then apply the geometric + transformations that please you (a number of APIs are there to + help you to do it easily). + + o Even if the glyph loader hints `straight' glyphs, it is possible + to inform the font and glyph programs that you're going to later + transform the resulting outlines. Two flags can be passed to the + bytecode interpreter: + + + The `rotated' flag indicates that you are going to rotate the + glyphs in a non-trivial direction (i.e., on neither of the + two coordinate axis). You are advised not to set it when + writing 90 degrees-rotated text for example. + + + The `stretched' flag indicates that you are going to apply a + transformation that will distort distances. While rotations + and symmetries keep distances constant, slanting and + stretching do modify them. + + These flags can be interpreted by the glyph code to toggle certain + processings which vary from one font to the other. However, most of the + TrueType fonts that were tested with FreeType, if not all of them, + simply change the dropout-mode when any of these flags is set, and/or + disable hinting when rotation is detected. We advise you to never set + these flags, even when rotating text. For what it's worth, hinted + rotated text is no uglier than un-hinted one. + + You can use the function TT_Set_Instance_Transform_Flags() to set them. + Then, rendering can be done with the following calls: + + /* set the flags */ + TT_Set_Instance_Transforms( instance, + rotated, + stretched ); + + /* load a given glyph */ + TT_Get_Glyph_Outline( instance, + glyph, + index, + TTLOAD_DEFAULT ); + + /* access its outline */ + TT_Get_Glyph_Outline( instance, &outline ); + + /* in order to transform it */ + TT_Transform_Outline( outline, &matrix ); + /* and/or */ + TT_Translate_Outline( outline, + x_offset, y_offset ); + + /* to render it */ + TT_Get_Outline_Bitmap( outline, &bitmap ); + + Here is an example, assuming that the following variables + + TT_Matrix matrix; /* 2x2 matrix */ + TT_Pos x_off, y_off; /* corrective offsets */ + + define a transformation that can be correctly applied to a glyph + outline which have been previously placed relative to the imaginary + point position (0,0) with bearings preserved. Rendering text can now be + done as follows: + + 1. Initialize the pen position; when rotating, it is extremely well + advised to use sub-pixel placement as you don't care about + hinting. + + pen_x = cursor_x; + pen_y = cursor_y; + + 2. Transform the glyph as needed, then translate it to the current + pen position: + + TT_Transform_Outline( outline, &matrix ); + TT_Translate_Outline( outline, + pen_x + x_off, + pen_y + y_off ); + + (Note that the transformation offsets have been included in the + translation.) + + 3. Render the bitmap, as it has now been placed correctly. + + 4. To change the pen position, transform the vector (0,advance) with + your matrix, and add it: + + vec_x = metrics.advance; + vec_y = 0; + TT_Transform_Vector( &vec_x, &vec_y, &matrix ); + pen_x += vec_x; + pen_y += vec_y; + + 5. Start over at 2. until completion. + + ----------------------------------------------------------------------- + IMPORTANT NOTE: + + Do not grid-fit the pen position before rendering your glyph when + rendering rotated text. If you do, your transformed baseline won't be + preserved on each glyph, and the text will look like it's `hopping' + randomly. This is particularly visible at small sizes. + + Sub-pixel precision placement is very important for clean rotated text. + ----------------------------------------------------------------------- + + 7. Font-smoothing, a.k.a. gray-levels rendering + + The FreeType engine's scan-line converter (the component also called + the rasterizer) is able to convert a vectorial glyph outline into + either a normal bitmap, or an 8-bit pixmap (a.k.a. colored bitmaps on + some systems). This last feature is called gray-level rendering or + font-smoothing, because it uses a user-supplied palette to produce + anti-aliased versions of the glyphs. + + Its principle is to render a bitmap which is twice as large than the + target pixmap, then simply filtering it using a 2x2 summation. + + ----------------------------------------------------------------------- + NOTE: + + FreeType's scan-line converter doesn't use or need an intermediate + second bitmap. Rather, filtering is performed in a single pass during + the sweep (see the file `raster.txt' for more information about it). + ----------------------------------------------------------------------- + + You'll notice that, as with Windows 95, FreeType's rasterizer only + grays those parts of the glyph which need it, i.e., diagonals and + curves, while keeping horizontal and vertical stems straight `black'. + This greatly improves the legibility of text, while avoiding the + `blurry' look anti-aliased fonts typically found with Adobe's Type + Manager or Acrobat. + + There are thus five available gray-levels, ranging from 0 to 4, where + level 0 and level 4 are the background and foreground colors, + respectively, and where levels 1, 2, 3 are intermediate. For example, + to render black text on a white background, one can use a palette like: + + palette[0] = white (background) + palette[1] = light gray + palette[2] = medium gray + palette[3] = dark gray + palette[4] = black (foreground) + + To set the engine's gray-level palette, simply use the API function + TT_Set_Raster_Palette() after initialization. It expects an array of + 5 chars which will be used to render the pixmaps. + + Note that the rasterizer doesn't create bitmaps or pixmaps. Rather, it + simply renders glyphs in the arrays you pass to it. The generated glyph + bitmaps are simply `or'-ed to the target (with 0 being the background + as a convention); in the case of pixmaps, pixels are simply written to + the buffer, in spans of four aligned bytes. + + ----------------------------------------------------------------------- + NOTE: + + The raster isn't able to superpose `transparent' glyphs on the target + pixmap. This means that you should always call the API functions + TT_Get_Glyph_Pixmap() and TT_Get_Outline_Pixmap() with an empty map, + and perform the superposition yourself. + + This can be more or less tricky, depending on the palette you are using + and your target graphics resolution. One of the components found in the + test directory, called `display.c', has large comments on the way it + implements it for the test programs. You are encouraged to read the + test program sources to understand how one can take advantage of font + smoothing. + + Pixmap surimposition is too system-specific a feature to be part of the + FreeType engine. Moreover, not everybody needs it! + ----------------------------------------------------------------------- + + Finally, the question of sur-imposing anti-aliased colored text on any + texture, since being even more tricky, is left as an exercise to the + reader ;-) If this topic really interests you, the FreeType mailing + list may host some helpful enthusiasts ready to answer your questions. + Who knows :-) + + 8. Other interesting text processes + + o Glyph substitution + + Substitution is used to replace one glyph by another when some + specific condition is met in the text string. Its most common + examples are ligatures (like replacing the `f' followed by `i' by + the single glyph `fi' if available in the font), as well as + positional selection as performed in the Arabic script (for those + not aware of this, each letter of the Arabic alphabet can be + written differently according to its position on words: starting, + ending, intermediate, or isolated). + + The base TrueType format doesn't define any table for glyph + substitution. However, GX, TrueType Open, and OpenType provide + (incompatible) extensions to perform it. Of course, it isn't + supported by the engine, but an extension could be easily written + to access the required tables. + + [Support for TrueType Open is already partially available.] + + o Justification + + ... + +To be continued... diff --git a/docs/i18n.txt b/docs/i18n.txt new file mode 100644 index 0000000..22f5da9 --- /dev/null +++ b/docs/i18n.txt @@ -0,0 +1,161 @@ + +Using national language support (NLS) in FreeType +================================================= + +21. 1. 1998 +Erwin Dieterich + + +1) Introduction +2) Using gettext (user's view) +3) Using gettext (programmer's view) +4) Using gettext (maintainer's view) +5) How can I switch off NLS? I don't need/want it. + + +Only Unix NLS using gettext() is covered here. If you are able to +help with internationalization (i18n) for different operating +systems, please e-mail me at Erwin.Dieterich.ED@Bayer-AG.de. + + + +1) Introduction + +If a program is to be used by people who are not fluent speakers of +English, the first thing they will ask for is communication in their +native language. If someone tries to implement NLS in a program +using only #ifdefs and other such programming strategies, it's +likely that this someone will get nowhere. + +Gettext() is a possible way to help. Only minimal extra programming +effort is needed; the translations are implemented separately from +the program, and it is not necessary to recompile a program if you +want to switch the messages to a different language. If you wouldd +like to know more about gettext(), I recommend reading the GNU +gettext tools manual, written by Ulrich Drepper, Jim Meyering, and +Francois Pinard. + +Currently supported languages are: + + Czech (cz) translator: Pavel Kankovsky + + Dutch (nl) translator: Gertjan de Back + French (fr) translator: David Turner + German (de) translator: Erwin Dieterich + + Spain (es) translator: Miguel A. Perez Valdenebro + + +Currently supported programs in the `test' directory are: + + ftlint + ftdump + fterror + ftmetric + ftsbit + + +2) Using gettext (user's view) + +Using gettext as an end user is very simple. If FreeType is +correctly installed on your computer, you can simply issue an +`export LANG=' in your Bourne shell or `setenv +LANG=' if you are using csh. That's all. In order to +switch back to English, just use `export LANG=' or `setenv LANG='. + + is a two character code describing your language: +de=German, fr=French etc. Every supported language has its own +.po file in the `po' directory of FreeType. If your +language is not there you should consider contributing a +translation. Just e-mail me. Here is a transcript of what `export +LANG=' does: + + test> ftlint 24 furiosot.ttf + Could not find or open furiosot.ttf. + FreeType error message: OS/2 table missing. + + test> export LANG=de + test> ftlint 24 furiosot.ttf + Datei `furiosot.ttf' konnte nicht gefunden oder geöffnet werden. + FreeType Fehlermeldung: `OS/2'-Tabelle fehlt. + + test> export LANG= + test> ftlint 24 furiosot.ttf + Could not find or open file furioso.ttf. + FreeType error message: OS/2 table missing. + +Doesn't this look good? But what if nothing happens if you set +LANG? Here are some hints: + +First: Is your language really supported? If it is, you need to be +sure that you have gettext() installed (if you are sitting at a +Linux box, chances are very good that you have). If you compiled +FreeType yourself and nothing strange happened, then your version of +FreeType has NLS compiled in, as this is the default, unless you +forgot to install the translation files in the right places (`make +install' in the po/ directory should be enough, but you need root +permissions as these files are installed somewhere in /usr/local) -- +good luck :-) + + +3) Using gettext (programmer's view) + +If you intend to use NLS in your program, you just need to make a +few simple changes. Here I only describe how NLS is enabled in the +programs that come with FreeType in test/. If you would like to add +NLS to other programs using FreeType as well, take a look at +FreeType's installation files; you can probably use these files as a +model. + +Every string that should be translated needs gettext() around it. +So + + Message( "Usage: %s fontname[.ttf|.ttc]\n\n", + execname ); + +becomes + + Message( gettext( "Usage: %s fontname[.ttf|.ttc]\n\n" ), + execname ); + + +Yes, it's that simple. Next you need to initialize gettext. Put +the following in the header section of your file: + + #include "ft_conf.h" + #ifdef HAVE_LIBINTL_H + #include + #endif + + #ifndef HAVE_LIBINTL_H + #define gettext( x ) ( x ) + #endif + +and this at the very beginning of your main program: + + #ifdef HAVE_LIBINTL_H + setlocale(LC_ALL, ""); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); + #endif + + +That's all. Just have a look at fterror.c in test/. + + +4) Using gettext (maintainer's view) + +I am too lazy today :-) If something isn't clear, just ask me. + + +5) How can I switch off NLS? I don't need/want it. + +Just say `configure --disable-nls' and recompile FreeType. + + +If you have any questions or comments regarding this short +introduction to NLS & FreeType, feel free to email me at +Erwin.Dieterich.ED@Bayer-AG.de. + + +--- end of i18n.txt --- diff --git a/docs/image/baselin2.gif b/docs/image/baselin2.gif new file mode 100644 index 0000000000000000000000000000000000000000..b9c28bd65232cc13a4b9cb292912036cb0a2b1b9 GIT binary patch literal 1282 zcmV+d1^xO*Nk%v~VWI#N0q_6-_5Sn-017Ms0001@022WK0{?`MsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lUK5`(Nt;hcO}X$TA|ACnfVKazdvaDfNo6Vz(15 z_v`S2#|bg{Y(9_E>My&!eZ#Nv`Lu3-;`7Tr|LFHO6e##ZSg3P|h@-e@)96S887VVK z31fNblBt>G(+R~1nj$*d^ofaT3Qs~)QGRx!~rUH=wIVI0-*l#gc)bL83xl93UV zphA|I##{|y^DlA=*@w}=+yd9+M4rBDM}S^3ma z&nj0@WmRZZoldG?^({bpPtaBk4H2Mii)d{IxYShbR9l3uwWeeX$-SU=uhhPO{#HmU zcyM4lhR^xyikLCNZiMqRZb$j9<#cJZXr6PK6&o*KH@8?^cUNW5r{9n+%^F$+F|cFF zo4xO|n$QhUA23sUw`|;Df)`ui`}bqxYmnFJ%-qezu17Q$KaVB4@q(+F%NeEb{}tN*0#S43Sz7T{D^c}0|eH5sTJf(_OM zATaM`N1%jdI2WOWys>AYE3I|d#fKoyCgOjWgd#? zl0@XGWusr-(Pnk@C0bRILaMf=L6!O^X@`)C$!UgueM(!WTA`Yos%2>^b;_54@z`}VfqS!+FTCsy< z>*kZAnyD?HVLGT7oq;+v*p?eA6Rx`=!F%SHe_lDMu4hi@(Y|(_hhn~9{QDb)`|gME zk=|0epS=Pzd0)Q=!>8YL6GJ$ivn>fUE1MZFY!=2jK4|HJB9C11fgm$t(zLYlXW_%d ziP{f{GK*$&%{0RdD9;`XrDIA*F(Y(XQ|0KgZDEm%^vx`X%qY@DF?jmMu56T;I#~-FPd?RCy(>)85y8tEVjB ze)Ij`-ly`X__Hm$sj+nYR1IO|T;Vv4Fy)nFE{Q#|mW#MApG*685>Q7iwM?h$oAiur zXC1HVdaIqf>}j*x^xwB1KKFzIdr7$C2?PGKSHyc9u~0En{5YU*m(En;oEs}WNMoH` z6Uiu>oU(z?YuNh5Y=tlW_~na!z9;FczrMxoOZ@&R@f$pU!1ddIe|Xc^yZ@Nqi`qYT z1rT2Yq*DRKbwE5N5KarUSpywnt!U+MKx(sG{IYkl2_6P38PuR-l2SVlZV-eP%wOX~ s$erM!&{ie%Ao*4pI~dAvhBU094R46U9O`g~JnW$le+a}Nf}sEaJ35|-iU0rr literal 0 HcmV?d00001 diff --git a/docs/image/baseline.gif b/docs/image/baseline.gif new file mode 100644 index 0000000000000000000000000000000000000000..f966ad2181777b512fabfb92b0ca98863ba715b4 GIT binary patch literal 2976 zcmV;R3t#j{Nk%v~Vafrs0Pp|+_5Sn-017Ms0002W0kZ%A0{?`MsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~{tpZahs2`sh)gP%%%<}RjY_A~s`ZM^YPa03 z_X`e-$K}G)TZmZ%L`p7QCuk;6g#!mrA5B51%U;W&e6Aqi5b z2YKR0sR8-631Ha~nurOfcxYGZp!$(|DY|po$XUY2dWRqj>e1Q9aJveNqL~1!U|iXS zhrBx&vy}>-qm5N>aoEsy}3zt%w-5jY5{#X6&yV!8PPMaBcSR8jM>H3?m z3;J(VBRZA{E|Wz`mp+BA{w>(Yupc6Rxg5>{c#vU0h5z^lQbYwo;KF+z^;MMUk7UV{ z7ZV<{xU!hafiy9`tC?&WT&9BEwrpJ3b7HZMkD^sd_nOwtqeUw|I~S?xoL%k0 zHd|F`N6=1BW7Z7zaBJbJBU2Xcn&Z~Wla~u7&Gz!@kePv}g>IaI8$d-Ld6+Q0FsECcb#R~CVHZUha-@(mFFIrGPZd~ zK^n2tPCQ48qa?| zbqP_cuC7ukMUi&MU^-XYV?~#8Od?Mf#{VMvA`uZ*kSq_+9veZlS4^v3vw65TNfmoi zs}s0|F$vqYVAkPnw&Jck;Hz;K(djwX>L4k*_QE-Ayh(f_@3qU`3vi~vdOB>t1|N)Y z!U`|UaKjEi3~|H~PfT&e7GI2U#u{%7#K5M`YeTRgbF2nnAv5Fg54Kp7GRX&<9C9~G zZ0Fs`F5f&3JyKj~GtNG<#xelPw^#y z8%oFKpm`dqc$#Xe)tuk-B|Rk1rvG6(xX>8x$ul_GwaZP0?pB`UevA>P9)m234(50* zXO48;Vg`8~YEt)E^JwBYDXCYhk0~|nT2^gfg0QFS_;X{H?rxPP?r34>3f8Tze(8OF z=9N7ke?#BdF54mPxg|L#bK)5}zLnpO7`UBl6^Xat+%utX^%|=9EMM_|R=$|}lhwY{ z!9`G<+ui=S^FILMZ*=oRT6=25HCMH&AhpudswSd|rcLTnyK$1NMiIPS*@|k9Dvc+s z)<83$Foi6P80K0CLxrs`hBRE*3~Pu(gVigCJOmg8dkDlJ3UP=;ETR#Qh{Pl+afwW9 zA{#>J#3=4;g;K0yqvqf!EB|T{i9uBC8}nM57zUs75%p z@r`s$BNa_C$2#iqV|i>;ANL4Itld$Ladg(jw%5WkcJYr(7^4mmnZhz6(u-5Hm?MuU z$?Z|nfsiCaAu*ZBYGjd<75k(SGkHm!jM52%d}Jzzh{{)1Yn5&=rM+4S%3IO$FT0!> zF7L(2CQ?w6gXkp^jA_GQGEpR(43jd4&`gI#vx>}|CNGfbENjY8o5ExoH?e`uJSb9{ zch0~6IWJD-Qfsz#wvzY6IAUczn$9Y!5n6XS}Gu0W(d-k!Md<uPv z-m{0`TPPXNiBNVb)c+zAC8!`TCD4k>a%u{#l}3LF!**H}k4O4wAON-1|Lm5oQ0>Q9M?LVZeTn8p$+uU&Qm=k>u1%$C6sagya2B?$EGwiM{hCFJmUXa{ee7cInnS@(wWn}hD?rC+ z+0BlPsVm#8L*aVa&epZBi{&gxjVjttz0{P6b!})78{5>zcC}n;?JRfe*$m>6wZQdl zR(oqx)e;uCIR6x_ak~nPoNg7luf=Rq>#5rQ*mk2Kb?kFzn@Z^_mAbUe?%4QhSCBf@ zyfobHcV%jfl-5?U)nzWN&bWLza^_O zQ9R-$LN&%OmSsjGn&KHR_`v|iD~*GEa^0_7%RTP2J{i?}{rI!>t#FOgyQ?4fH*_-?aB5fEnx!RqkxhO(J16Yo3pWS0 zqyH-M=iMiiLT`guWXGZiiAvXSf9dZsqO#d;@29I)(-vt`3@T0XcfBzfq z4E*HCzy39MG@j&s6f=Nkvwcowehd^+w}b@+s4a=0fc^)8;lNAu@-{Ogf!`N_9kU_O z(ti#ZCK)J7^79NA_eySPuaRG)hQ^tW-=pI7@Pvha*UbYlwhz z*aB@q!~j_b&d W?dXp02#@h7kMl^6^|%2A0028oMbhU0 literal 0 HcmV?d00001 diff --git a/docs/image/emsquare.gif b/docs/image/emsquare.gif new file mode 100644 index 0000000000000000000000000000000000000000..21dcfb34eadf72af2e18d12ce0b1cd7502fc7602 GIT binary patch literal 2917 zcmV-r3!3ytNk%v~VNC%N0q_6-|Ns90001li0000@0TKZK0{?`MsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~{tpZahs2`sh)gP%%%<}RjY_A~s`ZM^YPa03 zcNPeI$K+M`j6NICp0r!MRzKJbIsjhI%fbhK9DMZ-R}xG;!_XQ$W5GME^c*fDvR zAlFa{ScvK9i6SYv8B)oq*?0PP`N`Unnu-BSm}%%x+KQWUDr+%$D7IT`>zmuiE10>s z%S*f(%q+_W>3e7h9Ez&YSxmxM@(LGjs+tUlNZyB@T&;S&CY(JwYb}lq&pqPZ&2HI$ zKRw5dws`5RN!W%?jW~G(4bE~$?ijuc0!@JP7s*~7jsFGzHH5H@8bfs%NB!bBQBcKw z>qY_`W^Q1@k04*V9QQF}HJd3vyx~WQpU8I5Vy=ofQsyOPOF4ELs*Whoo)r05mDo#Y zNmLS<$wR61>&crabt=M2b%L~OXw_<6nlxaYje~Zh?>_zx`10%9pl?5a4E*~0KmTIxUx4=kC}4s65oln7|0&4efDJyl z2Z9iiA)ybkO;n*C8J>gJhLpsz7%m=GFrq~uZm<(%(?$15iDi_SqHFK5=!lCiZpPs| zD;C#^jTC0Ujws31#ae4p>BwV0{80fEaKc2RT5chV_2g79$#LOsB<7f;IjdQM8ZCm6 z_D+yAYA9x1U|KfNnDmr62bieMX^WC7(h+7@TP6mQL09EDS4@zUX=ax-&ZQ7rZ0gAx zWUwgu=b}dyG^m_`_HwDDjJ1R0U7b?;=$SX36_1K_%4nyRSANRnPQ-CZL7|4SX)1uG zO={(o#$>7_s*U~Hr=YaqD?a#*QMdH$Iuw#s5;t*~om z+wF*23E82J^?X)pZJtUSMUYaaitdq{x_jrV<;p7@ud%AN2fwFCN(n>GQbkj^9ofXt6OWmQ<`gmbAv{ZkV zwb9OH4f58;bv?AjU{5VJX=J~6cG(G%eYF;Aqn$R~aj(~P*lDXhH`aO6EwPiLgC1`DoeY=Du z(lWS_Uh2}7uN>udR{6$LauSn@oFpNGNlY-rk(pyOrgV^*Ov^>nmP*9tEC&S2LK4uL z(7`4vZy-!)_L7{{d8RtUDNT4%Qg zcbG|vaF<}pN=}R*jQ)jM}r6|2(O@Z1>RnC;Ao($eiaZ1pBBB!Du z_25aLTGbdz^)*z@stt|WRG#v1tC#6&Hm@31qH0v8LsctQL4Z%UCiRv}{oYZ}cUPoV zQ>P|nsv-aLR<8%#S`9bYz^#?=giV{`i0RS4(G{A9 zU7TSAHug0&pwGPjq=H-ge5S5<_k7|rW7X1^-YlIT z4QYaP+S6*5^qZv{UsR{Mz?mj>se=q;T#Ig!+6w%2AB zazt%?>t#FG*oOvmupcL8__Z0?&tCPlTg~iATe+6ht~PO94eVV%x!mTiZ@6Dgit(~L z*Tm*BqhUQwXj6K`+AeXR^X=_Fk9OJt|F$OPP49u9y5Ou13Bm;~?S+RL%3*yt#LxZi zbmRMy7B_gLGj44W7_s9X?=Q%c8(d+Myx|`w_{1@M*_HRX}UC{O>v`YGRJ*qF->gwM1uoYfxhPPYa zjpldyyuRrxW|3RRo8Sr_}+K6 z*Iem$Z<7O>luMvM{u=e?r1Ui)Xdo PjLXQ3&FG9DPyhfsv!2DP literal 0 HcmV?d00001 diff --git a/docs/image/freetype.gif b/docs/image/freetype.gif new file mode 100644 index 0000000000000000000000000000000000000000..8be6d2153eea713caf6380bd719cfb386eb4bff7 GIT binary patch literal 10545 zcmaL6cT`i^7dCuuNk~FSLI@Cg5?ZK+UIe^^jtHTMsGtGqphhfX_a*^EMTrOsh#CP= z5jCJ9w($lPu}5rJW`4mwj*bx&)ek$(!t@!h{If{`K4oajUf`E#Cg}4AT_8FWMm7P#9w=%MoPWi1 zYy_-rK>B%B^qDw7z(?O1{rNwHPrw<&=HPd7|2>B325|N>gxv*8URrwB zf!iO!|38?%NB{5Q|2=#DAM^i-1=(l<2MT3nRrUIs4I4MrZr)O-+FHM@p>g|;rskHN zt-E&bQSWVQ@7UM5|G>enL*0ju9M$yn9y@-b?_~d}(`U|}`~5tj9k_7u(%|KxD<`HP zS8v|hI3-FLMZKXLxfSc|Y!?8NA3nW+2=9X_&O)XolMhoZo_*|(iv40|!ekl{Dhw;6 z{RYV1WF;lVgqtTN!dE$4N593NMwxKzyc-Sx9S+E_^zAB3Y|cK1*vc^d7jX4NrHDkW z>F*t6;bvozV8|@mXp1LmJN|WVP7MsPCEq^)u`$kP@rre$1xb}&{{Q@-sB)CM=xm&$ zQS4D5qv$PybgS76mHF?WrPl&g_SP>x_{pm;xiy zIl|RgmzscZ`{g(Xy7>nN!T-i+6m!C~A}#7ckq!Yn9zfBw;M@xt9+dz=g*Yp7)l)jL zZNVp!28GW@@}vMAUvIG#;^?z8%%14wCafW#%3>tC;w9t^Jd(xYjfyA8Ry-qJmP1cm zn-9VjSwKeDcVHA|Ik5{EJH_DW4KJ2st#PGPOk!oTVrXu`A_s(@ZBSQMvZ^sEZ@I>4 zo3UgD1~GzFz*s)*ui7clP>4eje|d>G63KJZLg>vISW9|LY9!6Om{%l;NtHptE80Y} zD8{WK*vRp2(~H%Nx2lFV-SszsO1-`Vh0Qe&%TST8?nx)o`4H1M*lOkE9x@BsG43qW zWv>+Iw6Ly%ki%IOnXeh|_2233b!0;}!ZA1kh?dm}nhn)6ad?hx4L-*a^LPc<&nHr% zl&t$elY`j+BayxOZ?+4)wZM4Q=UVOmA zsncmP1Ie=g4Y+`cFmd}-f2{JNnd`jBqZNOS;|$K(vZKe1vftSD7(X#!Mt;!};@IXc z51dLUkYg)y9%%;H#t-^uLup|;k`dg*@%KG`bB7Cgj)JDnPK(H<<3FKfOTD^JW= zeBdLDzTOl!Q>KM!jdCjtzz!5hX+Qxot^rb=p6qAn7WF40V+h{|J1Mfb{m$;@!_AM$ z82%tbiiGwv81+ETEuVx`DcLES0DNL=B=RSXpxEk;GPdZIi5JpCrE z(4lY9J^*sX$b9IR(nIm6=M~CG0AW>1Dt%m0a5^)uw4m;h$ymQz?VN`PQVrI3S10T7JQ&Z)s?Vt%8Ir@lVEE`Fhv306bC$(-E>p$qh0(}BlF)L$X>Rngk=l&iQ zYmZxcTr1vuy^>SyZ2Ak)Iu{(V0AVq_sm0Wcb?%ANlB#N_*iLM|oT7wop9@LfV_W0G zUotPelXPT?5ddk|$w#n|43?%mnRC1O#LW5Axn_S%n_wT)EM^I&p8m_cwka_c`1|GO z`lh2sGB+~1BIbV%lCe+=rg2uXf)xMQKc| zn-b=dVj+9GDCF7gr{CLhNBv8-3y4$VEQ{u%mF`KAJ(F;Z9=WWL= z*|q~Qr4qzZglL)X77k_Gz!3tpp1)lO}C2GvqT4Z;Sgjvr8PBqXILp1Oe zYBNqp&gD2Lp!2u2^yAmJ#fR&sZrEUoovlRdE5wS}<@h)&9J2SvCjZYv8~ERCiz8e$ zpc_n|J*rZKK5k~g1h@yR9N83nYSuDSIYn0TaS0EN%Q=QRk0YE)Q0OJyz?AB0-T&x> zBMx9x|5Lm8%i}=xx7(7i3E%Bj#obV>;nRLdztg@fB!)JQn+P>>Mb^uMa1v0^y>85` zJJmYnfR+@kVe7!uN&G=V`Mc|`l4WY26gI|Gd{&cHXV!Z)5tG>>A?~ZI^$QDj=8!Yl^-w4U0_-hbK`70fk-7F@7-HKBcMOL zgM_lBg*&c{j$L^*O->;VCWgtk9AqJk)^vR&M-_RE+W=@vCp7F;2xYJoH|l;brNleH zGL~Y(qEcP)?MT(BeR7zh$`WvEYR+pTH93a-!>y?gR=jx)wcVTnTwY|SxQn1cpS=(4 zzg<3P(r)?hhCh)B13|aXfSCC+HLYb7OhkNaJzEKdE+nc}TJc=Zt++O4XN-|O&vcE< z2##0$IxG2p!Kw3Xw~9xL&sH)s)^_vc;YG_j!IZM3Ce)n~d+=K6bH4>MCpT}3^OOLU zt5;HMNfG!}Lr6!9U@$s&+8vhtZQqU=(BJ%NR0(2)p!O`}(u`o5CSyYnSZZ1J(1?9f z%b5M4FkEjrdlBgFS0<{WUY@CPw8AzHIZ6OvI3D% zM-X)Oi{!`B5(ibm_yhlQ3L)ReT)=~O`lMM-U%>ldfWz}B zMVn@F%w7cvVm|n-blTnm#LEwKNlWuEI?m@Wr7 z5|5PWpsy|csenm0tT`epVM$;Q2|Ps+RL8dp2P<2(Aj-5llb;u>pK;I^a+XEC1?Bs; zQcjLLsrv-?>H&|d5LF2GZT&@gyMpu;d4|CR^ajtYO?E*s`pEqt|5JvX4E;(pSGeGEY0KLZP1U@HyaZr3-#nKeNkm%gx;BCO+U01l?5f79#H0bJ@|Cl@ z5$l1-f95t$zyP#kamahI%O`Ydab!*CiYmIg@f+kak^9Tz@#B@Lef60>A49Knx}oHa z`H6 z6O{7IwlGat0?4i^SgQcDS)^<|T(<-!!|@wmh-()^2|QAeEK2dIkmob|eIzu#47HcR z`=5JR0msQC$7){+Tjf2fH_hpV=5FOys+EVb(lbY*LSBWtNZVt^;doP*d5z+z{3UU!wJric-t))6&?qDmL?=CU(zs40OSmRH+uX5unqTnu=R#wBV6+)9 z;$!Xy6mh0dl|F02F)d{BG#U?tf^rub(j%Wxmn>CXi?lyRW_yl-2;B8(NF!Y@o^z)x z+R=3?8%a$HELDi1F~1*}De`J!YYe9H2zDLn_EuC9LZON?rII-vygjQC9esF<+Se;dmV0 zwhK}TO+ziSznd{x2N&k<%^XIA8c2|K%wH!AkqEs`N2ck?%shB&3&}Ojm@E^St79@- zY;D0ATi%&UF$mT*^VA_Xr%rX{o!Ks*;$3M=zccCPzp)-0&wtHxXmvAx5IDJx<6%p{ z-=onaP4d`-b9c!^x_kmr4p7n_(ubGFoQGiLa8AIcrnh6fv=5Mjq`-q`6{<7UKR)${ zGRa<=V=4`himj9fmIvs=O=Q*C@+{`xUi3{RN7JD|jS~Zpbvt$@pE$OEq)Rt>veck; zKPK|l*xu5fUbzTV2`(3Gb1_#zj^I$W9*Xf0A?q)^xKFp|gY?uOvl>d8m6c~&uRz_n ze+UV}dkuK!i@?U|16lb3DD#J@7F}7i$T*gDbmgMZ%b$`r3xZ9Y!-7=seka$4e62N( zzBxv^Ix4j0ol!+kW~d^q)E3dAu%${)QR~3qW3kmmk#9Do_J@s)rfA`G#W^y2lA5{S z*G2VXq9tTM^7y6TN>9|fi|V7_u9%o!t$4BYSVd=_2sr4&EL8_v?u9BFy%}ZPP~cjJ zI+ivJy2^ImL?A0^n(^X6hac{#Qk~N5*H+Bb6j^C5A8+@@G|*J++QLeCiv+63m`lP^mFOu@@x`P-qp$p#QeIJvcZyU8AM4Z&%Ppt-DJ6IDob zhSn1s8IIn&>zjEHk-*m>-1x%u5@!=$+lB*_NKb$f0t#=*Q&Mg7$sKFX-OPWQmFkr7 zYNxSK$}NXo9Iww_=IQ&wRg@spee7xL>9zT9KoqT-0zX48Q(fEu{x^Uia_PV5m4)u$sH1rh$ZeIo&DcNr4gKmg z#8Yp9#;CZ&x?_LJ1W87??vaTAkdVa6*?kkU| zOOqra@hoKDTj88>;r||3|BUQ*EO!hMUF!X#XO&x|ZX@Wg8oD6?4x)`56@0~i)J%-; zt##8^uDES`>znCWzlMN~hi7)TBdKK1=jHpCp3Q4!C*l`tZZ3}F=_AbTg2qqUTE^(L zmA2g(P0PBSGfgv6b0!t}%C|-|I`F1UnE{a^lgjSvH+-|{gePJTN5T6UGt{-|hTe^j zhK!@sitO})=`)^Jv6H{Tu*g;P#?gGv09u*x=8O-e`Arw-0cW2J&*XZLO56lhCEqKP zxAgk`C3yTZKkcy7D_XwfCku8q0533?BtjOgoWI*8GH>tMCNFCfEIv&Txz{#3t1ac^ zo6+5=E7P>zd;@GukQ%q1zlp-hc$7n%<)n8o|LkabWom;K>?t{$+w6Vqc8kZSjPK~H zA<}2XlWc`~%n$z1@Wle6*Y4T_=R=+^$1K_V{tkb;BFaIJ-aA9t+%b079C+$-jlD>D_t!xY z-33nIYvGL|NRYJb(G-K?d&Zd4yvWQ1=bwMK1pKdUlyy4uP<3LBI?YGH@l+eCzKxTP ziHl&Rt@%H=lqJD5Dznsh2}?xLzYfOcsR*8qEl{~(Y;0_tN)w4x5}8b*A-MQTjAd%= zF?s6jvQ@^3Es_=@UX2k=r!|;_tJhBuv$|hDww3e`ZI$viCE};M{y0_o!EKR7YHh1K zbhU*y8NBO~(4Wj!F-pM#$rXu2ty>{lSVr81$orE`{VlXMN2=&Hp-b}jHbunN2n&>>+HJt*#}tuTwew7#Li5FJTsy(?53Ux^s65LZ^p0 zOH<(rC(eCqgQM7^oUSoJzlaXqKfGta%BL97*ipSD~wcEq{UMvgM~6iF*agBT3)ZGQt~X zkW?4u+{Z*CLrWgW2KRyj;*UE*uyMb@aZ*O016xivd4k?Hw|zdhZ) z7QAhb_hIugN0frDAS`!3cQJ7Msqej&`enuISyAoz!R<9q+{6ri7bi1+8$ES|?rL}C zGQ5RkZV=>|T6}KV7L)wfzHL#VXmW%5&9u8UF()Jgw4!QiQEMq9HOiRIqUzF&HwJHn z$^&(P(tIVMc<;n)6UhL{E?cLlt-k3?Me#rbge;8MSkkF-(qTsP#XPXPCBkzma8cu9}6>LWi(U(ff-HV~xd?3ROx2!+6?&ftxQ#*Y!= zqB&VI&<%zny564HwozJnyfp3F3#aXUvMY4{arHal`IjxX(xA6jTu;5J8FocXiunpk zfQaWk1F6Je8tblP05Rd=M7Mbj?{9?TFA<+PPtHi(@-!fX=Iq6(RqP`F5HZ$jAe(j$H&44yxsSb5x znl_0TJ)Gt&LG8n()31$JaX&>9Jul8-ySiMM5< z_reP0Qux41aOUn-+`a)ImxtHGl;OUlq>a<})oWq4M$7caNQwP~>9SM?qtRf&&uVy6 zU*8@kMqr8>Gh(SWXx`4VgbzT@@h%(doZrq}b&Zd@hz@4u;zkk0fQIRu)0_cfhT+Um zy^^K}xIexb!X$9y%&Td+Pt0L^JRr_%lhLpvDoEz{uM$bg?!w5QY*j6#(v-3*J<>cI z&||NgT1Kg+BhRas!Db?MjGI#doLy(_RlT=>t9^@k!hZ z%c^#K9)OA~92){yb!5(TTDAYB~->_A(o0}lQ|oC8#;eCe(DWYn8=!8o6XF!W%; zG*AMWiRe46SQv_f<6H|5%JsHt(wkugLvu523@diAxF=Uvm`YVT)H+B6nKfbHF12b8 z&kg6w2v6f0$SA-k49&)mIZwq+!3p;cw}Hd1hc1TGRZvswrTk{yfLVr`>_fkFv@e%H zelcBo_eS2`9!Bzf6?}qB^d!VXrb1B|t$ZoT1{2epMAMJ$UBD}D#n2NZ6Q@*1v(fp$ zIa2Bo$HlxMeHr5P7$>0{g!C-AY^w}e1CNr^`gb$9oqnUFo_yC10o|9iedDZTS%MFa z5PFciJINUyB8<9z@sR_Y&;067&Bu+sx6NJ0_hfWL9@pc8NyFXd2Io+!r3US~m`gO2bnI1pMR z?pH|I(mDTPyWK(do&9a<=fG8eAScBlmeT!JIr*iJu=5FSBGs?{4lcWK)Cj#ix92Jk zBWDwkiA)an#vqm~tdiTIN3ClhGzpu$L5SCxj7WVmKQzuzFCy6;z^q)byK$ZhE^qhY z?3>&0IKfiow3q4=G2Ba6oc7H%JHSbO^4Ztewg5{0YkS<|FA8^mH8oQRsMBUCX%_?g zD(;{ZZ-BZMNzql2v0XWYX2Jy1!>O{0t^k?Br(D`<@qs{4hCW}YG|LUa!5qn3Y6h&W_h=14QYTLxkWTAZOa+8z`cu z4{q`c`C_@<8C7g#`;5JzJ5Z0W1l;!wAJj=u7)wWlUq#%v|lMC?so z?Y4>BT&!RTtKs(9D}hi~&T)Etc}A}{ys5aHkz7ZQtppd%v$W&@TvmAoH+Iw8`E+2A zopeGx>3js<_ig0XJQDCC^I`{WSWsV6;Y<@s(a~FwiO;L}>;EO2xuLqFYtMlcBK4x0 zB#XLIlt-GzihS*U?i)l;`7=QifQof~*M==@DyOVrsQ3r*Nx2(nT(l8GZaEQvDOvJI3l1e?G-3~luZ0xY)vL13gIQouv=r~AHl@rvQ6&>izHik8|EP~I|r+As0TKw?T^a}{a( z2?Xz%W38e6>hLyK0~U|*0VzMvcf+cG+oGMteI3Unz>(Ai)B-q-TUd+1cj921OWbgC z_@C__7#8#282Gzmu`nG@BsRG$_M(eI+tXpmy}&+4ZwZ*Yrh(dZJIhuEZ#>}mgje|Y zXVRr=ApT-LSug%UKtE(QK`MEW9zyw(F6>|Ipi3DXVD1>Pv9DTlDh^VJ!K+2p7w#k| zDnPZXaia!~_H&{*!>R^Mq+aprK9bv>{4#UG9p<5811gq!UKLYc&k#qls!X;q2Qi9D zyYOK@ZGPq^V@X_~0o-fKo6=9)LV#q0)LiPB=EJZko_*2 zWsw)fjbwn$3~+&v)~Jrf#Uz1@6hNVVm660EQi3+14O;>0pmhEEOqTmyoo5uUhDbx~ zFsO$e@7YG#XZUSo2;P#li7bJB(eO|e=e!14Vns*Q(n+k$|Bj=u%o&x{?a`<2@=rbk zxxi|_Pzl6RFLPZUTG~NkBTZ`xX47>D>w@Pr^vmJ2|=bI>C_hr~kHI>Dv!X4hcY>VRm%yoOGIdUCwJ$d}T%U@(7eB1>4D?>$2Y z(U$yrcJk0jAYF&1@Zh)iGp4EGaAfoQu|zu@>Tb98Sz$)f@V5W8qip-ic(xRE12!O^ zqk+Pe&JREE5FM-&0N+SPXDXQT5tI&Ee7_x7Kb(MFK+4E#i!+c=;G<{*eOA*asWAHv zv|R~%7%+Fe`j2OdU`{N<9nDn3nL2bD;oW*FDJB&vs?IQd0oLOtY4Qn*la(<^1G$sf zWiv{@LCp>}7__`i_s!cT}WTyY(~*)kV+H%B!C!3il01;s8TBd;jOejJpZ{%aexj z@_(qJ8m(hp?}FXW)Q`9AbjPW)&ALR&SQv*hR9pG^N1g#50p67QrH`tO;Lus2aWO!Ji(H6Yhh`$!k0J zDWZANgj^|7e=p@fbkS3sc2^hwRqC(>`6ay|?>neQ*rG>->U1=i1FW*Ca{zRmC5H+?+ zaep?|KgsTiXgT<|X^#pxfVtzg)zWh)_{a z-&wlcF&-oOKsgAcD0{Jjs3tQXgI%}SJ4pSqB%v_3=}Cv%%sTmwq>pOZRcHX69@dv3~}dR=?nd2 z7n3_N_27&k`F_da`(-!o&wqD+p~-_q LIrrrNO#c4>PA>Z0 literal 0 HcmV?d00001 diff --git a/docs/image/freetype.png b/docs/image/freetype.png new file mode 100644 index 0000000000000000000000000000000000000000..d520046feea150e020521bbd357db478b4c50db6 GIT binary patch literal 10756 zcma)CRZtwjvfYK?Ebi_SoZz~+`@-Tbi@OI{f(3U%&_#n2G)Qm>ArKY_L4pQ{5ZvwM zRlRz@_g3}vRP{%9*L0nk>FN`&tE~dUrosjQ03bD0Mg4#K$-jlbMER$CIs*g&00w}X zq8ub>>Bs^reXD~^=!G7^|H(A}3xj{cfvI4_@mk~fhYfV@&!49T4^A55?iGs$uE&B9 zm7V4Z;dyi4$^WeUzuh^Up4;Uf&U*hLBhUHBE0V`LF=f|~Y9YhzZ86h3?C$MsGWg=c zoSrz&7uWK4vzR^kzOhuv?Zf=`+ES9UsBB$l?}7y9FlE@r8ckFx?&7(zwmvWyFQ_1r zGCcH6s2VZS_iPc=b&)@hzzC{cX<1It)n04tb1GxhT=*MJz= zu(RHH4wh7H}YPcA1X&o>1iGkz?8A1LC zF~R_E0L*D~vno=x0#a|lIl zR7il;Um~^db~ER$b`A8Xd#GRo1Qs0cy$^%o%3II}Dt#yD`Q-=Q!y*8QjwL~~NBji^re1S$Ug;BkwzTu};bbv?E&s>!m{v-10}#K|rQp;3}vb_0lU zs2%6*3|esL1GaKHm0?N)rA@y4&SOZ1zwquUKZJsJcX?t;&OfmmSUnl7jhU~psuI&Hf$2N=%I`3bo@Y3Mp}yH2 z-U9^yT2chD50SHH4WGbR&v4-zKehPbxKs83=;nDOYl$C;P%(Jz=pU-f7(j5#3Og*q z*FzF0&p@&hOr+O$AR=b!!homJK8x8uiAHfeVnac!IG3)VG~geWEnYbHZ%4`ru`?N+ z7x=%}KrXMUMQC!SNXR?=Om~ee!*s_!Rb6Ny6e;2GdV!#ntUx0~o`)8=5|qE%A(Gqu z{J{zQCC{{gp}pe6pv%w5qcXr=MgV`%cSAj@1riyS#0<$D5twLwln{yFl+#4jEUUY%M)f&LfN`_XHv~la1eIO_S+V7s!M+??xweuzmJ&iA ziBTm#cIMRs-Af3^jj{(xpQx)ki{V9w5~{xG4x}}vEx@FW3*2L9#739hTn)(sypZ}!c<6G(pJ7t1WFfEt_}S}m`T z8yzbd47tS$#A_?OVU^kqDM7h#DKCx>PFbZjf(Jlcf9Mwd3%id^;Sjkl?=o?$ivKZ= z^S#Y=OlzMSY3xat32BL83~Lg=T^Vj!_+yG4u^U2*?DrN}9<7NNNA;jZp%TgJI@hj{ zdy_4KJBD>9aZO$~?o0eWm=LL2xUu`nNfe3?!)sD=62YvbF}L{A7YhD@hfEhu7yivE ze+{qn$h6;%Zj!m7{O9>VB!)_e7Ey9j5DPb=NIuv=%4Tt5=-L|qTrAQ33{vZWg>3)g zH*@|#K+xoMI8(U5-FRi7VdUDXWkHg%QH>Sg=Th6e}gLE%dOoxil;sp{iS-Z!mms6+KO@oiUkwtLP( zpTfF4tT=jpJOhx#lfI8?X?PMFUZ?#<{(I*^3*^0ky=^6Mes#6X{JorMdu(gmd1F&b zKw@zA9tCiTV)z1tV9(nPVOO=? zG*fy$0>v4-fyTB0r8D?be!4Tdxa4A+kOK-SeH?kJ~F)I;5W={i6HQZ zuPYW1R{2>^*5*yYY0#PM)|Z&l#w--Np(@tivfCNGSo zo!YO&A0Wr@dm4xSbE%JE&mH~yK3N(p7ZqQgM~89It9|e_bE)~;@ct;%`tbS?dFIFS zuWU5@QEwCTega@Ijy8(GYLo)?tl~j2sbA$ZnE&4BTF2L_7r4B+$73IO!VKxPYEYa* zAll^RGBppp=vM$TCGqBq=UDC$ltdn8o6oL_!OrY(bgRxf&=~0;4J$bh>0L691s$Wlb!;c_Y6Ah@ z<1{+gT9??~N(b9KM*DXHbtYlB!xAKf+u9es>w5zLv}mKm8Cj}4Bo z!QNXLyrTBH4v)pZWBtxL0ZoL704xlW9gP~1VMvL!sg-HTA_JMDe3$Ol7*HiF+h~;P zPUa-L@8YB3_Z$M;^`BVci1YQr$Y|oHfIhrRkjtT+Wiab8XDARh;fxD767dJh!XDaf z-=C~vA(MWfpatN>c-@M zh@vCPUPdWfOcQgddXt4f^3)ldFhK}kskIGOH1heZEEFc0i&#-2E#rer9n@wn?K_oz zdossV^~E?F{Aq@Mrk09tyhIJ7%0e%g`7pFxpqGk8izovuWklkrDdvkbIk5*DJf_t}R^B!>A({!qgR1I=olz0D!2 z=>5_R+jP)rEKN3aQB)s|vq1>XE@kdfNk;$24x$=TjDDXHKbB~IebPN^%(z6$*>}tI--6-X|JZ@J4C1p z==TSp#bMvV{d>GQ{=%FL3lwavw2ob<=U3krk&*5r1Ys1gqu`89kjF2WGDqUwQ6yFk z?u9?_2suS7{rpqHwM?bVByX>LB=w)f-Cz@HPdJS8cC|n4_@(YM$t8y4RK*s{itW`(jk$F^h(r+gjTdpNslT{k-NHC3YC9g1^I8^E zvipm3+CS|M+)wxdJ646$03AeDlV5Yo1<9H;m*gmUN9_38`O#CN7HO&C-+kb+5Jv8}o9iC27QCZ~-5p#n(ZI@AEqtmcZA8HZx)3>i$Y7a0w7}k6 zkS6MVEvd3lu9;wiNORWFn|))4`oiJ~PtZR3m%}hKIbq71ox&}LX)zU4Q*8R?k>$J_ zmzqJt8Hvf;UvFqhMGjvq5O$3tS(>CgoH{J@$R{PTu3Aw1emgnWM`0qrLs-GJgC(zK zj34@+uyqv7OK&2n9fZ>kP2sjA9QEbKoaV~9mi#fzf@QVZh8$W4{5|on_*x^p(o8vT zRo_=N^1*f%!c=@RrNl90n~-T}M%tv6$+E+K!u??pf!Ijav}5J7MKxtc#ZoD~*K^I| z6ZLK1M3I3jf)%Y(uBRhF+@qqP7F%WEg4Eq_Tua03v z9~x@&h&L@`N>kTza(s-FCXpsC^E>!(HzADt!7b)5c~-`$TdQnDnO38vkyeCA`xjH+ znT_(3`0@HN;{*zm>?`TA?tpwjKq0j6h1kUL?I9Rx*t$0ZfWhQPcizpr$67Vl1P zM(d{#SB-9Z+?FqeefPe6%ILD{d9l~!v8Ff)w?K>?1}wqQeFN`30JJRAK=@|j;0sL^{`139H>S?6$&Y-^YuoMCK=&I%P?XqH6x;ID39FNw9!cza!E z2-o$VriFJY$XYMhEw`e=&-M)Wr2S@pjRoLfwL~)|o`R-9WCB-1ZS^vrfsRy8Rb!57 z4E~%t8N-_f3Dv}SpXxJs*ypgXg2*u`4W+U&7n%riWIL7QrI#!ACk}xq#W+ocBa8Xw zR&d7Zz8S3H#{`v7gzkKI=7zYN;E!3#4YFCRmR#dht?1kpOFIejs*akZR>`J*F-9L| z-5k73Ov@&)s*zHe>zZ6Qky5N1?wsF@hvwm-ge`4roa83QyMznOgODouM>Dx4^|T!H z!MCvhyDux zA45rE9;eyL$n>CTE%7uzr$biLN0MycDT-O}+iGZTyI44M`zt6h21bLQo;@2((8+8o zK{r^w_^pW9HN;CkAsO{O!YY(<)B{&7Rr0e8WL^oD+rtyNDQvU^ZJEniQV@iM&>b;I z@f{oN)|j~5evA>uquYzi^6DD&vyhC|V_hKhNhmw8vTMS*Iv{@K&TF>Ul_mcnp{};s z1x>w$=^_#evC013y8TT;;%jS?oQW~s9WIPG^z4zpWLMTGfssan9&e;`vI%{h-;K+e4*YXH+B3ny`uYx!JR zU~4r-qDXF$zRx^O(TY;QLxLNw=o|X|l8vp()USMniW&i$vZ@pXhL0Q$a$kcHBi)oX zc`|=d#EA8Zclel%g&5R_A*59=K)Onn^D?)ADvz2~xTL-|U9hC6sA_%e;J3?N2yAP~E~LQh$Q+99*tR3c z>G~4XB{lu`>r*JDlv(c&r(Afmm}F5YDmZR(QqT%lr;rQhj~$|A`ZPDYW&oz1jLPfG zXHm1!HNMPhN_R1X_j?65rwujYgiAn%_|9H&dD|b8M=jDqbyU~*Z5%1l3tb>nL;a6> z&a_>Rm!pxOO1|FKh-l}_%OqbNs9Xp|GVkYAbenq=CQFg(0_mi#zTb{(0ZQVwD=)Jk zneHE_)%j+G>lt!vqiDD#i>ODhPu)lQ0 z^e1?OK)qvsE6bLoG-Ep*H-4qz*2y4x#FpSBjXJ&U;YyepL%HtJy6NpUo9fzS$6}hOnl$I^}p3&CPreixim4{lS@r?lK z`gdsQHuj{iNo(>ezuX6{nNyVfH14{6`YS%9<#X`W@KhbY{A?uTTh}%n@^0tk?y7c! z`rSq_6#`e_f+StfBza+;FX^sn}2`GWh-Ly`;!@n1EDiK0j<$wU z(r<))Yk!{aNdX?Iz{68L!LN>Rry?>Vm*4n&?sjRw7T#`jnxD9Syb!811NWiznx1YR z|3#ZD=J1LzKrik7_pkYjJ&OwNqf|c+XAj(6eXF}MNmcq1Y6#TIil+V;dSs{qCiwP}CNW<04xI}vro3^megiv|l?TZq8GE2_=@9+BblK^_xjuWRq0oneme zK9Np;{>wrlGLIjRbhB0|ecmzX3pWr(>@Y@wY@~sY-$CEQnkj=`QC!_cU(GAF5LMgY z^+c8oPF2ttCG{@Kb<$#R54xw|E<0r5bbX&x+32rrpK@%!etuFiW;HwS;2D)b*KYen&lcK7&_-Lt53a5J za73C={G@_jw*RJMN#{7<(ry)yWkRo#i-e)yJzWPAr8*0St!tKq@} z{N#zhZw5XcjqgAjDk&YzrT$=U(*i(aJ2-Yjc3k8WQ-D@t4Nd9MByvBPX|Wkj^&hL; zv5?=rly@4_drW?gii}&7hYYnves4eb1^_kjPh5hJGOl34-OutgpPu|!iQffG@P0^M z{;BEuk~{!%CHowM8TQmoJ6>M$KKqGKnrO}P!6HUZp zDb&Y66Dt_*d|SieRqa%q&nEC#QZ6csZJXAUXe}R zv#dP6?HBGF>rOUtl&$Ng-n^ke_(yVjf7*Vt9on!p^8LDFNSmt_N)m+S+aJy}rg1fd z&}tdhUSFscUpC&}d&}HunkJ=(F$O56br7DDFS&1gZSGcvdqr z<6EbH{K~1l`Ik5e>IxVNe`hRNSSYF-)zmBbw_HzoRu~p3vwL$W;pItU!Y<}mZ*lHv zBHA~sS5J;mCOC9+Ji6TpIq}6ClOaMeW}G68%Xal{l-JFYkRqrHzqme(!x5e92v4*g z{$L~c7=e$>NZovC${H3A53oi<@kqvR$Cy6{CaUF%%WW7?Cdfer;gD_ORl6?!`4{6l z<1WKFhl=cE8#D5P){L=z~qGWn>zX4NWOm+qt6YFFq;7}rjn zkg_8^>3IQR!_txuZhHT1erT0q4XPc^z!LYXQaf*gt+RO8u+vf4Ul8i8wE*z?Om0z{ zc!E1TI$Yt;y$d}&**fV3)CDXsp@d&=dk!w`Pl;~4?}4hfUwpQ$XZPJkpR8%52U_sc z;+@ewzu(UOm~k8B)}vz3L|9=rJ8;EOC7juIPtRnp8r!XuR}W{a$^eN%An?(2&<`PI z(WI1_szL)qfNs$01%pj5Iuh5slpbbX)WCD6Zi>39Av5HtRK&%T-R;|H?RPMAN&D47 zHqYX!-VxhBK39_xL_~NP#F1x)2rS|$==qhhV!Zv+ z@-@2&L%qz*!hBiJmB9Xy=PSXI1+c47Wjvzqu{87(rn@jE!kzd?H&XvsJ>HDAMJ883 z+8JvgPc};>yLd}eJT!P=BnQowT_HHsI?TRbg4%6t<^->+_SAZr+3{ zcm(|Nxtq!K%#T?Jin2qN3_^#A6pVZ`VW?}BS;qN_r2v^$8jk8pvtc!!VSN}`~hEJPQgtMw^+somedxl)69CtX>Vt823>BP7ADlmfan zuc#r6$q*O5;a(hk!|3!Km^oxyhgNU$9KX^pgmA}!SuY^B#Ch3Q%7UjC_tI(ICz>eV z_%-l7A!YOv@y2t5b)B(!F=}#9w?VxU7Y4P~g~W4z&hr1=!v=e!aOHzH@T;sg7;q&7 z_QT4Th#2OlYAay)MUD!X-1LBs#4F?UbpJMjj6ZD~SGzbv5tgDH%p?ReAHwTyDUhFF z9!q~O($m5OD(8=!4k*P2tOUHx$j+et)N?*u4#!J}EW#hzo~i3XI5Y-V>C6>Aci0ec zfU@nB2fJ-PR$sb$qPUy6oAdLpy7+#ygfEs1NFSrsQu**rH6$Mq#W*#j@nyh&;c3eK zSsoMEt2NPet(;axB&;vAuX2AbghPac7Q^(Nj;)fAOPK5!b^=y*-?Gz1Z1!vly*VAE zye3gvplr+4vBGyGwidCS3BSm;-R?C-=BKq{srAI-8#?QTurcukS{;Hfoq8|4N^4iz zTM6&5kz=Aiw42(0+G~2I28y^FwP)MyhJ++6XPAaO_BZHUL4PA9kG-+W|Ivvr;WpSdfy7;h7e>sB&* zVD~CJqV)PNN*XB`xl;?}hkB0dZKMBWM`TCww3Vb>I5AtWq}M?Lv5rt+R^;3(Xb7mF z_A03Ytlw0(O*-o*E;(T+*fS&468|hm#%f}=7xUncg1(*s3SwFc=~Ddn7ffbEAAOSu zS&4FC$>jHAoAiV7%f3J}{qn0MKOx#KY)w$}te0Ih+XfPg!(0%%7`tr`HcaniEFw3Vh3AwfsmoHSpS2r3Jq=`FEw-=f#$xB9O`m$ z*Ldmt)+k47z~@Fwx3Q(QWpt_E;E}alY@JTOS(N!!7aG~9jv4z)7n_y=!(yVB_sP2< zDiy``Q^r=Z`&0m(&4^Z!mOu0Y?GTf?^f?LH7oNSMTH5fp*{XG)8g)gESx}i zV1VAo{iyYB=kw1Ocd)@9aZ<+&;1oF^j;?1+x|1V*)tqOngP&EB4br7JZ2dad`%&sd zj9*pZD?bS+FKU{mPvB4&C`{`gm@lf6=Kf_MBQ&dGY5ryoyY7%j52B8>ogz2;khJez z+>~5kb=W*lix3$2v|-%6(9K=O(1Vq{gRa-dqv0|TH&l<&mg+P5(Pb*_lxH0YfbFG5 zJxdReCu9KE#R45pk`Tu(36pZWDqv5_Ny^#Ohs;fccfzr`yLZMBlXmA@n+@7#KJBVl z_u8{dik}t(!L^S5sFKN{4q=N;nr_<~HOcqbNS0ARFvY}|is|)FrR7BB_yx18c>9_O zsew>|iB0UBO$$I33xS8TjA0;r80JruJ&dhQmCN*6Os)7%uW)WI zBK&xqwO+5WXrJxze?%4qd#kNFk-YejDw@HLo%y4aBtPvksj=94T0?_;@`~(^O^))` z9mC4jmBS=s3-XczE-)YIO>PB4B|a<2*BUFtQPKGF*hD`1}(jd?vp_C7fb*v6~I=Cs_)cH5OL-ZS<6!Md$X<5QgMKB zM$fngopazqY#=H53STRM7d({9wmtJmZg?MVqc5%ls9XLWxDoAoPv(?OdesJ((|@e` zD^We8u$b}7qRjHdpk^&aA|8M47sAQ#H))6KxDBg)!UHzBQR!U~V&J*PIg=k_(qo3~ zx@xDVY5M7%Lzao#ScJiy7nw(u$+eeyuomRvnp z$JqmimnSb-NW?q-0weiLUO|Hn#;7<=?~J@m@Aoxf^y>zu=C0PC0D-?klTCz`#}k|O zq5-j%&Mp;3#8d#(J2O#$NG@H?xU!82mePag_R)*Cg`-+Oj;80|>COfHC=vfbJ7+F? z#upalzW!XI`_o{yO_vszB*EH)Vk!UUz?|b-uRgkS(11{J@TLjT<@EWUo^Mp8q@at> z8Dz~gxe{+lLrj0^G<5!b2g;;VNHWOWnxMo}P`vnp6I(0J@o1HLbso7_@~|m!$1`aw zwT0LF1d%x;8F1oU-Yp~&uCOR{xh zpI6(62s8c(UQEie^Cdl`_gmXQ(ET}1;AzhB;rMsbN-VQ&i|E42F#nrf8@Y>f>Lc&s z!MsQ@p1{5rh_EPa$$nRw_e=N#?%h?y-P%1L#!?!qOLMu5=WQ}VvUO3^4X9lFQY1s` z%(HrT?>-A*VB{k=?)|;G4^?+mY|NH2@;1Z%23>+t{H(#RDp9dEHcqnZRq%K3j4&fW zYfn0QH^n?C7f)tdSh~EFa~wnZ?o3Ayce{7ZwYUd=S>xQ5rryO4rD}fJ}Nr`IfX+J4W=b`-- z?v!uX3xq=mcC;{2`o8fo+T+8=ox5l)n>i`UY+9d+a)ED5zG1^N28`84;kJY={L@nN zaXe9Hj~wDoj;3}Ep3!d4;e5aTD-z}Z^DM0#AMsiEzZY~!DwzJGa$@+YX(?e$Vq*Zv VCH&QwuKt+-YD(IQ4f57+{s+Khk!%0} literal 0 HcmV?d00001 diff --git a/docs/image/grid1.gif b/docs/image/grid1.gif new file mode 100644 index 0000000000000000000000000000000000000000..db15e23cf1c1288efdc8b4b395c8dcbe6db2e592 GIT binary patch literal 1399 zcmV--1&I1bNk%v~VbB1<0Pp|+_5Sn-017Ms0002c0KotN0{?`MsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8A7Sw@Z-}BD*iH`FLhcY0Lh)kk%N2T-Wxiz8Gs%2`;RP&ZBD1k~{ZLJuQouwTazN$6;)w?Wt&fSH^j{MGRE*>vGPZVpfzt7+A z{|_+WJwP-H>N=>%o~(QZGcYW~>m9s$=p+)eI13{-jsF9~G!*vn8p4GkCxRR)GS@?g zCA*>2ScxOdix@kWtLSJ9P73a>>?HOx8mOS_(hwarv{+JRyOcI%>gXsqolc`xl?D}S zx~E&M&O|EF<{z=mzIu}xY~@LoFI}o^$rCP3wr|_UwL5pM*{hbFY@EpNO2+vTP zQg7nLYuq_Df)34N$h9K(5+lWOWynk{Q^w&LH0R2jJDc82x}4mNcv;ikE2<{!tlSJk zYJC>Buh-93=jLsaF($;pi@Q}ko0jb4$$e~x==h-hvbcBlW+g4ZGz9CTmRgDNp z2xXa1o+${KXod-tng%sF`Ry`g-Vtr2mqLDXOO~sj8%HO3UhC%QiWwshOHp>mHzn z+Sj+;o>F9@o=)2;wW((7>a*=`o5!QtIty>9ng+=cp70eaOtOMvyDuB&8G4?K0RKB> zoC)XI*nE8gswl&OcK5Kp2%91AyYy~6FKpws@Nr@IP8jkEC97lZkkvBl?qAm~jIO=v z(vvc{&33G@$0PT5atb{Q@$(5mW1}OlIU0@hX_VUKV`-F8z-0v~edjkgK@3hr>+ z5TAQ-!~w&cIN}sTq-=f_7wjkFkN+Qhx#jBl6uH7<8>~6#pI1Km;VNfN6W}uc*|*{- zg8h<~Y41Hc&U3T99fY&5&U@Up$1Aq$H|I<|x3FufdI-s%Vmfvo4DNHkjl}GG@wERA z%b*cak2%@BCj?8;0*z08`R1RGKKcSHBr4v^OVfOp$~zkWw<-c1yyM%hpKibX z-Az`D) zI1>#9aCiK>p8k@)OKNJO{uaj%rJa8jt><(Lf$5@o!Oi z;jg%W#2eNwhku(w-k1VK2Ubq;c3cGB9V%FnEH066#_$wT@+L+Z25<@3a!M4}n58Dc zDJUw`Pje!3$2Y?95OIRy8S9urxs7p;Y^35A2?;X7Arc?0Tcjf&3CT!Ga*~v+sdSUHhAMLa#@_tN9|+;pYlfcBKSoZh9_fYsK;p3r?BXUC^wl{ z39%S?qIlWpi4ia0xmWv5Dui@KV?cjs%$nfh4_)7$AV z%J$33ocas98%^3=7|R+P-O7p0-OD^(tu0M#e9p3#EL&;oeyZx{Jl`5_KTr24418bj zJe(_DA!uOw6jX#RVY-4C+8itgPuxI(^Z-6sbr7FLc>j>bnUe%j9Y2W*OQK*Xs$I2U z{~}7;#WAK#a4ZQvs|YdNzM36v)|}(gq)2o8%oo(aHon-5)rmzZO!YOMusl`%k!f2KI zl5Jp(ieu)@im}sO!G`5j=8GBR*u^OmQ^a`r7UYZ|Ka)P&@A1r#9!+10>{=eF%b77_ z{j1@2F27RuS&O>Osbr>fxjD|MTQ^*s-g@t?{Ykkpz}FlS$D1?Y>Cz$vt<_ldxMq&E zrhnw!7&=&k#BrB+J`}$C`5SPRzev4;e3Sd>`~UAuRZ;R$Ltudh9*AIq3NFZCgAP83 z-hZAHx7lwX^w(E@5^g8~g&1-OVu(R}C}N2w_CVr^Dz4~;hAh4a<1sGANMnsAq-bM~ zI(9MRjz0c40ggZpNu-cO9=W5DNG?gEl1x6iqLWZgDWa5AUMZoKSZ=AFmRx?xmzQ9U z$zP9To(Y|pXs$V-nQXpUCY&71INWeTxT&I=SN539I(Vw^r-^z(simKHPB|!(UeY4Z z5P??t=$Mg0LTO=+5;`fDnfk(MTR&`?C8$(-H=CuviME?%Z(YRPRgF^g1*UT9r%Yw2 z+De;hv>DcvSfZiTRIsM@Doc#iJ(pjywEqIKY>>@%7-XNksyZ!lomy5ZtGDKgEv~8p zCMr6|D$8uS&YBA?x^O(pDkj6e$}PMIb(kG2?^5e7jN`JK@45b_`|rBy_De8Q+1e|w zIgzMyElQ!$E9;AhxF2(iDqaGI9Im47 z3ft(dCF6?muFIKR7|joFY%Edywi|H4MiUKi(k~-D(YCzydNW}-!)ryQ;!SHQ$u;gf zFw;katn}B#b`5sfaDmeec+@g%_Nw1`%Grxt7wvW3ZQngM-FU~kG!8L0wCCSQ3NFeH zgwrQ7kcaEtB9@7lxG>^6&KQl=m$*-;A4%Ip?Jd_xK)Q zwjQc<5{DW3h6c`_X6>;Ph6pE>ry+)n*^y8m}z_~M@lzWGAIPCoDIpJBcBnx8&@>f2wxa&?{)s)o+?pCq)+ z-A{hrBVhgvNHw6nZUi1P4*uQ~K>8K1dk3Uo0uh)ov5-kr#ERUV#s?zy&1ZQ)@zz+N z_N|AkO@sRYxqO|v15ZVELqE1h(3hOctk;&d3r9Rg8|LJXrB2RKAYVex0#s@eQ(mP8P? z5KS+vO&f(VEW3;`d7-JJ711ZhE&&jJfeaP;Zgd1NqVbIN;~pcSxX4KE?0xWaq9Y{< z$wu~YjE}5h+$i}$B&tv#%!{5WPl?Lnr3Q(htb!jASIAcSEtdXyr7XulOIY60m6qIO z88PWeO-gZSY22k06e&zHPVtGs%%n3vV$5RLvP-#)ri|b;O>5Snn$*-L6p;DM3o4VC zofKy|>EX>KfU}wGG$%0Knap!?@{{QVMK6abz<9pXhvSS^J)^_T-2Jmn*bJx|ljwtN z+R>l`&F5Awsn3XplmDOc{G~*p*-#>^6P^>D=S4Z%PKxf+Eg3zOKOGuUk9O3eD_y1r zOIiayl4q2qOr=e4iqitEvL7(jC__QlQ%BshpHu{?QAPSuq&_sLK-j2KQ_51Py406W zWok@^TG6TEv#3u!DoL%%1chcstYEFrPia@yW1clEWKC;V(MeTujx?%XrR!V2>Q)<6 z)vhX)s$7%WSFg4;uY1)hQJGm+!~QX^$Xo0A7~6!wJ{Gd-bZmSqJF0IT1FLgYY-j)4 zQqEE~289K!Us0M^)52}EJ}oF~l_1&6zV=3=oGA&%k<;Aj7N;Bqyv!~ZpIXixgvF^KlL%Pp>In>*d;>HxWM(r#dczwy!f0(y>Ba7P-CJGfVwAGjvFM+ai&*>S_qyzbFQQNr#10r(T;&a%PU5m! z;5Ilz;QRU6Fx&WN9YZd@`-AJ|42$C`y=6SW#6S4vN%@qnMbr{J+!%@VUBB;@4VbOJMO$0sPk6IjOP^V zc}Xv>sQ-fFoQFXlsT_vdrfapEwgk@!(P>b$;%o(*ufR3WTSl>%PwQcb{gzlV?3rdW zoaIk<7|@{>G^KMy>UhntJ{tD4om;KyyIML)&9NcYNZjXF6Vkgnj#>#*uj&63FTR@>BIK1C&Bah8@A<+i%3jON> zhfhJ{5igCTOPp|4iyYy#W-4wWyy<=CTj2k0d9#tsG8U_WZ$mf{%3u*oDR{!jW10Pel zS5NVi<1?}uA6Cep2#*u@Id~-xxjbSV%c9lK z4!FJho#b|3{lrGisSBSPP@@M$??dFWtO*^)L}xmGiS}YM(cSj6PrW?h9;KPd@Yr1# zeDevf`s4n7cXo32hn5fekY9h`+m9yn7mxVAYizNGdDu65`xkyC_kYhPegrsX;|F*L_;~i`fJ=9I?Z$A9Hi5)uYQA)O3D|$2 zCV=$BU&GL7Q5S#=*nz8Ng2nV&UStThbAFK(DZ$}>y>oImacqO~f{_;jo|A(cmwPg| zdk=VlJNO#mlQSmtGc=cf1z3Ab=zJh(R>5~X(h`KgrfVFSeG907`=xDlbx^UAbXHhk zSU7+uSYwWNAt*zG&6XF>MuZSpf5ewGWMbzW@yCZ|H*WB8hd@_?TZn>$ zc!mv_hULd1;HQOVxNa&3L3G$8)@O*1n1Tq1NGXSSlIVL7RC?*hiHQU%{r@FxjOc-v z$bX{8Kv#!*OW256c#4(iBz6&s=(ky}7>kY=dS$4B+SVQWLq}praYML*LpKPD=qSio zOU9US$_Qt1Sa4qG0cBw!x=4nph>5-!jlxKRozrXB2#!wpfs@n_z(_r9G;R1HJK~6n z>?n(m@{LBwjhmoTfRu=}=t^sKc9N1Q@d#FZ2#^6OkocH818I;432s=|C;P~Y4H=HF zXlUw3kRy{m-sF#)SdZy+k)Y^4+O(0SD3RuPh}MX2PZ%wMcxI+ph$PvBD|HR`r;;NH ziz_*k5%>WUX_G*elZ54rJBbD{X^EA%ix26O8(5O#2$4i7jYSERL;vZHELmMe$s6B>6mvK3lCfS!X8If`Ma)cQ)gEWMeuFt)ipe1=p;Qj@F@L$0f~l0u z*i%I~ndXF!h-jCADU+cIRaPaLNHs5a>6VabR*f`*oJ1#9$(pgZ6{Nz2u{oQQ=bBU) zVV_x;XIYn-8I&J~hg^i3p5&XoD3o9+n!|Z~_2YE6nVhUBoO>CZVd*gmf#se>~MtNL!9O*C@1EU>`8i2>7DSYn>O~I^c`8Bh>4#?qM!TepZ^J< U0V<#aN}vU5pa+Ve=2idzJ7~natN;K2 literal 0 HcmV?d00001 diff --git a/docs/image/grid3.gif b/docs/image/grid3.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b8035dafd23338b90b92a2b6f593cf75105bed8 GIT binary patch literal 3313 zcmV0Nk%v~VVnUW0q_6-_5Sn-017Ms0001-0U-eZ0{?`MsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=lag~{tpZahs2`sh)gP%%%<}RjY_A~s`ZM^YPa03 z_X`e-$KWVc?u2h-M$^|%o{%3nVZ>v zKIjizKvU}g))O?&AhK}D48p7TFCs&R4Vv+jNYUXveE$@(u^@&i2=uPe&O9L#rW6=4bg*tNNw@W9t)gepg+(r99Z&N^){|vg z_JG;1(iFKf^OahO8{y8`u+73uRj5yM2!$6t2->)AZP(bry}f}?@m0F9|Jdw(hB)b{ zx`*ch{(Pu(PF1UCmHz!l)6bQ9m7n82e)RO)8~^JKV1NP+NML~m9*AIq3NEUK+k5usJW01E%C}fdF0BK~BM-r)IlRY5mWRy=bDP@&3Kv`ros!T^^S3F@Eq&?H@ z6GWF=fT<&zkyZ8Nmu9-C=26$Rc~6`&zBw72KHzzUop2T+6`vspT7{n~cGt~Yo#{kf zeJzPbP(Cr4N9d20dN@sGH_cSgT61;cQAU~`Cg~`bmf6uUd92zItGc+_7pyI1iWESH z!3Lb9kKU@4FmrwS=oz@6sA{XmzItq|$^R~bY_K{x#+YcjtQOa^R=HKiu*Ej3EVs-q z+mo!}cI)0qjUkp3hoh~OsJV-rDhs?7Qn=2ikU^`bZ0VMoTE1(ZD6fRv`HJpXQxWED zVXhda7@2hj9ASC2+LaH(1iv*aaJCM1QpPW)DsIBxdOI%3B9~0A!{y%Ut6F&p^+84D`=J&#dn|k#4@Kd*X^9PffPgSKIydU3A-*8P00By~*4r*R6Km zejEO8;e6{yO4@fg4o84iJ_ETM0{>1vWRC-4j$Wz^ehzx*qK`g0=e&{T8tTuH&U)*v zzg{{y@!7{)7$G%`}N}={{8giOaB?D=RXb1@sZnq;m!HsZ#nDq$y ziLZL>TOareNWcTmW`5RkfdI?*zV^jWg8ECK`%W{zIicWz@T*`14R}EXhH!+T*&YD* zyd*wV&93W}wJJJjK})Mq{hK5tq(17Qm-c*GAP(SsNi z;-FL~yW~^{c2umQ6-k#I*#FqjiRBW~7P-iQFS-egdx+tS%!s)h8j*=2Od_NJ+6^hMbzXE8HvYEKJr88sM)W?WJeyJl9HmFWd}W(Au{S1I^$(->J=b z!qc4NRAWGSanN$QQ~#pqyyiBUNxO*3v!V!9XhIp9&WG;Lm?Cu{N$FW0cop;wE0s?? z1{Ow*E_9+B)tyB>+S31(gk>FFA}KjaQJZ!Yr1U#x7RTvRq7Id&GX<(D$yhJX^ouqo z$f*j!sLN;ZQlJq#0gKEj8I<e`%z8<)Z>?!uJxj}MDwdG56;^1KSKFN3ws^VC)^3LfHD-(!wM}hp zabKI-45kLA;s0bUa*z92*G5;izh&u2c#6rSmX^4GeQtMy>%?(LEP&PRQ+X}dO4PiP zt0z^iQGQjci)9wDr`@i7>+4)0-fNhfap+CCYg*%e*JI&z%UXBhU%3i6z}{srcnzwY zi%D~X=Pgu)&uFSnZD&61Rqd57JcZuIXdd^JBI+oM;uO2ivPbpsbg3HK0n75f0v559 z5)9iJ<9ES0cJb*t?Bn$SImiwK@#Bbmnc>p7!2ss2jlufh`Mzt(FLrQ@t?W&#j+KYC zFmk-0`jDlOcgQ9b@0GhuX51o05$v&zU){=NDqq>jUd|a};Jejn=6B9=)-jJqo6({4 zO1}M7^8b$GeCQWH`4`Ah%z=kd=gb-PDR-UWB_a(7Op{?D|JX33(~M+2)A!Gb=5wjD z9BQUrw!}r5qKaP)YXz}5pH6esLwgKeQ~@7VT9{gZfUwMw_8|UF9b871&C` zwT#b+Y+d)-*D>9*pAjAHYe$)mDIN1+v8o+%%8S`IDs~taC1wtPyTHLYvqj;Y>^?)= zyX5|5dON*dQBND&{EqjjyU6abE;5<=-uArxo$Z4YIN)*Nue!Zx?sFS>%WPfduuV4| zg4Oy`_2xpySxPAlgHyQHR=BpMjqrU_I|I(fvdLfGP(Wjr#E-4D?_!PfoF~sI0A2Zm zF8}Ux5PZCC5${mTmHqFSzq#ldI=Z}-p72pJJ(tJsH_ESm%c@s-xZG9(Bm$eer6J?>Zm<-=|An@%kcs-+>-vnyUCGJcJb9(x7jKBUfP zJM^b7`{-A)`nX{}e}vxX$c9?*Uk1Nl$Zt09%b`o>SEuiTpMC7p9v@+)E!yEP{r}(3 zeJ>h(ed90Bdis}t_?Kgp*L}*QNdMP->()pW7f|RYX_uyc#xr^qXmhBCfu}cX{_!po z*f#fvc)%Be`&U&EXkC~$fFqcKFh_k!W`c5qf(4j+Dky_3D0In%WG~1BhGJ&arh`l1 zCyU~KAjpF8CxD;@Q8xH7t93zG@_sZZT?F`4#iVL5c!RrCW!9&8Mks~3hH7Et6}j;@ zPec+Pp+l+QfnAe^0(FC>K`%nafMO$7(b0I;;SP~Rhjdkf#rK7bb`F(M92}zwrD1s% zgI!J)eqH!%GgyRk^dLWo8#Pmh@x^BBf)`ts9^4^@M;L`r=!FKz8HHtq?f+tk@l$^o zBVP_!NC3i#pU8->sD#HSieq?Z5MhRcxF&hAaTLainnNUl6*-eKha9LdK}1+?Lp)nY zCBTSr8R(492#ssFB+*EX)d*`d2P!)Ui(Kf5i>OKUG>bE*jp3y|q1QaeRE|V;j)9eq zL--Sk*oZaAjq!+pi=&Q2xQ#2AkManP|(nydYW{?M2ehN7`PZ*Hi zIFI{SeGVy+0vVA5sgM+jkr&C4`pA$n_mP2@kRd4t|JafIh?1T7ks5iDDp`>bNsuh* zku7PFGf9$$caw=Vk~vulJIRwZAd@LslR^oT+!vHCxsf(Wl*4zFL(qwoG+C5C>4;Jp z3xpyjK1r256ppqAPurK3aYH}db~F7~RIM15PKlOe6?jB5Uix!FIN6OZ_mXn?jcZv{ z8Rjoqf|WdJhwg(g^$3Yy$#NluDAbZ&dMKF46F!JCmF^ONib$7G8JRs5C4HGhe~F5Z z8JE{*mXkSlY?*E_HV`JMluucjX=#@Y)0UZZm5E7EGczY|d6=%*II4k}Tv?B_2{xrg vnYy`~3)Y*y36@zno5DGqfMT5agPh69oXzQ+&k3E;DV@_vozYchI(HVAwNw2!I&qc%{fFX%t!b zc!@h!8Pxd+F)EBTs|i`x1N+dAA> z`_>DqyCEkL?J#{C)2xS#{b?Dzf_=OTE*`GD>?iACPQ6apZau5KON~C{8R!5(Ph&cgKB-%Vw^<_%>tS!}A=U`8)b&=%Ql_PtM%)R_w+@Kkx0dsdPZC zuNSTk+4bS`)vFzUOgka`@wmQWG@sV|=I_2|xBvH;op4_3Z>w#X#$_e$)(=(!c2{Fd z9R=o|dVYb}l6&+G84`6w9?2JtNG^E;jNdHCWEoEKFlBf$UWsLvT5ic@mtKAe=9XWG zw_cQa6*QljRHmtBo8+rNG^VV-ft+1C6IIg32NW30_59jb+WIDXFHO8p44| z>4Vy+4Z+yytatFaAvoPsijpzDdK#+;^Z)GAUuwsink-HFv|22)2tE5-v=RP;lUqWC zC6ufKVN0vDs+N{bGjrVv6Sw5{rLBu0r37lO7QP#2y!h@bgTDO!+hMO$2n_I^!0uVF zHU6F$M@9+XvM{5RJWQ3p{0(6-#hLUU6~ z^-e%Fh>z<(cQJulrjlj z!D$8TRSli$Hm0{7hUd!^zB*6gb|HIsnVGaJySTgE`|gDY?|W5qZ!zprJCfDbx}lEV zaPk&#i6-dRI!|{N%PMH5?xJJK6Zg_PwYm7uyIVfq=l?nX@?)`|b|&p_TXDu3#m6l?RuSLjGxxUo8}qSL`Q3iH(Vc^2-YYKhPx^f@Frk!(R95;vwx-(1JJg zUh{^yLL#mYf!ktRsTSx&Apfcld{FG16sJf<+;MP=TC^b-pGcY)^eBX96hsa1!#Q>= zs)Ohg92r%l!bV*&k5vSt8{a6dqlNK4W@KF<@hC(c?lF;8TqN+glSXpXOF5WJ-&y)t zy%(18kaNVJ9@U6RM{;2=N~v2nk`g`4DAF&9l9vnX__;fFl7OMSSs+_ECVptHTTnse zw*aRRZLJ82Ka3?OKS|5J#b+z5%G7|`h08zoGAISC2lZ50k@UsThsCs`ELVw0SDh}K zyoA-Rl-WoidJ!}gQBH1j*(iSqlSJQaViso^PG=d*FxFGoFJ%QY2u844?F^sXxREqh z3UXZHGMwvzn9O9_YyVWlv*xl=r>q_N&7Y2`B(4BTDLKNhiVht?N#(-Fpok4|M%iUZ zSCLB-u?Iri*-rI{xj;XT?WEqkCo=O%&CJP7DdPl4=$OPtR+4X(JT>GoYpKI=5T&D= zfG6N?X|5xo>VryrB`l5UQ*fd*k~pFsO)09Y>778J1{A9_dYH+t_OzS$94puK#@5)u zab8`Gt0p%YR;UX0q4$F6l58~6tP(S@D153y?dmbNmLRVn>+6>uTF=MUb*+0{D-ZkX z*As%3u0Mrr%#sSI4Z=0FOmr$^v07R!P?l_%_Z~gjP-sL{cy7K+se;wT3 z_qrFp`gLx2TU+1kMii*htZ;fErQz9yn8O=}9)k%i;s;+CwK-HU+|b+Lx6+rJ5l(4| zxpqkjPjJ5=9I?WOwa&ds)ckU9id~EO_N}zrcK^)p!v%oM$SN&I@;&{;_N6!#}x=@nXRO2 zqe|k@tIXen@NBQFXwQD@qckOI+g@EKBqO*N?Ei_HxI%;<| zcG!BorozH{R%3Lwn3?S8SpS*J&h_!LkxlB(hS|~|HZFpoy(Sj77|C zzw3Q>7b(0i|AElJwLrIkr9AKF?%TJO7IM4?Y-V~7d}VDM_b6Fy<%REi+S^{Ryc7Oo zi4(5i9G5M`$1HG-hbh4oe=)*aO=FR7T+vgSr>|9OCqknVEjeYHGZ~NLas&==_eeQH$9^A?0?y#SovtVlac#qEYyJIWw2Jhe-34a!_ z&$njzR&mGGiUY_0eeYE6dgG~%?N{nR@rf6D{bY?V&gT}$hxfcmO%L^e!kqG9TrBBO zZ`j1!@>oeMH|#e}dSOiL;wV>dxLJQxp&4DIVD{_ppYAeh3opI5-&F4X^znX&7ipvf zh1a3?I{9I~^uvsZsG@(aq*K58f!e*=mrCI6JO6$oi91)bDta}7tNpy+WBda)fB)-) zpP~F7nOz1deD$|J{fA{1gjePVaJYnc@emjQh%x)OJz}?cH+OxTHy$#PW9oESVH05$ zm;)a8eTDZ{tJ8PucXl9nY$sPLSa(-@cYq7-@fGdL=t zVK(@Hb>b3{QiO;GO-2$;yfas(hl1Z$8C5k+lQwJ7BRa`5aAyWlA{ZmgmT1OcQ)V@S zidA<6S90YxXi?}))}kw7IEGVJh7Tr$aga0ngHRqdPHz}+aoBu*cWL%kO`V4(=awQ; zSZh|56TQWU52S|HBsf}jeVxV_0wQd)V_|$4fsN>A7lCTpmIyV&V|5pPYX5ju8EA-6 zuvK1hX>JE{x<`lMb3-15ig>1n7`J#T*L&Vahe_y3r*#;IB2|6kPv-=U_VI@@wt%BZgx8WeiS|xY*My76gp~t1 z)*EzJaQnRLybK;NqhJC|RDTr7!2MIQI zH9(TlOoiBx57`7pLZ9c#4!$iiL|$gO20W-Gih=;>6D4Z zZBto*R*99;mX$HtlT)*ms{ob5^_8cWY+>ndW0{CBh?elujb^!)xTltHsgrJ5baIIc zGtxem^EZ_Ug?9O36GdrAxQ_+tmr;^xQV37w6fVA4nB}uMzSxGlM3{|~iC>-G6vbi2x1xZNn98}j!)FI)!@C|C#hRcLrHs3_>?D1Z7xe z{YYvMRjkyyEZSJkbIArL28s~3wX10pk~I++Jv58f(IhF5L4ikh%NB=3wM^2!}yxVi;5e>FVVTj;i>FQyJYy!i3t z%bP!sKE3+&?8!rI4?n*A`Sk1Czh620qo~Q&W87?aL;fR5OP+N-=aTZ~W zBM}u#GB4)Hos2hT)MH;hN|xe|G%8f$H;3>fmQsxkm?R1zT4EJ18eJkyO4JOg50zC` zSmQUWB=Te`YC;3liOWSGWIS=UwgFE|wPV~CTmBd(j6o`C)GDe{nn;?ZM|qHxsHHTr*yNDvgaxKJ6Y`1VpDA3)Ok`de$?9={ zA{1qxnZjwus;lO8YgR|1*eI`exB}}9$^TmUj-PE#c`Pz>qSer^eLl;;w6RFr#j<31 z)M~F(>G7(zhRGU*I#V%)C1GwF%Pe;2J^_wT_8y~VyZVNO$bJ5nC*r>J^c!$61$XkK zEOMCp>aIz7HKq@VdQr<}?i)O(`B$Dj@at~7b z%7ic_r(sqfrp97Rt{2VXxh6O-izx=hH;yOq&b0PiGM4BV63Lc7ht}1D;rNGO28h}+ za;<1|4Wxq4P0gW{;BV_qIN!?Z=vvm%MMs~XkN>+$qT-7WE}!LwLr%Hon={U`PKQ&PT;`&aakhTp zzFx!Wpp0WQoUPaHn&+{D4)@r$+m1WQ@P3YY@2j&8yyU{?-goiDDL;ASuFDO3kYa zF-Lv;1C#WEXFh1fZ-A`J9{cQvw`}Q7fT?RB0;31Pwghm4=wsmX{wKKYxo=YEvx5Gd z2Ex(#Pki`mp8P&I!n}!)g%g~C>@GCF0=kQHDNI`eVQ@nT?N5hv;$aLG!$A{*PdgV3 zVFu$;LJ7LigG1DzU62;V_y5`OgeW}X_@2lh0A`VC6|`Uv`?tafYH^Ir;35;fSU)hD zXpIUa-V0#}M+2r2ifk0467PsdHOf$qx2a(V%V@?t?vQ{QgkSZxxWq0hGA-g6o+T-0 zD0F?t|Q zELutp>ZDm2ientL<}9tsRLeokMNv)0(ApW(Gb;y_p-I*;u?5_IHw{Y<|!Q zPAArMv)c=)EJf+BkdgMDUPbM{;z>@VRx_!`d@ab>NkZ1rHjuWx?Nqx8NkF=`x90gR zZZ&(_;S$$9X#bt4J5htZ<+7)_678mNeJWk`Ci`$3GrbB=(D8uM$zT6+WwMbxWeAL<7k< zuCkT6i)G;EhL|gp@sm|*Uonr_wPnt+PSLF3)gDA)T(+2--z?_{*HbgfHAjYuli==} zXkb5q(*KMu);xYb(8+*?a*Z8jDuWe^8(F%_Zj_6&6*VW&tSu{1?X{7e?&7b&!Xkx% zd=5u{7-g)^=})-&WiQNg%JRGmGC6JCZFm}GQQhjyE)B2-uPmLa<}sR{@#Z~6N+zUU ztZzXxYzE<4&q1s9rc45pF5Ti4B$}x&pv5qpx$F*w1%Dd%6S7@^fI@X9BT2dyDwzuolwkejZCR?Qir8PE}y;A(O zeNDG|*JiSZ#r39Sd3q1rUJ{x4x=;&Ob72?)cdTnQ?R4k4!ejjChR~el|M7aGG#V_7 zi=mc+HPqSZU z&NflK-slLC{i4?V;=AJ>#G``!-*Vr3+ONg-vk&|cSf85G6F>O7&oJ|W<0IsEh*?2) zsIXey@IUK#=(XqS@^QX>o#SEK-w%5DvGdgOoB#YcOud}6pEZK%OYCJY82wpl_W%3y zEC2A=>%pGpezN9eb;ffiC!h^a6r2xEm^HgMZ*4D;Iz(7;;yV zdMlTM<)T7HmV#t8ge_<@CAMg{cQQ%ng!%G(@3DkXC}UNqd!9FGN7F#=f`f9R7wgh@ z-C$=hXLdA$hM=|-J(xOY*mX*w3OG?6ZL%k67co`{X?d7z%$9yMwNF~8h8$BicxX%; z!*}F1IQ7SIhQ~EtNQhd*h_J>pK81e+5{7rk5mNYweRzgh6@1qA>AJ1K40m;e9( literal 0 HcmV?d00001 diff --git a/docs/image/small2.gif b/docs/image/small2.gif new file mode 100644 index 0000000000000000000000000000000000000000..25f6afe83abb581be27fa92840f367768541b2c6 GIT binary patch literal 8814 zcmeH`6REeL_nGWX`~cEP!S6d zk;jL5Z`}KD*kAU$KFrMZTWg)yah}&KO>GT1d57;nC-4jSKMM{3XaK+f01g1~09e7{ z02~d#F#sF~!133cXgGjI1859@#sO&j^;rxYz@PyP2EgC|4F38m4i4bZ01gA-Z~zVu zDgk&nfJXy(41mW0c(4GqL1|D6ybPYkU-!9QXgC}LhvVRI{B>KfLZjhm3>=Mvqw&`i z;3ftQ$6(+X92|qch62yx&~O|Ej>Exmc#sji3df`2cnlnmgX6)jAT=lkLW7hb7PtpC z2DL$HPz$__zczGTgA0R3eSYa?|3=WOKU)u#Kz)c(mjl-dFc+fov1)fFY zF=#vvjR)<4d4QPUZ7>edKL`Oj1gSwW5E`TekAfUvV^ABE2DR|l$z5-QHMnpX4E{Pu z&>z?qtZ+CC4iDxE+65`VO$;7~!Gk%1NrM4^T;OpqXwWSfC71_@3El?d0GU9;phJ)v z6a%5bn;;g*0X7D;L23N;h^|kA+h7eYJUB5hNYEeH7OZf1{Ph6;j{lnC??kWX`FBXy zP=9m39`D~MuNnWQb3N_9hOd$Tdbl3`U#x2fe>;KF;NJn95*Qxn>2It5`(ONj{Kfg3 z5OUp87hxd;>j9cy$6=TNZ(AQa|p z2Ir8?9?#RXTYkI1Mu$0NnZ5xe&IZDVJ+iTGZ?(G_%#M@xg22`WplmAj8Rq^PLl2eU z$|dp;=uPKYpS4?%ju^rqPM(iZ^s(=5x>7sc+O_ZUAR|`GrYqq%@#<`oW}nbo8}*`w zLRB7QGE3N|wPjZo4q9ILJ%yxQJqm`!oSckJHIWH8D0RFa;JtBa${NM_?VvdS-o@qP zi?CTf6*D>;H$oKg}$ZH;y3MP8a1hfwX%4bQxHhc^G*~{zVWQG*QLM6KQYAp( zXU37ssPmc$8L%M@kcsdt#H9vfLLTSHC(=I-Ucdlb-b5j5&M~fy(>wNeZta#h({~=) z05ju!R?wI{S4ND2v;{}Ro_um`(h?%MmV^Lzz!FFBnz1~MCgRtAv;k_fp*)_-vNnIA zkmCb-Qk$L?b^J`zs`@I)#Z0j56QzK)wHNA05M4Xku%BEx(OKP^H7c{7CSqH}S6OOd zZ(hS+rt;aBmWswU8KNfqg@i}cleKMRG=brnpG=rnsSne%WA!{#Hm2Jhom6cz`h2Yg z_)fknkmmP99O!-5UoF&ruxPr2^=VH#w4q|VA?8TX9Bz()z77!?+`c+`<^|l`Uh19I zaR2JBaZ>-im*q*iZ)a!A22;Y?)oU*@kve&=7`d!Z?QH^9b!8FhwJDN8h9#!uoj;gn zEfB?xMKRs-B|>aHcfZ}r@5xy^*sb{D5bW+s{Dc8EL#fN;j3Z*cg_x_&``KKBT3@Me z-4?v;idDKa_qy`pE{O?>p)|h1u)MV+gYlRX0$@S@>tkJ0cTDWvOJz>o0vAK}nOmRF z&(pDwCt7`KM$-wjh%IF<6G|3*nd$ysV}6^(CL@ijNMiSxO71X8vs)no`fX@7V6vf( z23u`4`*kBJmG=_+7E-ij?|ep1qhPtH(d=2bsiPb9ga0;*yA3zFh-EAEz7~D?)u=_M zyX!`3(a-hIN3H+uMBW+FdzrK&?^t`JhbwU^{=};S8D6HZCggo_&_3gPHTvYsiP^LN zY+x#-6}U^q8s@klQt_5W+ONmX^#&t}gtqZagaifmiY+Mk;3sn*&*4qvYVG|E?`W(z!BlwM z>GSH|Im=jJTh)W%Mg1A`oZ}>qjBb-< zf4CYvh&V5-4d(h$SQnI!D4(A8UCmdoqInM^V|s3Vxg6Hwc*y>uZ_b@`A+OQn&axZ{ zPFKmq-ldbT?EFmU;5Q}gndKS+_hB)6DB)=#cXh3r;J_=^!0f_|$3LxgsQtR9t8)em zm_2{fJ(h%}lyDw;5bM)(MsoqjDRf!~g&g&0yb)^}d z6pX2;%-N$`t6xQoY&xrL2bPLMJc8!A9wd7a_;#G-Ufi|yDY)Vis*QTR?iF0E7hO_xlc7R@(<(fv34 z-e#SA3ORpr;>-I{8WJP0tcZ?CK0-*EBt!qP>&{X$8O|k?cEIn>3sVUd!PijQdYDda zNx2?*jpK(Obf2&T+;3KIJjibcNQA@dAmeK=f-Aqc-p{oID#N3nf7+vk#0A%+(z`=g ztu9ECaL2uO?f=$gN!YijV@9E}LwU|v#SnfjeFt_7w*L0~?+=LtEnOtq;bT!Vl z&5mZzeF{k5cUWhb8DoUxXX+EwccRT+Jj_hDM+H-ym`KeLU=Jc>+{+d8-MpQAf&%t# zDyTb!J`5jseglYGk=X%aBhtk!MZ`ilKf>{*OxVlUov+l%(lvq)iVz3e3(dF zxJ`1$rsR*qkfqpTqUX|nLqv30Pfk=&d#{k~!kcVxa^q*x9Zk~mTYXZ@Fln7(t$zwX zuQp(}jEKT)j$gaYoy~bRW3ydoqe^eY{wkFZ%=Delo2;m4@R~!Ky}3G@o_@ncqUz^v z8ui4e<6URbYhzX(eu+=tp+|I=ho5ve9h4s(!6ZwM4rmyM&iH zGU8{ZZ>yy`?$R&7X5gT{$S%PnsJPqen^H^r?IyDsr|{9Ox9g1Nas=z5+m`_dK_lJ( zKI2%^nkmPEfttf$&mN3In;-3k?1zvizXuu$mTO4*5j57U8Fxvyl9^N>k6ju9?6$_D zmdG);Yn|hUYkeV=m1(`koAE>Kgf6o{w*Tq&KEGnE8AoxOnFZ3Hi!S`&rCfGR zkd67X!gjtS!p)^MaPH$&D>ds7f(i-pCydOM@H&*T&3ABoyd)kjtuIrhZ9x@GHNuaM z_u3tUDO3Y#1P&b)ktEgLElb=fvZ5xPo^x210Z-nh!jNev##Kyr_7hSQYx8;e8h0 zUY~S6A4@EZWPz7$BC4-~;T~2Qjs&*iBkhA&Ta5#+R^Hk6NE$IwnfjnvQXQB@WKDz~ z8JBgiD^(j;F8Y3{)$Qlvom-A@__}d>B(z-+Q7xwObuTk#pb`A@c3vtQgpGLCxscu4H`7cGu zUuLT&NE?O+oQ)za&IDN0D3%V8&8m5cuI!H)*p=fHIZ?`MaTFEYF+|}>)(HtBJVocf za%ISAt*qn< z$dVrjujU_}Dg;&AH((QQn?k#%6_TKeA%~Qo64~tt5hE|%QP@1$@civcfX7|%i>lf} zJIpEEIcB7YVP9Y>Jdb+aGMLea_KGC2Fjeant!e3GZlEE|Nq;w|C|Z}@ zLF6C$`$Jrc+j}zekfJ$xj80YQ0s-P_A1sFpx$p?_Lt0c_O042hw%zRD)fGd+C!z#IQ9{KDk!pe zU7O6<>~OvC(RA=6pT68?|rRfA!dD7+N z>USbfahcE@Ai2~fz$syIb<0)z0al`^FH3$pFXde1jZ^ui5uG?miA%iMKYL;iWwL}U zbtF`6nP{A-sq6j}u?96huI5ets>a1$OdIyQu9BV~MMK3G=gEZRQcjSBxC*+FHf$K1 zm2lpx#lmL%@5ycm67S_cGnQSI6Q)sQMhLMWr(_O_-ZOQ{~BjfxV3=zdW4n%x+S*BYI9LowU zB?w7*dNq@ZY2bD%SH+aV{@-hP#3I`SH0bl3a%RI!vg87a>mHCFP@41y5^-tBU)+VA z0QM+VALpjbB1ytDITE#}mIdCUMBYmA(v=mmw$kd>P8K9R32!?TrLE}1gu>sT>=+Bf zm$ax7Oci2I_2xPS8PC$kgj^O+Lp~)w9Ed9_IX6j461UKl@E8z>ICH#`j%jxiIV7Qs zRkxzph5B`to1F!puNiSma0taqG8%UpP+1PCGLm}eA3S1TsBLoltvR5fnMBj4q^eO+ z#gTN$S+4H(C|2lXtk)bZPD|m)#+MipuJp>e*Q*KPFUv(LCEs|`{%~zz!m1r0yt`5B zi|p#(s?}_}T7k8O`lM@!o;VvUG%>9%b|)h%7T+~+BsmW@g)(<__1&;wS4h~VmHe`z z0`tUBtIIW}OZSCn`BiEgUTU<$J2KJFkGSmAbTT!Zkmv0-H>=h9Kk3t4nq-<&!MV6& zksgf1f?1AT4@@+d+WYdz?$FW*xtE~2a9izAjI z-l8`pzFHa)!bRcd)?rSa%}v~KCKJkajU=4j_X?k%!EH6KlQa>>5 zWgHa0N=h@>iEJv^mtBADZyRiEqbnD8tbMOkbGTsC%Of?~N>h`>+ziz;lQJIQG_B|I zz-7w4d|Nw-$AwOE=CX-9+e=x%tIxSC_V|VmDevUgKw5?_vjX-xOP8J2aWLeT-eyxY zMEakYBpK6cY*EdGpO=Ld!^jw6jN;TZTLN3+nBfdpq?qBu!S@pbeBHBz?Ms9Om4upO zfi00~b2qK*C{2fpGuR@U#UuYvKM2+e2GgoV>R&`oC+1Bq(7d{7s9`-TKnJ5a9js%M?P&YeA8&%wt?=AQSI!W= zGFDd*f6(qNT3U=mK2%azh~4CF32LG7p9(Ox^FM8@m2|1)H>3MuqGL*l?WuO4cN3@` zQvc!|rA@gt0heZW)o1l#O_>*i_^PdiFIlf@Qt{bjQY&KzKFzL}enG4(M-Bc-&VA|c zxwK;CAUzbp#DX0NeMsXbyrQy*WrnSVG0Usbt;N>P<0RbFi!BiT zt}P-W!JE;aOAG_WR^%0Aek zX4)A-^fOCD4(+3qd$>ZH3?VGTknl^js0Co4KP5 zWghj0tli#zYeSclYa;v3%ccF{cSutzRcH`y)0KIL4jW~WvblG|k@=J7TWZ!j3y`Ty zI{om#AsRJ9N#^nPfxve_`RK0h4ZZ_{UiTZZ0$nZwKB=^Dw<8xCC!cd_?<){in}Ws-sa3uM86Tq}?JtEdCGt=oc%6~aayRwm>}%5$k+Zp~As0>CLT1V1 zg_-*12$uWK(t87nh=|^`4&DH{8SU_J#|p+%<~LVr-27sh+URJy#_&n;snaiK%a3)f zKL1y%kYN1vCpy&o5pCDvHapwWchT*!RccbSLxW?}(mP2O=PM}Tg8Xy@%ibcid*TC| zC0j-phgdU$UVMV{xvU-PTgO^~p>Sa}Sz7O#TACpN!>=h_Yyfj*8lc{xyM_OhUD^or0=%PhsS~3l5yk@ zjLkn#lRb-(bklG{jsyqtMGHHf*L_WMl@Hw*o`ZZdX= zFP&JoXL&mNIf0|YZ7GUpaWe_4@$d@HPcwwrXl|*?OKsL ze>G(e=#@*NDSEyB-;OHq1H+bqxi7FRbkNO3d_yjIgHKP@+@bmpD^AZ^?uic9*yr$s zC9#kI#2#RX0Dw56+iYsZ2Jetb#02Is#FWUfn^9^afaH5zDxFLTu{M@x8c-te8VsWxnTsVPNKq5?chZW#m#@qafpnd(()7Q7 zVDbG!JSim+q1H#ZN@}BirU%h?>LYl5`NsbV$-#lRi zFZu4r6DQ3HIim8xl(575W%ga9!*YiEMzeqn*HwyJAlev5U2!<*QK>dnm2X@peaYZx zM)!=s>$&jc8VIk zlU>vx)3ec^836ZK4WHKjbFygkeaJ%SxyWTHSHv^N$x{ts8JwJ3Q|lhNT3h)jmrjgC z)}NA3eW#Vo_DWg=0Ats6LpBI;&jZ`hj%*IT@ z;~C*CCL`URH;Vb0!|50CFa$Tfk#^-F!|6w{OH_wWT|NqGIF@5wq5}+ZAdmTHQqFJ# zhnAm@+sg@=VB-sp87*^<|4@l{UK|=-edc;Q52cbKC#L!Mf*a2w)^V{(kfD%cG@B~I z^p2oideumwvkubjoI3tn?{zN6Mv}FMMlbHxk#MbOhue$RKLe-ONoAP-oF3~X350wI zPBz&hw5uYk4CmRbTy9tl!^3_Tp1>{k13Gcn_Hy2lXqK#a`tQ< zI(@OFHP3voNv!d9)MZx6hW>~|YSAc>uD-ipXLtLl?U$}z)ZBkUJ=<;jrgZ#M?&&T}_pLh^6&LuKHikJ6Lo)SbutpndTmL_>Umhw2|<#O@_>X3=ICQ zGIYBwVzl1S)CQft%=!>|+x5(7M*w2&|FcN8#jR#z>OeH0S2Fhb;I9v9nL@{vS*dX? zL!}{2BwWd-BNUxMv`Bw*Q zNng$Nm8{1p?I6n|f1*3=>oMvY^y^CU#hF3tss9#=&1Hl(H|C+pW(Qu#CcKp~5Nou@ zz5BP6siJ;K?!o|O?7mf;c;)zuvE`PBjj)xDQ9rgWg(3yE8Tm-H`6dn2FemQF>a8Et zo=MdEy}`Vrz6Hx(@2f>O@gLl`Nq!s2Ki%dFy^l29?+$`cILvUW^ra_?_O>sqGzGV9 zY}azcDesCHO4(y=vo`~VsuL*?5I@!J-qJdmH*xI&grwH zL|6s`MPk?p3*%SweM*aLodjjRxK^Fx&0SZW8%W`$8hcyBt<2g}KK8rSp7En;o?K=n z<*ygTepzM#Rm-L6nOV}Qx?3zSWh9U&y@+yQ7V1~T>O4<~?kO4Ra#F9z8by=vr%PdK zg-Dbf`o1UA_Ui^0U*&fbnKo!-jiC6gh{t*8M5QKJXq%&uMUg*0+9xy@`rc2~w^(Y( z8`;<2wGOL!b5`vuZNaMVz;>^{#qV_;d-QdFt zzYhM-oym;JD}!Ng-GsKNgV>CtRYJqOr$X;s9nG}oo~mb;P%QD=WYQ}o@ZHaT?6Ec< zWm5gRxHdWSj|Vcb#U-Dfjn&!>fg4)wdy53>o{nps^ z(wK6#ufjp;Zf3NK4y5b!%{uZm1ka2d$V0cVEMO(24CA>Da43*36NL&Rk?`dcu9^g0w+rzEdr1SG-YvjiQU` zZ5rdL>VTq-Td$wHZ_HX<1r(1fq9q?~;9NBVOI8QbGCdn}zDa>)2a2wD*Ei-vCjy`R N9CTHtm*fBx{s(Vx(8K@$ literal 0 HcmV?d00001 diff --git a/docs/image/tfp-back.png b/docs/image/tfp-back.png new file mode 100644 index 0000000000000000000000000000000000000000..53be67191db4d8d9588eb820470f4f6806199085 GIT binary patch literal 53962 zcmd>F_di>2*gg?rQ#&YXRc)pADr&D%dsI-X_N*-^sx_+is@j{_o2b>=qh^iRdzRX~ z^!vVl#ryn_Pd+)xdCqgs>%Q(g;V;$X@o}hd006*ORCu8Y0BCRk0HLtZ?mlU(Qmz7k zM}XoBDJ{>Lopjvz6(KxX+#pt{^b_>E*C3nwH_}f?-)AC7Yl&}}^wrX|ikkA}MTC7U zt*m^uQf(F0)uY4S|36)w_?dLkQm-+v?^ifC?ulnabl4mhGxvWI=?pW6(s_7`skFv1 zwG;na891eM-K87&iGZH;{aWf^EuS71b(}orxyj@N5Zc?4%uN5*o}yP+k2Niq^Qn7_ z|8?W@J!-C&+Q9$4I4{4?K7e2Ep43{tU*kpygphzdqt12! zo{P^xf4`iCSB+^UjD}7!c&_n}{jNzsLQfDAczVEpmn)bn%Wd6%4pToi9^+a*=_y%o z!sS}{0oMgCKc9r+={X+H0b;$yT=%y+9O|xjd1_ha%8)w;sLWJvW%m49Rjuc|HAG3p=icc;s$ZI5_vMd5{h83Bn+FZiCB3l_bG}(K`V|-3Ka(PDhD|o;m;eH4 zD|=eKh|zJs5d~vV;3KH3MA^Ci+~Z%j5^Zg z7kK{5FM6`v?C^LwVE*PK(T9c!Ol;1IEn+vz18$xiyp3z_7S-RPWJ87|^}cNKu@guV z9wC|tHz%o>tm=Ey3&De;O?@ZB;IoetDDL69ac$wgorWd*OB3;NZx7I1pU>gd|H}32 z_pTyf2LRBN1yKCKkQ_I>k_gjY=vV%(cM%l!k>Ydpm3}H6g3pufLw8$w)+w zhVYK~ElU{zhzT_YgT9I(88t|e0onAck8S*0{4yP`8h0u$b#%tDc1NXfJgqwner#u$ z`wRZ_`U{X40#IxF&|8wuG#+2%Ql=*daN`4QT!c@%v7?WYBc*am(*eJjRt(}JqqRslvC>?`0Rq-20fRq#P_4k^gIb+wMJiBcn7d z3Rs@>!)RH5#E0X|oPdN*noYxg=T~}YNs$0DG~~EyG<|1>xxp0H238>{9vSN7f)~<} zr}LNAQJc7wD)RB8<)5OH6teH-N$|b1o73!fgmC9fv7-pD(#pVPQ`83pvF_cv*@sRZfnEg z+!){LL|me8Do}4m*GstkIxywQimO*PhZaHNzgS2Q-@YvLFlwsfC>WwN9ThxhS~K`; z(7V_$$_AED3gRzvkEZRXTqk};C8K18rW0mSm#Zj|@NIkiefui7x|%GzqZgQu;7~a@ zzX*mJJ^M{N@VsNTA}6Pg&-26afU&FGuF-ri6%qx!VM{mm7=?7SpW6|Ab5EH##iQE*{Y&%lcySw+E+M5G%aSyPPY!vtPFNvJu%43^-_K zg5kQ5o;f8wEE?q{GNa-f~0&5G3+zbvWzy5BNlj-U(RrPb49bHFuZhsv1Ur<{Udj6t5+U9J9-954L6DYgYg4D z(5uZ|eXseJ+Ce7x!5{CAE%OhVhC#dNovY zQ3Xsq3!@dUS$ouVrCDZ)8ko0L!O#uduz# zbnt^xPkO=c$dPZkuXBO<42T>M^^v|g7Rg!D7S>y{{oJHmqjOL7Yz1F!M|-qaP>Nq} zT_MS|{E|)XY|92f?T$}wj7yUyH_ z>4~VWOS8nj!Nzd=923vY5{k&zIF5vUoTksi2hAVkXe_AR|Qsw$Ws zdF0Y-t1B93(WEn+XH{Ku(5Kxu`*&`5OA?57UQ)RSK2jY5IvmgG3YM8Xvj-uyEq_fR zJX$M%wK6e%r67F3ybYKFAS8JUkc5y{e;rPKtDd{wS%j_mG2)RUFtKVw(E1iU3HZxn z(JYkk&c(6!TfS=Ps%%^Mdf9CJs`2}nGY#M|OK$Z_*j}jWHmpv)ROMS+Ur7N;)*;xSjZby zo+qYBlsx4cHwJe!I{q5_6d1JW7_)(iq(BU)Yi0 zodP3NaYIIJz}~Mdh27Fv{8_-XN_FvK6wk)Q9)D09UoB?Wd5lbnJc`n?DyKr$;=?x4 z@3+eNas2&_`m)V=rtl*S9I4?v>|ES<^C<#FMZ z@JYM$ZUK4f1&p8}6oGkOt@?B{0<287LrYD+#+&AA&gJ)OpHOetv%(BAnqCj#k9oAv zHq+JG`dmpEA2fW%h_M3g0C0KdmHW^K2SV$9kq7T)k}6xUD}A}V2pLS(OkKTZtKKY- z-meZc9*2Yi-M@(p#wxTAy_P4cjm6;nXa^pv{8CQmnr@E|k?z|Z@Sdf9BheQOy5;Wr zT@Qxv58DZ`kb4i1X@mw8aP1hXC+DO0sqO{3dCCzmVL=;SE)52_Jr9Au;;%s}#-<~7Yvld7xYZb}>$pDfu*w+3Y9yfBp`qs4{ zF3WxK=dVuYy`dO%nyY6)Fm-GCaVYt10lGcFI|upUQ#9OU4`$8Y3bm?@4-)sBBCV$ zUH-);<-&D?u{$1op-}prweih6wnf8~&(JPh8r2{qZl$?P~7g0xwKg|m;J z<$Mng`$VVa?JN`rT8~BFeCw#ar#f-t4n$e;w!Eh=)53f3ukh=%S9JOz)E*_-9m#tg zm5g{wV(>0tn}_%$N5vinpoEexR|s)XC7)|_Q_wv3AP2D?R<88kPM+tZ%z&*4jrZ61 zv)RIOG$-G56U@qCzbAeUlvwvEbVDg<+l#3cCsKz#MitMAUbFx26ZmD(uy}%=s(SA) z2-mAYjaZ|;axwb>hmBqt(I?>faZ?PyacI&sokIVYCk+ybU3o<|H6!x4-Bn0&V+btN z`rVt05WK7QFGJUJV{@^GDuhyW$`jbd=57ZM>SS^gGDcz}3o-Eqo_^5!%?-oPXa^qS z&0{+83J1f7G2{1c zWTR-LZFw^br}7NNC?&CFQ1fAFrNa({kU{c!22aMM&#Ijl)lWS2onOGhG=I zN*-4O$kf5t?QaqL8s{DS2VXrRIFX${dYFajhk;JGIFlqZNWTT&-v!k5^tZwa)4X(Mj%NMp9} zXxUAqa*Gr`2FY|bgGBWyp}w>D5g@^4sp-WAg7X-Zlw!qAptOzcMG2*NmCl1g<$t6@ zJ5&3b0rA5a0Tt`Pcn)SGzi1kd?`&KTb&H47I~1Zoh%n%*65CayoQaQ)?dz}_LRj>6 zhdNtyBL#Biskz#T#oCIsA1>V3?jlt6gVg4(r8b8c%Z}e;;9n)pjUB~ojRsQ|c<_sX zW6U_D)ht}w0@?l$3>KmzK!eM$8Sx5qfRbdnaZ%VHA#TBbziAvK3sLR{ts)=A@4gE_ z>+f^V-0yN-=lFnQkX4I)6ps7;)GNYursVEYG(xkE2cy^BS$?$rsp@~5W0 zCdWZlQ6e61r%BOY{M63Dg?GqkE)#n&odQCw&E+MNDjUXXa_maN+8p2VcUgu~vHv5g zmduD}OQiFuxh9?pJJ4FD71=9ra#nj~0Q>0|=IZG{d(XG+=(;aKsT`<9^4wVj-Phz1q@q4Q_Y{_oIXR z{W4wM)SF5i0H_rpz8^I|ZlcRW)Vts!%5jWvmd~JD`9z)z1Nj!7aG(CKGDJQ_fLQ(< z;RECn#yv=MRwp(BK^6T`pNBkb2rtqLYz>*)5jgfk+?G5g4dIf(zRH&L4GUGg2?~rAZTA zuRfFdXP3@vweuP1V8BPoNVJ`lErkahjN7GLp+Gj%k{KdrkJ>HlTE)?#P5Yho6>p6e zZK@WulZC~;)o~~hn)WIMn^vg|&9eY__)Ne3+p@kVUA}upOp{wMz3pR>?0(O_RKa7* zTrzaT+-qiXWM$OLdmi(w)qg|9#{JFf5)qv_sgg@~Wup`=^zLOJ?F}wKM!k18Ia!EG zYY_7rCzUn&o1d^yA)QQ2InI8T_CpI+a*Zhn?%T>TALloKZ9l9>ST@YY7#1*KNAy^k zQGraPmYBzlg`=TT28`rI|3|s#65Ao8+6rfCyLY5i7YX^aQa}HSo~;L*4mD+#Se=7mV9w0k*>sg z102EpV3gv25){A|@Vkt$J2r$19)ID9FS1OAMlo+3YLd;Mn9klalLH7@rKei)xs`7Y zVEtZzD1c&#yoH2GdG?JTGK>21X%x38Plu0Od1T82z9>_9$0?p!g$}pMDiv zm9RHKYH5%;&6ghSI(hAn#VPXHP$jygZFmQ*?RDB+K+UY}!BA;1_vkJbPW>Ov`AXW^-ST|Fq zpUllhVgQ&l3E%9w(8b)9u+H1B99ad-0 zl7^1F&r6OvnbGSpSv8ejqvDcI)o$k4{aG`>TJdlb|I|F28`}^S(~#xeCa)$~hu=d) zIO<%Vux^&mRO(H{Y~jFr`~h~hJ_g`%)WFx}y;;ENs)KttY8@z96}=~Joehc8faY(< zQF9-3jf8k<=z~v-hQkP}2$3RcJ>PF^4+y2?!z5oq84Uq7u{xd`CNGdQ$Cp(FcG;Z-!+Q=?E+FQdT9EQ#c=zGi|R zKn+Su0>7g{FBqYWdrRpN=>R#M(tS!LWNNPfiE;IGY2#7%qjbn-{(|&qv@`31obDo0 zP_|G)m6K})t|)~M0W#R6c$gKm+f)Y9+XZ`yDkS57EYE+yrD=MHP@JyHrOf$v(DeQT zbrPS^NnR14p(so1t+@HzncCm%O}MAXXalvBEKdWN-BI=9R*+Qen@4+V2?ELElvV&L z9L%G_9QL)jNQX4_bk+Q^lW6!O6p2Z1lYm&r&2*iPZsR%%Uz1u zNe-@uMr1Q5x|u%2C(W3fM3Y@UE9lY_bQ-u(x5EZOnjZe?)Oz*@X@F6xv`_O0cRyNk zHSZ#{gN@^9NlW^q@*D<=UTu$|iRpa_oG{7;SiwA_chOui=ncC>-bV%jL&u`nlU!U;25CoGa|0AAt`Xi|f z3~{AIC}I-%k-+oS02T=Ke{nuqDM%1GMcMcDUG1bj2VU`WB{=oiOH%9x77?xtFJYyVTF${QCc06@o1 zp~#=FvvH9f-r@N7{f^FbMV@7qh6!ChKR<%pYkTN~KT5rSXBZzBU3Qem_+V^A3-^_W`(w8{7 zmw-oOGnOEl=a0~sb&zjC(AWPwl=U`-{#tw zwKw*{aMC|d_rb*Dx*UF*H@z?d(prR`p&>9f*gQLM(_3kfSQ*zq+3g$aV;3MnTj5@T zbs}tFL6z>DyqmdNGizuV)I>nxq=fdWDYbNzL zNLk6|7{a3y0C@o*^Jkv~V8Oev?s3i%C-6J2Pg?lU)je=NVXMGd$9rwf%E&!ag|vUG zUTZQ})Ne>^MhDV-c(F z8gX|utNF?Yw8IUmZ}{}GRrda<6lTb|VeiDjD+R4kY6>BUq4Yw|)4%701y7jdb~Xb_ zw13w9L{T9xzTwb#H=-k7gptt}iJ&1CjreX~1MB!2c?Q3p{0CKOUnH(XZS~iR>*Mmj zB$p9~>bw!``~=Jsdu+TtCxG|hApdZ|@xL)VBc?nI{ANqM=>fF)uT#Mdaifa^{EW@7 zzu^3<>gGX+>5S2KJO_}_%>($u{N9!AoWmAcolJG{*`nPU{Sb*sNH^f|W`Xl{k&qGK zWDHT@4%vbrLXYi1(B>V4qcPn}j(2Z_(GgIod&aeh!C8K%8qYmX8KNMbas!FS}OE8xM&9aT%cDsjga+wL4sKOu~u0}y8~mF{nY>7-~+ z%{eL(E(YU4XBrla*IefZBsIw{NbF%^=tgp1*qEe&3=-*maD4!&p0hpbf}8ALy1E*E z*@B&gff56u*sv{&h9?2vDTt2l43Z=f{jO0n`F^+!14-bSNOewoU-laT2gB))_E_34 zwXK_8g|r?dEm(t7|JcI}xp920h&RarNq;=J1=fA*b;%5cfmh3~5d72GitOTh#i9#Y zWBh6zP(md~!V)s9a~QqCjfVIyYhD#FoduD8(#b5Rp>m*-Gusv7h0oE$FW(QJJV9LE z*_j_uHfHi)lo4cZ&-iQ>a(p7 z(A4}0B-G;}?F|b#a;x#d%xwrD@L$$${&E@!bAiPBKx*6moON@abv%dg5{XaF#Mx*w; zrbS~>yM#uCrv4@P4?!yaw-FC6RDshb4IHxOpppNZ1^8!8{>H>5dn!SvkRa_hzfahX z71evyLu-XY~Dk}3o{0ty{4I(nSkS@VO~gAfNNB9LF=AZSjoSgzL{i z9I!Ke9>;hS;%B=0`^J-P(Pq6~BN z2yTD&SB3do^+Q_g@O?GIPT~Q7 zJDdY`kX{1by#rsxF`e;ga)gBpCl(LaFi%9gfBZ3Sbihzj9VZFQ~0QB4b+50=<{jc=`fGg z$!$yIa=*|3zAYvDJ)wP;`rsXPyL|J>|&|G`N57>SM%&P|VyjO&pXO^c<_NhUU zUw-@(#Rd|_MizdxmzdYHwW93F|Gd`8Cx-E zKgKLFmHHRwCrSrL@E=XnVW$?P?&w&}qbAkx@>+K1>q?Mk69c@18Av#D+vvVSxQDrl zPOjZ+-ArdQ@0yH5?x-d!wE)u>Z^Oz%kK9}GJTZDNtT=?)$|kwLw}sj|VUME0!U=un z7)|64o>rYruEdIoy)b=5f4Cfrq6JKhRO>|};sSbdKaq~}*NaGrI{Aj2mUK>vW(r%MXZdY(%nnC1%^6cQ;Q{%<4?WM4Zz@Z$IUVWa|%2(zX z-FLQ~p%mnpEI&hu)p~}}t-V2EtvSg0NwuLQ4BH{ZRCH_>?QwerdJ9Nsy{Ej*8N+E1p6>gMdH#oYhrD>^ zY1iN+CWmhkHk>GYJ?p1D-n>M{pMdR?3ytj`X)rzMrMsw!t65^$S}n6OCdB+}fL-bj zpw3mk+NV;nu2kmKNaz+($8u2q0O=riJMJ+3wm?#n<7PYWETbE4zb9~dk=&i%gNPH& zPIqSDqIU+h2yGjWTrT{j?C6nKR|_jOP`jglAwysAl@)v+VYk}SZhrARBZb$IbC?`; zoko>-7Hw_=-W~jEKsOY*I(X7qSk%R^zBT$=AG9{S9gU&rv~v9yHFC>-n2pR6_CrSF ze3*B>Mh)C9cD@r`>8jg@*7uBC2N*MRd*#V9FmGfW z*64AMc?SGE*`>;TzQAPbG?Y}tpf?lM*O`Zhb`WI9^C&h7!uuVD9lqV;Q~A}jogcSoCtAA$Fpw(kd8!M%^6R54847fk26_G?28J>C zN(xuFAW$<;vO}|_)>{don}VBN&m(ykX=!7-GHL;DeKz6x8T8;(<{}nluq| z%>$siKYo}iGgaU)BNMU79Em35j*|In9alPo?T%l)3*k}om8lW_LRP0i6wXqFl99gH zmC157zK{tlOeXwRkz#hKXWMu&8`J&T5>=g_h{Nbu%`>kGdMkt%@IHi)~w-L!h>ja^t-1(1XJcPJpA(MU7t}n;Z zpGU9C%bsHMc*eTUT4ycA2tdhfK*5tEl?PD^T(7><@=nh&i+S!E0y<~X1p1d4Z$-0X zpOkwX(@D7A=OipZlr6ruFx>R=HDn=lScMObCtjV~`VsGJ@bkaE=%{bRf>$(=o|+Yy7u+tLRT3(UgC? zAgH7NW)-^J)yX*uiY6GA>;?opUzvWL9DVX`C|D7JLlc^PqXbOivUP`w4LIu(I^KCI z*!blS@?xwZ^uF5(0&6cr!cANDZEW7Fln9OjA(+$*tRR6U($vrVZ9zc=pVB}w{mDUv z?lDz^*Z0gV^5AgMU1)ai&aar_;|_}Bw!1{wN`g#yx}>-77G--XeJl;B10GsFq=zR~ z4q_GO3Yc%v0MXdUl%G5bOA_^T)8I0}iQQ_vz-cQ4#D_VXoF%S>atnNAEMP!6DLy$G z)3v(PqU-WREwUoO$V*c8_eX4_pZgJbA1*`46|ibM+zpkXjyfOEg0zBYAC5k=v!JB` z8RfTuO`Vt@zjIqj?_coQv5bv=p%iyTOne6wc^1!t9h*WPq-1h~oEn9rXn&1qCdlAr z#2EB$_WS~&d~G{QcwwCuEj}|}76J?z?E{`O>p4RB?5Vk*0SVpi(h^E5?LXeRTK##C zroSKhx{l{#{#kZyTg9)Bx5cFP9khPizI!KA)eAltuWz+1{g%AmN2sUV4$~W4-{j#B zC5v!Jy<%sg$ne4?UFG+8;K?vJWk+%n)w+#h&SNI25`Jk{XR-RneT-x?l z&P!+HxUQLl`dki^z=?oX+;Ho?0GxksY`L9j{^bR>j{Sw(%xCH9e-5t*bl(8lTX{`@ z-LH-@W@X`I#=j#Dn-IhzP{IRWe;+y9@c#7T9a~2{MAeWdt!nw@({J)WxVq^Z9yjk= zF8jxk<+6R>UbX1|0fEcC+B>pqResfvF)*((%#EScYYUG=5~rONKTOer9=Pt*9-#Db z26w<*EYYixM5ZMz(irFX$bz7yArmuY-=@ev}c!??2-P1_Ds03Qi>Z4DN8m3njc+|%Nk1b z7OZs=eIal|gAyFr$sVPh&>BrEU+uKw%hCZOA54K_bQHnv_}RBaQ22gz!+<9`>I=HA zsK_ED?kt`(ti+K(+nwU5N7tyCxePR=>7{j5EBg6H#IOGj8);4bqJrAN_n~( z0~4$*)K)tiakO%0*M2HH6c9m3qt(cYBSGtfKWmqx|c4BVn(js4SDM$hDZqQ z)p!EYb25*M7YnGpy-{wv%Rk**M@M?00`X6C((&=PKS}1QA?(P{*PvN?aQ|M_O4bJu zWuv0+@mtnvW_Sg785jt5RedbN+cyOQQ@(#%&{2LDA}>=h+Fli_>+|I)E9^~ZRyHOAHLY(Q3BP<<17*b*&7DJ<=Tup?y z=V3fT$~Mt#=yqy5vFacfL#^+$i&o(CwsJH@N+ESweWRjNY1N7I9HIMX6C!|G@%RM`m3wXAVaGBgR1 ze*9T=((`f+%{HcTSvJ&X50GVqNQgz`8>RTgy#Q-t_Ov0^4R?8SwT`_M*);l03LJuU zF=eSQ6?0`EJmw`)W>9_E2t6l&Q6G zrg^pX{9BGOe~K_pFmstDGNEzB9JVo!CxoWAx|U#ARP15{W%&#wXDc$@6-xLpquPO! z=c06{R8?X^@N*&;#-mt6*&A9QRgY{4r-r8&?^IO7g2daS==osoWvIBf)I&5xdQ75K zWFyhr(y?E5(`qKgf2Fs7)d;>>uX8DQopJoKgKJ*odVp&4Z0hLuNGwg%lW002nFzhJ zbf^WdaP{uU>CY0Qh#54B-*i_7>Sp@}x>!uut@&U<_%vj|kYM#)AKb$rcQXvoF*ANV za*3_tt`I#C{<+wG&GwECabHho`?MM2AjVM~vN+M8@lJ)o6!`6Mk+OF4g0KA4Tc9cH zkFe=;TkjPm(NV}G<_7IW9yc$#)1HWxDzAmrqqMF`dU(U}J5|B_N{zSQtJEvjTbMvG z+|i9y!rh?gG+^2USJNl4F(gw8F=5%nWHTwA$a*^l{tSNOy5#uX9e@g$tJM7^h)u zs&2!x_;Cx{c)ecry4oij$O+r8+p!~tWE&aN4PfMVShyOnKl^CHFy5d_(=`uYtk5Vk zq(-RH9@_#ry!VYiywlrxL*5zmu)@0U%W9}RZiGzlYJsv`3?^7i{!gLPZA}v};q@Ft zjIDU8iPLT9v4QoKkTw`u2+pktf8pgdCY0PY@qo+A3oVoK&1;V4TvjT+c%xy?coRk$ zla|DrHM3BE9>-X4y=px6nW#Q$&O%h=SISe6S9U06mTrU#B1z{)aB zvjiq;W?S;>F0qN|ZzMnbXFgS3;PSe#C~X>vG`N`t?d(HqNYGT?M*<8^MP_RLiVI?R z@_<@4Cc87rr6^hKm)wPIUB*uU`YfCfBsRA6*1r$Ur5n3h;&wb~M0eCAo{IoUk1ZEs z?IiKzw$L}ihYGowQdC&=>>?t5=mGMT{GJc}wY{H^s(IhyK4Gfe@bv^UgUC^G)H>$H z1f#{dNnhU25VWNE%rC=b6HyERb;&*j5Vg!MpEYWY+$_#mjRlN+^XcQ?@HGR9Pl_1#$ZU2ae&zQvs<+q1X9^vOHf9!QRVvR5wi)ID19S?2mh3YkLz&ZALq4wMWAj#6^`o zD?uj^8S-@b!C4%|`k_@LK??xAdNbqv(^$mxz+_;K=!B!c6E_h;c-NEsd?p8s@zrxF zI_XkFLG^n@p97bln1+-NRAnQnz@B#C`iCYivGu~EBv((r1$;0pQ0);4KHiYVHWI`>?d-zAw%nn%cG=UC)(EuG_*If3;^- z)(*Y*8r%>q8V>zxVFS_rg`JudK!ec@{H2*&03R=@KaSHc;YJ~hQB9CGzgrx?y5Fzn zz7#SusmwGojkhk>z1)5F8#DT%l>@$s=Pyi$9ei60k$2*A+C0-1d?d8$bf%R=nX!IM z16Z=b7X9zJMwQB`tK>hePv~qsNiqf_&`!~y7Z^HA9P)pbcL+o9sBRy4Ax2$=oSscQ zu(>*T3z)}~gHa(##Ki(|S1|N85)U2-pJjN5;5aWyC#q7HrEM1X<0-LkiKIkEk$)Uc#F(AdknDP>$}oqADk6>Gj5EfE72w}w zPvF@sN51_Z9Ef7UlII>T2}(aU6mq zUk~DiFy0#ZP=*Ipdm_aN8GtKFnLmKsYL6Bx=I1SFER z(tI;}+#0dv0A3f>LU-D2US!vo(e7?0M3P^zmI?eewvc0)a4<~co&&?;PuY6Euv19bW zW;4e~&9{%UMd+mqcl{>#K=@*hB7>|gTK}34AeiP^W`To@8i@!JIq=574o{~(E8)6v zKH7b+0gZ51VWbs+N@O#%YPkxK96dO&;g9r)@M%gHJ}qD|J75z^YCqTuf0xW8XAk*( zBjAK~kbpi(JwtEsd4T>T{l*2bmCMK#=e1^1qX~&AVPUobV%y>X=*~*uR(?IE)BE39 zB2-9GptcC+_^nlW_^MLPHc7!C#FzY@bG zUo5;cXgg0j!WE5>AwjkWNB&es%4aUw>L>@*^)7|JWW;`)jb!Be^Lozch84nIJt@$L z2cgzp`22v-D3z#&v}`=aP2ffD*XGLFVk>)$NGu z)2r7}>PW&*h~WIO=&9JCdM>T3rF?tvUHg^YJEL$x-%h0X6tGhhfGZZ0p?R8$QG_ot z+-z*gUF#cT^2C@;XX!aKG<_RS*g}Vk&wt_pA)_mLOj_3HI3+T&_V7+98<25sHT0W zND80;d5MJ;m7zh~bn0zR{K0y%Laeip+Ja`?$&8<{FD6`*8FZLO?0+kA!>mkoqb^et zRV=N2Ns7yp(oK5}4MkYA+eG7U{1vw+k0T{+yKu&ZR%CRo$1SyA+I%nR6F9GR`2oW) znE)+(7ph)=cbH-7gi8M8Q2hc_$4%=$C*O}|`MYQ6-OJiGh8Bh734C}yG=v6nO_S_ z3S6lMin>h~ixmYnIXVHf`N6Vs%U{00j&fQnPnu**E)C~0-B03a`*uA1_WRoM6xp(b zdSF#OFqbE`Xr5v1dF?2l5Ls~9F#%n{@#EvQa25aHwHVKOySOUsj*H-9{^#FiqF;tC zAlr=!pBhQNT0)igYtSA{vps_x1SuyzK;AAASA!NvdBcA#cRkhlQ=SMaId$PSbHp4X zd4j!1iB`rm{Nk7Jg#%z>4Y(TQW5I^(!%fO2GKPA~wQ`C0FcQj)-@T~oA&29qi%`DP zq3v4eR6H2yTL1H%y(^66F81wQAJ&@zT5Ij~lcwA3u#3Rf;LbHQ-Am zfq@6}b0OZOf{)X}$>swj@)BtzVpud^uz*eb;WQLcZ*_@aX!ZWeh&t2>~EWf5+`_-K_FI?F7ufe%J zuP(0EnA<cVg24N6 zjDbDM7MLJK=H3i7Xs*-&ItzRvMT$Sp4|w8(G)A z<|`#*G=wS8Z#x0GO4gmSP1)i6t62DaewqbJ@cK{2abauj*_GNh1u!KpwZAO*o2KZP z@@V8kF#l9`Bleif4f?|8!Y-8k{+ia7@%H)5#Hvy)ZP!zw0Cqb!>Ou9)qMs|6GJLsW zl&i7SJ`$HQczg^8xaRe&L!s1)+#kXUT|D#jvn%U~4=ihZ+50-iW3!j92GMLD)lFGi zZII&qdN!akun22vp}@Iobk^ZS-ufzIh?mm(FRSPqruKMw6u1Qt7h<5&{qU^rj;2dX zWg!-0$mA82`)l!_sPm3uJVw;dYyV7n^T!{Y#F&<6k~|VDtJ0bT;{ybu2`4f{0hMvh zRxlDr*|m14=xf28<@7T=f<1G+wnYb4i8d({9;kS1+Dc;Be7`f`y{n@8V06n?Y{bOu zz~fo4bShgFx*;zCW%Kw@81_$(th;~28U%~#a~1^Ul?-||J1t4ZC0QvKqH(mDKf%Ebwy-O|6n`?7>|R_n-0!LvK}_}I`wtI##lk>F z)2D=cS^)(<&~OYMVa4};cziFVs;W|l{|t2qy1gUb%YajE*A<$mx z=Cx`r{AhJ>;i=^`d>r4rBniOO-y4Ut(;wFGiRUl^>tdc|zKE)22P=95(BZ*%)q#}O zK7pG{7| z0K6h%Q>?;1pqG9(1?Ul&Xo_Irql|c)Y5Fe6X6R91E1~mGT8)cO zx+CuTPEPo!3TmXf7;N(}AqNBc?ovIkEseF>k>lf&JZ3O(@U<3q_o7spKlfqeEkio) zNZ987>coEQ0h{l2yE(gTqDiZp)f4KbN0BcZ!DQmhisEk$kUTx1)JaE z=5Bpd4Fga8`Wcj`y$u@R&17tgEL{?3@05hMW-e^9$9xTZBy5HdAtvN=_jHP-Ilr13 zRK09GKosKk=6bl-$9@;Dw0MH$P&J)7S zuCXU+#?Z$0zC^#cR?MlT)Ujng@T5iJB&Ms(YW-MiMUa?8k(Pl_pt&bME(;c^Db&Oq z1>pA7$UJ)jj8i(#;p&ekR(JCq*#KAgCf&#WFE<3c$ATHc577_2_4;Q-9Eh>6y)6*I zc&*uIvq!TiyNcb2-sO$%vuL3HEFmy{&Z8)-=OcU*ppC79GV#29W zZf?*YM-f#YH=em^eHnR4LS1~)c;Mikgl-5!<3qD`PJGdzp4UP}P5$QPVgj3+BwYMU z9SYbcsP*h5`17ArrnkNzul8R#sLAuI;5cYOxYLa}l#!?ovgpW>uGfi;))7@YK z6_Rm-#~p>p(&(S%S|Y!edgLYn8CNbdNrdk7pjD^aKq~ArRMmB0t99 zrsO(dn2H-swBy+DmfmCj@tNh`k~BqT%%1blNEcP*&$$JjNpu`?ON;3xMB68vr*6bZ z=;}cslb$RKZLnD3z7X_w!%9wC$zjI;H^Yr|Byfm0Xi8oh^1U9 zp$BAEY-U-if1bO6dhLlOn@CYBGosjZ!2_Fa%)%(e&q55t0z4@+iZjAVc{<2v!4^c& zJ{Wa-esxyFPP;^uir1l4x||{69k)4#k5qOkn}e)n>M7*`P;$P@lhlE~J)`d2kNxk7 zSz(@k`nU$7D3 zglCfM^wRg~yznkVb^}k=f!D&HDtLrx(D=~b643nt*4!CmWdqIyAI(=JNHO`C*oT;C z$UYaN{HYvfx*auLqV@t%5E$`j4-KA`%ge-wKrgJih1W72|MfHePPI{a_wnkG2{KPa zG0rk{S^zQ6cdf?*r)6#jZzM_YD~Pl%@9x=n5P~cQUn;Wt=gLk!>71Ce>J?cG5cRR( zpDbsBpLY4Z0fy;6_d7zEV)%RprFN^Rz~rZq%HA}cgLj5(~J=Y9-KUsyd9bGAmXJ>}V*lB(vxMTc6!<#sCOd8L8 zt>|AW*@iBjwa)PH`_VDmqN9nI{V@f+IYB>Iw;sh!F9S2tlS;Ka^><*~4?TDI%I(q4 z=xZe1LhD@xHO>4Y7Wh1&@b4kLsZQ4Q46e%J&J;m zutrI!+Du?er3xNHVvdJ!v8A-w5~35}LO-H4%KRQ;+nOyZsLwKx^nBVN5hwV1^`7ET z-R?tM5CWJhuVs0)2h?}sZuZ?xR&Pox4sbHsvs5Jl#?j^Vw!4->9=;98`fYF-7c@Xx zBI}b)7yobtVYEDyg90$CHF3COY6V8Jq0{V(sR@vo2>+4%!d$?XLk$vpuB|s;^|y1T z&h=y0mBkA=b%9pe&hg`w^DenZB}+Y`HxyICZ&WKD2qvM)WmbZyV6*zKpDRL@-<;;q zZfb_A`Y$@A9PR1Wfd8=#f&PZOS;My{&cIT%kDpRMl2u4XY$L`+2&{{E=#L8 zlaGI@f87zKH92J_SN*o(wdSs$zk&J5^XCGBzQ2qMqejeWOWeQ8W~rheJ`Wq)n3m?U z6Mo9qlh=m3wWpZ4H&KAeKx0OR4iCyFuxSVbL57}oks_wJd{{}b?f-i!MEbla~I4D`f#`p_~!PUqB+v7Gh zekdZPw263^3AF#7@Qlg7#~-NAU09gX_e>aElS6kAbIa7*#3_s3lu|<}BQL9xNT}&tA3mZ}-)+|% zdXL>ox4DXACkU_l^JX#hThwmrG*}~bjSo6<^tAV@p%mMKVdapI{ZUtPP0E4#wl-%Q zSV$o%of5Og&uii(L@X^xwGmh5|v+fugwB^Irj~y1Q zXIT@n`ir|4SaQcm*&c@%6AUem6j!0Uv_x!S@;h$+&{{t+Mu73}Lx_yAaiAc*LW#pG0LfSS+po=3<@_+n(bagO6RjpC_p4emsrYMsFFpR{t%_TQKk zRf&^{T@+r?D0cTJ4G)D@j)f3IUtHiUx=Nh*<^q}_oWIxG5RHtsFo>kxOjmMOMZ?VUq!7 zB>T3pFYZSdFR)sx!ZsE6n_%{6)5Wgt{eTIv?}aF%y$?Id8ut@Z(|45RoRbgOkH_2} znzJni*MtB00R7%{vICo@0hd3sb7$&^3r7+PFSmzJ7|>!=`(5n8SsGFif5={$&lAv|Na)C-HRBvLLAn?)TuQJ zx%h>%00B|(nIjSso=^-!!~S6&8`(_)Coh=csXt?X`SG9M%Xq_nxzlEaXC2-B>&8pW zp5)u3Qo9(F>CZzX10pat``72yhK69|mGV7`#Y*eVq0yK+pS7c%jc9MbMRiOK2R0EU zEe&;R%x{*O7Fw6!+V&7@2~*E@Ir-NmB8;w8w10dsb*q;3yzg}V!2C}El9&r1Ms=}k zv}n76Xa^?{j(FbgXmYDxYqU+253jPD(t@nZjM~2VXI)S5vWy<WQ2+ylBC&I0U z$8SzEsv?y$W=pTas_Q-xn{qLUDVFmxx^U98^3O2F6e5bwQ{FPYVrSvbx~wlc6K@ev zf3lDIW!GJtMFu~0^IaMN7c_TAsNw%vMK18VH|)-g8#oa&3wD*T`nqTRs&Mz}@R3^B zW&ZZDq96~pXPO|9n2vmxgJEMWym&twXPF(abEp^p)r+`+>3F^_-P3o2&19$JqrVIl zvh^ba5C~$o}`gR5nV|ygBI(e#Tz;VC+ z$P<`kQ?ak6e6w^{y0f068Mq`kcT>wUnZlS!TrcKgx7NkSo13~b1@xiZk1SI2rrEFb zsKBl^6HgR#Fc{LQHqM`tRu>buB+$dAsF?K^N6Wgg{krBa?+#(mzMv|6&b z>Z>&!{8eI^YI5;nCPnTZ0>>!et7ZGrm-jnZ>URy>#Y-X>PEboO@k+t>%I!Q7JHquv zx!dvQvTdTT*JR)(q|mxGfUWJO?0{Wnk^pDp>Li7eIm0XX-A*g0>GF^*o~KbI(HTWj z@P$H^J-m9w)=R3wJe=Uj86ImGAlVdm{J~B@(6KxPZX78Yj1_)$W%!3D+ofLTyIjY+ z9+(!7IbGpxFkW^Iq?dZzzlJaA;8)#s*iJj1O!VLKB>GLyN5m;J@$?>z>n;}0evq$; z`Gjnh@(EqIglHLV(4}vb8-n`%6|Tif=(l3`@6r13*D*YhR|63P-49(MQX481BgU^x zTOJ~Qe&Hmq>k(pl)qGXv!^`}PR5??=tui46d?f$AcRst?)QOiolElWGD4BPs2l=O( zhB@-&K7pMBmBa^qxu7<9q)p#ln0Q%Y{%b&RB84t8Zv2E| zWJ5p|1@b)R$Q)s9Lx7o}Hs$wm`4 z6?mmI-5Xw$44$1>WkVl{x3F#=#tUn|Btu)U@8Q9$fEao}yvjX3USAPg!sw{Ulk#F? zc30WbanMeoT!ggSiC%Dt;+vR(Pa~mT;OECpTDeATvec=;E|V%uIJ?5@!dHZ@XGizt z-`TF-5;bSIjg)oY?-fzndNL)wP9x!PBIR#wT@DZ2JdZui%y*OeQ7{U$xP6=nDDg-M zduRyCim;K|;6ZzOZnF?cs(qyh#QCAPNL|fR@rjKl4HDUL1$~=^*r5LHGfq|_z8$*# zpyGpBht0khT{!JY=BFVP<;i}bp**Ash5ccLw?w;XbV!_;7KoY0FScKn39XlB9Oebo zI8oM1Vgk@!MV}R$o*-e2iTwps05!t9^TaO5>9n<&<6vA*1GbzP;Kw3CkOYqT+|v*n zXtI-2p?v0LUi|HNgCm6k9#gTCqIW+djnwQzLEh?dMh3O8l_)JGc|@x3SP(xY__T_KSl@?fj8TMIWM0!k?3xl*#5aoY zyiHT_vgt9A-C*MPwb1^j4&yBzE4)^xS#pt0At%^iG1K@{F#oh{D5}BC?B^H72bD5V0)cH&N<2#=;Ibc=qo%*!=z_Jm7(UnF{hBdYir| zZj(NKOT%Mbd_N+tEBy9NemUryH@PA)GU=ZuKix{}Z=Ts5F!El{#{jlQ$R#QB-0!Bl zLYSO$=iZq;>|?YqJ!{|DBBi~)&_C$yv#BfX7M;+wO{-8se^ayCW0Zd;Lg?-bZAp!z zB$3yIM9O%xf}Gsrj0*{Ye( zZIoGjjaR*k<=BAY9CNt^@RR))6F3Q#f7HyIjSAnM!3uuCT>VdRdRU=(;qv*xC1t%; z&8dAuQn7-<)70-$wGK+wkzD8!np4ncYv&W~9|68RUGUx^$Yd}2D|kP|Jl>Uwb@D;D z(IdWh5snGo<8Q{+2G8DqD)8!|EpI$7CbwB)IG94EspN8S7~w%ykLiFZ4(C_{A5F6wo3L-tCx@)PRaNwZy>A<1`@DTTtsZIc;nq1IgICMp zOWmGcY`@X2sLbGHnqzKciJYf34fIy+r&~E24Bx}Nn0??VXyL*2umh^@6yBh_obCJF zYiBgKR+pT0#8y;s8hBbPFlivXF!QmR5Sdt5Jo3iPIihNDHJxb*|HN3i-ab9E-&h8u z|LHn0aXz%N(M$N;w<;Q=@@qF7FsG>_df#pb=G$l^@+}HDiUG>gI{$V>j=ra9Wt(W~?5>hSZbn!Lv84eL4$z0GLT3#QGYX)UQQ#LlSV! zY9Y4h{BwJ9=i8yv39gH4_j0s#gCxVgLk^W(UB9L?0)!LNrATKWodoE^!m0f93@)rI zRaqcDe|LbBo=k^A6kHomAqE7mQTrzkusamwr?My?{0h^_$M7P1c;%0<>sCtV`6&^u?n~&Q& zXFFPl`cm|#T^g9p2=bS(X$vYM?{NeYfSyfxJ3yX6Y@AL4I4$Yc(tH2Xzc6NG_hzh) zytSsYjMkz7r~MKC1uf2FH!eDlp^3s+WhgJ=h+GNl$)oW^aH+$$SanjgIXoo2%lbm% z?#jTV_xP-ED(EC27pXfDt4)%>LNezp5V*=;ChiGdJPCWOfW25hk{M^^+sVD#aF;Mh z#x4t6dTsu(@JlGZ^X5Q!a4$b;t%E5toESU*J_1<@urQ65KlA5}(1n2k+b%|h1cAC>_h~VOE6IEH^Tpaf$l(3ta zQd}i3u+hKj&UN;W+{S{D@{>Cr%-~U6$YguaA&&!GJ1KE6I=Qx88%+R_Gsg7CABl7R*p1ys(7{mfceLMfs zXV{D5*b#L8VNigbdw{5RmDWE;G91j??@oH|n7775QPMLpzk%>V1ZAd=mt=KpdNe_0 z)Sd26Ox9%M(_+8AJP==E6@%Ka;Otnuhz+-NWCxq9c$V|ylZg1J!buf9Ylh8_a; z9F3rQSXdw)F*yo9Rz}zFpwyE`!N?r%xvy7nZ6@cg`yJ$L4jB z`NjF}WH&An)gK12k8+5<5VsHfz3c>Ov5FJ+7$awn5^GxLaj2inMyv&$fN&s*8dWU8 zYk#e^)JQU3gd0=TS0?KU;Xr9h8p`*d*rZnzKin*(6Nbqe;iLPUxIq4we=ekgUH_Vt22_F?BNxn$xSTK5Cqq(uCc;&CJa%-Bafs*-235ug5CE5R^MRPZ9#6mM?2 ze&hv_#i43r)eKQjYkoG4BO;nvq-}Co)_>*ro}_R{Ps@J~({A`B&dLjb;&_QS51 zY!^+xhcYhWR_jWaEfiTg@d23DUv(s~wT)Km6iS!h_GZuTSqr-6QSu>7#OJz~!J(NI zlNzF(#@CBFGUQhzhpEz0;sOkp8 zKL&_$3B7rVDgtDv@|<(;o<{>)8gXYHO4k@Y0RB^opF%BH!k%f%r{SK^llbp`BOR)@ zEm6CH5?_^JT?D0mUe~7gb$i%@q6?dsO5KD}(LahLnh$oe%{RrP&h^F2^WEzEdX+1f zT{kF)(g{UnFfLN-6m+lwl0lZ|CqG6;T{r53=lSRJKYav;E)}+~6=#`dlZ*=j7zcXa7mwp0~Rr^KA5!Ad(V_(vU3iy}QezndJicf!3t75u1TLVk3 zi$m$v4VM8?#L+&T*p9W?k<#v4)R=*ATy5fy-ykT(XrLunYL69mNDXrm#Nh$fxdY(J zipS0&F0>G0WUFI+YYO6Bb-m>fY1S_?$WO@J$_m)_R)Y=0Rf({WX?8kEprKct^mzlv z6Fw?^;3Zhgi?|n*$lrR%JBSJ)XM_|}Dpj-sRbz#W&1~f*kU~7sJZ^3a?aMGcb8$U{ zLjM!M+s#{^08b%ma&jDna1$W41Rsp2QGno~{f4J^Bk1&ESL+OyY@?389M7rP384}L z!2}WIvE^$ZLwjo4LL88e7u3!Uas&FUGw@}s7qbdi^4(1M(nw$~CPRyFT*+Z!SQ~zeg(AoG1J14{y$kIP1`Tg$%;UW;KMvE!PJNsYrw0 z`Co6IwOwN~Oxyu`SCXO;cY(FFBQ4uWTGNm!uaZULv6v)vtlR zzMMf_Xzw?3U(n5qr|R_+vXlqBxwBNX)s7csrW4LjH~LKiGOlalPVf*p6*MTlPi7gg zj4wmhF@$5@S$n|x7tPH|viqcNm7lTaVI@y=_McJM)O*%YMjvq16-(Rh}zd7Q|tQE=U)QLl4? z-l#8f(XiW~xN!Z+xZC+@ygK#ZGp!Ez+fR(J|fPe`_U<*HJPX5H{naU{bw z@L1Qw6R-l1QAezPaxBr&r}I0CfX-1n0kY|(Kn%U6-LR0G#Q(Ga?VjZXpv7jZo+!aQ zL#7v+#zyR}>GTnKLA{`B@u`dGLh|urahwT4)OzjRoS{;j*7qt#FmGZRk%b&a_YdUN z4!PKC8uwxQ-;svt6#YbS_7T4yVy`=1IX%s#2~1+vD0g!oZcsWvh*$jC&u3d3$D5I| zB&N1ZRH{o%B3*s-LPk@6Xw;aiz$SKJ29287oE6`P+?g2u4T7+1O;EBvEYOn2zo3#+ za6Rh;`U;|9UVB^R$<_Q7MD+f1WUigNq8A^d0#2{Eq9eD`oOfPgeyIW*?4F~6qb~4+ zPjlZt)Ne-V4ZYRuicdbxeec=7+rbA_+<6bT_e1?JZk5} zycMC%b$iEy(a}^z{$Oq*T_z72?^d?ozAEQ#j+P$H0t4BE-L)kjq4-QS1@L$j8Qc|L zeq15oA3Lsv(j89R_vDPHulud{A7?!4y1THH&p4Z&r!ne<1k5Td)L(*w-}AF31K^gJ zkLk)#7fyKUCSciSkH@Ms@S(&{8mfhEKO5)}!(c{d>c*OjxJWPLhmy0$rV=V<%9*AU z*QA*`sO+uLFyMY)&O9_?!d*ma%i#;+h7T69HAq6FUG3@dw34@MhYRu#I?wxy?Ax#X zRa=nY3`5yE{nwv-q>Tif=1@6Blk5CFy)7oGTTapI7TO5BA2uZpUad-(j542BRTzyT zdUUkb@Oq9%C5z&aXTa0Y7KD{DNpx=0?^HwLZ%^9`n)Lmc&Z97E04OYJ2`I3~w2nfR z%V3ICz4%lyBT#;J_?7f|UWZJnDGtgT^~f$H53AIrfLYcrao*Wc1CqG-2sBoEj*X?9 zkUlMaNK7Egmc4rLlZZ^=)vioV9~CS7spo z)e5Ykq0^ zTS0*|G*cExnAsKgt2$Hvw@Lh_2_kt#J)sTuT0luD`dK@|&w8f&;E{lILLmvS_35i>qq1KnMdg-8N8NLPG8fNe>*4E|7=08T&zv8q&2-61Mx zvL=9Y6Wf2w#Znd$oJ_Bu<>I=?a(iv9bEPi@%D6YIS7m4leck-^W#u~Rj>M4v1gn+b zke@_UQy~i-A%MSjd~|!m$4R@FLM&)qrRDsh>-^YfchJ)x$8|fLJ*wqP-S@Hx=ALr4 zG22dvd&c&l#k+f>JgWCLrhCp`5s}y*2^{bvO8&#NC|E4}hI)lE>6*Ia4i+mz*ZT3p zzo6pTJ|NOd=`J5oC{w}V`tNJcfA%5_rgnucI-4^9$I(37j2v_O?njANj%4qmS}a zt|#fy{tUbMYMh;){P^@O z_fBzz&_~rre28+5{HigxS8Wktv%612z20CI@M^p;v!YpV{t+2iwQng6&Td_XtmH(Tf<5n`ft2v^A@5LYZP%pe$UaQDQ(+u1gL2)rb0;s4K;X zD#PgQxmQlJhvyF&oprX}YZ8Yil+5KmoT@y{!L#PkxjoeW@WEz)=2B12_CQD|JqASk z7^fm`%XJr54kSPRqCw**5vdkzK9Hv_dJfW37|=6ZspXOB99rY9)W>hJmGzZtSY&gh zHAt*^fGt|=)t@t-V}7Kq|Dqgoh#wl5O|1R;;0<2A9HVf`QvTRU4~fLhQp2Lr?r~1U zFqNRv(Ac;Q*#jht8~;7WLFpf@c=j#AN7z7A*8?HE@FK&~8*4{WW-;?Hu{l$6(x(tc z4r+K8_YY)_6z)GM`4j51vxg(Ej``V=qkq*MA5TzLhn`g^N03^z`oh}o*d4D?abo+H zjhB$QwIL^ck1xbpC`BS-xyC}N(pl94&J&E5QkDUJuEMH^7gL*LmxkmiZYw{~omZ-9~!s5JD_Tmq?KpL*r#k z*51@bc(flLeg&`+Fs*#n-QeKA75uHL$jL6}fx^rO)PVd5_diR{HV9+H3jNoKO7dJp zjP*lumQwpHA^~>Lf1(lSwqGGg!%xnpFJYX zK{A98e}yLT&`#T5mhP#1P!45MIL>%cf4+YYYS&NB4rkjvzSKbH7A_0#`nm02RG(-k zrJ-5iuwHtyF72NMTEvZ1$o9eUeBrh8qryIWa{=1d4lAJ|8Upv1G65%rzt&J2%bzvs5$RmY44@`ut4toH`=D$VrR4kV)( z81=i(49g46qCONAHv@T*a9eod$*^Tg90Z9k?!MrIM%!`93H3UFn7VsYd%VlclYzO$RHIQo zgfBlS2)Dst{uPjF2SPu}O4i{;wdmT;Or>pctswv+A#vgZ>|gKX zmKCtdD6sWZi(%UxJ{DtQB6=c&&Fyj8+(uO+Ne0 zn<8E-VB_W=GCVsycyu@m>(?Q_2W3ew8L@TRCl5!CizyCT|3JOmkRz&vniOw+yR~e0 zp1UOksu35@fk=n2AKFPm>hfvrHNj1pgmxK@AuHRUkrWz{<~XK=Se%x%lPzG7wTa5O z@WkyA2HO(0)`}I6N*clkEdbaao{EevD$B~R;!4M($z9@lDI4*3T87B?juo1Onwv|z zzr2ez+rMZyu-J)QBamA^5?xv&b1=OkaDKE$0PeO+;~O;OuuPv#)UI4RSl7o320XASZc&$6hx zTF7PB%&|bXR?+cy?f0h@**QEvUNiilT}2g92UEe8rvn>nZ1SYGxA{$`d!BmM&dgM; z?@3kSW@Mn{B=5Xj5@tdSTMT3R=|IZh8Y06A<(2ISD)NBLHLDP1An9Q?IFgXvOV{od ztJe4mos6h)Hp{((hjYO^h!E9S5%N~k#4etMCJIi}347{aH}7IUC4b`MFbb0$?iUV3 zp0m3TX_*spZwYi-$f4Z>%pPS(1ql7vT9vfoyAEoa+2()G^&j73Yqm_}#_lI3w*87C zyZUh#CnH?{Mmuu0>6GDB{kCd2`!h9h>!2g__xoa%K^DVl!z7!r2-pd7fYRU9g!SFS z&5fT+C;Rt(I`-aiKrVM$JVS*VF<5O0D$}1&|EPgiMAf&eOlJ3#O=BO^L}^=sE61KT zCmNeA!W9AbI*#wjleE?0o26SjvS)8!3*8jj!llB6Q7K(@UJ<4Qlepz#6giY4><_Qb zTU&k3sR=h%j{3SLd>jtb<-XHUcJs8>Jk|E34r6yg*Q&$VKdX}zb=|4g6$>2F=styH z{^xtqn>!=hIp7Yi_oMEXQ17lYa?gAkn*j5A#B+|a0-#96mO%4 z-J^a5ax_70_1|USdAt6NtuPG3tY1sEqr%j|l+&fN`Th}oRh#%W$DrCXWJ7+C$l@PU zz>R!b^ci%&&J!aSuo%8k?6E!gTHtF9s9tAPcLY5o|G<4gRC_UEtOh0l@FEq?yn4sOt)V&dRg0bwULFR z9G*StxVujYBZha)Z%cD>1VC-I0JMe?^c&fileCBvkmZ&SNUV^U4TdKd(|1_|2}BNE&(M2|Cv2Rf&GP;Bun>B;JD#eL%sM zg*+fWkokvKEef}w&M9P>gUK&2x{V0lWVs|Ue*WpvbY8Zc z@_+P;e+8)2Arl7co@n>*zvJHF&fjr+ld{Yt_9sJ0a79Dc^bm+m-CSeWT?{WBSJoLr^w(MtTz1AD_4 z)k}4K=8RRdo}9o2(Z~ABj)~bolw=F`po>VMg~IxGDGvO_-tx_cpk6a0qjBQj$X+2z zOXicGT%*?DH6>J2Gi&wme)baWudMX=WSXHvhVaFbCbi5vf|{^+DMHA&&^rUxP%G9D z=>uE3*(UtR03R6#gvWq}TOAz*Vx=$)#V!hDL@ekYA#)l4Xv|2H z!eMTu9<D8-y{nfSHt$)3R6k$ZBE@{;?3 z-F?kPV$q=bn&2YlXOXJ{CuFeIE-P?8c&5DzjBO27phSfWfuWuf#89_!W zM4o?r;MH>6RHWRCd?Nu{G~_#9)~dgH3)6R_YpbKU$p=i`r6Et<-kCd>f$48EYNdW} zo9$j#vy82CU%p*HvQ{N_nNHfm*KT=tkGt77M55n)CHS*Ho&M277g)_EYwx2{@FuR7N zvTys)1>`d5^Uj8=|Ef5qoOxfJCaQ|^Nl1)ctw~WB-@DP6wg?;#*~p2)KJ>>g)0px| z0Bibh3?)s``mwI0&bbu#JoM~r+PM5i68JD) z9Gls5$8y!UV|f6k|D~s>Emxl|t6)5Jlyo?pCOjE*&cfKS3RVg!SC*&80e^3bz|{tc zxB#r%U_fYPIHZ5Qk{G_VxJ$nGd+Y4nO)Hj{nQ^9n3{73(PXIsJog4jw^^WU2EQ*yW z_;Ye`5(r`rwd^Qv{F3d-M;a}<& zYf=~x)xa7p{7t#vzP1@9491q<8|uK^ol`~erz20#R!i3=eUPs{G7Jiu0lKwh@Js6+SolWcq+(3t~P%J^(krgKuoF$mW$;i!}c4vzd zt*_vjSYcRdR}e$9oS~DANM(Eb>sk@xqM)Q#VM8}>2`)x}BV&6^0y^lg$1QFg)%Ai` zsOGYs7r-;=%;ME_jaXXPNEuU9B=4cP=YtEU?2Ac3+f@RjpEP_y`|goWU#tu2$-2DY zMAifOe?|@;5Tyk67;&?(fd&!CWuMjFWe$5~l^`KUTk0Omw0U6nwE;j$v%~Q$mNNPH z{%+lmRjYT{_@{dgg5Gl1745i6wq})YXu;uRIcz!_l-tat5JSpR%Z~`_uEa-L0Sc9G zQtb+Bl!;L>V$jEtyr-#jySVS(*6Y&U{6LhCFz)j?TE51-MA)_A5~{KbbmFJ;eLV0^ z_<@@dmba=Hrk4h<-Rp3XPLC~P6Kr1~6EMc-Cb*emREXMIiI9hlgcZl@$NOczCx@;Q z`UjE7NJ3-P(YfA6%K6yAop(Q^jlU?5>n`gj>Ngt84~{E_oQDk)k;2a1e5K_SJ6Lpu z)%#I8-J>{m$XXBL0oRQ$us;aZov=%eE#bmEuJB(y?XF^tF6E6Hv>V&$a;Usm&&E}b z3Wno2!Y)2UG!7ejOYtl=)b5GhxUJUB`&X#zNW&ragBiQ%J%K3P+q9V#qb^s9MZv@= zFSP(LHl%|TeyfVH(0IcW6Y&^bTyf&RC1CAG+I?{sc^oxzks*=91kw>dUzOKbB|-Lb zB00pc*K6o+U%F|O8@QIAd|S~@WI5LSfi_zmoR8BYx3e`-=M(5}_vs1VH6(8Ox@ z~Jm_KQK=o~%cH)cX_DZ)Akso+C zhAcg(@a?1hCi4E@zwo>5Z)P9ap*a+^A2qD#+BIX0d<(ko^llt!*iII`n+Y*9q4dHb zb`|8h36OIDR!nj(?2p;UPHb26`+G#B;K&pf{CrmQmUaC|~6xVv);FvsfC?&MtUB!`*Vr7!y7-!dGGeafmprJTeaBLVhPAH}>&&mJP zkx>DAxgFF(rghUBdpCj;+E3RR`f4Y2_5&_!tQ$+4?wHJmi_iXX{OR~(&;u%I<)y}z zUEA6HSy#*BeB=-*$@fTh@%u&^3tLg7VxVNFd(`d?>67XGk63!)IPZyMiM2K7$^ckwxt zg;AN8-JRk^X{^Zze>F&Ayggacv%6%f;}All|DFk@cgPk)ZQ2IS+P@8`N1Xo~86M@? z9V+C-pi7EQy$H5&l1~5Oh@U*+jsh=}`YZtH7eHQ7ZU%0n+4Y=ca@$xOOpKP2DZhX^I12`fA>QE-6@kvR2#~@rm%C~G+8*gh!>kj?o zd&xYz!}5ce6&^$gsZ@Tm*(?M#Ls#A={r6hRXMlQ;X3KSM%5PDi{T*OF1ZCdd6~dnr zJ^ng}`PnM^-Z7`^IVxhitf=Ue3a{myr1>ic_-VNT%Nw1sAsWtTcF9qKIT9v+cYR{&gAC&g-qLZZRiM1c400+EiF5or|lg*5Ke76T;WIQnMdVx>@%sHQF zk)*`aacM?FIrN91=n}lVaD_jDjriucVQ~y>obMhVN`YTbPauiQfFtp1>Hy4*RbHq# z$j8UxuG1+=+SOr%F8Z+$)wdxABVuf366kptTahR_h!&6aO;eoY(}}QID)Ox^uXPq5 zxq>&lq${boX$#n-@PuevMX~WPbXA+~e35gYfH(aO>%odfZ+QL*y3 zRo^FxHU)-#>XRC&WPtGOEOpr<>T$tF4P9=_r0LrD-oxIlNunj++l<58ePfMsgfH>p z2z$LAJv6TCEn)$L9dJ0|47(X2UeW3QO>juShl2^nvhzimN{L#v%GIcPdC$hY`BNHV z7~1<&$}9bUT7Y6J;@?)?1u>Wmyx|vL1m0b)1~0YboxG@%ADmT|=)!V)oIdN781l$9 zbSzr>xkCq3o9uAF7EM>esbu+$WmfzQ@=J~hYKke#LX6`w$E_O2ymA&$6%yrO>?F`c zJl2kt+@R5pcG%ljCrEfMJ0G}nzK?544z%1SSRP!i7f_4!rHhLFLn);`I#f4p-%CqgS#a#ioVNYsZ0JUT{w zzqts}Q!`~}yEb4k4UvB2UmR-LEx)ktNVP_cfi>;O)6XPjQ0K&UUijGJesCJ=n~dvtvBJ>oRpAZixWb!k z&hxOjy?DSw`FwjnbhVb^VQ>E-iR;4{fFx^G;%mQheca=z2R))eVj|54S00^ytV=tbkQWojSaXk zl8bzSTCr%D9oh!Sw^v@3vd#4THG3fXf;JtQhkc4m+A)k^6KlI`cu7w20q^Rb$;Udl`?Lh$|qbPSiBp@!zTvaUNlkaabK@=F4!TXNU#iX*i7 z?p3oI?=gqdv?bon&}8CB(aK3_*0}}u9f+Gt;8v~M7R&O=Ya{!5VlBv&!^mG!Fnw3c zPw-42iUS|=B%U*ZO({k(I-}+K|7bePzo_1?3!hBhjb1N(%tyX@5S>coX>sE+56smt!w?$%M+Qv{h@sFG2ZNIdo$IXyu>#B zcDKD)!AW)ly*)HNlVID*Rg3&Z%HNyXV`<`0#B`k`cZTglhrKuO;8!j?u6-8@)uSCN z1Z>G<_jngWaB2v{+=Qtmy5azz$MsKL894u@IXqyMs!b#PJ2I>)Cn9J~iIgoWS#z4x zJu>l+9C^EndsWxL)O=ePraFBX2`^Nn=w-V}Bv6@x0^Msqny)3^+Fn{c5X*BkvVLPR zCu3u%r*sqX{zxGPI;mfxNGTKWiXHv)27TBxdCu;#3| zMLJqsLwnimME?IcUvJ>5J459mjO?T-1~(VIFG-&2_3VwO_=hMa2QFg!QHdLiYI#&? zHxbeIO$pc|f9SxjFjr;Hdy1)?r+&g)mPY_Ufl02)0nw85Si2r!J0@j{9fDdECy6|aqMy%8;+n2tRPBq|o$j9iwSC8&GoHW7tLb^gsL{52 zcODi8cbEvh_Zplm$?p{w%`}>t8I`h>{&E7OIu?4ik0@7pw7)0)wdr_kfjM5maS~o~ zB{atctm-Z*{9L)`s|YCThcbx!hUM~dte?ci%aUAp^`65J2U+Nd`{tKwbfXNgZ1r?f z-S(4ZgTu)R3x*377uH}6Q2ISPi`$q5Y90)=NT8?+``T(4M|QxyxRXbeye}d_n%RzDN=- zGv^ucLJumjT6dF-_z@yw;?=zy$n45bqlTyTwWB@-liUgp1}=Q00TGvrf4v>) zp%=wKDCj z<{a&#!TXSB_$iLKp_vMY+{7sRcKSi%u4;Aat|Vlzo0Efjalvdl>o>;XAX2hY=$HA& z5aio%+MFB9%enKVXS1!o!bfWy04*Uroer?unFS3W3cq|Jfy&JMHDMQ(-z9>0O9ij$ zLU_D&)_!Q*D6``_i6zTzQ2wChI~o;ZU7)i+?dOgfi?C*`uW1 zq>yp3#772^TnA>&hZi{&A6h}khz3FYg3djc1;QpR7RI=(PWK5_Ugp!F>dlTvpS7{v z(`uNHuU2cVsCMuBd7ozp+nwL!8kS#!*uORBY5Vr+s05)iaPSNn zyI6~%J4+Nxwh|77YtCvyjv9^u(3#z6p?LA~F?(9kG;R~}aRu*EUsuwTE|dD@#n0iY zhoK*{~kUTc;pFl8C$SaZ8msJ4am|8uyjEBhmy7D=+YZd$^PHZvJ(vFiJNZIm@tE z#sHhuL1@@V?(M38jh+5pB_L`tlo3B6@@27NdIJiR5v(}Fy<0JP^Bf2Z5aF! z^aqJBDkC!A5Mfb4C19-SQuUIdcyd*8Y4sO@ZFtu&DGt?IuBGnx!h2M-v%+vNT4e&8 z9UESwD4gwW^N$o7G?aEM$04vJbN^XtEaMs*zV1-^Vz2aGN5tL-Ctc`(({|B^t9IWFM9 zlI9coA}Ovwe|hrhY~W(b131s_CaT`g#EOiMlJ z$L_XM@Dzxuqc>uhNNy5PR;H5_*Ii&PQ}ljqqT;@>_fTum#cKsDy=XRP^bsU>CC|wV zsyGpq8tl8Lt$caXpYyhptPfB@-jxjhN%Jt)-IK$N(*fH3D4~H8apphQmoEwaG&0N@ ztyB%fP>NZP{3aBa0s zKg2|+`&V)A{IC~>LcF!tT6lmH^fdQp%0e!H=oF9@j z6twi~^Xz|zda)f56b6NhDM1`%8*Q2N&RY9523HanPMfl8O?aie3|!XA6zQC=(m!xZ zye|kMNi@$>JYegJa%2$yh9lxe>GRC5o#*=DL)H1_h11~9$D(ec2!42!XP9wvsz#fa zs60Qk4c}4I<+*aHFdfqxzUFuJw6DC7%u4znhVO}SP)GM%kcb9L~S>rLE$7&OB*>%q8T`vA+u^nc%F(2zfsnq4|@c*&OR z)Pg4%(9^ZoR&rz8cKE3M5w^K6cj|n|fjPAiE45p1jo<;yh~n<<|LAyszj2Sc_f$Vt zPF;M77M4t2=eFe=W^R3x#J_a*t`ZzIiUAS%9lko&^fthHgNp5Q#Mb+DbYU(V{{&Ev zQ&M+~l{c+zHd+(aUhZaoc(!c57*^oXLq66hL2adLu)NUB@XlF2?obWQ{qs+NGewAz z*L^0=1g#&xhK;Xz&^?8>QgSxl)3zVV4^pm0qZ}MhmZNZOdjh@InIC@!I7&fI?os0= zQpZ4r03*AUAFz#Ij_m!q;bv2YMqW=F7VD{GGdY5R>21WDpV+`=>J|Bos|rv|K#37Q zbOoL;Ecj1tvTL^AAB&u{_cNrh+m+jt59dfr->5*5eL%1wV*!Tp^cS6$^e$>b5w5zn z$^gsWr=H$E9jNnXP&KxV-K$jrK7A_g%8GAMNqb)%)>#T7d9QhLEbhu#~iqr!gH&OjPHX zFRmt{*W;~+p~I9WSD(IJG-?Mpzako5Ss^{qvVn?d02^ApUTQdZ9#gbRdUDPJN8;Y&=#B=Q z?DH0!LMHVmHoQl`<(&%g(5y$`pBRd^AXz4=ZD5;)ep`!ti8|M%5vxD#z4KjB=5}zT zo$1}=5eWerpW%v0$9;H8xy@L-Jt8yXy4ig!-1c_IaiH8mmSmyralWf}=ir<=n~sIB zIsm7o2M`YBMR%mTc=eT}=}Y??sMoHaSXwL?`a}YqwlKEz^g^P>=b~dlg!i64?{PMN6l-4#w>vQ3T5I6iD4BHZa zoT}}$`xdSxC8#j}KgAq60k68}d{Rf2-Q`|zQpXHM;9Q*m-r<$Pq}q&g_gY1gYmR~Z zghkxO)ie!5`XQE^<*k&POw${4h96rlQ3<+T`50U}nb~W9vOqO5=*YLHLqxk4Y0Rt3 z5cq1ToXBsN`J3H=EWPzKo+{@fkgHNoaupfS*54bgJ+cn|JFa+l`X9PmpG7_E_1AU5 z3c30|Ow+e>ynTgOh~qzvi6%_k%Mn7M?H|_&iWOeqRav!06b90l4-apO$9f2A5xI{C}(3#7f1yoQgb&S z>h~1RDAJ)pRG}g9XY!dLBEyFkF+E}p%ba(5-%J4fc8-b9aUHugmYslr5A3E5ip=4{)Mg+a==n0nRq2vdwZ#uSk>}-J}9uWD-Zluz_L}qUP!knr&@QdgT5jl88&1<2-u zcP6kF0FQp@U;T&#>PUk! z#>dNgZ>rLdi@xvLvN{vPy{qJblm5?RuH<`c@Jvg{6AKF45H0L_=v(Q8#6Tni$ge;Di_)FQ6M#9ulozqE`u2ObM_JLT+TMgsC0|;C!Oou`Y3g0#u zQU9@)Z>!|WX-;ed?J;8{ksE6m<)tc~1H%}JXd~+tXP;kH1m!4;jqMr>!1^8ax-lBt zeHJr7OP4khE=Qn#?f(5vD^Z~RV=FBV1XUX0U78hpwKrlTFGy63{0iSv{6mf?$>Yt@ zq)-%>7AHLYq%G(S42xNH;guH2R1r?6d zdx{eyUs`hbYMu)?gAukg!3rTDo|cif8$32Et2`wpG2}%1?zF=7Q{fLSlUp)@%DZ@& z=szzESDA@RCHkCCVV%zr`Tp;wh!-w#=0-N@s;2j_r*ouesT2T>oP2Hl53otbrD%ks zqNOY8J28_`TUFhRZ_qDXu~>_{CyxA-y!1z=E&_9PUUl+}-M1`^Gv_(oOhQBUBDfPy zJmusC2kx*aeYU?6WIYrk*3VK6D+i1xZa^4lQx zb#z-^tEm~wAEgTbNcSEpC3KnrA~^OZKV&CeHVnmIB=@4gh;#Wi!+LjdA`>DS;N<(V zlAgZ?-;BP3vsG!SgN&ckFMv@=k6Z)``GW7GjZ=qOI=IIbGPsN z$`ai#whtgRYW9B9m>Y&GVzb@6q)|CrOd>vFeM8>X;jWkhGBC;A*z?Q(E?j~WNQ%JA zPdp5#i31^=;+@$rh3QE6(~6O{^BU-Nq=&7QUtIti(gAoWPFGIz+V87msSLM4DnLH3 z^|G1VAA)e1oJI1R;~)!^C=kuz9TtHWWA9*r7Orot)ZwlFWrb&L2t5^{?XN{El3}OU zWV5y47;aY>+w`sU1_rM7d*GCRUE-2$2>yM6g2++!#TtL*w* zFv>eNy&u&340B^cgqrj=_T!ykU3-iaEC6?L%6#jJ=WaWs-Q)N3ACKgLi!3XT8=QI~ zOqf;bkn0WqOjV&L5P*r;{11PH6pv9vYkHm^Xhep2;PjLy*0Iv!|9N8`W!Js%3=3(& z3pN9p*q=V18mj$CJ!SS@WE8sBosrq`DD17;v4W>uPIB~twhA9f8D>hjkZVy%=&^O{ z^*InCqC_zaP)l69*OD+MH!&Vy%Bb+Vdjlfv-#3|>9LEQNBKJAua%)>rn6UEwnMl-^)@cr z#KvPG>&eYl?_{OlydIJp<9e{9LZIxcP^7F`oi5)46d0B1*>`@CUv&{E1}BrR5*|gd zwKG9u?CK7gXAn3Bll5*8%4=8_dRbh;eHJU?mb_4 z5&*bkSdh_4r;8SkOB3j4!@%7yWs5E#X+Y zObc<Hz1=p*@#x9m`64R2`moJCk#PV-#82@aShopbDa0(wGlK zmpEvy)0-iIkOeR~zW+zRHovu7<+`1Z2ssHI%$hua=R`O$S``(bM2=S}w|ro*>G8J8 zONZT2|Llx!X}&7k1m3l$*wlYCQyaf>2%4+Am}UOT3E?yTr0-7N6xHR(fej)zwy^Ua zv)C51e-kmzsES6<2Q_%`dqX%rfX^ z3x?eX-8zxWXLRC({lI(J0Ub=}8%z>&6X$FcHM)93dh+fi0OG>x-dEqDG=(2u@_z~W zXp*S%==+=9;eL0~^NbhNl%57j`%_RlGD`rq`&3wTHlA`!G>Vmkq(}SmJeDqwg30N} zfX?ashLfu6crSl_&lvv~b>n=8@(WVR-$Bv7G&@N6W4sv^;B4=JT|7y4faiNVO&M67@` zHkijlMq_1lNzpuDb#=Py-;+Z)SuerFzh*j=po2*h8zBg)(R=YI3$!LZ$MMpbOL^xI z>Sy6kbMk8Smn;9GG5VVt$~HA>ynM$pcFuSc8icC|IAk3GNY*YjPN@>Zd$?TeA4g-q z;*U4-H8o^KX{JG81|o%nas9sX=O#?!5hiu@uOGsoX_aDUP44#Lwm^Jt3&O(?6KBGf z41pWg+|q<8FIrpO1u`icXQe{S1zRasSI~X2 zpsAcF(iwL?}y;iw==q68c;XxDqrtnX}v9>Xd zabfU6#C4Sm-vime3M^d~BB=#o@Ri+5kjiQh6m@YCN$*%iuSu*l-XJRA7a;$fUyP2N zg#1Kp#Qkw95Nd3zU4!LJz``u|!0la{i;-WLb%C~tKE#nP8G z4^JMB+|<{M26EpxUYn!24#sdY?fh8gqa9*j#{yP=i>BKV+YvAHDgc#)GyC@s-XLEe zE9Ojoy?k28C3dU~1~S5MZ@c?|tnL@XMJzfEe?(*2oMhdO;>5Gqcot`9pzdy_c+-+( zU}o3z9#q?dZ3C$RJI{rd>Q~+jgCu)RIt>L5(a6m#3;-%#wTwIVmvCHoW~JSRE#!My zk(+L0xUecM+DTt{QhBWxU~)tw>tFkX|9o6OE7F5B} z&jPA{&V%?0s(X#q7Nkgt0D>1=7^NqG_L?XSS$4?#R-TT?4)qUz`RKqWuW={7c1@HE zR9Dxa&Pk`X%EErRh%Jhn{j-j|=4SS3%g>Cw$qFOhaVPU9Clf5uwRRrsi;@Ehp{TAy zQstj~OFXl!KUkJ*aqS&oQ<%I6>{I#iilc(gX9(5vCRJ3dN^*T4!t5$fJfqan(9*A2wsQacbWz3`?kV3VJdri&-UqJw{?ER`gN@HEAbo z4@?+9U(aC}aj1X2hlOkx9+U-UpNxDb#%6OCaWMXS?~VvW?VS7LeGYB};4Nh2j64N&`|Z8 zCyv4*WhOcfPtY`kT2CXe@Mei_4`cupa1ToGd{xkxUL@C=7)Q7xhstwuf!(|at6zSj zpJUX}JkwOCW+XYmFt>i{_Fm(8{@T{dYaKBB-ug~dhd)?a55P2z2s4mc!3oDDe}MuZ zg#*%Go(8Qkn0K9kbBJrMi$S%Fi1wpkZg^>R9=egV;E{!h0Y$*;tKq%Ydm1V}V^1=NVO&-Fw>UiGRq)XW`_H%xwAJTZqc-v%Fph!0lI!y zX9}Kr&6*EKBFFUNO$Kf04F=P?KA9bbzSyW8qpm1uPW@AdD=shRO=dLo>axhHvGHd~ ze8jgQDr|qZ6uXzqpVWSk(N>6+^@Tzv@IBB2%7WsxPko=r;h5G>YD?LP?kH#$CP1eV z{N9=w=okk`|Ewy$dnJrYYR*kn$?7-mNpGKlJVEZn5y(YP!~JvNuE(&DuG0HV(1Uni zhXLRCO)8PS>U;0(|6DJKDZg%Akhn$%x8^pkPWhfa6~ZkD5&eAB#u44IXw`Z}D48V< z10x1uBU*&FAhKw4tDTTMtMRk#Zk$jt7t!tpAU%kby6A3vo2`5FAO7HHyqHit<=>M% zG6j8T8ip@!dA9s!GHed|8|@81YUGjts;indWp&`E-arRtBJ6$F6e0*>D-l+t3BMLt+`iV@Ktq%yS ztPt)nnmA0t#8`gv2ZxP0VxA2w_<0t7@`|~k<>}OXmVh#=3)~clklws&9yu6D5b^0> zPeqU;o;cvA9U5kMa#p9Zsy94v6}f;45Gn-Q_p!NrN=5{wF_ZucR$v$R3U&-Q^MIRp z{DUGpNUOi^9*tXghMK<_w@8)rAz}%O^vqPaZB$&lAY+&#uNCT5m73s6GWr?rei7>T z!*n*6ve9k^#2bE!*7ZDFfN#`FRL|p)$)Vo|BZz^DjMj(PvNavY?)X33q?ex`Mrlvq zTIhb@$}Zx4Pai<>9F-sH1j%Uu9mBb&UO@GFS{p)N&4EdACl1YsV(`A^5h%WWE=TqE zWYF@V*u{?&L94mp$aO>l1Qb0z;KMbibE0@XhITmzqC>a-LmY}Kv5rEKZO&teoreXX zlfw&}pBbn4XWxNr1dp6#Y6?hl#BRpQ{^8C(DSag*+dkdv98`J6c#w6RX3c-AO5G5) z6DX?n*P*f2jk*W+QcgiSB6^HK#^B{E8R;JO(QKrE4ciYh58cVgVaYb34PTI&StGe*ea%PA$<2{qi0#RZO7 z0i>D!fz^Y^4Mi&sQYFD08}LFoEPsFknx2M5$SD<9xp>j4P2Ii^>+LpVf=CNdtQ?*# zY`nQ~SFw3}!08;20sIwPCs> zMBsc?{?2*K_f_t1;fM`_nJbu;rW4G=m*b>r^@h(F#*fG67_VDUD0A!$I6|5wY7%Ti z@F1?UZ6nBS%bfuh^Y@X*E_{K7fs;OBLhP@-SpjNNxf{^)d?g$O3dB_l)_c%DXoG=f zAF7n%)wPxb(h9pM!F}zk=^4yE2 z7|BTvr^DeznTR`yO z+`VI$z^L(mOJ`;DNtyuG2jc({cU&3+w10t7xq>9L7D1Jh*2^8Q;->>wQY_FCHO2`* zd+=!w*ZXo1KHP)LJzNtJfrNG_EOJe&^>Do>p2DI5hwau;y0R=K$@*yRMw((a1^a1dhOEz z6ZBZOV1BTuV)4Vky4&N?@+U#%cgx}1t~Hc}VwD5p8YuE2zU@bnyL=)KerxBy;k(J9 zn<^(OA7Dyoe?b!3;nG|WeUHz5@980YCtUX$fGQr6A*zI1z05AeR4;N`(?g7CLg9P( z`4yGOknie3_bphhevcWgN3WAlrs|YQa3Z{ zNptFrG01B|%AYTBlMA!*Lj_<7=*iq4r5b$>{?Ll>F3amyXH%8B>f2yK?I2-NZc@NW zOhDP`GeJmAAfMJQJEYT_HNBp}P=aFK>jkIN>s-=5@UBA#KxxSqxF!K`^>&G4GXpTv z4fsYr^~-C30$aY`bHSOxTuDzefTJex#RY=}8WHT=A%^V?1X4wHc-@woT?BqJkoGI4 zi6l(>uf3|l^_o!f8G@Ii@x;{6L}yzUafu6B@-tbfkhoPr+n%Z=c4EZT>2>`FiCDIP z_UPtfO2Jqr=|?k6d1KjU|L!c7y7K<;X>Sml*wOc{I#dF#(GkSJ3DB2vC@;WlFP;5# z2K7n$V=i;%ooJ!L=LkW$LD*l1F*U7(NMpkWVg<%UQY`Xr4H|&`9vO6uJOcKbtNpQD zr$p4`b_x$rm5%O-(MNNk)>XLoAX3|1#J&h@=On$8-f-kupmMXKB0mdC(d3cU) z8eSUbTXN)|{;_KJ9Q03khMISKBaj>oKSD(o0EXMlqg1j@5}j*)P)aL{1#8E1q{Jie|OX0wD-ND^~)1H`^nh z*#{yxrixt19#x?s2!SF{&|&b^?6K5~J5dUS&N>%?j^r~*(dMX~!1swQS~D|(F|T8% z1CzS&Zq~UCl~YIezwya11}fd0bYdWUG1im;NmhD~4k>|tbelMKvzI~P=q;W}Y*Akw z4*+tr-VQN(Ma#XrLXOz!Boz`u#6dFS5n4-(#fkz;a$NJ{@YG(wuW+;*Eq=B+C+yD3 z?IDBB&sgO-OpNwtl336ca7}SGx!7auK4DkTCvIRd8W8T_g1x9TpCZCn;XAAD;{`?9 zOK(f-*WMzeql)oCO@#&l661sQaErGo&TDaU_of%UP+^`YJ{?+p+GB`ov{HEwG7S@; z)mESciwZ^H!WZ8d<iL#j1|t8jRqfhVr3F+=rNb^SVWI&szx22)}Ro zVc__Q0a&yGSkmw7u}@j~4pbq~WSGeKa^G;-UdYwyGTcJjKZWC?!#eI2#xIhD$6>%R z^Bn5D^4KI^7OJ?ia3;QD3S^F4B8cE?u^YW+ox z*Pn|LDxf_{*+*Y9T|laSR9?NjIe01uo=~1e%6uU(tpc8f`-P+ZkE2Re13e?W5x5&Y zB~QXDef87xFp&)}Z`}fs-?M3Bv<^Izi8ffUMwG?`vI>QXzR8Zy`ME##5|VQOiUw$L zDJO(XcRRdyKwLjUFxx(j#}~4h3T&{>VW(+bOKtJYpvU_0cf7P{g$|XC^H!n%x|4n3 zEPea$YG0MOQ}xQCLj;?}*8;6(zZC83sM7Ke;!?|gPkaFX9cDN6)Z<)zun zdvVv%5qf!im_2!;0Z_$r;o`t^`hg`Urtp8}a$J56%ckWVwIOd_^>_HZquTZzlhBUNO5%W1uDkzzzI)zU#a=z!M- zG2E4iis1hEs)p?`;CbuJk?|Q)A2`_;qmWIc9>H=#Swx=x%Pwqw3G6&HodbxY*zhi@ z3k;Q-+V|z2fY|OGexC0;Z{k2sfVN2BNg^&6U8(@;;{+yX!%^S)gL`tiSkD=Yj(r^A2K>mWYe0N3b zpr+&K`P}ScEMQRomuIc-6+Q0373mW)(&bK0-z;<+ir*R6aFV;UuyP8cfGNjwW_jWdI1e=z z0T9lg5U=xVK>rJS9 zGkMhkiLrIYZ9+0^1wz}`5E}Fvz_;{7hXubR5!Tbv&b;d&^xPlm-*4=$o5JVJ zK052M^vAXUi&D8+lc1O%W7VF`CRfxRXZg)GpFEVmUZAivUeujv2rmRRrM-N^I$gso z(D7=0`QuG)IBCAAjxAo#OGsf4Bx_cQC{B7T!h=4E^T3_Szv5 zgD;?+){vMT3;O(;=f@-Z_KeJ-?}?|v@H#yBDyDie&qGhI_4EQm7P80HzWyK5eN z2F84`92DjytRVGPemtxW8hmq0sF%Es!8iNhY_qw2Ag`sco582sxWy;V8JII~A+%7J z*0y5-MpaxPHMs7K*%Shq<-1N>rEfO|8%HlK`k9q2PVQcq9y}=%84UwTNT3^vM8JfZ z`bL6(8s(jks}8j_&r#WV-WUX-2s4Lg!(^^#ym4(Y7VNLbaN%T-`U?>h!II!&8`to<@^gz!wH~I$y<6=|GRe#=z+t`vG(Dj(Md>N+GKtWPOtGp(7@^lcy{2 zQQVO*yJMXLzH4f0}ot( z-tK0^nXQiaH#w#1DByE1y1fFbUsLB0$Qaz^N(ZjLJJi&13hu*`L}YLl9SieZmhp;DYTHBpla{rvIj*lXtXA`oZKTvfGa)e$}sTx&JZ%6Ih;fXLL)j0^D% z!+XfJ5$<1E?nx=}wP=(k>?WcgH}a)_ z7HCIof(BTPSOeo24|!23t9oIh@V;3FD?btMTl$dirI3*3hm)n**nl+F3tRK^w+dTEU zYrPJuoo>7BVA?;(@1;8RCj#08Zn)ru`fL@(pW?=wpR&};BCX%(aZHlo)L^%pmVIOd zG%NPioP}t7ZZP+Zd0+EJ_bEY5O~S8KFuwUCh?PT|16p97`K8=<5~UxhQpfhjN|zj4 zmHjt_YCQI98bWqHR%SL`6Ml&YoFB?sKLgQGuvb(C4ZE}N4N+YH&vZTt@U))&d17R3pLh# z+PGG?I9E;GDG`U*6wj&WT?;XIwy$g=!BG9gO7ie$rZ7Vmn>T*cx-r7#OV_Il&5Za^EepqFeKt z59aZR;OuGAuhzqCKlb0J#LXznFG^I)uYgXR$fZpdFqqZ9Z0m!vO5}@GdsJtf1#jHM zZ^1_qr!0ydn(qB0A}au2&FGcRe-LWs@m#E!m9a*ksg7(J-(Hqp8@8oM4RWv+4rPs(k$fR}6?f(>wazZ%jQ2BQn4TKzXK+3vp#FEngM{}xMcmw+CL(T)i$ zxuE$3rFnLGB}81bSXDc^uj)f2vBu*SKD-R&FW3>J9Yy-`0M7nWLcNjGxIb8U}4PG@;pC0P5^a2Lc$RAxa|Q%|j&ZFR)*OgCe2@hYCbNeab%QQfmQC^=4(QXLH2eokKm_s)4 z*9m6{jAqJaUg~d-%`&1MhOG;P_I1RnTzy~CS@#GsDd~)~aa>}7B>$~_8(#G(OUbZ4 zP`@ww&>}j%HSS`VoUV~q%?HZUEK&lUcA@->M{Xb@>1)P&p2^D>fcq6S z%jwJJnM?q`k3aB?BXr0TGoXBJ)Y@^DZ;6)0^du$u{RTE8t5p#vmmqw7I;Rd+85UIuo;TIo|S#Zxu<>PNqe z%>g@vu8Gy&p=hhW2Z)fFvjJpIL=(QF#=j(2?{p`z*Ux}=nT-wbs~ zx+!icLNkf4Rc_t)=YA1-c%M0zaXhRFPz;-T_3AcB$*<};QLPHHOL%|xiA@+DT5$nn zO6UcLyWQVQ5};wU4FF!ppr-jZAo)Z%R$fo^bXbdojV=JmW1vQ5**hT7lrjh#F#!>X+0>Y0_2v0m{(DxSR|qFevG&^oNhixow(#oK zW#a(_ERU3qJ=3Yd8unzP?6h3Lu)MUg-Fk$zmeZZR$$!(%P`8)qX7k(b%d>s6 z84}3#e&K*0*9s}-uhb5d7%Wcgs<)iv=R`kVy(((f`^y^;Rf|w-Ffekw+oE-Kr;2zC znMQj!*JLqf8Q=amnqoL;266dV#p(@#m!8NUVf>t$@7(`GGyIlmt9z=tT9@#OBH+L? z9mo}+jq31(9gHLtw4(M3^DaYD7X*7OSkt8e?W^yU~M|6XCm zniG$|BqOtOuX-B+7hxJtA9En;#Di5aL)s_XWODIg*ga(XldQo$0VL;Nnrs$Q0Uw^& zF|x4qjswHa)CliCzVY6;`b~oI@*)h&z+hlwD+wz~U7cDc4nhQ>6YX9E;dfS{%`Iah ze;S2(eupBVrb+0yEVRjzHqY~ZBvl;lUwA?aJL6GX9X*UnKA~_&dB=ul#|n>v_5{Q^ z6>L*DcXfF8HEn8pr!t@~1ZwUZ&!ZzDB77ArWB-WY?|TiK-nLV5kn|dl$`W;op)c{P zmL}rA7$6Wfsc{VB50Iu;w2j>11&Kz7iq|bkpD<=Pvh!LR;)^OlW*;7Yi7A*d<7U{2 zq;0mcRlUF15@ArH2q@H9F<=^(H_D=xcx(jUXk8bb)M=(+A)(8sQCtn38{q^>$;V$*tK;U{H-Etus71~DXSjl zOzy0Hx3h{5%cH`fR!%(v03ubq}Ec(Df` zeQ5V1z>YitKBC>V9WoSB+@;v`Tw1m&}#ES4g_!1RztSZ ztK~siX`s%hbeaJ$lgthk*?a!wL`k89uv4;W8G@KDtg&PvHc6$i&A%}?0p0OrG{Uz!0$hE#Hk~9|7-{~_8NSPSq3&5h>D?PtEM-z$OSkyz8vBCsEqTp)lVm1R z`{Kz8@M3fZstue{I32-X@_z@Q_Z`2&m0r1w?JzH^{26i{*(N5tP6f(ZoI?saU^dWU zAJW21$2xwJ@qXpR&fL?#j_(DmZCzr1!Twh0lD`dx;Pc-U9N?ohDG4fwN zxC4)MK3~cf;+O2D7i8(?-A7G&(_g6R84bPP5n0UH)F|=a;1@m~C-Vq@AG^jl$Y_vP z9d2`ly1vrM@}@LT(K--Mlw<4!bBIsjdCuYCnA!DIZ>46fcdTd@_PRI@zK=Gr)I7*{ z1^bAy=?|vErL%0sz|ucUt!`p7u~p0UoY8Ib1+^zhcI%kF6mcmEJ-$0lk22V;`S z$llAbVE8ng*M<%|#k(LR%3<#mQfbA7*v9l4`ze=tbrS?ESo85tL!g)!ar?pNRf_cV zK^yDNu3tq2eIPXdmF~}v$z3*)#d3?mJ9mxc*oZc*M-9@HoQk_sx^{9HA_b6j5uoY? z5bcT=V1{p{LZpEdIMK=V-R+OI9K8v8eAE!%1Xf;V+NA~l52lYW5|~@yX}cJgH_iT4T#9@ zMc>TRK+Kzqhc%V;$rKZ5=6+^^h8GGq?R@TW<{V#?t$+^kJzn*m>Nop2Y+lT+xZyP? zc3ga@HAo@d2J4J<2b|U2%3f^$jLyI26@qh*%b+IBPz2JbEfv>mZt8@QX~l|&b4&J~ ze(0e6(|_NySVEslvYuwhB~MoPls~QJd^=_;?zxQne0>%+}{~v9w#83VNd*-$&^2S!_CB&>H4%*ZY~L}B;qC0Jekk@o_e^0iM)QB8@EHAn?VS5R zll>pZuUR%Uhe(O&E{fY?Qx0V$d=RMMQLki!^}tsFMojBg>_Bt*NB&{!ddIm}Iz zHODYHEv1Q^$DF3`==%qJ|A6oN$LqQtkJtPCdVj9ZCy7J7lgo)R#2m+@pQXb?yhrf0#G?)LAe0 zIpX}|)!B9J;Bc|}Pm=-z)uh9oSNeGivrq8Eg~g}c*OXk6MNRlV+8Xt1qem7%z-`m- z#UppwF3qA=tWhA9zHScC zX%Z1Hc*@BKr6&t(4HUvon}C-yL>b^uVI1<;eJPd?n^trH11M0}y=!KwK-sm*It?@& zrgk1X#hW>E)|KCyzv@@^?Hlt8rWFhbGXJmJM*=99+ovj`EaEc+spw#Bi-zdW&u=7R zPX-_iXMbeBy!*hOONGm7;yKcN-Z5{%;{wzlaau|b>au0B1n<+2+n_sSk}eDq4YUhC zRA3F1i_8m)a#Sb0@L1(hQvhE8AURnyw{zMDsp=#4^FiyhB9rXl|ewd=`>>HBx>QY1PG69zB>SO4r} ze;{~tiG{SB@qXG52FNB=@Z1ws>Ak8M*Fe~5g*Wo}D5k<}Mg%u1Kg98y&D9G^lg8H) z8)6!y)ktLUn6ZoJCAF@}2+=Dn;xi+!4uCx>!NI|M^zmJM%fU6`#Y2c^*OlstN9{B* zDG7W22zYDn)rqDs5jh0+iQhnj7uvjdUU>?!8XbQX0MSb?(H=`$sD# zyz%U2zv4$?BxU+|Ho;8Wt@_@j60);a=V7ZEPdfipbQQCEC9%pl_#bOrcin53blwp5 zgmnr>+G&EN1?UUec#X97u)i8iAh%ctcs`pHvA1k1jb^*Kn0k9JlL1GHRh*jM?u+AG zOZ2e6=O+C?mI=CWW*wgV>>0nUxCN;^cW zQ@jWDQV-NZ{(Fsk^T$0!5DwmLQ-$R00lmO#_+qK=G?S)3S$w&9p2Gb+C5RY>G#X>3 zq}*5Tg^p|#re@y5n~E6q0GQd=gQ<~*pUTNr^KGR$EH{8|0APu*+)~TZjE zv6l<@=D++km-&Tix^@JLZye+9U&)jT7*#1B`l z*0@-oF4I`k7A!bIFa9(_#>}CVU8(@}iI%5DgLXWOkp0BQfimi!7oi_$3l24;WL^Ny zd<3?gy*ksMUVELtpajC+DlfNm3H>CYm(y*Djrn)q02M24U^;R@cBt7~=Xj^S zID=k;C_9ZCD43~q@%H;Rrx-s+>xU~yjcL43oQ(VEZ+BNUHmi+c03E=^Ctm#`SxcOH zYb@6k6}__iHArk1gR9e@jWC@9PK9en5Hi_*!!C8#SG&7b$CMaZUuyW3W>xL9yK)+M z)Wd08Ugde~KVXk2rTK*beu>;)&zgvhtZAoB#p zS*0?fAhARazW+prdU9UwZ?EQG%-MSRH_d19^ol$}=U249PJ1Rb%}`Wmb;V_IuYzPZ zS+JY8#zU%37h4~aOgJRQ*-h|yubxuxh1%NkYES_@x<-& z+M2t){D+HO$}V_DNy`bKTpaTzinhn8%^AJ-XS8MoOL7RMtE+oPX~t?j#gmHb@QBc> z3x_{6(EdYBOTVpWoF%d>E}O--4ErGRLmQU6#4(Qf+-?s1R?(I65MUd(n;HItxk42L zsK0Etw(4HvkPVOa5z|}7()qf9?n|~X z+|7p|!Y)`Mu%f^i5`N|mP(S6IB@umXU%rq9*DtU4V2fpAGzxG1giraxL^iB{$S%I@ zN;kbnZdn-Hx`@kSDs&8w)Z-X{O5^w-C?KIpQqvS=AEv#Vv?gH|*@T|!>*}hm?};PS z-AJi#{en;ZvO8@Gm6JMib>k8`>`*-7D?e8?5HHirx;!ggbX=@`D(uii6q3aHvG~zLc%&B5*?-zCj5Q+O2;>7y{rB2mkj6Vvy}>r zPKTHdHEpzq6i3R$0&+YWO(vZt{T}YOG{}CFkMOwu~-p@54(R09rAabN8P1v6ZAW6F7QQ5*O_3P>oj1pm_p+i-KsO{UBTDpL5*B z+3!!LE&4ii#tA;%S$FiH?K9d=>u8dEw&Hb=QJzjd19MUaI0@nQDOyEVZaUI}-3(oHq`)#E9{EflF>;K9;KT@&tigvb1C-SC|&6;1Xs zn$1|_=bn6YD09tFQ7Yp+qHkkZK}JA z7J`rUjaYGggiOJ0s-PAaa?A1_#Cum(vYCr-HVjkVWAL%WT(};TgRv`B?U-;YVd1*E z!r4bR=~KGFl;WDDq}C%ZV<~yVNGYPtbKIyr=<&H=Qkzf1wlHO(3iu&QlJgJZS6zff z2=JHn_{_ub2&T!C8?)2%limBGmzTS?V>J|*jWrunQEN~W4~Yga1dVXz3qR$LKYO12)7=4W#;PUtn)LbLE)Fd`xtV<>G0dBK0t(k64(<*^Rlo#@Upz| z*I7Bnw1ORF?gP5+?5)bHlBVzr3s_zq@24c{rhQ5@3=9K>e#p1r(lzW9~I zYzjs4AmO3Da^UB*A*0MK;V$Imr9twoEq03OSP=qi(#uYp0s1Hu^zK6Pc1L1G2n#8^ z3x?Bbk@CEZ3W1>n_6ajhG<=LP;-A%o4(s2kv>aH$d_lZ(O>o2vOHS?`zhlrY!hsN+ zpRkM^T!EcVh|*AD$4A@GhG+#8q-9I^PG2|Q4v-U=b{hpe&|ZX^i!Bgf zR;GyZ-S+eU@jp4RNm`Zuv_53`EKNA}3;@tzD;o/ft_conf.h , + + where stands for your platform. This release also + provides an `ansi' build, i.e., the directory `lib/arch/ansi' used + to compile with any ANSI-compliant compiler. + + The configuration macros that relate to performance are described + next. + + + 1. TT_CONFIG_OPTION_INTERPRETER_SWITCH + -------------------------------------- + + If set, this macro builds a bytecode interpreter which uses a + huge `switch' statement to parse the bytecode stream during + glyph hinting. + + If unset, the interpreter uses a big jump table to call each + bytecode's routine. + + This macro is *set* by default. However, it may be worthwile on + some platforms to unset it. + + Note that this macro is ignored if + TT_CONFIG_OPTION_NO_INTERPRETER is set. + + + 2. TT_CONFIG_OPTION_STATIC_INTERPRETER + -------------------------------------- + + If set, this macro builds a bytecode interpreter which uses a + static variable to store its state. On some processors, this + will produce code which is bigger but slightly faster. + + Note that you should NOT DEFINE this macro when building a + thread-safe version of the engine. + + This macro is *unset* by default. + + + 3. TT_CONFIG_OPTION_STATIC_RASTER + --------------------------------- + + If set, this macro builds a scan-line converter which uses a + static variable to store its state. On some processors, though + depending on the compiler used, this will produce code which is + bigger but moderately faster. + + Note that you should NOT DEFINE this macro when building a + thread-safe version of the engine. + + This macro is *unset* by default. We do not recommend using it + except for extreme cases where a performance `edge' is needed. + + + +II. Replacing some components with optimized versions +===================================================== + + You can also, in order to improve performance, replace one or more + components from the original source files. Here are our + suggestions. + + + 1. Use memory-mapped files whenever available + --------------------------------------------- + + Loading a glyph from a TrueType file needs many random seeks, + which take a lot of time when using disk-based files. + + Whenever possible, use memory-mappings to improve load + performance dramatically. For an example, see the source file + + freetype/lib/arch/unix/ttmmap.c + + which uses Unix memory-mapped files. + + + 2. Replace the computation routines in `ttcalc.c' + --------------------------------------------------- + + This file contains many computation routines that can easily be + replaced by inline-assembly, tailored for a specific processor + and/or compiler. + + After heavy testing, we have found that these functions, + especially TT_MulDiv(), are the ones that are most extensively + used and called when loading glyphs from a font file. + + We do not provide inline-assembly with this release, as we want + to emphasize the portability of our library. However, when + working on a specific project where the hardware is known to be + fixed (like on an embedded system), great performance gains + could be achieved by replacing these routines. + + (By the way, the square root function is not optimal, but it is + very seldom called. However, its accuracy is _critical_. + Replacing it with a fast but inaccurate algorithm will ruin the + rendering of glyphs at small sizes.) + + + +III. Measuring performance improvements +======================================= + + Once you have chosen some improvements and rebuilt the library, + some quick ways to measure the `new' speed are: + + - Run the test program `ftlint' on a directory containing many + TrueType fonts, and measure the time it takes. On Unix, you can + use the shell command `time' to do it like in + + % time test/ftlint 10 /ttfonts/*.ttf + + This will measure the performance improvement of the TrueType + interpreter. + + - Run the test program `fttimer' on a font containing many complex + glyphs (the latest available versions of Times or Arial should + do it), probaby using anti-aliasing, as in: + + % time test/fttimer -g /ttfonts/arial.ttf + + Compare the results of several of these runs for each build. + + +--- end of OPTIMIZE --- diff --git a/docs/porting.txt b/docs/porting.txt new file mode 100644 index 0000000..a73aaa2 --- /dev/null +++ b/docs/porting.txt @@ -0,0 +1,1078 @@ + + + The FreeType Porting Guide + + or + + Everything you need to know to make FreeType + run on the weirdest system + + +-------------------------------------------------------------------- + + Table of Contents + + + Introduction + + I. General design and system modules + + II. Memory component API + + 1. The alloction function: TT_Alloc() + 2. The release function: TT_Free() + 3. The ALLOC() and ALLOC_ARRAY() macros + 4. The MEM_xxxx() macros + + III. File component API + + 1. Streams and their functions + 2. Frames and file access + 3. Differences in thread support levels + + IV. Mutex component API + + V. Summary & Advanced concepts + + 1. Porting summary + 2. Exotic filesystems + + VI. Troubleshooting + + Conclusion + + +-------------------------------------------------------------------- + +Introduction +============ + +The FreeType engine is portable in many ways: + +- First, it can be compiled by any ANSI C compliant compiler, which + guarantees the widest possible uses. + +- Its default build uses a tiny fraction of the ANSI libc, mainly + for memory management and I/O access, which should be available on + most systems (i.e., malloc(), free(), fopen(), fread(), etc). + +- Its design is modular, and allows an implementer to remove all + dependencies on a particular runtime environment, to adapt the + engine to its specific needs. For example, it is possible to use + memory-mapped files on systems which support them. + +This document explains the engine's design, presenting the `system' +modules that need to be changed by porters of the library, as well +as how to do it. + +Note that this documentation is _very_ detailed, and you may +DIRECTLY JUMP to SECTION V (Summary and advanced concepts) which +gives you a QUICK STEP-BY-STEP GUIDE TO PORTING each component, +without the need to understand all the guts of the TrueType engine. + +Several issues are discussed, including the use of exotic font +storage conventions. + + +-------------------------------------------------------------------- + + +I. General design, and system modules +===================================== + + The engine's design is intentionally highly modular. It is made + of several `components', each with its own specific goals. Three + of these play an important role with regards to portability. They + are: + + - the memory component: + + Found in the files `ttmemory.h' and `ttmemory.c'. It defines + several macros and a few functions used by _all_ other modules + to allocate, release, copy, and move memory blocks. + + - the file component: + + Found in the files `ttfile.h' and `ttfile.c'. It defines + several types and abstractions (streams, frames), that are used + by _all_ other modules to access font files. + + - the mutex component: + + This component compiles to a null object if the engine is built + in single-thread mode. Otherwise, for thread-safe and reentrant + builds, the macros and functions it defines are used by the rest + of the engine to protect shared variables. + + NOTE: + + Because the ANSI libc doesn't provide synchronisation + primitives (synchronisation isn't portable accross platforms), + the default implementation, found in `ttmutex.c', is made of + dummy functions which always return a successful error + condition. + + You _need_ to re-define this component for your system if you + decide to make a thread-safe or reentrant build, even if you + use the ANSI libc. + + + When specializing a component, i.e., rewriting it for your + platform, you should respect a few conventions which are explained + in the following sections. Note also that the system-specific + implementations are usually placed in the + `freetype/lib/arch/' directory. For example: + + freetype/lib/arch/unix/ttmmap.c + + A Unix-only implementation of ttfile which uses the + memory-mapped file API (this greatly improves the engine's + performance, due to the random access pattern typicals of + glyph data retrieval). + + freetype/lib/arch/os2/os2file.c + + This is an implementation of ttfile specific to OS/2, which + directly calls the system functions DosOpen(), DosRead(), etc. + + The FreeType/2 DLL (a free TrueType font driver for OS/2) also + uses its own memory component which calls a special allocation + routine required in its runtime environment, and also provides + additional statistics that can be displayed by an auxiliary + tool while the driver is running in the system. + +We ask you to respect this directory convention. This really needs +a minor Makefile change, and still having the ability to compile the +`default' ttfile and ttmemory will help you debug your specific +ports by easy comparisons. + + +-------------------------------------------------------------------- + + +II. Memory component API +======================== + + This section presents the macros and functions defined in + ttmemory.h, and how they should be implemented, if you decide to + rewrite the source file ttmemory.c from scratch. An easier + solution would be to replace the calls to malloc() and free() with + your own functions, though. + + +1. Allocation routine : TT_Alloc() +---------------------------------- + + This function is used to allocate blocks of memory, just like + malloc(), but defines a very different interface. Its prototype + is: + + TT_Error TT_Alloc( long size, void** p ); + + [The FreeType source files use abstract data types like `Long' for + all internal functions and `TT_Long' for externally visible + structures. See tttypes.h and freetype.h, respectively.] + + We can see that: + + - The function returns an error code, and _not_ a pointer. The + reason for this is that your own implementation may perfectly + fail for more than one good reason. For example, it could + detect a corrupted heap, a memory exhaustion or an unusually + large block, and have a different error code for each of these + cases. + + If a memory allocation error occurs in a FreeType function, it + is always taken into account (of course, for safety reasons), + but its code is directly sent to the caller. This means that + your own applications and font servers will be able to interpret + these errors and let you handle them appropriately. + + - Its second argument is the _address_ of a typeless pointer. + This means the need to typecast it before calling this function. + + The macro MEM_Alloc() is defined in ttmemory.h to do it for you, + as well as the `memory extraction' performed by the `&' + operator, so that you can write: + + char* buffer; + + + MEM_Alloc( size, buffer ); + + instead of + + TT_Alloc( size, (void**)&buffer ); + + Note that the engine _never_ uses this macro directly, but + ALLOC() instead (see below) in order to _always_ test the error + code. + + ***************** + *** IMPORTANT *** + ***************** + + - A newly allocated block should _always_ be filled with zeroes! + This is a _very_ strong convention used within all the engine. + It helps greatly to reduce code size, in general. If your + implementation of TT_Alloc() doesn't respect it, you're pretty + certain to build an unrunnable (at best) or (worse) instable + engine! Beware. + + +2. Release routine: TT_Free() +----------------------------- + + This routine is naturally used to release any block created + through TT_Alloc(). Its prototype is: + + TT_Error TT_Free( void** P ); + + We can see that: + + - It also returns an error code. Note, however, that the error is + ignored in most, if not all, parts of the engine. This is + because freeing memory usually happens when all necessary work + has been finished, or when something already wrong happened. + + - It takes the address of a typeless-pointer, and _not_ the + pointer's value itself. This is used to set the pointer's value + to NULL just after the block was released, which avoids dangling + references in objects. Of course, there is a macro defined to + simplify source writing. One can use FREE() like: + + char* buffer; + + + MEM_Alloc( size, buffer ); + + .... work .... + + FREE( buffer ); + + /* now `buffer' is set to NULL; the following line will */ + /* seg-fault */ + + a = buffer[0]; + + + ***************** + *** IMPORTANT *** + ***************** + + - The function TT_Free() (and thus the macro FREE()) will accept a + NULL pointer successfully! This means more precisely that the + address of a pointer may have the value NULL; in this case it + will return with a successful error code (TT_Err_Ok == 0). + + This convention is also _very_ strong in the engine, and + simplifies both code size and style. One of its primary origin + is the engine's object management which requires the ability to + release an object, be it normal or `partial', with the same + code. + + +3. The ALLOC() and ALLOC_ARRAY() macros +--------------------------------------- + + Two macros are also defined to make the FreeType source code + easier to read and understand. Their role is to perform an + allocation, while saving the error condition in an _implicit_ + local variable called `error', and returning a boolean which is + set to true in case of error. Their definition is + + #define ALLOC( pointer, size ) \ + ( ( error = MEM_Alloc( pointer, size ) ) != TT_Err_Ok ) + + and + + #define ALLOC_ARRAY( pointer, count, type ) \ + ( ( error = MEM_Alloc( pointer, \ + (count) * sizeof ( type ) ) ) \ + != TT_Err_Ok ) + + They are always used in `if' statements, and can be chained + together. Here is some example code: + + char* buffer1 = 0; /* temporary buffer 1 */ + char* buffer2 = 0; /* temporary buffer 2 */ + TT_Error error; + + + ... + + if ( ALLOC_ARRAY( buffer1, n, TT_F26Dot6 ) || + ALLOC_ARRAY( buffer2, n, short ) ) + goto Fail; + + ... work ... + + Fail: + FREE( buffer2 ); + FREE( buffer1 ); + return error; + + + Notes: + + - If an error occurs during the first allocation, execution will + jump immediately to the `Fail' label. + + - The failure code, which releases the buffers, doesn't need to + differentiate whether the first allocation succeeded or not + (simply because FREE() accepts null pointers with no + problems). + + The equivalent code, without macros, would be: + + char* buffer1; + char* buffer2; + TT_Error error; + + + error = TT_Alloc( n * sizeof ( TT_F26Dot6 ), + (void**)&buffer1 ); + if ( error ) goto Fail_Buffer1; + + error = TT_Alloc( n * sizeof ( short ), + (void**)&buffer2 ); + if ( error ) goto Fail_Buffer2; + + .... work .... + + Fail_Buffer2: + TT_Free( (void**)&buffer2 ); + + Fail_Buffer1: + TT_Free( (void**)&buffer1 ); + + + Which is a lot less clear about its intents, and uses more special + cases. + + +4. The MEM_xxxx() macros +------------------------ + + Finally, three macros are defined to perform some common memory + block operations. Their names are rather explicative: + + - MEM_Copy() + + Used by the engine to copy one block of data in memory to + another one. + + - MEM_Set() + + Used to set all bytes of a block of memory to a given value. + + - MEM_Move() + + Well, guess what ;-) + + + These operations could have been embedded in functions like + TT_Mem_Copy(), TT_Mem_Set(), and TT_Mem_Move(), but a lot of + compilers are able to inline directly calls to such `intrinsic' + functions as memcpy() and memmove(). Hence, macros make sense + here. + + +-------------------------------------------------------------------- + + +III. File Component API +======================= + + This section describes the file component's API, and the things + that are needed to port it to a specific system. Note that only a + fraction of the source code in `ttfile.c' needs to be rewritten + during a port. + + +1. Streams and their functions +------------------------------ + + A stream in FreeType (version 1.x) encapsulates both the + location/naming of a file, and its access. This is due to the + fact that they were originally designed to embed a simple ANSI + `FILE*' file pointer. + + This means several things: + + - A stream is created and opened via the TT_Open_Stream() + function. It takes, in the default build, a font pathname of + type `char*' that it uses when calling fopen(). + + - It can be released/closed via the function TT_Close_Stream(). + + - It embeds a `current file position', just like an ordinary file + descriptor. It is thus seekable, through the function + TT_Seek_File(). + + - Raw data can be extracted from a stream through TT_Read_File() + and TT_Read_At_File(). + + However, it has certain properties that differ from a libc `FILE*' + data type: + + - Because each face object has its own stream, and because most + operating systems limit the number of opened system resources in + each process, it is more than helpful to be able to `flush' a + stream. + + A stream is said to be flushed if the system resource it + contains (like a file descriptor) has been closed. However, + this resource is re-opened automatically when needed. + + The function TT_Flush_Stream() is used to flush a stream. If a + stream has been flushed, it is also said to be `asleep'. + + - The engine calls TT_Use_Stream() before each new stream access. + With it, the file component is able to awake (or `activate') + streams that are flushed, if needed. + + - Consequently, the engine calls TT_Done_Stream() when it has + performed all I/O access. These two APIs (TT_Use_Stream() and + TT_Done_Stream()) let the file component track and manage the + engine's access patterns, and allows it to cache opened streams + more cleverly. + + For example, one could implement an LRU list used to track the + `oldest' streams, and only activate the 10 `freshest' ones, thus + limiting the total number of system stream resources used by the + library, independently of the total number of opened faces in + the engine. + + +2. Frames and file access +------------------------- + + In order to resolve endianess and alignment issues, the engine + uses the concept of `frames' to extract data from a TrueType + table. + + - A frame is simply a sequence of successive bytes, taken from a + stream from its current position. A frame can only exist within + a stream. + + - The function TT_Access_Frame() (ideally) reads its data and + places it into an intermediate buffer, which is later used for + parsing. This function also checks that the whole frame fits + into the original file. For example, it will return an error if + detecting `over-reads' in the file (which can happen if the font + file is broken). + + Note that the intermediate buffer disappears in the case of + memory-mapped files. + + - Each frame has an internal cursor, which is set to its buffer's + base by the previous function. Note, however, that it differs + from the stream's current position, which has been advanced once + TT_Acess_Frame() is completed. + + - Data is extracted from the frame through calls to functions of + the form: + + TT_Get_(); + + where can be any of: Byte (unsigned char), Char + (signed char), Short, UShort, Long, or ULong. + + Each function returns the integer below the current frame + cursor, and advances the latter in the buffer. + + - Finally, when the frame access ends, the engine calls the + TT_Forget_Frame() function, which will release the intermediate + buffer and set the cursor to NULL. + + Here is a typical frame read sequence: + + /* first - read the next 12-bytes frame in memory */ + error = TT_Access_Frame( 12 ); + if ( error ) + return error; + + /* now, extract all data */ + object->field1 = TT_Get_Short(); + object->field2 = TT_Get_Long(); + object->field3 = TT_Get_Char(); + object->filed4 = TT_Get_Long(); + object->field5 = TT_Get_Byte(); + + /* done - now release the frame */ + TT_Forget_Frame(); + + /* now perform some checks */ + if ( object->field1 == -1 ) + return Error_1; + + if ( object->field2 > object->field4 ) + return Error_2; + + + ***************** + *** IMPORTANT *** + ***************** + + A few things need to be noticed by porters when they implement + frame loading (i.e. the TT_Access_Frame() function): + + - The functions that need to be ported are TT_Access_Frame() and + TT_Forget_Frame(). The TT_Get_XXXX() functions should be left + as is. + + - A frame has a state, and must _always_ be released through + TT_Forget_Frame() in case of an error. This means that the + engine will _never_ use code like the following: + + error = TT_Access_Frame( 12 ); + if ( error ) + goto Fail; + + object->field1 = TT_Get_Short(); + + /* now check error and return immediately -- */ + /* WITHOUT RELEASING FRAME! ERROR! */ + if ( object->field1 == -1 ) + goto Fail; + + object->field2 = TT_Get_Long(); + object->field3 = TT_Get_Char(); + object->field4 = TT_Get_Long(); + + /* check for error, return immediately -- */ + /* WITHOUT RELEASING FRAME! ERROR! */ + if ( object->field2 > object->field4 ) + goto Fail; + + /* now release frame */ + TT_Forget_Frame(); + + This means more simply that EACH successful call to + TT_Access_Frame() will ALWAYS be followed by a call to + TT_Forget_Frame()! + + - As a consequence of the first rule, and also in order to keep + things simple, NESTING FRAME ACCESSES aren't allowed. For + example, the following code will produce an error: + + /* First frame access */ + error = TT_Access_Frame( 8 ); + if ( error ) + goto Fail; + + /* read a file offset */ + offset = TT_Get_Long(); + + /* seek and load another frame */ + error = TT_File_Seek( stream, offset ); + if ( error ) + goto Fail; + + error = TT_Access_Frame( 4 ); + /* The function TT_Access_Frame detects nested calls */ + /* and ALWAYS returns TT_Err_Nested_Frame_Access! */ + if ( error ) + goto Fail; + + data1 = TT_Get_Long(); + + /* release second frame */ + TT_Forget_Frame(); + + /* read next integer from the first frame */ + data2 = TT_Get_Long(); + + /* release first frame */ + TT_Forget_Frame(); + + This simplifies the work that needs to be done wen porting the + TT_Access_Frame() and TT_Forget_Frame() functions. + + +3. Differences in thread support levels +--------------------------------------- + + The FreeType library can be built to three distinct thread-support + levels. This section will present each other, and show how this + translates within the ttfile.c source code. + + a. Levels + + The three levels are + + - single thread + + No synchronization primitive is used to protect the data in + the file component. Hence, there is only one `current' stream + at any one time. Note, however, that in some cases, more than + one stream may be `active' (or `awakened'); e.g., when using + memory-mapped files, each opened face needs a valid mapping + before it can be used/parsed by the engine. + + - thread-safe + + The thread safe mode synchronizes concurrent accesses to the + renderer's component through mutexes. For the file component, + this means a single mutex which is `locked' by a call to + TT_Use_Stream(), and `released' by TT_Done_Stream(). + + As a consequence, there is only one possible `current' stream + when the engine reads files, like in the single thread case. + + - re-entrant + + In this mode, concurrent accesses are possible on many + components, including ttfile. This means that each + TT_Use_Stream() must _really_ create its own system/ANSI + stream for a single file, and that the file component _cannot_ + have any state (only stream objects have!), like a `current + stream' and `current frame'. + + This mode must use mutexes to protect all shared variables and + lists from concurrent changes/reads. The only component which + is still serialized in this mode is the scan-line converter + (a.k.a. ttraster). + + b. Implementation differences + + Because the TrueType engine serves more as a `font format + driver' than a general and high-level text-rendering library, it + has been decided to keep its code as simple and compact as + possible. + + This implies some implementation differences between the three + thread modes, which are briefly explained below: + + - Single-thread and thread-safe mode can have a state, which + means for ttfile.c, a `current stream' and `current frame'. + + - In the reentrant mode, the `state' must be stored in a + thread-local place, which means the stack (or more simply + local function variables). + + What follows is that some ttfile functions won't take the same + number of arguments depending on the thread-support mode. Let + uss take the example of frame access and parsing: + + In single-thread and thread-safe mode, the current frame is + automatically set by the TT_Access_Frame() function, which only + takes a `size' argument to determine the run of bytes to extract + from the _current_stream_ within ttfile's state. + + Moreover, the TT_Get_XXXX() functions extract data from the + current frame, and need no arguments. A simple frame access + then looks like this: + + /* read the next 12-bytes frame from the _current_stream_ */ + error = TT_Access_Frame( 12 ); + if ( error ) + return error; + + /* now, extract all data from the _current_frame_ */ + object->field1 = TT_Get_Short(); + object->field2 = TT_Get_Long(); + object->field3 = TT_Get_Char(); + object->filed4 = TT_Get_Long(); + object->field5 = TT_Get_Byte(); + + /* done - now release the current frame */ + TT_Forget_Frame(); + + In reentrant mode, things are a bit different. The current + stream and current frame must be passed as parameters, and the + code looks like this (notice the new function parameters!): + + + TT_Frame frame; /* define a local variable to handle */ + /* the current frame */ + + .... /* we suppose we already have a stream variable */ + .... /* named `stream' (how surprising ;-) */ + + /* read the next 12-bytes frame from a given stream */ + error = TT_Access_Frame( stream, 12, &frame ); + if ( error ) + return error; + + /* now, extract all data from the given frame */ + object->field1 = TT_Get_Short( frame ); + object->field2 = TT_Get_Long ( frame ); + object->field3 = TT_Get_Char ( frame ); + object->filed4 = TT_Get_Long ( frame ); + object->field5 = TT_Get_Byte ( frame ); + + /* done - now release the current frame */ + TT_Forget_Frame( frame ); + + + The differences between these two schemes are striking. Though + an `easy' solution would have been to only write the engine in + reentrant-mode, it would have resulted in larger and slightly + slower code, as well as the source a bit more obscure about its + intents and thus harder to maintain. Also, the reentrant + version is only needed in rare cases and environments, and it + wasn't thought as a good idea to complexify _source_ code in + order to comply with rare uses. + + The problem is solved within the engine by the use of a set of + carefully selected macros, which help generate both versions + from a _single_ source file. + + Moreover, as the macros imitate the non-reentrant syntax (i.e., + the use of the `stream' and `frame' parameters is implicit to + the macros), the source is kept clear and easy to understand, + even if compiled in re-entrant mode. + + The code looks then like the following in the engine: + + /* read the next 12-bytes frame from the current stream */ + /* assignment of the error code in the local `error' */ + /* variable is also implicit to the ACCESS_Frame macro, */ + /* and its result is always a boolean (no ANSI warnings) */ + + if ( ACCESS_Frame( 12 ) ) + goto Fail; + + /* Now, extract all data from the current frame. */ + /* The macros GET_xxxxx use an implicit local `frame' */ + /* variable in reentrant mode. */ + + object->field1 = GET_Short(); + object->field2 = GET_Long(); + object->field3 = GET_Char(); + object->filed4 = GET_Long(); + object->field5 = GET_Byte(); + + /* done - now release the current frame */ + + FORGET_Frame(); + + Another advantage of the above code is its `expressiveness' in + the sense that it really describes what is happening during the + frame load, hiding the boring but necessary details required by + error checking and reentrancy. And if the error checks are + within the macros, we are sure we won't forget them because they + are `too boring to code' (one of the reason why `exceptions' + caught so quickly in C++ and Java). + + c. Consequences on ttfile + + Of course, the macros only hide real differences in + implementation which must be reflected in ttfile.h and ttfile.c. + In order to ease this task, some other macros are used, which + use is reserved for these two files. There are: + + STREAM_ARG + STREAM_ARGS + FRAME_ARG + FRAME_ARGS in ttfile.h + + CUR_Stream + STREAM_VAR + STREAM_VARS + FRAME_VAR + FRAME_VARS in ttfile.c + + All of these macros (with the exception of CUR_Stream) default + to nothing (i.e. a void macro) in single-thread and re-entrant + mode, which only differ from the use of a mutex lock and release + in the functions TT_Use_Stream() and TT_Done_Stream(). + CUR_Stream defaults to the file component's current stream, + found in its internal state (as you can guess, it designates the + `current stream'). + + On the opposite, the macros are used to define additional + function parameters (if a function is called) and arguments (if + calling in a function). For example, the following (fictional) + code: + + /* return the size of a given stream */ + long Stream_Size( STREAM_ARG ) + { + return CUR_Stream.size; + } + + expands to: + + long Stream_Size() + { + return file_component.current_stream.size; + } + + in non-reentrant mode, and to: + + long Stream_Size( TT_Stream stream ) + { + return (*stream).size; + } + + otherwise. + + Thus, we can see the following reentrant expansions: + + STREAM_ARG --> TT_Stream stream + STREAM_ARGS --> TT_Stream stream, (note the comma) + + FRAME_ARG --> TT_Frame frame + FRAME_ARGS --> TT_Frame frame, (note the comma) + + STREAM_VAR --> stream + STREAM_VARS --> stream, + + FRAME_VAR --> frame + FRAME_VARS --> frame, + + They follow these simple rules: + + - An XXXX_ARG is used to define a single optional parameter in + a function _prototype_. The parameter is said to be single + if it is not followed by anything, e.g. + + long Stream_Size( STREAM_ARG ) + + - An XXXX_ARGS is the same, followed by a comma, in order to + place other (non-optional) parameters behind, e.g. + + TT_Error Stream_Seek( STREAM_ARGS long pos ) + + - An XXXX_VAR is used, _only_ within ttfile.c, to _call_ a + function having an XXXX_ARG or XXXX_ARGS in its prototype + resp. declaration. + + long Stream_Left( STREAM_ARG ) + { + return ( Stream_Size( STREAM_VAR ) - + Stream_Pos( STREAM_VAR ) ); + } + + - An XXXX_VARS is the same, but can be followed by non-optional + parameters. + + The macros allow you to write some code independently of the + thread level within ttfile.c. + + ***************** + *** IMPORTANT *** + ***************** + + In general, porters should not be concerned about the use of + these macros. One easy way to port is to take the ANSI code in + ttfile.c and modify only the parts that really access the system + (like fopen(), fread(), fseek(), etc). + + These details are explained here to make you understand how the + code works, in case you are interested in more elaborate ports. + + +-------------------------------------------------------------------- + + +IV. Mutex Component API +======================= + + As said before, the default library source code uses the ANSI libc + only, and the source code in ttmutex.c only contains dummy + functions which return a successful error condition in all cases. + + You thus NEED to specialize it in order to successfully use a + thread-safe or reentrant build. Here is explained what is really + important: + + +1. The TMutex type +------------------ + + The engine uses the `TMutex' type defined in ttmutex.h to handle + mutexes. It is only a typedef of a `void*' and should be kept + that way for the fastest porting. + + Your job will most probably be to store a system mutex/semaphore + handle or pointer in it. + + +2. The mutex macros and functions +--------------------------------- + + The interface file ttmutex.h defines several macros that are used + within the engine to protect all shared variables (like lists) + from concurrent accesses. All macros default to `void' (nothing) + in single thread mode, and to calls to the TT_Mutex_XXXX() + functions in multi-threaded modes. + + These functions are: + + o TT_Mutex_Create() + + Takes a TMutex address as an argument. It should place a NULL + pointer in this output variable in case of failure. + + o TT_Mutex_Lock() + + It also takes the address of a TMutex as an argument. Used to + lock the mutex/semaphore, of course. + + o TT_Mutex_Release() + + Guess what ;-) Same interface. + + o TT_Mutex_Delete() + + Destroys a mutex/semaphore. + + +3. Redefining the TMutex type +----------------------------- + + You can also get rid of the TT_Mutex_xxxx() functions if you want + to use your system's synchronization API. This can be done in two + simple steps: + + a. Redefine the TMutex type to suit your system's handle types. + + b. Redefine the MUTEX_xxxx() macros in order to call directly your + API in the case of multi-threaded builds. + + Both methods (specializing the TT_Mutex_xxx() functions or + redefining the macros) are possible. + + +-------------------------------------------------------------------------- + + +V. Summary and Advanced Concepts +================================ + +1. Quick step-by-step guide to porting the system components +------------------------------------------------------------ + + a. Port the memory component + + o Look at the `ttmemory.h' file and change the macros + MEM_Copy(), MEM_Move(), and MEM_Set() to reflect your system's + API providing the equivalent functionality. The reason that + macros instead of functions are used there is that many + compilers are able to inline directly these functions within + your code. + + o Look at the `ttmemory.c' file. Replace the single malloc() + call with your own allocation routine, and the single free() + with your own release routine. If your allocator uses more + sophisticated functions, you will probably have to rewrite + more parts of this file. See section I above. + + b. Port the mutex component + + o Look at the file `ttmutex.c' and specialize each routine to + have it use your system's synchronization API. + + o For a more advanced port, you can also directly redefine the + definition of the TMutex type in ttmutex.h, as well as the + macro definitions (like MUTEX_Create(), MUTEX_Lock(), etc.) to + use directly your system's API. The TT_Mutex_xxxx() won't be + necessary then. + + c. Port the file component + + o For a quick port, look at the following functions and replace + the ANSI libc calls (like fopen(), fclose(), fread(), etc.): + + Stream_Activate(), Stream_Deactivate(), TT_Open_Stream(), + TT_Done_Stream(), TT_Seek_File(), TT_Skip_File(), + TT_Read_File(), TT_File_Pos() + + o If you plan to use memory-mapped files, you can have a look at + the Unix file component found in + `freetype/lib/arch/unix/ttmmap.c'. It should give you an + indication of what to do. + + +2. Exotic file systems and font resources +----------------------------------------- + + a. Other file naming conventions + + The high-level library uses the `TT_Text*' type to define the + type of characters used for a font file's pathname. By default, + it equals to the `char*' type, which allow you to open a face + object with the following call: + + error = TT_Open_Face( engine, "c:\fonts\times.ttf", &face ); + + The implementation of TT_Open_Face() passes directly the + pathname pointer to the internal TT_Open_Stream() function, + located in the file component, which really opens the file. + + Some filesystems use different naming conventions, like UTF-16 + code, where each character is coded in 16 bits. In order to + help them to use FreeType, all you need to do is the following: + + - Define the macro TT_HAVE_TT_TEXT. + + - Define the type `TT_Text' to the character type you need, like + 'wchar_t' for Unicode. + + Note that this should apply when compiling the FreeType library, + as well as WHEN INCLUDING THE FILE `freetype.h' IN YOUR + APPLICATIONS. + + If the configuration macro TT_HAVE_TT_TEXT is not defined, the + file `freetype.h' defines TT_Text as `char*'. You can read its + source code to see it more explicitly (look at the very first + lines of the code). + + You can also use TT_Text as a pointer to more specific files, + like a simple memory address when the font is located in ROM, + etc. + + Just synchronize the definition of TT_Text with the + implementation in ttfile.c! + + b. Font Resources + + FreeType 2.0 will feature many architectural changes that will + help make porting easier, especially with regards of the file + component. + + To do this, it will separate the concepts of a `font resource', + i.e. a file seen as a storage, from a `font stream', i.e. a + file seen as a stream of data. Only the resource related code + will be visible to porters, and it will be much easier to port + (for example, nearly all thread-support levels issues will be + treated internally in the rest of the engine, and will be + invisible to the resource component). + + We're sorry for the current design and state, but TT_Stream + started as a simple encapsulation of an ANSI FILE* variable, + before font-specific access patterns made them become what they + now are. + + FreeType 2.0 will be a good reason to re-design I/O access more + clearly, and fortunately with more power and flexibility (like + using easily files of different type, ROM-based, memory-mapped, + disk-based, in a single engine). + + However, all of this doesn't mean than the current design + doesn't work. It does, so don't hesitate to use it :-) + + +-------------------------------------------------------------------- + + +VI. Troubleshooting +=================== + + To be written. + + +-------------------------------------------------------------------- + + +Conclusion +========== + + To be written. + + +--- end of porting.txt --- diff --git a/docs/raster.txt b/docs/raster.txt new file mode 100644 index 0000000..34d05eb --- /dev/null +++ b/docs/raster.txt @@ -0,0 +1,577 @@ +This file is an attempt at explaining the internals of the FreeType +rasterizer. This component is quite general purpose and could +easily be integrated into other programs (but still under the +current license). + +-------------------------------------------------------------------- + + The HOWs and WHYs of the FreeType rasterizer + + by David Turner + + + I. Introduction + + II. Rendering Technology + +III. Implementation Details + + IV. Gray-Level Support + + + +I. Introduction +=============== + + A rasterizer is a library in charge of converting a vectorial + representation of a shape into a bitmap. The FreeType rasterizer + has been developed to render the glyphs found in TrueType files, + made up of segments and second-order Beziers. This document is an + explanation of its design and implementation. + + Though these explanations start from the basics, a knowledge of + common rasterization techniques is assumed. + + +-------------------------------------------------------------------- + + +II. Rendering Technology +======================== + +1. Requirements +--------------- + + We will assume that all scaling/rotating/hinting/whatever has been + already done. The glyph is thus described, as in the TrueType + specification, by a list of points. Each point has an x and y + coordinate, as well as a flag that indicates whether the point is + _on_ or _off_ the curve. + + More precisely: + + - All point coordinates are in the 26.6 fixed float format as + defined by the specification. The orientation used is: + + ^ y + | reference orientation + | + *----> x + 0 + + This means that the `distance' between two neighbouring pixels + is 64 `units' (1 unit = 1/64th of a pixel). + + Note that, for the rasterizer, pixel centers are located at + integer coordinates, i.e., (0.0, 0.0) is the coordinate of the + origin's center (unlike what happens within the TrueType + bytecode interpreter where this point's center lies at (0.5, + 0.5)). + + A pixel line in the target bitmap is called a `scanline'. + + - A glyph is usually made of several contours, also called + outlines. A contour is simply a closed curve that delimits an + outer or inner region of the glyph. It is described by a series + of successive points of the points table. + + Each point of the glyph has an associated flag that indicates + whether it is `on' or `off' the curve. Two successive `on' + points indicate a line segment joining the two points. + + One `off' point amidst two `on' points indicates a second degree + Bezier parametric arc, defined by these three points (the `off' + point being the control point, and the `on' ones the start and + end points). + + Finally, two successive `off' points forces the rasterizer to + create, during rendering, an `on' point amidst them, at their + exact middle. This greatly facilitates the definition of + successive Bezier arcs. + + * # on curve + * off curve + __---__ + #-__ _-- -_ + --__ _- - + --__ # \ + --__ # + -# + Two `on' points + Two `on' points and one `off' point + between them + + * + # __ Two `on' points with two `off' + \ - - points between them. The point + \ / \ marked `0' is the middle of the + - 0 \ `off' points, and is a `virtual + -_ _- # on' point where the curve passes. + -- It does not appear in the point + * list. + + + The FreeType rasterizer, as intended to render TrueType glyphs, + does not support third order Beziers, usually found in Type 1 + fonts. Type 1 support may lead to further development of the + engine (it is already part of FreeType 2.0). + + The parametric form of a second-order Bezier is: + + P(t) = (1-t)^2*P1 + 2*t*(1-t)*P2 + t^2*P3 + + with t a real number in the range [0..1] + + P1 and P3 are the endpoints, P2 the control point. + + Note that the rasterizer does not use this formula. It exhibits, + however, one very useful property of Bezier arcs: Each point of + the curve is a weighted average of the control points. + + As all weights are positive and always sum up to 1, whatever the + value of t, each arc point lies within the triangle defined by the + arc's three control points. + + +2. Profiles and Spans +--------------------- + + The following is a basic explanation of the _kind_ of computations + made by the rasterizer to build a bitmap from a vector + representation. Note that the actual implementation is slightly + different, due to performance tuning and other factors. + + However, the following ideas remain in the same category, and are + more convenient to understand. + + a. Sweeping the shape + + The best way to fill a shape is to decompose it into a number of + simple horizontal segments, then turn them on in the target + bitmap. These segments are called `spans'. + + __---__ + _-- -_ + _- - + - \ + / \ + / \ + | \ + + __---__ Example: filling a shape + _----------_ with spans. + _-------------- + ----------------\ + /-----------------\ This is typically done from the top + / \ to the bottom of the shape, in a + | | \ movement called a `sweep". + V + + __---__ + _----------_ + _-------------- + ----------------\ + /-----------------\ + /-------------------\ + |---------------------\ + + + In order to draw a span, the rasterizer must compute its + coordinates, which are simply the shape's contours' + x-coordinates taken on the y-scanlines. + + + /---/ |---| Note that there are usually + /---/ |---| several spans per scanline. + | /---/ |---| + | /---/_______|---| When rendering this shape to the + V /----------------| current scanline y, we must + /-----------------| compute the x values of the + a /----| |---| points a, b, c, and d. + - - - * * - - - - * * - - y - + / / b c| |d + + + /---/ |---| + /---/ |---| And then turn on the spans a-b + /---/ |---| and c-d. + /---/_______|---| + /----------------| + /-----------------| + a /----| |---| + - - - ####### - - - - ##### - - y - + / / b c| |d + + b. Decomposing outlines into profiles + + For each scanline during the sweep, we need the following + information: + + o The number of spans on the current scanline, given by the + number of shape points intersecting the scanline (these are + the points a, b, c, and d in the above example). + + o The x coordinates of these points. + + These are computed before the sweep, in a phase called + `decomposition' which converts the glyph into *profiles*. + + Put it simply, a `profile' is a contour's portion that can only + be either ascending or descending, i.e., it is monotonic in the + vertical direction (we will also say y-monotonic). There is no + such thing as a horizontal profile, as we shall see. + + Here are a few examples: + + + this square + 1 2 + ---->---- is made of two + | | | | + | | profiles | | + ^ v ^ + v + | | | | + | | | | + ----<---- + + up down + + + this triangle + + P2 1 2 + + |\ is made of two | \ + ^ | \ \ | \ + | | \ \ profiles | \ | + | | \ v ^ | \ | + | \ | | + \ v + | \ | | \ + P1 ---___ \ ---___ \ + ---_\ ---_ \ + <--__ P3 up down + + + + A more general contour can be made of more than two profiles: + + __ ^ + / | / ___ / | + / | / | / | / | + | | / / => | v / / + | | | | | | ^ | + ^ | |___| | | ^ + | + | + v + | | | v | | + | | | up | + |___________| | down | + + <-- up down + + + Successive profiles are always joined by horizontal segments + that are not part of the profiles themselves. + + Note that for the rasterizer, a profile is simply an *array* + that associates one horizontal *pixel* coordinate to each bitmap + *scanline* crossed by the contour's section containing the + profile. Note also that profiles are *oriented* up or down + along the glyph's original flow orientation. + + In other graphics libraries, profiles are also called `edges' or + `edgelists'. + + c. The Render Pool + + FreeType has been designed to be able to run well on _very_ + light systems, including embedded systems with very few memory. + + A render pool will be allocated once; the rasterizer uses this + pool for all its needs by managing this memory directly in it. + The algorithms that are used for profile computation make it + possible to use the pool as a simple growing heap. This means + that this memory management is actually easy, and faster than + any kind of malloc()/free() combination. + + Moreover, we'll see later that the rasterizer is able, when + dealing with profiles too large and numerous to lie all at once + in the render pool, to immediately decompose recursively the + rendering process into independent sub-tasks, each taking less + memory to be performed (see `sub-banding' below). + + The render pool doesn't need to be large. A 4kByte pool is + enough for nearly all renditions, though nearly 100% slower than + a more confortable 16 or 32kByte pool (that was tested with + complex glyphs at sizes over 500 pixels). + + d. Computing Profiles Extents + + Remember that a profile is an array, associating a _scanline_ to + the x pixel coordinate of its intersection with a contour. + + Though it's not exactly how the FreeType rasterizer works, it is + convenient to think that we need a profile's height before + allocating it in the pool and computing its coordinates. + + The profile's height is the number of scanlines crossed by the + y-monotonic section of a contour. We thus need to compute these + sections from the vectorial description. In order to do that, + we are obliged to compute all (local and global) y-extrema of + the glyph (minima and maxima). + + + P2 For instance, this triangle has only + two y-extrema, which are simply + |\ + | \ P2.y as an y-maximum + | \ P3.y as an y-minimum + | \ + | \ P1.y is not an y-extremum (though it is + | \ a x-minimum, which we don't need). + P1 ---___ \ + ---_\ + P3 + + Note that the extrema are expressed in pixel units, not in + scanlines. The triangle's height is certainly (P3.y-P2.y+1) + pixel units, but its profiles' heights are computed in + scanlines. The exact conversion is simply: + + - min scanline = FLOOR ( min y ) + - max scanline = CEILING( max y ) + + A problem arises with Bezier Arcs. While a segment is always + necessarily y-monotonic (i.e., flat, ascending, or descending), + which makes extrema computations easy, the ascent of an arc can + vary between its control points. + + P2 + * + # on curve + * off curve + __-x--_ + _-- -_ + P1 _- - A non y-monotonic Bezier arc. + # \ + - The arc goes from P1 to P3. + \ + \ P3 + # + + We first need to be able to easily detect non-monotonic arcs, + according to their control points. I will state here, without + proof, that the monotony condition can be expressed as: + + P1.y <= P2.y <= P3.y for an ever-ascending arc + + P1.y >= P2.y >= P3.y for an ever-descending arc + + with the special case of + + P1.y = P2.y = P3.y where the arc is said to be `flat'. + + As you can see, these conditions can be very easily tested. + They are, however, extremely important, as any arc that does not + satisfy them necessarily contains an extremum. + + Note also that a monotonic arc can contain an extremum too, + which is then one of its `on' points: + + P1 P2 + #---__ * P1P2P3 is ever-descending, but P1 + -_ is an y-extremum. + - + ---_ \ + -> \ + \ P3 + # + + Let's go back to our previous example: + + P2 + * + # on curve + * off curve + __-x--_ + _-- -_ + P1 _- - A non-y-monotonic Bezier arc. + # \ + - Here we have + \ P2.y >= P1.y && + \ P3 P2.y >= P3.y (!) + # + + We need to compute the y-maximum of this arc to be able to + compute a profile's height (the point marked by an `x'). The + arc's equation indicates that a direct computation is possible, + but we'll rely on a different technique, which use will become + apparent a bit later. + + Bezier arcs have the special property of being very easily + decomposed into two other sub-arcs, which are themselves Beziers + arcs. Moreover, it is easy to prove that there is at most one + y-extremum on each Bezier arc (for second degree ones). + + For instance, the following arc P1P2P3 can be decomposed into + two sub-arcs Q1Q2Q3 and R1R2R3 that look like: + + P2 + * + # on curve + * off curve + + + Original Bezier Arc P1P2P3. + __---__ + _-- --_ + _- -_ + - - + / \ + / \ + # # + P1 P3 + + + + + P2 + * + + + + Q3 Decomposed into two subarcs + Q2 R2 Q1Q2Q3 and R1R2R3 + * __-#-__ * + _-- --_ + _- R1 -_ Q1 = P1 R3 = P3 + - - Q2 = (P1+P2)/2 R2 = (P2+P3)/2 + / \ + / \ Q3 = R1 = (Q2+R2)/2 + # # + Q1 R3 Note that Q2, R2, and Q3=R1 + are on a single line which is + tangent to the curve. + + We have then decomposed a non-y-monotonic bezier into two + smaller sub-arcs. Note that in the above drawing, both sub-arcs + are monotonic, and that the extremum is then Q3=R1. However, in + a more general case, only one sub-arc is guaranteed to be + monotonic. Getting back to our former example: + + Q2 + * + + __-x--_ R1 + _-- #_ + Q1 _- Q3 - R2 + # \ * + - + \ + \ R3 + # + + Here, we see that, though Q1Q2Q3 is still non-monotonic, R1R2R3 + is ever descending: we thus know that it doesn't contain the + extremum. We can then re-subdivide Q1Q2Q3 into two sub-arcs and + go on recursively, stopping when we encounter two monotonic + subarcs, or when the subarcs become simply too small. + + We will finally find the y-extremum. Note that the iterative + process of finding an extremum is called `flattening'. + + e. Computing Profiles coordinates + + Once we have the height of each profile, we are able to allocate + it in the render pool. We now have to compute its coordinate + for each scanline. + + In the case of segments, the computation is straightforward, and + uses good old Euclide (also known as Bresenham ;-). However, + for Bezier arcs, things get a little more complicated. + + We assume that all Beziers that are part of a profile are the + result of `flattening' the curve, which means that they are all + y-monotonic (ascending or descending, and never flat). We now + have to compute the arcs' intersections with the profile's + scanlines. One way is to use a similar scheme to `flattening', + called `stepping'. + + Consider this arc, going from P1 to + --------------------- P3. Suppose that we need to + compute its intersections with the + drawn scanlines. Again, this is + --------------------- feasible directly, if we dare + to compute one square root per + * P2 _---# P3 scanline (how great!). + ------------- _-- -- + _- + _/ Rather, it is still possible to use + ---------/----------- the decomposition property in the + / same recursive way, i.e. subdivide + | the arc into subarcs until these + ------|-------------- get too small to cross more than + | one scanline! + | + -----|--------------- This is very easily done using a + | rasterizer-managed stack of + | subarcs. + # P1 + + f. Sweeping and Sorting the spans + + Once all our profiles have been computed, we begin the sweep to + build (and fill) the spans. + + As the TrueType specification uses the winding fill rule, we + place on each scanline the profiles present in two separate + lists. + + One list, called the `left' one, only contains ascending + profiles, while the other `right' list contains the descending + profiles. + + As each glyph is made of closed curves, a simple geometric + property is that the two lists necessarily contain the same + number of elements. + + Creating spans is there straightforward: + + 1. We sort each list in increasing x order. + + 2. We pair each value of the left list, with its corresponding + value in the right one. + + + / / | | For example, we have here + / / | | four profiles. Two of + >/ / | | | them are ascending (1 & + 1// / ^ | | | 2 3), while the two others + // // 3| | | v are descending (2 & 4). + / //4 | | | On the given scanline, + a / /< | | the left list is (1,3), + - - - *-----* - - - - *---* - - y - and the right one is + / / b c| |d (4,2) (sorted). + + There are then two spans, joining + 1 to 4 (i.e. a-b) and 3 to 2 + (i.e. c-d)! + + Sorting doesn't necessarily take much time, as in 99 cases out + of 100, the lists' order is kept from one scanline to the next. + We can thus implement it with two simple singly-linked lists, + sorted by a classic bubble-sort, which takes a minimum amount of + time when the lists are already sorted. + + A previous version of the rasterizer used more elaborate + structures, like arrays to perform `faster' sorting. It turned + out that this old scheme is not faster than the one described + above. + + Once the spans have been `created', we can simply draw them in + the target bitmap. + + g. Drop-out control + + To be continued. + + +--- end of raster.txt --- diff --git a/docs/readme.txt b/docs/readme.txt new file mode 100644 index 0000000..2a37bcc --- /dev/null +++ b/docs/readme.txt @@ -0,0 +1,106 @@ +Welcome to the documentation directory of FreeType. + +Here are short overview where you can find which information. + + + apiref.txt FreeType high-level API reference. All the types, + functions, and error codes of FreeType. + + .................................................................. + + apirefx.txt The API reference of FreeType extensions which come + with the library itself. + + .................................................................. + + bitmaps.txt How to render a glyph outline into a bitmap. + + .................................................................. + + changes.txt Guess what :-) + + .................................................................. + + convntns.txt The FreeType developer's conventions guide. Lists + the design and coding conventions used in the + engine's source code. This file is incomplete but + contains information that should be read by any + person willing to hack the FreeType code. + + .................................................................. + + credits A list of persons who have contributed to FreeType. + + .................................................................. + + glyphs.htm An introduction to glyphs in general, its usage in + glyphs.txt TrueType, and how FreeType handles them. The file + `glyphs.txt' is a simple text dump (done with + Netscape) of glyphs.htm. + + .................................................................. + + i18n.txt A short introduction to the GNU gettext package. + + .................................................................. + + porting.txt The FreeType porting guide. All you need to + configure and adapt very easily FreeType's source + code to tailor it to your own platform. + + Learn how to provide your own memory, i/o, and mutex + components, optimally fitted to your system. See + how you can build a singly-threaded, thread-safe, or + re-entrant version of the engine from the same + source code! + + .................................................................. + + raster.txt The scan-line converter's internals explained. The + document is still incomplete but presents many key + concepts. + + .................................................................. + + threads.txt How to use threads with FreeType. + + .................................................................. + + user.txt FreeType's user guide. A guide to FreeType's + concepts, a step by step example, and a note about + future works and projects. + + .................................................................. + + FAQ The new up-to-date FreeType FAQ. Look here first if + you have problems with the library. + + .................................................................. + + TODO Things which probably will come, which would be nice + to have, problems still here, etc. + + + +These documents will probably come later. + + develop.txt The FreeType developer's guide. All you need to know + in order to be able to understand and even hack the + engine's core source code. + + extend.txt The FreeType extension writer's how-to. All you need + to be able to provide new extensions to the engine. + + undoc.txt Undocumented TrueType! + + Yes, ladies and gentlemen, the TrueType + specification is fuzzy and misleading enough to + disband some serious commercial developers, but that + wasn't enough for us. Even though it took some time + (aaargh...), we finally discovered through hard work + the real meanings of the specs, fixed some errors + and even found surprising undocumented behaviour or + features! + + +--- end of readme.txt --- diff --git a/docs/threads.txt b/docs/threads.txt new file mode 100644 index 0000000..6e157fa --- /dev/null +++ b/docs/threads.txt @@ -0,0 +1,117 @@ +Threads with FreeType +===================== + + +The FreeType engine can now be compiled in thread-safe mode. +Because we want to keep the engine small and fast, the thread +protection is simple. This file gives an overview of what you can +do, and what you should strictly never do. + + +How to enable thread-safe support? + +A. You must have a valid replacement for the file `lib/ttmutex.c' + which calls your system's API to create, lock, and release + mutexes or semaphores. The current implementation is a dummy and + doesn't do anything. + +B. You must re-define the configuration macro + TT_CONFIG_OPTION_THREAD_SAFE located in `ttconfig.h'. Then + recompile. + + +IMPORTANT NOTE: + + If two threads create and use their own TT_Engine structure, they + can freely call the library concurrently on each of them (as well + as all their related objects), even in the non-threaded build. + The following remarks only apply to concurrent requests performed + on a single TT_Engine shared by multiple threads. + + +-------------------------------------------------------------------- + +- What you can do: + + With the exceptions listed below (in `What you can't do'), you can + call all API functions concurrently with two different threads. + This includes: + + Creating two or more faces from the same engine (i.e. concurrent + calls to TT_Open_Face()/TT_Open_Collection()). + + Creating two or more instances from the same face object + (i.e. concurrent calls to TT_New_Instance()). + + Creating two or more glyph containers from the same face object + (i.e. concurrent calls to TT_New_Glyph()). + + The same holds for destruction of objects. + + Load two or more glyphs concurrently for the same face or + instance (i.e. concurrent TT_Load_Glyph() calls). + + Render two or more glyphs at the same time, in the same engine + (i.e. calling TT_Get_Glyph_Bitmap()/TT_Get_Glyph_Pixmap() or + TT_Get_Outline_Bitmap()/TT_GetOutline_Pixmap() concurrently). + + NOTE: The scan-line converter can only render one glyph at a + time, for a given TT_Engine. Concurrent calls are + synchronized through a mutex, though. + + If you really, _really_, need to generate bitmaps or + pixmaps concurrently, create an additional engine and use + it with TT_Get_Outline_Bitmap()/TT_Get_Outline_Pixmap() + (you don't need to create any object in it, the outline + can come from any source too). + + This is, however, not recommended (it works perfectly, but + this could change in the future for various technical + reasons). + + +--------------------------------------------------------------------------- + +- What you cannot do: + + - You shouldn't try to delete an object while still using it with + another thread. The engine doesn't protect you from stupidity! + For example, these concurrent calls: + + TT_Close_Face( face ); + TT_Get_Glyph_Bitmap( glyph, &bitmap ); + + will act unexpectedly if the glyph is a child of the face (i.e., + was created with TT_New_Glyph( face, &glyph )) + ^^^^ + same face + + Here are some other examples: + + TT_Get_Glyph_Outline( glyph1, ... ); + TT_Load_Glyph( instance, glyph1, ... ); + + or + + TT_Get_Outline_BBox( outline, &bbox ); + TT_Transform_Outline( outline ); + + etc. + + You get the idea: Only the face and instances are protected -- + glyph containers and outlines should be thread-specific. + + + - You shouldn't initialize extensions in an engine concurrently + (which is what every mere mortal will do anyway :-). + + + +That's about it. Now enjoy the lib ;-) + + +PS: See the `MT-Note' and `MT-Safe' remarks in ttapi.c for more + detailed information on each specific function. + + +--- end of threads.txt --- diff --git a/docs/user.txt b/docs/user.txt new file mode 100644 index 0000000..d24d693 --- /dev/null +++ b/docs/user.txt @@ -0,0 +1,916 @@ + + The FreeType Engine + + Core Library User Guide + + or + + How to use the engine in your applications and font servers + + --------------------------------------------------- + + Introduction + + + I. Basic Concepts + + 1. Concepts + 2. Handles + 3. Conventions of use + 4. Object classes + + II. Extensions + + 1. What is an extension? + 2. Where to find them + 3. Writing your own extension + + Conclusion + +-------------------------------------------------------------------- + +Introduction +============ + + This file has been written to present the FreeType core library to + would-be writers of applications and font servers. It first + describes the concepts on which the engine is based, then how to + use it to obtain glyph metrics, outlines and bitmaps. + + The last part discusses the ability to add and use extensions to + the core library to get access to supplemental TrueType tables + which are not currently provided by the core engine. If you would + like to write your own extensions, read also the FreeType + developer's guide. + + +I. Basic Concepts +================= + + + 1. Concepts + ----------- + + FreeType defines several kinds of structures called `objects', + that are used to manage the various abstractions required to + access and display fonts. + + In care of good encapsulation, these objects are not directly + accessible from a client application. Rather, the user receives + a `handle' for each object he or she queries and wants to use. + This handle is a stand-alone reference; it cannot be used like a + pointer to access directly the object's data. + + 2. Properties + ------------- + + It is however possible to obtain and set object properties + through several functions of the API. For example, you can + query a face object's properties with only a handle for it, + using the function TT_Get_Face_Properties(). + + Note that the data will be returned in a user-allocated + structure, but will also contain pointers addressing directly + some data found within the object. + + A client application should never modify the data through these + pointers! In order to set new properties' values, the user must + always call a specific API function to do so, as a certain + number of other related data might not appear in the returned + structure and imply various non-visible coherency and coercion + rules. + + 3. Conventions of use + --------------------- + + o All API functions have their label prefixed by `TT_', as well + as all external (i.e. client-side) types. + + o To allow the use of FreeType's core engine in threaded + environments, nearly all API functions return an error code, + which is always set to 0 in case of success. + + The error codes' type is `TT_Error', and a listing of them is + given in the API references (see `apiref.txt' and + `apirefx.txt'). + + Some functions do not return an error code. Their result is + usually a value that becomes negative in case of error (this + is used for functions where only one kind of error can be + reported, like an invalid glyph index). + + An important note is that the engine should not leak memory + when returning an error, e.g., querying the creation of an + object will allocate several internal tables that will be + freed if a disk error occurs during a load. + + o A handle is acquired through API functions labeled along the + names: + + TT_Open_xxxx(), TT_New_xxxx() + + where `xxxx' is the object's class (Face, Instance, etc). + + Examples: + + TT_Open_Face(), TT_Open_Collection(), + TT_New_Instance(), TT_New_Glyph() + + o A handle is closed through an API labeled + + TT_Close_xxxx() or TT_Done_xxxx() + + where `xxxx' is the object's class (Face, Instance, etc). + + Examples: + + TT_Close_Face(), TT_Done_Instance(), TT_Done_Glyph() + + o Properties are obtained through an API labeled + + TT_Get_xxxx_yyyy() + + where `xxxx' is the object's class, and `yyyy' its property. + + Examples: + + TT_Get_Face_Properties(), TT_Get_Instance_Metrics() + TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap() + + o Properties are set through an API labeled + + TT_Set_xxxx_yyyy() + + where `xxxx' is the object's class, and `yyyy' its property. + + Examples: + + TT_Set_Instance_Resolutions(), + TT_Set_Instance_CharSize() + + 4. Object Classes + ----------------- + + The following object classes are defined in this release of the + engine: + + o The Engine objects + + The FreeType library can be built to be completely re-entrant, + even though its default build doesn't support threads (more on + this in the `threads.txt'). + + As a consequence, it is possible to open several instances of + the library, called `engines'. Each engine has its own set of + current objects (faces, instances, etc.), and there is no + sharing between them. + + The idea is that the library could be compiled as a shared + library or DLL, and then be able to provide several distinct + engines to independent client applications. In this case, + each client program must create its own engine with + TT_Init_FreeType() to hold its data. + + Closing an engine will destroy _all_ objects that were + allocated since its opening, releasing all resources, etc., + with the exception of user-allocated outline objects. + + o The Face objects + + A face contains the data that is specific to a single TrueType + font file. It presents information common to all glyphs and + all point sizes like font-specific metrics and properties. + + You can open a face object by simply giving a pathname to the + TrueType file. You can later close (i.e. discard) the face + object. + + You can also open a single face embedded in a TrueType + collection. + + See also: + + TT_Open_Face(), TT_Open_Collection(), TT_Close_Face(), + TT_Get_face_Properties() + + o The Instance objects + + An instance is also called a `pointsize' or a `fontsize' in + some windowing systems. An instance holds the information + used to render glyphs on a specific device at a given point + size; it is always related to an opened face object. + + For instance, if you want to generate glyphs for text from the + same typeface at `sizes' of 10 and 12 points, all you need is + one face object, from which you will create two distinct + instances. + + A device is defined by its horizontal and vertical resolution, + usually specified in dots per inch (dpi). A point size is a + scaling number, given as _absolute_ values in points, where 1 + point = 1/72 inch. + + The `pixel' size, also known as the `ppem' value (for Points + Per EM square) is computed from both the device resolution and + the point size. It determines the size of the resulting glyph + bitmaps on your screen or sheet of paper. + + The default device resolution for any new instance is 96dpi in + both directions, which corresponds to VGA screens. The + default point size is 10pt. The high-level API allows you to + change this whenever you want for any given instance object. + + Note that closing a face object will automatically destroy all + its child instances (even though you can release them yourself + to free memory). + + See also: + + TT_New_Instance(), TT_Done_Instance(), + TT_Get_Instance_Metrics(), TT_Set_Instance_Resolutions(), + TT_Set_Instance_Pointsize() + + o The Glyph objects + + A Glyph object is a _container_ for the data that describes + any glyph of a given font. This means that it typically + holds: + + - Glyph metrics information, like bounding box or advance + width. + + - Outline arrays sized large enough to hold any glyph from the + face. This size is extracted from the face's internal + `maxProfile' table to optimize memory costs. + + - Other important parameters related to the `fine' rendering + of the glyphs. This includes things like the + dropout-control mode used at low sizes. + + - And it doesn't contain a bitmap or a pixmap! + + A glyph object is used to load, hint, and rasterize a single + glyph, as taken from the font file. + + See also: + + TT_New_Glyph(), TT_Done_Glyph(), TT_Get_Glyph_Metrics(), + TT_Get_Glyph_Outline(), TT_Get_Glyph_Bitmap(), + TT_Get_Glyph_Pixmap() + + o The Character Map (CharMap) handle + + Glyphs can be indexed in a TrueType file in any order, + independently of any standard character encoding, like ASCII + or Unicode. For this reason, each file comes with one or more + character mapping tables, used to translate from one specific + encoding's character codes to font glyph indices. + + There are many encoding formats, and each one can be + distinguished by two values: + + - its platform ID + - its platform-specific encoding ID + + Their values are defined in the TrueType specification and + won't be commented there. The FAQ lists the most commonly + used (platform,encoding) pairs. + + It is possible to enumerate the charmaps provided by a + TrueType font and to use any of these to perform translations. + + The charmaps are loaded into memory only on demand to save the + space taken by the maps that are not needed on your system. + They are part of the face object, however. + + This means that even though a charmap can be accessed through + a handle (obtained through the TT_Get_CharMap() function), it + isn't a stand-alone object. For example, you never need to + de-allocate it; this is automatically done by the engine when + its face object expires. + + See also: + + TT_Get_CharMap_Count(), TT_Get_CharMap_ID(), + TT_Get_CharMap(), TT_Char_Index(). + + o The Outline Objects + + An outline is a vector representation of a glyph. It is made + of several control points joined by line segments and Bezier + arcs, themselves gathered in closed paths called `contours'. + The outline have also several flags, or attributes, which are + used by the scan-line converter to select the best rendering + algorithms to convert the glyph's bitmap. + + Unlike other objects in FreeType, outlines aren't managed + through handles, but directly with the structure `TT_Outline', + defined for client applications. Each glyph container + contains an outline sized large enough to hold any glyph from + its parent face. Client applications can access it with + TT_Get_Glyph_Outline(). However, one can also create its own + outlines if needed with TT_New_Outline() and + TT_Clone_Outline(). + + Note that user-created outlines are NOT tracked by the + library. Hence, the client must release them himself with one + or more calls to TT_Done_Outline(). + + A various number of methods/operations are defined for the + outline class to simplify its management. + + + IMPORTANT NOTE: ********************************************** + + The definition of TT_Outline may change in the future. + Developers are thus advised to always use the outline + methods provided by the API rather than reading or setting + data themselves. + + ************************************************************** + + See also: + + TT_New_Outline(), TT_Clone_Outline(), TT_Copy_Outline(), + TT_Done_Outline(), TT_Get_Outline_BBox(), + TT_Get_Outline_Bitmap(), TT_Get_Outline_Pixmap(), + TT_Translate_Outline(), TT_Transform_Outline() + + o Bitmaps and Pixmaps + + One very important aspect of FreeType is that it is unable to + create bitmaps on its own. Rather, it is up to the client + application to do it, and pass a reference, in the form of a + TT_Raster_Map, to the scan-line converter (the component in + charge of generating bitmaps from outlines). + + Hence the importance of the TT_Raster_Map structure, which + layout is: + + struct + { + int rows; /* number of rows */ + int cols; /* number of columns (bytes) per row */ + int width; /* number of pixels per line */ + int flow; /* bitmap orientation */ + + void* bitmap; /* bit/pixmap buffer */ + long size; /* bit/pixmap size in bytes */ + } TT_Raster_Map; + + - The `rows' field contains the total number of rows in the + bitmap. + + - The `width' field gives the number of pixels per row (a bit + or a byte, depending on the map's nature). + + - The `cols' field gives the number of columns, i.e. bytes, + taken by each row in the map buffer. + + IMPORTANT: The `cols' field must be a multiple of 4 for + pixmaps! + + Typically, its value should be `(width+7)/8' for bitmaps, + and `(width+3) & -4' for pixmaps. + + - The `flow' field gives the map's vertical orientation. + + For example, if the first bytes of the bitmap buffer pertain + to its upper row, the flow is said to be going `down', and + the field should take the value `TT_Flow_Down'. If these + bytes pertain to its lowest row, the flow is going `up', and + the value is `TT_Flow_Up'. + + As an example, the PC video modes use a `down' flow, where + the first VRAM byte corresponds to the upper and leftmost + corner of the screen. + + - The `bitmap' field is a typeless pointer to the map's + buffer. + + - The `size' field contains the buffer's size in bytes. It is + usually computed as follows: + + size = rows * cols; + + NOTE: For bitmaps, the leftmost-pixel is related to the + highest (i.e. most significant) bit of its byte. + There is currently no support for the opposite + convention found in some systems. + + (It can be easily added if you really need it, just + ask the development team.) + + +II. Step-by-step Example +======================== + + Here is an example to show, step by step, how a client application + can open a font file, set one or several instances, load any + glyph, then render it to a bitmap. + + 1. Initialize the engine + ------------------------ + + This is the first thing to do. You need to initialize an engine + through a call to TT_Init_FreeType(). This function will set up + a various number of structures needed by the library. + + This allocates about 68kByte, of which 64kByte are dedicated to + the scan-line converter's `render pool', a workspace used for + bitmap generation. Note that even though this space is bounded, + the raster is able to render a glyph to any size or bitmap, even + horribly huge ones. + + NOTE: You can reduce the size of this pool by modifying the + constant RASTER_RENDER_POOL in the file `ttraster.c'. A + smaller pool will result in slower rendering at large + sizes. Take care of never assigning a value smaller than + 4kByte however, as bugs may start to lurk in! + + Example: + + TT_Engine engine; + + + error = TT_Init_FreeType( &engine ); + if ( error ) + { + printf( "could not create engine instance\n"); + ... + } + + 2. Initialize the extensions you need + ------------------------------------- + + FreeType provides several extensions which are optional, + separately compilable components to add some rare features to + the engine and its API. + + You need to explicitly initialize the extensions you want to + use. Each extension must provide an initialization function, + following the naming convention: + + TT_Init_xxx_Extension( engine ); + + where `xxx' is the extension's `kind'. + + Example: + + error = TT_Init_Kerning_Extension( engine ); + if ( error ) + ... + + 3. Open the font file + --------------------- + + There are two ways to open a font face, depending on its file + format: + + - If it is a TrueType file (ttf), you can simply use the API + named TT_Open_Face(), which takes the file's pathname as + argument, as well as the address of the returned face handle. + + Check the returned error code to see if the file could be + opened and accessed successfully. + + TT_Face face; /* face handle */ + + + error = TT_Open_Face( engine, "/fonts/arial.ttf", &face ); + if ( error ) + { + printf( "could not open the file\n" ); + ... + } + + - If the font is embedded in a TrueType collection (ttc), you + can use the API named TT_Open_Collection(), which takes also + the font's index within the collection's directory. + + TT_Face face; /* face handle */ + + + /* Load the collection's second face (index=1) */ + error = TT_Open_Collection( engine, "/fonts/mingli.ttc", + 1, &face ); + if ( error ) + { + printf( "could not open the file\n" ); + ... + } + + - Finally, when you do not know the number of faces embedded in + a TrueType collection, the following technique can be used: + + o Call TT_Open_Face() with the collection file's pathname. + This API recognizes collections automatically and always + return a handle for its first embedded font. + + o Get the face's properties through TT_Get_Face_Properties(). + These contain, among other things, the total number of fonts + embedded in the collection, in its field `num_Faces'. + + TT_Face face; /* face handle */ + TT_Face_Properties props; /* face properties */ + + + /* open the first collection font */ + error = TT_Open_Face( engine, "/fonts/mingli.ttc", + &face ); + if ( error ) + { + printf( "could not open the file\n" ); + ... + } + + /* Get the face properties */ + TT_Get_Face_Properties( face, &props ); + + /* Now print the number of faces */ + printf( "there are %d faces in this collection file\n", + props->num_Faces ); + + 4. Create an instance from the face object + ------------------------------------------ + + You must create an instance (also known as a `pointsize') which + contains information relative to the target output device's + resolutions and a given point size. + + o The instance object is created through TT_New_Instance(): + + TT_Instance instance; + + + error = TT_New_Instance( face, &instance ); + if ( error ) + { + printf( "could not create instance\n" ); + ... + } + + TECHNICAL NOTE: Creating a new instance executes its font + program. This can fail if the font is broken. + Never assume that the error code returned here + is always 0. + + o You must set the instance's properties to suit your needs. + These are simply its device resolutions, set through + TT_Set_Instance_Resolutions(), and its point size, set through + TT_Set_Instance_CharSize(): + + /* Set the target horizontal and vertical resolution to */ + /* 300dpi in each direction (typically for a printer). */ + /* A fresh instance's default resolutions are 96dpi in */ + /* both directions. */ + error = TT_Set_Instance_Resolutions( instance, 300, 300 ); + if ( error ) + { + printf( "could not set resolution\n" ); + ... + } + + /* Now set the point size to 12pt. Default is 10pt. */ + /* Don't forget that the size is expressed in 26.6 fixed */ + /* float format, so multiply by 64. */ + error = TT_Set_Instance_CharSize( instance, 12 * 64 ); + if ( error ) + { + printf( "could not set point size\n" ); + ... + } + + TECHNICAL NOTE: These calls may execute the font's `prep' + program, which can fail if the font is broken. + Never assume that the error code returned is + are always 0. + + o You can also set the instance's transformation flags to tell + the glyph loading function that you are going to perform a + transformation (like rotation or slanting) on the glyph. Note + that the glyph loader doesn't perform the transformation. It + only informs the glyphs' hinting instruction streams about + these flags which may use it to disable or enable various + features (grid-fitting, drop-out control, etc). + + Use e.g. + + TT_Set_Instance_Transforms( FALSE, TRUE ); + + to indicate that you're going to stretch, but not rotate, this + instance's glyphs. Default is, of course, both FALSE. + + 5. Create a glyph container + --------------------------- + + You need a glyph object to serve as a container for the glyphs + you want to load from the face. This is done simply by + + TT_Glyph glyph; /* glyph object handle */ + + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + { + printf( "could not create glyph\n" ); + ... + } + + 6. Find your platform's character mappings + ------------------------------------------ + + Each font file can come with one or more character mapping + tables, used to convert character codes to glyph indices. You + must know the values of the `platformID' and `encodingID' as + defined in the TrueType specification for your platform. For + example, Windows Unicode encoding is (platform:3,encoding:1), + while Apple Unicode is (platform:0,encoding:0). Both formats + differ in internal storage layout and can be used transparently + with the same inputs with FreeType. + + The function TT_Get_CharMap_Count() returns the number of + character mappings present in a face. You can then enumerate + these with the function TT_Get_CharMap_ID(). Once you've found + a mapping usable for your platform, use TT_Get_CharMap() to + return a TT_CharMap handle that will be used later to get glyph + indices. + + 7. Load the glyph + ----------------- + + The glyph loader is easily queried through TT_Load_Glyph(). + This API function takes several arguments: + + o An instance handle to specify at which point size and + resolution the loaded glyph should be scaled and grid-fitted. + + o A glyph container, used to hold the glyph's data in memory. + Note that the instance and the glyph must relate to the _same_ + font file. An error would be produced immediately otherwise. + + o A glyph index, used to reference the glyph within the font + file. This index is not a platform specific character code, + and a character's glyph index may vary from one font to + another. To compute glyph indices from character codes, use + the TT_CharMap handle created in section 6 with + TT_Char_Index(). + + We strongly recommend using the Unicode charmap whenever + possible. + + o A load mode, indicating what kind of operations you need. + There are only two defined for the moment: + + TTLOAD_SCALE_GLYPH: + + If set, this flag indicates that the loaded glyph will be + scaled (according to the instance specified as an + argument) to fractional pixel coordinates (26.6). If not, + the coordinates will remain integer FUnits. Please refer + to the TrueType specification and the FreeType header + files for more details on the 26.6 format and other data + types. + + TTLOAD_HINT_GLYPH: + + This flag is only in effect if the TTLOAD_SCALE_GLYPH flag + is set. It indicates that the glyph must also be `hinted' + resp. `grid-fitted' for better display results. Note that + this also means that the glyph metrics will be + grid-fitted, including the bounding box. + + You can simply `or' the flags. As most applications will + require both flags to be set, the constant TTLOAD_DEFAULT is + defined as: + + #define TTLOAD_DEFAULT (TTLOAD_SCALE_GLYPH | \ + TTLOAD_HINT_GLYPH ) + + Example: + + error = TT_Load_Glyph( instance, glyph, 36, + TTLOAD_DEFAULT ); + if ( error ) + { + printf("could not load the glyph\n"); + ... + } + + 8. Query glyph properties + ------------------------- + + You're then able to query various glyph properties: + + o The glyph metrics can be obtained through + TT_Get_Glyph_Metrics(). The data returned in the metrics + structure is: + + - the glyph's left side bearing (bearingX) + - the glyph's top side bearing (bearingY) + - the glyph's advance width (advance) + - the glyph's bounding box (bbox) + + These values are expressed in 26.6 pixel units when the glyph + was loaded with scaling, or in FUnits if not. To obtain + vertical metrics you should use the function + TT_Get_Glyph_Big_Metrics(). + + o The glyph outline can be queried through + TT_Get_Glyph_Outline(). This can be useful to process the + point coordinates (e.g. applying stretching or rotation) with + functions like TT_Apply_Outline_Matrix() or + TT_Apply_Outline_Translation(). Note that these functions do + not recompute a glyph's metrics after the transformation! + + The outline's structure is described in the reference + `apiref.txt'. + + A bitmap or pixmap for the glyph can be queried with the API + functions TT_Get_Glyph_Bitmap() and TT_Get_Glyph_Pixmap(). + These functions take a glyph handle as an argument, as well as + a bitmap/pixmap description block and two offsets. + + The target map is described through a TT_Raster_Map object, + which structure is defined in the reference (see + `apiref.txt'). The offsets are given in the same units as the + points coordinates and glyph metrics: 26.6 pixel units for a + scaled glyph, and FUnits for an unscaled one. + + IMPORTANT TECHNICAL NOTE: If the glyph has been scaled and + hinted, the offsets _must_ be + multiples of 64 (i.e. integer pixel + offsets). Otherwise, you would ruin + the grid fitting (which usually + results in ugly glyphs). + + Example: + + TT_Glyph_Metrics metrics; + TT_Outline outline; + TT_Raster_Map bitmap; + + + TT_Get_Glyph_Metrics( glyph, &metrics ); + TT_Get_Glyph_Outline( glyph, &outline ); + + /* set up the bitmap */ + ... + TT_Get_Glyph_Bitmap( glyph, &bitmap, 0, 0 ); + + 9. When you are done + -------------------- + + o You can close any font face object with TT_Close_Face(). This + call will automatically discard its child instances, glyphs + and charmaps. + + o You can also close the engine with a single call to + TT_Done_FreeType(). This will release _all_ objects that were + previously allocated (with the exception of user-created + outlines), and close all font files, as well as extensions + that were inited for it. + + +III. Extensions +=============== + + 1. What is an extension? + ------------------------ + + FreeType allows you to access a various number of TrueType + tables, as well as to render individual glyphs. However: + + 1. It doesn't perform some high-level operations, like + generating a string text from many individual glyphs. + + 2. It doesn't perform kerning (which can be needed by operations + mentioned in item 1). + + 3. It doesn't give access to all the defined TrueType tables, + especially the optional ones. + + While item 1 is a feature that will never go into FreeType's + core engine, which goal is to provide easy access to font data + and rendering _individual_ glyphs, point 2 and 3 can be added to + the engine's features through extensions. + + An extension is simply a small piece of code that extends the + engine's abilities and APIs. It is possible to extend the + engine without touching the core's source code, this is + described in chapter 3 below. + + 2. The two kinds of extensions + ------------------------------ + + There are basically two kinds of extensions, which require + different implementations. + + a. API extensions + + An API extension is a set of functions that extend the + FreeType core API to give access to tables that are already + loaded by the engine, but not provided for now. An example of + such data can be: + + - the horizontal metrics table (hmtx) + - the `gasp' table + + This kind of extension is made of: + + o an API extension header file, following the usage convention + introduced here (all labels prefixed with `TT_'), and which + will be included by the clients which want to use the + extension. By convention, such header names begin with + `ftx' (for FreeType eXtension). + + Examples: ftxgasp.h, ftxhmtx.h + + o One or more functions used to give access to the tables that + are already loaded and managed by the engine. They usually + only copy pointers to the target structure given by the + client application since these structures are not accessible + through the 'normal' API. An API extension doesn't need to + be initialized before being used. + + b. Engine extensions + + It can sometimes be useful to load and manage several tables + that are not considered by the core engine. These extensions + need to provide additional functions to fit into FreeType's + internal object management model, and are more sophisticated + than API extensions. + + An example is given in this distribution to provide kerning + support (or more technically spoken, access to the kerning + tables found within the TrueType files). It is made of: + + o An API extension providing new interfaces to the client + applications that need it. See the file `ftxkern.h' + resp. `apirefx.txt'. + + o A specific implementation, providing services to create, + load, and manage kerning tables as additional parts of a + face object. In the case of kerning, the directory of + tables is loaded when the face is opened, and tables + themselves are fetched from the file on demand. This + implies several `hooks' in the core engine. See the files + `ttkern.h' and `ttkern.c'. These are called `engine + extensions'. + + o A specific extension initialization function, namely + TT_Init_Kerning_Extension(), that must be called after an + engine's creation, and before any face object allocation. + This function will `register' the extension within the + engine and make its API workable. + + 3. Writing your own extensions + ------------------------------ + + As it was suggested earlier, writing an engine extension is a + delicate process, as the additional code must follow a certain + number of design rules, presented in the FreeType developer's + guide. Unfortunately, there is currently no extension writer's + guide. + + By writing your own extensions, it will be possible to support + more advanced TrueType formats like TrueType GX or OpenType in a + near future, without having to torture the engine core source at + each iteration. + + If you encounter some difficulties when trying to create your + own extension, please read the core source file carefully, and + in the event that you may need changes that are not fitted to + the current extension mechanism, do not hesitate to contact the + authors at `devel@freetype.org'. + + +Conclusion +========== + + The engine source code has become rather stable since now, and + its quality compares very favorably to Windows and the Macintosh + rasterizers. Its internals will continue to change, though very + slowly, even if the API isn't expected to grow much in a near + future. + + FreeType is really a glyph-oriented TrueType driver. Its + purpose is to open and manage font files in order to load single + glyphs and render them as cleanly as possible. A number of + features, important to developers, like text string rendering, + font mapping and underlining/stroking, to name a few, aren't + provided there even though they'd be highly appreciated. + + We hope you have success and fun using this engine. Much time + has been taken to make it one of the best in its genre. + Remember that it is not intended to be a complete font server or + text rendering library, but a pretty solid base for these kinds + of applications, as well as others. + + We thank you for your time and consideration. + + David Turner, Robert Wilhelm, Werner Lemberg, + and all the FreeType enthusiasts... + + +--- End of user.txt --- diff --git a/freetype.spec b/freetype.spec new file mode 100644 index 0000000..e367b11 --- /dev/null +++ b/freetype.spec @@ -0,0 +1,162 @@ +Summary: FreeType library +Name: freetype +Version: 1.3.1 +Release: 1 +Source: ftp://ftp.freetype.org/pub/freetype/freetype-%{version}.tar.gz +URL: http://www.freetype.org/ +Copyright: BSD-Like +Group: Libraries +BuildRoot: /var/tmp/freetype + +%description +The FreeType engine is a free and portable TrueType font rendering +engine. It has been developed to provide TrueType support to a +great variety of platforms and environments. + +Note that FreeType is a *library*. It is not a font server for your +favorite platform, even though it was designed to be used in many of +them. Note also that it is *not* a complete text-rendering library. +Its purpose is simply to open and manage font files, as well as +load, hint and render individual glyphs efficiently. You can also +see it as a `TrueType driver' for a higher-level library, though +rendering text with it is extremely easy, as demo-ed by the test +programs. + +This package contains the files needed to run programs that use the +FreeType engine. + +%package devel +Summary: FreeType development headers and libraries +Group: Development/Libraries +Requires: %{name} = %{version} + +%description devel +The FreeType engine is a free and portable TrueType font rendering +engine. It has been developed to provide TrueType support to a +great variety of platforms and environments. + +Note that FreeType is a *library*. It is not a font server for your +favorite platform, even though it was designed to be used in many of +them. Note also that it is *not* a complete text-rendering library. +Its purpose is simply to open and manage font files, as well as +load, hint and render individual glyphs efficiently. You can also +see it as a `TrueType driver' for a higher-level library, though +rendering text with it is extremely easy, as demo-ed by the test +programs. + +This package contains all supplementary files you need to develop +your own programs using the FreeType engine. + +%package demo +Summary: FreeType test and demo programs +Group: Applications/Graphics +Requires: %{name} = %{version} + +%description demo +The FreeType engine is a free and portable TrueType font rendering engine. +It has been developed to provide TT support to a great variety of platforms +and environments. + +Note that FreeType is a *library*. It is not a font server for your favorite +platform, even though it was designed to be used in many of them. Note also +that it is *not* a complete text-rendering library. Its purpose is simply to +open and manage font files, as well as load, hint and render individual +glyphs efficiently. You can also see it as a "TrueType driver" for a +higher-level library, though rendering text with it is extremely easy, as +demo-ed by the test programs. + +This package contains several programs bundled with the FreeType engine for +testing and demonstration purposes. + +%changelog +* Thu Sep 9 1998 Pavel Kankovsky +- Simplified (and fixed) file list. + +* Wed Jun 16 1999 Werner Lemberg +- Updated to version 1.3. + +* Sun Oct 25 1998 Pavel Kankovsky +- libttf.so version number updated again. +- Default localedir based on prefix. +- File list adjustments (howto/). + +* Sun Oct 16 1998 Pavel Kankovsky +- Source filename fixed. +- HOWTO removed. +- libttf.so version number updated. + +* Tue Sep 29 1998 Robert Wilhelm +- Updated to version 1.2. + +* Tue Jul 14 1998 Alexander Zimmermann +- Added missing files. +- Added %defattr tags. + +* Thu Jun 18 1998 Robert Wilhelm +- Added lots of attr(-,root,root). + +* Wed May 27 1998 Pavel Kankovsky +- Changed group attr of freetype and freetype-devel package. +- Fixed misc glitches. + +* Sun May 24 1998 Pavel Kankovsky +- Split the package into three parts (runtime library, development + tools, and demo programs). +- Added missing files (headers, NLS). +- Added ldconfing upon (de)installation. + +* Thu Mar 12 1998 Bruno Lopes F. Cabral +- NLS for Portuguese language is missing, sorry (may be in a near future) + (please note the workaround using --with-locale-dir and gnulocaledir. + NLS Makefile needs a bit more rework but again I'll not patch it here). + +%prep +%setup + +find . -name CVS -type d | xargs rm -rf + +%build +./configure --prefix=/usr --enable-static +make all + +%install +make install prefix=$RPM_BUILD_ROOT/usr + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + +%files +%defattr(644, root, root, 755) +%doc announce license.txt +/usr/lib/libttf.so.* +/usr/share/locale/ + +%files devel +%defattr(644, root, root, 755) +%doc INSTALL README PATENTS announce license.txt readme.1st +%doc docs/ howto/ +/usr/lib/libttf.so +/usr/lib/libttf.la +/usr/lib/libttf.a +/usr/include/freetype/ + +%files demo +%defattr(755, root, root, 755) +%doc announce license.txt +/usr/bin/ftdump +/usr/bin/fterror +/usr/bin/ftlint +/usr/bin/ftmetric +/usr/bin/ftsbit +/usr/bin/ftstring +/usr/bin/ftstrpnm +/usr/bin/ftstrtto +/usr/bin/fttimer +/usr/bin/ftview +/usr/bin/ftzoom diff --git a/ft_conf.h.in b/ft_conf.h.in new file mode 100644 index 0000000..c19b442 --- /dev/null +++ b/ft_conf.h.in @@ -0,0 +1,211 @@ +/* ft_conf.h.in. */ + +/* This file is part of the FreeType project. */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +/* The number of bytes in a int. */ +#undef SIZEOF_INT + +/* The number of bytes in a long. */ +#undef SIZEOF_LONG + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#undef HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define if you have the libintl library. */ +#undef HAVE_LIBINTL + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +#undef HAVE_TT_TEXT + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ diff --git a/howto/mac.txt b/howto/mac.txt new file mode 100644 index 0000000..6ed97d9 --- /dev/null +++ b/howto/mac.txt @@ -0,0 +1,19 @@ + The FreeType Mac Compilation HowTo + + + Please note that the FreeType team does *not* support the + Macintosh platform due to lack of knowledge. + + However, we provide the basic files to compile the library in + the lib/arch/mac directory (OK, `folders'). Also the project + files for PowerPC with CodeWarrior have been contributed (in + contrib/mac). + + A noteworthy point is that the precompiled standard MacOS + headers should be turned off to compile the library, to avoid + errors caused by conflicting definitions of `Fixed' and `Byte'. + + +Good luck! + +--- end of mac.txt --- diff --git a/howto/msdos.txt b/howto/msdos.txt new file mode 100644 index 0000000..6ab0c40 --- /dev/null +++ b/howto/msdos.txt @@ -0,0 +1,250 @@ + The FreeType MS-DOS Compilation HowTo + +Contents + +Introduction +I. Building the library + 1. Quick Compilation + 2. Manual compilation + 3. Notes +II. Building other parts of the package + 1. Test programs + 2. Other contribs +III. Special issues of 16-bit MS-DOS + + + +Introduction +============ + +This file describes the compilation of the FreeType package on a +MS-DOS system. It comes with Makefiles for the following compilers: + + - gcc/emx and gcc/djgpp with GNU make (32 bit) + + - wcc386 with wmake (Watcom -- tried with 10.6) + + - gcc/emx with dmake (32 bit) + + - cl with nmake (16-bit Microsoft C -- tried with 7 and VC++ 1.5x) + + - bcc/tcc with make (16-bit Borland C++ and Turbo C) + +NOTE: + + You are advised to jump to section II.1 if you want to run the + FreeType test/demo programs as quick as possible. + + + +I. Building the library +======================= + + +1. Quick Compilation +-------------------- + + The easiest way to compile the library on MS-DOS is to go to the + directory `freetype/lib'. Then type, depending on your compiler: + + gcc/emx, + gcc/djgpp: make -f arch/msdos/Makefile.gcc + gcc/dmake: dmake -r -f arch/msdos/Makefile.dm + + wcc386: wmake -f=arch\msdos\Makefile.wat + + cl: nmake /f arch\msdos\Makefile.MS (for version 7) + cl: nmake /f arch\msdos\Makefile.VC (for Visual C++ 1.x) + + tcc: make -farch/msdos/Makefile.TC + bcc: make -farch/msdos/Makefile.BC + + This should build the `libttf.a' or `libttf.lib' library files. + + You can also use the following targets: + + clean - Cleans all intermediate object files created during + compilation. Keeps all library and executables in + place. + + distclean - Cleans everything, leaving the directories as they + were before the compilation. + + debug - Makes a development version of the library. Only + useful for FreeType developers and hackers. + + Note that you can also select to use the `debugging' flags for + your compiler (instead of the `optimizing' ones), by defining + the `DEBUG' symbol, like in + + nmake /f arch\msdos\Makefile.MS DEBUG=1 + make -farch/msdos/Makefile.BC /DDEBUG + etc. + + Doing so will automatically select the debug target instead of + the normal mode. + + For 16-bit compilers, you can also try defining the `BIGFONTS' + symbol, to enable the use of the `huge pointers' needed to + handle some big fonts. More on this at the end of this file. + + +2. Manual compilation +--------------------- + + Here are explained the steps that are required to compile the + FreeType _library_ (and only this one) by hand. + + Unlike previous versions, FreeType 1.1 and above can be compiled + in two modes, called `debug mode' and `single object mode'. + + Debug mode is simply the normal way of compiling C programs, i.e., + each `*.c' file is compiled into an individual `*.obj' object + file, and all of them are linked together into an archive (i.e., + `*.lib' library). + + Single object mode is slightly different: All C files are included + in a single source during compilation, resulting in a single final + object file for the core library. This has the advantage of + letting optimizing compilers do more global work, as well as + getting rid of all external which are used solely for the purpose + of components interfacing. + + In both modes, you need to include the following paths to your + makefile/command line: + + the location of all `tt*.[hc]' files + the location of system-specific files + + For example, if you are compiling from the `freetype/lib' + directory, you can type for debug mode something like + + gcc -c -I. -Iarch/msdos tt*.c + + to compile all required files into object ones. Then assemble + them in a library with `ar', `lib', or `tlib'. + + In single object mode, you only need to compile the file named + `freetype.c' which is located in `freetype/lib/arch/msdos'. From + the same directory as before, one would type + + gcc -c -I. -Iarch/msdos arch/msdos/freetype.c + + You can also compile the extensions located in + `freetype/lib/extend' separately from the base engine. You will + need to include the same paths as before, though; be sure to add + the path to the `extend' directory, like in + + gcc -c -I. -Iarch/msdos -Iextend extend/*.c + + +3. Notes +-------- + + `char' is always `signed char' in the sources! + + `ttconfig.h' relies heavily on a file called `ft_conf.h' that + contains information related to the target platform, located in + the `freetype/lib/arch/msdos/' directory. Depending on your + compiler, you may need to slightly edit it. + + We use gcc as our reference compiler for warnings. This means + that we use the `-ansi -pedantic -Wall' flags and try to get rid + of warnings in this situation. If you're compiling with another + compiler, you may encounter warnings, not errors. Note that the + Borland compilers seem to produce lots of irrelevant warnings + (like `potential loss of precision'). + + + +II. Building other parts of the package +======================================= + + +1. Test programs +---------------- + + These are located in `freetype/test'. Most of them use a tiny + graphics sub-system which is simply used to display bitmaps and + pixmaps on a variety of platforms. The MS-DOS version is a very + basic one that only works in full-screen using standard VGA mode. + + To compile them, you must be in the `freetype/test' directory and + invoke the makefile in arch/msdos. For example: + + nmake /f arch\msdos\Makefile.VC + + + NOTE 1: + + This will automatically invoke the library makefile for you! + + NOTE 2: + + For now, the graphical test programs only run on the following + platforms: Unix, OS/2, Dos, Amiga, and Windows. + + The library, being pure ANSI-C, can be used on any system to + generate bitmaps and pixmaps. + + +2. Other contribs +----------------- + + You may find some other contributions to the FreeType project in + the `freetype/contrib' directory. Each of these programs should + have its own Makefiles and documentations. Also check their + licenses, as the programs are not necessarily distributed under + the FreeType one. + + Most of these contributions are targeted to Unix. You are invited + to port them to MS-DOS, and then contribute your improvements. + + + +III. Special issues of 16-bit MS-DOS +==================================== + + As usual, 16-bit MS-DOS have some limitations. + + First, and mainly, only the large model is usable. The small and + medium models are not usable, because the library uses more than + 64kByte of data; and the compact model is unusable as well, since + the code of the library itself is slightly less than 64kByte, thus + leaving very small place for the real work. The net effect of + that limitation is that performances are not very impressive, to + say the least (32-bit DOS extenders perform usually three-time + faster). + + Even with the large model, the rasterizer is still limited in + size, particularly with pixmaps (that is, with anti-aliasing gray + levels). + + Another annoying limitation exists with some East Asian fonts that + have 16,383 glyphs or more, since an internal table then + overflows. We tried to overcome this using the so-called `huge + pointers', but then good support for these in the run-time library + is needed. To enable this support, try defining the `BIGFONTS' + symbol with the makefile, like using + + nmake /f arch\msdos\makefile.MS BIGFONTS=1 + make -farch/msdos/makefile.BC /DBIGFONTS + etc. + + The Makefiles for both Microsoft and Borland compilers depend on a + special file, `arch/msdos/depend.dos', which is built by a Unix + script named `makedep'. You may consider editing it if you + heavily modify the source files; or better yet, re-run the script, + using any clone of the Bourne shell and gcc, the GNU compiler, + with + + arch/msdos/makedep + + in both the `lib' and the `test' directories. + + + +Good luck! + + +--- end of msdos.txt --- diff --git a/howto/os2.txt b/howto/os2.txt new file mode 100644 index 0000000..2ce5bab --- /dev/null +++ b/howto/os2.txt @@ -0,0 +1,200 @@ + The FreeType OS/2 Compilation HowTo + +Contents + +Introduction +I. Building the library + 1. Quick Compilation + 2. Manual compilation + 3. Notes +II. Building other parts of the package + 1. Test programs + 2. Other contribs +III. Troubleshooting + + + +Introduction +============ + +This file describes the compilation of the FreeType package on an +OS/2 system. It comes with makefiles for the following compilers: + + - gcc/emx with GNU make + + - icc with nmake (Visual Age C++) + + - wcc386 with wmake (Watcom -- tried with 10.6) + + - gcc/emx with dmake + + +NOTE: + + You're advised to jump to section II.1 if you want to run the + FreeType test/demo programs as quick as possible. + + + +I. Building the library +======================= + + +1. Quick Compilation +-------------------- + + The easiest way to compile the library on OS/2 is to go to the + directory `freetype/lib'. Then type, depending on your compiler, + + gcc/emx: make -f arch/os2/makefile.emx + gcc/dmake: dmake -f arch/os2/makefile.dm + + icc: nmake -f arch\os2\makefile.icc + wcc386: wmake -f=arch\os2\makefile.wat + + This should build the `libttf.a' or `libttf.lib' library files. + + You can also use the following targets: + + debug - Makes a development version of the library. Only + useful for FreeType developers and hackers. + + clean - Cleans all intermediate object files created during + compilation. Keeps all library and executables in + place. + + distclean - Cleans everything, leaving the directories as they + were before the compilation. + + +2. Manual compilation +--------------------- + + Here are explained the steps that are required to compile the + FreeType _library_ (and only this one) by hand. + + Unlike previous versions, FreeType 1.1 and above can be compiled + in two modes, called `debug mode' and `single object mode'. + + Debug mode is simply the normal way of compiling C programs, i.e., + each `*.c' file is compiled into an individual `*.obj' object + file, and all of them are linked together into an archive (i.e., + `*.lib' library). + + Single object mode is slightly different: all C files are included + in a single source during compilation, resulting in a single final + object file for the core library. This has the advantage of + letting optimizing compilers do more global work, as well as + getting rid of all external symbols which are used solely for the + purpose of components interfacing. + + In both modes, you need to include the following paths to your + makefile/command line: + + the location of all `tt*.[hc]' files + the location of system-specific files + + For example, if you are compiling from the `freetype/lib' + directory, you can type for debug mode something like + + gcc -c -I. -Iarch/os2 tt*.c arch/os2/os2file.c + + to compile all required files into object ones. Then assemble + them in a library with `ar' or `implib'. + + In single object mode, you only need to compile the file named + `freetype.c' which is located in `freetype/lib/arch/os2'. From + the same directory as before, one would type: + + gcc -c -I. -Iarch/os2 arch/os2/freetype.c + + You can also compile the extensions located in + `freetype/lib/extend' separately from the base engine. You will + need to include the same paths as before, though; be sure to add + the path to the `extend' directory, like in + + gcc -c -I. -Iarch/os2 -Iextend extend/*.c + + + +II. Building other parts of the package +======================================= + + +1. Test programs +---------------- + + The test programs are located in `freetype/test'. Most of them + use a tiny graphics sub-system which is simply used to display + bitmaps and pixmaps in a windows on a variety of platforms. The + OS/2 version comes in two flavors: PM and full-screen. + + To compile them, you must be in the `freetype/test' directory, and + invoke the makefile in arch/os2. For example: + + nmake -f arch\os2\makefile.os2 + + + NOTE 1: + + This will automatically invoke the library makefile for you! + + NOTE 2: + + The test programs come in two flavors, distinguished by the `fs' + suffix appended to their name. For example: + + ftview (PM version) + ftviewfs (Full Screen version) + + The full-screen version is there mainly for debugging purposes. + + NOTE 3: + + For now, the graphical test programs only run on the following + platforms: Unix, OS/2, Dos, Amiga, and Windows. + + The library, being pure ANSI-C, can be used on any system to + generate bitmaps and pixmaps. + + +2. Other contributions +---------------------- + + You may find some other contributions to the FreeType project in + the `freetype/contrib' directory. Each of these programs should + have its own Makefiles and documentations. Also check their + licenses, as the programs not necessarily distributed under the + FreeType one. You are invited to port the non-OS/2 applications + to OS/2. + + For OS/2, you will find the source code for the FreeType/2 font + driver in `freetype/contrib/os2'. Read its documentation + carefully before trying to compile it, as it certainly won't be + easy. + + + +III. Troubleshooting +==================== + + There is only one important point on OS/2: + + `The test program crashes with anti-aliasing on!' + + It has been discovered that some versions of Visual Age C++ + contain a bug which miscompiles the anti-aliasing source in + ttraster.c, hence resulting in a page fault when trying to render + a pixmap in the engine. Apparently, not all levels/versions of + the compiler contain the bug. You'll notice the problem + immediately (page fault :-). + + Please apply the most recent fixpack to your Visual Age C++ copy + in order to get rid of it (newer fixpacks seem to solve the + issue). + + +Good luck! + + +--- end of os2.txt --- diff --git a/howto/unix.txt b/howto/unix.txt new file mode 100644 index 0000000..1824580 --- /dev/null +++ b/howto/unix.txt @@ -0,0 +1,255 @@ + The FreeType Unix Compilation HOWTO + +Contents + +Introduction +I. Building the library + 1. Quick Compilation + 2. Manual compilation + 3. Notes +II. Building other parts of the package + 1. Test programs + 2. Other contribs +III. Successful Build Reports + + + +Introduction +============ + +This file describes the compilation of the FreeType package on a +Unix system. Using the `configure' script it should be rather easy +to build the library. However, detailed instructions on how to +compile the library manually are given later in this document. + + + +I. Building the library +======================= + + +1. Quick Compilation +-------------------- + + The easiest way to compile the library on a Unix system is by + using the `configure' script that comes with it. Simply go to the + root directory of the FreeType package, then type + + ./configure + + to run a script that will probe your system and detect various + configuration issues, which are explained later in this document. + + From there, you can simply type + + make + + to invoke compilation of the whole package. You can also use the + following commands: + + make debug - Make a development version of the library. + Only useful for FreeType developers and + hackers. The default build should come with + `-g' (i.e., debug info in the object file) + already. + + make clean - Clean all intermediate object files created + during compilation. Keeps all library and + executables in place. + + make distclean - Clean everything, leaving the directories as + they were before the compilation. You'll need + to run `./configure' again to be able to + re-build it. + + make install - Install the library files libttf.a, libttf.la + or libttf.so to your system library path + (`/usr/local/lib' by default). The path can be + set manually with ./configure. + + make uninstall - Undo a `make install'. + + +2. Trouble-shooting and simple customization +-------------------------------------------- + + The make build seems to fail on some Solaris systems. This is + mainly due to the fact that the test programs (not the font + library itself) try to use certain libraries and/or utilities if + they find them on your system. In some cases, the Sun versions + are incompatible to the GNU ones. If you encounter such problems, + please report them to us so we can try to fix it. + + The configure script and makefiles that it generates can/make use + of the following things: + + - gettext - In order to compile the internationalized error + message string extension, which isn't part of the + core library. You can disable this and get a + clean compile with + + ./configure --disable-nls + + + - libtool - Used to generate shared libraries. You can + disable it by typing + + ./configure --disable-shared + + which will generate and link the FreeType engine + as a static library. + + By default, static compilation is disabled if the + configure script detects that your compiler + and/or operating system supports shared + libraries. You can ask for static libraries with + + ./configure --enable-static + + For more configuration options, type `./configure --help' to see a + summary of what is possible. The option to change the library + installation path for `make install' is, as usual, + `--prefix='. Example: + + ./configure --prefix=${HOME}/local/lib --disable-shared + + to install a static library (libttf.a) in `~/local/lib' (after a + `make install') + + +3. Manual compilation +--------------------- + + Here are explained the steps that are required to compile the + FreeType _library_ (and only this one) by hand. + + a. Generate a configuration file named `ft_conf.h' + + This file contains a certain number of configuration macro + declarations which must fit your system. The configure script + generates it automatically for you, but you can also take the + template file `freetype/ft_conf.h.in' and change it by hand, + then save it as `freetype/ft_conf.h'. + + b. Choose your compilation mode + + Unlike previous versions, FreeType 1.1 and above can be compiled + in two modes, called `debug mode' and `single object mode'. + + Debug mode is simply the normal way of compiling C programs, + i.e., each *.c file is compiled into an individual *.o object + file, and all of them are linked together into an archive (i.e., + a *.a library). + + Single object mode is slightly different: All C files are + included in a single source file during compilation, resulting + in a single final object file for the core library. This has + the advantage of letting optimizing compilers do more global + work, as well as getting rid of all external symbols which are + used solely for the purpose of components interfacing. + + In both modes, you need to include the following paths to your + makefile/command line: + + . the location of the `ft_conf.h' file + . the location of all `tt*.[hc]' files + . the location of system-specific files, i.e., `ttmmap.c' on + Unix. + + For example, if you are compiling from the `freetype/lib' + directory, you can type for debug mode something like + + gcc -c -I.. -I. -Iarch/unix tt*.c arch/unix/ttmmap.c + + to compile all required files. Then assemble them in a library + with `ar' (and run `runlib' if necessary). + + In single object mode, you only need to compile the file named + `freetype.c' which is located in `freetype/lib/arch/unix'. From + the same directory as before, one would type: + + gcc -c -I.. -I. -Iarch/unix arch/unix/freetype.c + + You can also compile the extensions located in + `freetype/lib/extend' separately from the base engine. You'll + need to include the same paths as before, though. + + + +II. Building other parts of the package +======================================= + + +1. Test programs +---------------- + + All test programs are located in `freetype/test'. Most of them + use a tiny graphics sub-system which simply display bitmaps and + pixmaps in a windows on a variety of platforms. Of course, the + Unix version uses X11. + + The default `make' builds all tests programs automatically. Just + go the `freetype/test' and launch the programs when you are there. + Documentation on the test programs can be found in the file + `freetype/README'. + + NOTE: + + For now, the graphical test programs only run on the following + platforms: Unix, OS/2, Dos, Amiga, and Windows. + + The library, being pure ANSI-C, can be used on any system to + generate bitmaps and pixmaps. + + +2. Other contributions +---------------------- + + You may find some other contributions to the FreeType project in + the `freetype/contrib' directory. Each of these programs should + have their own makefiles and documentations. Also check their + licenses, as they are not necessarily distributed under the + FreeType one. + + + +III. Successful Build Reports +============================= + +Nelson H. F. Beebe and others report the +following successfully builds (with gcc 2.8.1) of freetype-1.1 on + + DEC Alpha 2100-5/250: OSF/1 3.2 + HP 9000/735: HP-UX 10.01 + Intel Pentium (200MHz MMX): Linux 2.0.30 + SGI Challenge L: IRIX 5.3 + Sun SPARC 20/512: Solaris 2.6 + Sun SPARC Ultra-2: SunOS 5.5.1 + IBM RS/6000: AIX 4.1 + +Chances are good the the current release will build on the same +machines and platforms. + +There are build problems reported on SunOs 4.x which have the form + + ld: /usr/tmp/cca07291.o: assert pure-text failed: + reference to [offset] at f754 in /usr/tmp/cca07291.o + +This may be a compiler bug in gcc 2.8.1. + +You can work around by just building a static library with + + ./configure --disable-shared --enable-static --disable-nls + +Maybe `make debug' will help here too (untested). + +Other successful builds: + + Sun SPARC Solaris 2.5 with Sun C compiler+linker + +For updated build reports, please consult our web site: + + http://www.freetype.org + + +--- end of unix.txt --- diff --git a/howto/windows.txt b/howto/windows.txt new file mode 100644 index 0000000..196ef83 --- /dev/null +++ b/howto/windows.txt @@ -0,0 +1,344 @@ + The FreeType Windows Compilation HowTo + +Contents + +Introduction +I. Building the library + 1. Quick Compilation + 2. Manual compilation + 3. Notes +II. Building other parts of the package + 1. Test programs + 2. Other contributions +III. Special issues of 16-bit Windows + + + +Introduction +============ + +This file describes the compilation of the FreeType package on a +Windows system. It comes with Makefiles for the following +compilers: + + - gcc/CygWin32 and gcc/MinGW32 with GNU make (32 bit) + + - cl with nmake (16-bit and 32-bit Microsoft C and Visual C++) + + - bcc with make (16-bit and 32-bit Borland C++ and also Borland + C++ builder) + +Throughout this file, we use `winXX' if it applies indifferently to +both 16-bit and 32-bit versions. You should replace it with win16 +resp. win32, as applicable. + +NOTE: + + You are advised to jump to section II.1 if you want to run the + FreeType test/demo programs as quick as possible. + + + +I. Building the library +======================= + + +1. Quick Compilation +-------------------- + + The easiest way to compile the library on Windows is to go to the + directory `freetype/lib'. Then type, depending on your compiler: + + gcc: make -f arch/win32/Makefile.gcc + + cl: nmake /f arch\win16\Makefile.MS (for C/C++ 7) + cl: nmake /f arch\win16\Makefile.VC (for VC++ 16bit) + cl: nmake /f arch\win32\Makefile.CL (for VC++ 32bit) + + bcc: make -farch/win16/Makefile.BC + bcc32: make -farch/win32/Makefile.BC + + This should build the `libttf.a' or `libttf.lib' library files. + Of course, this assumes that your compiler is regularly installed. + + You can also use the following targets: + + clean - Cleans all intermediate object files created during + compilation. Keeps all library and executables in + place. + + distclean - Cleans everything, leaving the directories as they + were before the compilation. + + debug - Makes a development version of the library. Only + useful for FreeType developers and hackers. + + Note that you can also select to use the `debugging' flags for + your compiler (instead of the `optimizing' ones), by defining + the `DEBUG' symbol, like in + + nmake /f arch\win32\Makefile.CL DEBUG=1 + make -farch/winXX/Makefile.BC /DDEBUG + etc. + + Doing so will automatically select the debug target instead of + the normal mode. + + For 16-bit compilers, you can also try to define the `BIGFONTS' + symbol, enabling the use of the `huge pointers' needed to handle + some big fonts. More on this at the end of this file. + + Another way to compile the library is to use the IDE provided with + the following compilers: Borland C++ 5.0, Visual C++ 4.0, and + Visual C++ 5.0. The project/workspace files can be found in the + `freetype/lib/arch/win32' directory: + + freetype.ide for Borland C++ 4.0 and 5.0 (and perhaps 4.5) + + freetype.dsp project and workspace files for + freetype.dsw Visual C++ 5.0 + + freetype.mdp project and makefile files for + freetype.mak Visual C++ 4.0 + + They generate a static library, which contain the core engine as a + single object file, as well as all standard extensions. + + Notes: + + - You may need to update the include paths in the Borland C++ + workspace settings. The current one looks in the directory + "c:\Program Files\Borland\BC 5.0\Include" for include files. + + - Take care that some compilers may overwrite these files when + generating the library (e.g. Borland C++ creates its own + `freetype.mdp' file, which isn't a Visual C++ project during + compilation). + + This is only important if you try to compile the lib with + several compilers. + + We gladly accept project files for other compilers. + + +2. Manual compilation +--------------------- + + Here are explained the steps that are required to compile the + FreeType _library_ (and only this one) by hand. + + Unlike previous versions, FreeType 1.1 and above can be compiled + in two modes, called `debug mode' and `single object mode'. + + Debug mode is simply the normal way of compiling C programs, i.e., + each `*.c' file is compiled into an individual `*.obj' object + file, and all of them are linked together into an archive (i.e., + `*.lib' library). + + Single object mode is slightly different: All C files are included + in a single source during compilation, resulting in a single final + object file for the core library. This has the advantage of + letting optimizing compilers do more global work, as well as + getting rid of all external which are used solely for the purpose + of components interfacing. + + In both modes, you need to include the following paths to your + makefile/command line: + + the location of all `tt*.[hc]' files + the location of system-specific files + + For example, if you are compiling from the `freetype/lib' + directory, you can type for debug mode something like + + gcc -c -I. -Iarch/win32 tt*.c + + to compile all required files into object ones. Then assemble + them in a library with `ar', `lib', or `tlib'. + + In single object mode, you only need to compile the file named + `freetype.c' which is located in `freetype/lib/arch/winXX'. From + the same directory as before, one would type + + gcc -c -I. -Iarch/win32 arch/win32/freetype.c + + You can also compile the extensions located in + `freetype/lib/extend' separately from the base engine. You will + need to include the same paths as before, though; be sure to add + the path to the `extend' directory, like in + + gcc -c -I. -Iarch/win32 -Iextend extend/*.c + + +3. Building a DLL +----------------- + + The easiest way to build the library as a DLL is also to use the + Makefiles we provide! Go to the directory `freetype/lib', then + type, depending on your compiler: + + gcc: (not yet supported) + + cl: nmake /f arch\win16\Makefile.VC DLL=1 dll (16bit) + cl: nmake /f arch\win32\Makefile.CL DLL=1 dll (32bit) + + bcc: make -farch/win16/Makefile.BC -DDLL dll + bcc32: make -farch/win32/Makefile.BC -DDLL dll + + This should build `ft13_XX.dll' (`13' for version 1.3, `XX' is + either 16 or 32), and the `libttf.lib' library file. + + You can also use the following target: + + install - Install the DLL `ft13_XX.dll' to your system directory + (`C:\WINDOWS' by default). You can override the + directory by specifying the name of the directory: + + make -farch/winXX/Makefile.BC /DINSTALL_DIR=C:\TESTDLL install + nmake /f arch\win32\Makefile.CL INSTALL_DIR=D:\WINNT install + + Note that you can also select to use the `debugging' flags for + your compiler (instead of the `optimizing' ones), by defining + the `DEBUG' symbol, like in + + nmake /f arch\win16\Makefile.VC DEBUG=1 DLL=1 dll + make -farch/winXX/Makefile.BC /DDEBUG /DDLL dll + etc. + + Another way to build to DLL with Visual C++ is to use a special + Makefile that does exactly that, without relying on any settings. + + With VC++ 6.0, just type while in the `freetype/lib/arch/win32' + directory: + + nmake /f makefile.vc + + on the command line. + + For other versions, modify the $(TOOLS32) variable to point to the + directory where the build tools are. No need to set any + environment variables. + + +4. Notes +-------- + + `char' is always `signed char' in the sources! + + `ttconfig.h' relies heavily on a file called `ft_conf.h' that + contains information related to the target platform, located in + the `freetype/lib/arch/winXX/' directory. Depending on your + compiler, you may need to slightly edit it. + + We use gcc as our reference compiler for warnings. This means + that we use the `-ansi -pedantic -Wall' flags and try to get rid + of warnings in this situation. If you are compiling with another + compiler, you may encounter warnings, not errors. Note that the + Borland compilers seem to produce lots of irrelevant warnings + (like `potential loss of precision'). + + + +II. Building other parts of the package +======================================= + + +1. Test programs +---------------- + + All test programs are located in `freetype/test'. Most of them + use a tiny graphics sub-system which is simply used to display + bitmaps and pixmaps on a variety of platforms. The Windows + version is a very basic one that only displays a small graphic + windows in addition to the console where the flow of messages + still goes. + + To compile them, you must be in the `freetype/test' directory and + invoke the makefile in arch/winXX. For example: + + nmake -f arch\os2\Makefile.VC + + NOTE 1: + + This will automatically invoke the library makefile for you! + + NOTE 2: + + For now, the graphical test programs only run on the following + platforms: Unix, OS/2, Dos, Amiga, and Windows. + + The library, being pure ANSI-C, can be used on any system to + generate bitmaps and pixmaps. + + +2. Other contributions +---------------------- + + You may find some other contributions to the FreeType project in + the `freetype/contrib' directory. Each of these programs should + have its own Makefiles and documentations. Also check their + licenses, as the programs are not necessarily distributed under + the FreeType one. + + Most of these contributions are targeted to Unix. You are invited + to port them to Windows, and then contribute your improvements. + + + +III. Special issues of 16-bit Windows +===================================== + + As usual, 16-bit Windows have some limitations. + + First, and mainly, only the large model is usable. The small and + medium models are not usable, because the library uses more than + 64kByte of data; and the compact model is unusable as well, since + the code of the library itself is slightly less than 64kByte, thus + leaving very small place for the real work. The net effect of + that limitation is that performances are not very impressive, to + say the least (32-bit DOS extenders perform usually three-time + faster). + + Even with the large model, the rasterizer is still limited in + size, particularly with pixmaps (that is, with anti-aliasing gray + levels). + + The test programs rely on a tiny graphical driver that mimics the + ones available on other platforms. It has some peculiarities. + First, as the test programs need a `console', the programs should + linked with some emulation of that concept. We used successfully + Borland EasyWin and Microsoft QuickWin for this purpose. Then, + the graphics window that displays the bitmaps incur the usual + 64kByte limit: The size of the window is quite tiny, particularly + when displaying `gray-level' bitmaps (the size is then 320x200, + but contrary to full-screen MS-DOS the pixels are not magnified). + Ultimately, no efforts have been done to accomodate the colors of + the screen: As a result, displaying gray bitmaps in 256-color mode + uses only 4 levels of gray (instead of 5 rendered by the library). + + Another annoying limitation exists with some East Asian fonts that + have 16,383 glyphs or more, since an internal table then + overflows. We tried to overcome this using so-called `huge + pointers', but then good support for these in the run-time library + is needed. To enable huge pointers, try defining the `BIGFONTS' + symbol with the makefile, like + + nmake /f arch\win16\makefile.VC BIGFONTS=1 + make -farch/win16/makefile.BC /DBIGFONTS + etc. + + The makefiles for both Microsoft and Borland compilers depend on a + special file, arch/winXX/depend.win, which is built by a Unix + script named `makedep'. You may consider editing it if you + heavily modify the source files; or better yet, re-run the script, + using any clone of the Bourne shell and gcc, the GNU compiler, + with + + arch/winXX/makedep + + in both the `lib' and the `test' directories. + + +Good luck! + +--- end of windows.txt --- diff --git a/install-sh b/install-sh new file mode 100644 index 0000000..ebc6691 --- /dev/null +++ b/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/lib/.cvsignore b/lib/.cvsignore new file mode 100644 index 0000000..e61a727 --- /dev/null +++ b/lib/.cvsignore @@ -0,0 +1,3 @@ +.libs +*.lo +libttf.la diff --git a/lib/arch/amigaos/Makefile.gcc b/lib/arch/amigaos/Makefile.gcc new file mode 100644 index 0000000..ef02372 --- /dev/null +++ b/lib/arch/amigaos/Makefile.gcc @@ -0,0 +1,69 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for amiga using ADE Enviroment. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/amigaos/Makefile.gcc + +ARCH = arch/amigaos +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +AR = ar +RM = rm + +CC = gcc + +CFLAGS = -Wall -pedantic -ansi -O2 -g -noixemul -I$(ARCH) -I. -Iextend + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxgdef.c \ + extend/ftxopen.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttextend.c ttfile.c ttgload.c ttinterp.c ttload.c \ + ttmemory.c ttmutex.c ttobjs.c ttraster.c +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M libttf.a + + +$(OBJ_S): $(SRC_S) $(SRC_M) + + +libttf.a: $($(LIB_FILES)) + $(AR) src $@ $^ + +clean: + $(RM) $($(LIB_FILES)) + +distclean: clean + $(RM) dep.end libttf.a + +depend: $(SRC_S) $(SRC_M) $(SRC_X) + $(CC) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/lib/arch/amigaos/freetype.c b/lib/arch/amigaos/freetype.c new file mode 100644 index 0000000..723c8f4 --- /dev/null +++ b/lib/arch/amigaos/freetype.c @@ -0,0 +1,25 @@ +/* This file is part of the FreeType project */ + +/* Single object library component for AmigaOS */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttfile.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttmemory.c" +#include "ttmutex.c" +#include "ttobjs.c" +#include "ttraster.c" + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/amigaos/ft_conf.h b/lib/arch/amigaos/ft_conf.h new file mode 100644 index 0000000..6aa4b3f --- /dev/null +++ b/lib/arch/amigaos/ft_conf.h @@ -0,0 +1,220 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for AmigaOS using ADE enviroment */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ + +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ + +/* #undef HAVE_MMAP */ + +/* Define if you have the header file. */ + +#define HAVE_STDLIB_H + +/* Define if the X Window System is missing or not being used. */ + +#define X_DISPLAY_MISSING + +/* The number of bytes in a int. */ + +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ + +#define SIZEOF_LONG 4 + +/* Define if you have the getpagesize function. */ + +#define HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ + +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ + +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ + +#define HAVE_VALLOC + +/* Define if you have the header file. */ + +#define HAVE_FCNTL_H + +/* Define if you have the header file. */ + +#define HAVE_UNISTD_H + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/ansi/freetype.c b/lib/arch/ansi/freetype.c new file mode 100644 index 0000000..820687a --- /dev/null +++ b/lib/arch/ansi/freetype.c @@ -0,0 +1,32 @@ +/* This file is part of the FreeType project */ + +/* Single file library component for the ANSI target */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "ttfile.c" +#include "ttmemory.c" +#include "ttmutex.c" + +/* the extensions are compiled separately, but we need to */ +/* include the file ttextend.c if we want to support them */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + +/* END */ diff --git a/lib/arch/ansi/ft_conf.h b/lib/arch/ansi/ft_conf.h new file mode 100644 index 0000000..352e646 --- /dev/null +++ b/lib/arch/ansi/ft_conf.h @@ -0,0 +1,227 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for the ANSI Build */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. Unix-specific */ +#undef HAVE_FCNTL_H + +/* command.com can't pipe stderr into a file; any message would be */ +/* written into the graphics screen. */ +#define HAVE_PRINT_FUNCTION 1 + +#define Print( format, ap ) vfprintf( stdout, (format), (ap) ) + + +/* The number of bytes in a int. We use the ANSI header file limits.h */ +/* for determining it since there is no easy way to guess. */ +/* */ +#include +#if UINT_MAX == 0xFFFF +#define SIZEOF_INT 2 +#elif UINT_MAX == 0xFFFFFFFF +#define SIZEOF_INT 4 +#else +#error "Unsupported number of bytes in `int' type!" +#endif + +/* We now try to guess the size of longs in the same way */ +/* */ +#if ULONG_MAX == 0xFFFFFFFF +#define SIZEOF_LONG 4 +#elif ULONG_MAX == 0xFFFFFFFFFFFFFFFF +#define SIZEOF_LONG 8 +#else +#error "Unsupported number of bytes in `long' type!" +#endif + + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#define TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/debugger/Makefile b/lib/arch/debugger/Makefile new file mode 100644 index 0000000..6da004b --- /dev/null +++ b/lib/arch/debugger/Makefile @@ -0,0 +1,96 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2 or under +# Unix with extra debugging capabilities. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/debugger/Makefile + +ARCH = arch/debugger +FT_MAKEFILE = $(ARCH)/Makefile + +CC = gcc + +#CFLAGS = -W -Wall -O0 -g -ansi -pedantic -I$(ARCH) -I. -Iextend + +CFLAGS = -Wall -O0 -g -ansi -I$(ARCH) -I. -Iextend + +#CFLAGS = -Wall -ansi -pedantic -O2 -s -I$(ARCH) -I. -Iextend + +# Detect OS/2 to add the flag -DOS2 when compiling ttinterp.c +# +ifdef OS2_SHELL +OS := OS2 +RM := del +else +OS := UNIX # Unix build otherwise +RM := rm -f +endif + +TTFILE = ./ttfile.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxopen.c \ + extend/ftxgdef.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + +# We place the library file in the ARCH directory, so that it doesn't +# interfere with the normal build. +# +LIBTTF_A = $(ARCH)/libttf.a + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< -D$(OS) + +.PHONY: all debug clean distclean depend + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S $(LIBTTF_A) + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M $(LIBTTF_A) + +$(OBJ_S): $(SRC_S) $(SRC_M) + +$(LIBTTF_A): $($(LIB_FILES)) + -$(RM) $@ + ar src $@ $^ + +clean: +ifdef OS2_SHELL + -$(RM) $(subst /,\,$(LIBTTF_A)) + -$(RM) $(subst /,\,$(OBJS_S)) +else + -$(RM) $(LIBTTF_A) + -$(RM) $(OBJS_S) +endif + +distclean: clean + -$(RM) dep.end + +depend: $(SRC_S) $(SRC_M) $(SRC_X) + $(CC) $(CFLAGS) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile diff --git a/lib/arch/debugger/freetype.c b/lib/arch/debugger/freetype.c new file mode 100644 index 0000000..b431cdf --- /dev/null +++ b/lib/arch/debugger/freetype.c @@ -0,0 +1,32 @@ +/* This file is part of the FreeType project */ + +/* Single file library component for the debugging target */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "ttfile.c" +#include "ttmemory.c" +#include "ttmutex.c" + +/* the extensions are compiled separately, but we need to */ +/* include the file ttextend.c if we want to support them */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + +/* END */ diff --git a/lib/arch/debugger/ft_conf.h b/lib/arch/debugger/ft_conf.h new file mode 100644 index 0000000..061b378 --- /dev/null +++ b/lib/arch/debugger/ft_conf.h @@ -0,0 +1,236 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for a debugging build */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. Unix-specific */ +#undef HAVE_FCNTL_H + +/* command.com can't pipe stderr into a file; any message would be */ +/* written into the graphics screen. */ +#define HAVE_PRINT_FUNCTION 1 + +#define Print( format, ap ) vfprintf( stdout, (format), (ap) ) + + +/* The number of bytes in a int. We use the ANSI header file limits.h */ +/* for determining it since there is no easy way to guess. */ +/* */ +#include +#if UINT_MAX == 0xFFFF +#define SIZEOF_INT 2 +#elif UINT_MAX == 0xFFFFFFFF +#define SIZEOF_INT 4 +#else +#error "Unsupported number of bytes in `int' type!" +#endif + +/* We now try to guess the size of longs in the same way */ +/* */ +#if ULONG_MAX == 0xFFFFFFFF +#define SIZEOF_LONG 4 +#elif ULONG_MAX == 0xFFFFFFFFFFFFFFFF +#define SIZEOF_LONG 8 +#else +#error "Unsupported number of bytes in `long' type!" +#endif + + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ +/* */ +/* For debugging, we use a jump table; this allows some interesting */ +/* things during development. */ + +#undef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a `static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine. */ +/* */ +/* We use a static interpreter in the debugger; this helps in setting */ +/* data breakpoints to fixed memory addresses. */ + +#define TT_CONFIG_OPTION_STATIC_INTERPRETER + +/* an extra for the debugger */ +#define DEBUG_INTERPRETER + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ + +#define TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode. */ +/* Set to DEBUG_LEVEL_TRACE for the debugger. */ +#define DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/mac/README b/lib/arch/mac/README new file mode 100644 index 0000000..8033486 --- /dev/null +++ b/lib/arch/mac/README @@ -0,0 +1,47 @@ + +This is the readme of the freetype.hqx archive in the contrib/mac +subdirectory. Please note that the FreeType team does *not* support the +Macintosh platform due to lack of knowledge. All questions regarding the +code should be sent to both David Williss and the freetype-devel list. + + +---------------------------------------------------------------------------- + + +These are CodeWarrior projects for building the FreeType library on a Macintosh +I've only provided PPC projects here, but building for 68K shouldn't be hard. +There are two directories here (OK, "folders"). One contains a project for +building freetype.ppc.lib and the other is for freetype.ppc.dll. (I havn't +actually tested the DLL yet.) + +The Macintosh stores TrueType fonts in a "Fonts" folder under the "System" +folder. There is a standard MacOS API for finding this folder, so I use it. +However, the fonts aren't normal flat files. They have all the data in +resources in the resource fork. Each font is an 'sfnt' resource, and each +file can have more than one 'sfnt' resource. + +To get at them, I made a copy of ttmmap.c from the Unix implementation and +modified it to load/release the resource and lock/unlock the handle as needed. +This only required a change to the open and close functions. After that, it +works just as if it was using Unix memory mapping. + +One thing however. Because of the bizarre scheme for storing the fonts, I +made up a way of specifying the font filename. + + fonts:/fontfile/fontname + +Where fonts:/ is a literal string that means "the fonts folder", fontfile is +the name of the actual file and fontname is the name of the 'sfnt' resource. +Currently, this is the only thing it understands. It might be nice if some +day (2.0 maybe?) ttfile.c and ttmmap.c wern't mutialy exclusive and it could +decide which method to use based on the filename or something. + +Another thing that I had to change to make this work. It seems that Macintosh +TrueType fonts have no OS/2 table, so ttload.c needs to be modified to make +that nonfatal, at least on a Macintosh. + +--- + +David Williss +MicroImages, Inc. +dwilliss@microimages.com diff --git a/lib/arch/mac/freetype.c b/lib/arch/mac/freetype.c new file mode 100644 index 0000000..5db4438 --- /dev/null +++ b/lib/arch/mac/freetype.c @@ -0,0 +1,48 @@ +/* This file is *not* part of the FreeType project, because the team */ +/* lacks the necessary expertise to support it. */ + +/* freetype.c for MacOS */ +/* single object library component for MacOS */ + +/* Written by Dave Willis on 1998-07-30. */ +/* Modified by Antoine Leca for the 1.3 release, but untested. */ + +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* Note, you should define the EXPORT_DEF and EXPORT_FUNC macros here */ +/* if you want to build a DLL. If undefined, the macros are defined */ +/* as "export" and "" (i.e. nothing), which is the normal behaviour. */ +/* The macros are placed before each high-level API function */ +/* declaration. You can then use them to take any compiler-specific */ +/* pragma for DLL-exported symbols. See 'ttconfig.h' for details. */ + + +/* first include common core components */ + +#define MAC_MAIN_OBJECT +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "ttmmap.c" /* Was "ttfile.c" */ +#include "ttmemory.c" +#include "ttmutex.c" + +/* finally, add some extensions */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/mac/ft_conf.h b/lib/arch/mac/ft_conf.h new file mode 100644 index 0000000..4043ae5 --- /dev/null +++ b/lib/arch/mac/ft_conf.h @@ -0,0 +1,211 @@ +/* This file is *not* part of the FreeType project, because the team */ +/* lacks the necessary expertise to support it. */ + +/* ft_conf.h for MacOS */ + +/* Written by Dave Willis on 1998-07-30. */ +/* Modified by Antoine Leca for the 1.3 release, but untested. */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the 'const' keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/mac/ttmmap.c b/lib/arch/mac/ttmmap.c new file mode 100644 index 0000000..3a7a917 --- /dev/null +++ b/lib/arch/mac/ttmmap.c @@ -0,0 +1,1069 @@ +/******************************************************************* + * + * ttmmap.c 2.0 + * + * Memory-Mapped file component ( replaces ttfile.c ). + * + * Copyright 1996-1998 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 2.0 and 1.3 : + * + * - adopted new design/separation introduced in ttfile.c 2.0 + * + ******************************************************************/ + +#include "ttconfig.h" + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include +#include + + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttmemory.h" +#include "ttfile.h" /* our prototypes */ + + /* This definition is mandatory for each file component! */ + EXPORT_FUNC + const TFileFrame TT_Null_FileFrame = { NULL, 0, 0 }; + + /* It has proven useful to do some bounds checks during */ + /* development phase. Define DEBUG_FILE when compiling */ + /* this component to enable them. */ + +#ifdef DEBUG_FILE +#define CHECK_FRAME( frame, n ) \ + do { \ + if ( frame.cursor+n > frame.address + frame.size ) \ + Panic( "Frame boundary error!\n" ); \ + } while ( 0 ) +#else +#define CHECK_FRAME( frame, n ) \ + do { \ + } while( 0 ) +#endif + + struct _TFileMap + { + String* base; /* base address of mapped file */ + Int refcount; /* reference count for handle region */ + Long size; /* stream size in file */ + Long offset; /* offset in file */ + Handle handle; /* Macintosh style handle to lock/unlock */ + short resid; /* Id of resource file to close when done */ + }; + + typedef struct _TFileMap TFileMap; + +#define MAP_Address( map ) (Byte*)( (map)->base + (map)->offset ) + + /* The stream record structure */ + typedef struct _TStream_Rec + { + TFileMap* map; /* mapped file description */ + Long pos ; /* cursor in mapped file */ + } TStream_Rec; + + typedef TStream_Rec* PStream_Rec; + +#define STREAM2REC( x ) ( (TStream_Rec*)HANDLE_Val( x ) ) + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /**** ****/ + /**** N O N R E E N T R A N T I M P L E M E N T A T I O N ****/ + /**** ****/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* The TFile_Component structure holds all the data that was */ + /* previously declared static or global in this component. */ + /* */ + /* It is accessible through the 'engine.file_component' */ + /* variable in re-entrant builds, or directly through the */ + /* static 'files' variable in other builds. */ + + struct _TFile_Component + { + TMutex lock; /* used by the thread-safe build only */ + PStream_Rec stream; /* current stream */ + TFileFrame frame; /* current frame */ + }; + + typedef struct _TFile_Component TFile_Component; + +/* The macro CUR_Stream denotes the current input stream */ +/* Note that for the re-entrant version, the 'stream' name has been */ +/* chosen according to the macro STREAM_ARGS. */ + +/* The macro CUR_Frame denotes the current file frame */ +/* Note that for the re-entrant version, the 'frame' name has been */ +/* chosen according to the macro FRAME_ARGS. */ + +/* The macro STREAM_VAR is used when calling public functions */ +/* that need an 'optional' stream argument. */ + +#define CUR_Stream files.stream /* thread-safe macros */ +#define CUR_Frame files.frame + +#define STREAM_VARS /* void */ +#define STREAM_VAR /* void */ + + /* the 'files' variable is only defined in non-reentrant builds */ + + static TFile_Component files; + + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + MUTEX_Create( files.lock ); + files.stream = NULL; + ZERO_Frame( files.frame ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + MUTEX_Destroy( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ) + { + MUTEX_Lock( files.lock ); + *stream = org_stream; + files.stream = STREAM2REC( org_stream ); /* set current stream */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream + * + * Output : Error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + HANDLE_Set( *stream, NULL ); + MUTEX_Release( files.lock ); + + return TT_Err_Ok; + } + +#else /* TT_CONFIG_OPTION_THREAD_SAFE */ + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /******** ********/ + /******** R E E N T R A N T I M P L E M E N T A T I O N ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +#define CUR_Stream STREAM2REC( stream ) /* re-entrant macros */ +#define CUR_Frame (*frame) + +#define STREAM_VARS stream, +#define STREAM_VAR stream + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + engine.file_component = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code. The output stream is set to NULL in + * case of Failure. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + TT_Error error; + PStream_Rec stream_rec; + PStream_Rec copy_rec; + + + stream_rec = STREAM2REC( input_stream ); + + if ( ALLOC( copy_rec, sizeof ( TStream_Rec ) ) ) + goto Fail; + + HANDLE_Set( *copy, copy_rec ); + + copy_rec->map->refcount++; + copy_rec->pos = 0; + + return TT_Err_Ok; + + Fail: + HANDLE_Set( *copy, NULL ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /*********** ***********/ + /*********** C O M M O N I M P L E M E N T A T I O N ***********/ + /*********** ***********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/******************************************************************* + * + * Function : AllocateMap + * + * Description : Allocates a new map from the table. + * + * Output : Pointer to new stream rec. NULL in case of failure. + * + ******************************************************************/ + + static + TFileMap* Allocate_Map( void ) + { + TFileMap* result; + + + if ( MEM_Alloc( result, sizeof ( TFileMap ) ) ) + return NULL; + + result->refcount = 1; + return result; + } + + +/******************************************************************* + * + * Function : ReleaseMap + * + * Description : Releases a used map to the table if reference i + * counter reaches zero. + * + * Input : map + * + * Output : None. + * + * Note : Called by TT_Close_File() + * + ******************************************************************/ + + static + void Release_Map ( TFileMap* map ) + { + map->refcount--; + if ( map->refcount <= 0 ) + { + /* MacOS System calls */ + HUnlock(map->handle); + ReleaseResource(map->handle); + CloseResFile(map->resid); + + FREE( map ); + } + } + + +/* Whadda ya mean "strdup undefined"? Fine, I'll define my own! */ +static char *mystrdup(const char *str) { + char *ret; + + if ( TT_Alloc(strlen(str) + 1, (void**)&ret) != 0 ) return(NULL); + strcpy(ret, str); + return(ret); + } + +/******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : Opens the font file and saves the total file size. + * + * Input : error address of stream's error variable + * (re-entrant build only). + * filepathname pathname of the file to open + * stream address of target TT_Stream structure + * + * Output : SUCCESS on success, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ +/* +** This is not a totally generic implementation. It currently assumes the filename +** starts with "fonts:" and uses slashes instead of colons like Mac code normally +** would. Given a filename of the form "fonts:/filename/resname", Load the resource +** and lock the handle +** +** The "fonts:" at the beginning is just a convention I came up with to +** indicate the Fonts folder inside the current System folder (find via FindFolder()) +*/ + + LOCAL_FUNC + TT_Error TT_Open_Stream( const String* filepathname, + TT_Stream* stream ) + { + TT_Error error; + Int file; + PStream_Rec stream_rec; + TFileMap* map; + + int size, err = 0; + short vRefNum, res = -1; + Str255 FontName; + char *cp, *p, *fname, *sep; + Str63 myName; + long dirID; + + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + map = Allocate_Map(); + if ( !map ) + { + error = TT_Err_Out_Of_Memory; + goto Memory_Fail; + } + + stream_rec = STREAM2REC( *stream ); + + /* Find the dirID of the Fonts folder in the current System folder */ + if (FindFolder(kOnSystemDisk, kFontsFolderType, kDontCreateFolder, &vRefNum, &dirID)) + goto File_Fail; + + /* Break the name apart */ + fname = mystrdup(filepathname); /* Make a copy so we can muck with it */ + sep = ":/"; /* Things that can seperate file path componants */ + + strtok(fname, sep); /* Skip over "fonts:" */ + + if ((p = strtok(NULL, sep)) == NULL) /* Get filename */ + goto File_Fail; + strcpy(myName + 1, p); /* Make this a Pascal string (Yuck!) */ + myName[0] = strlen(p); + + if ((p = strtok(NULL, sep)) == NULL) /* Get res name */ + goto File_Fail; + strcpy(FontName+1, p); /* Make this a Pascal string (Yuck!) */ + FontName[0] = strlen(p); + + FREE( fname ); + + if ((cp = strchr(FontName, '.')) != NULL) /* Strip off ".ttf" , if any */ + *cp = 0; + + /* Read the font into a buffer */ + if ((map->resid = HOpenResFile(vRefNum, dirID, myName, fsRdPerm)) == -1) + goto File_Fail; + + if ((map->handle = Get1NamedResource('sfnt', FontName)) == NULL) + goto Map_Fail; + + HLock(map->handle); + map->base = *map->handle; + map->offset = 0; + map->size = GetResourceSizeOnDisk(map->handle); + + if ( map->base == NULL ) + goto Lock_Fail; + + stream_rec->map = map; + stream_rec->pos = 0; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Lock_Fail: + ReleaseResource(map->handle); + + Map_Fail: + CloseResFile(map->resid); + + File_Fail: + error = TT_Err_Could_Not_Open_File; + FREE( map ); + + Memory_Fail: + FREE( *stream ); + FREE( fname ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream + * + * Output : SUCCESS (always) + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Release_Map( rec->map ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Stream( TT_Stream* stream ) + { + /* XXX - DUMMY IMPLEMENTATION */ + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : Length of stream in bytes. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->map->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Seek_File( STREAM_ARGS Long position ) + { + if ( position > CUR_Stream->map->size ) + return TT_Err_Invalid_File_Offset; + + CUR_Stream->pos = position; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Skip_File( STREAM_ARGS Long distance ) + { + return TT_Seek_File( STREAM_VARS CUR_Stream->pos + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_File( STREAM_ARGS void* buffer, Long count ) + { + if ( CUR_Stream->pos + count > CUR_Stream->map->size ) + return TT_Err_Invalid_File_Read; + + MEM_Copy( buffer, + MAP_Address( CUR_Stream->map ) + CUR_Stream->pos, count ); + CUR_Stream->pos += count; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ) + { + TT_Error error; + + + if ( (error = TT_Seek_File( STREAM_VARS position )) || + (error = TT_Read_File( STREAM_VARS buffer, count )) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : current file position + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_File_Pos( STREAM_ARG ) + { + return CUR_Stream->pos; + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : Error code + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that aSize is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Stream->pos + size > CUR_Stream->map->size ) + return TT_Err_Invalid_Frame_Access; + + CUR_Frame.size = size; + CUR_Frame.address = MAP_Address( CUR_Stream->map ) + CUR_Stream->pos; + CUR_Frame.cursor = CUR_Frame.address; + + CUR_Stream->pos += size; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : Error code + * + * Notes: The function truncates 'size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that aSize is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. The 'overflow' is set to zero. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + readBytes = CUR_Stream->map->size - CUR_Stream->pos; + if ( size > readBytes ) + { + /* There is overflow, we allocate a new block then */ + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + + CUR_Frame.size = size; + + /* copy the valid part */ + MEM_Copy( CUR_Frame.address, + MAP_Address( CUR_Stream->map ) + CUR_Stream->pos, + readBytes ); + } + else + { + CUR_Frame.size = size; + CUR_Frame.address = MAP_Address( CUR_Stream->map ) + CUR_Stream->pos; + } + + CUR_Frame.cursor = CUR_Frame.address; + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + /* If we were using a duplicate in case of overflow, free it now */ + if ( CUR_Frame.address < (Byte*)CUR_Stream->map->base || + CUR_Frame.address >= (Byte*)CUR_Stream->map->base + + CUR_Stream->map->size ) + FREE( CUR_Frame.address ); + + ZERO_Frame( files.frame ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + Byte TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } + +#endif + + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Char TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Short TT_Get_Short( FRAME_ARG ) + { + Short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((Short)CUR_Frame.cursor[0] << 8) | + (Short)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + UShort TT_Get_UShort( FRAME_ARG ) + { + UShort getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((UShort)CUR_Frame.cursor[0] << 8) | + (UShort)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + +#endif + + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Get_Long( FRAME_ARG ) + { + Long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((Long)CUR_Frame.cursor[0] << 24) | + ((Long)CUR_Frame.cursor[1] << 16) | + ((Long)CUR_Frame.cursor[2] << 8 ) | + (Long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None + * + * Output : Extracted ulong + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + ULong TT_Get_ULong( FRAME_ARG ) + { + ULong getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((ULong)CUR_Frame.cursor[0] << 24) | + ((ULong)CUR_Frame.cursor[1] << 16) | + ((ULong)CUR_Frame.cursor[2] << 8 ) | + (ULong)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } + +#endif + + +/* END */ diff --git a/lib/arch/msdos/Makefile.BC b/lib/arch/msdos/Makefile.BC new file mode 100644 index 0000000..ba5d50b --- /dev/null +++ b/lib/arch/msdos/Makefile.BC @@ -0,0 +1,132 @@ +# This file is part of the FreeType project. +# +# It builds the library for Borland C++ for MS-DOS, large model. +# Due to size constraints, it does not try to pack all modules into one +# (`single-object mode'). +# +# You will need Borland MAKE. +# Tested with Borland C++ v.3.1, 4.02, 5.0. +# +# Use this file while in the lib directory with the following statement: +# +# make -farch/msdos/Makefile.BC +# +# +# A debug version can be obtained with +# +# make -DDEBUG -farch/msdos/Makefile.BC +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# make -DBIGFONTS -farch/msdos/Makefile.BC + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.BC + +CC = bcc +LIB = tlib /c /e + +# Credits go to Dave Hoo for pointing out that modern +# Borland compilers (from BC++ 3.1 on) can increase the limit on +# the length of identifiers. +!if ! $d(DEBUG) +CFLAGS = -ml -A -O2 -3 -i40 -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -I$(ARCH);.;extend +!else +CFLAGS = -v -N -ml -A -i40 -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -I$(ARCH);.;extend +!endif + + +!if $d(BIGFONTS) +CFLAGS = $(CFLAGS) -DTT_HUGE_PTR=__huge + +TTFILE = $(ARCH)\.\hugefile.c +TTMEMORY = $(ARCH)\.\hugemem.c +!else +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +!endif +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces before the \ at end of line, +# otherwise the substitution for TLIB command line will fail. +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ + extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c\ + extend\ftxsbit.c extend\ftxgsub.c extend\ftxgpos.c\ + extend\ftxopen.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c\ + ttgload.c ttinterp.c ttload.c ttobjs.c\ + ttraster.c ttextend.c ttdebug.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\.\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Borland's make does not handle $($(LIB_FILES)), and using +# -DLIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing TLIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# It is commented out below. See Makefile.TC for an application. +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| +# $(LIB) libttf +-$*.obj + + +!if !$d(DEBUG) +# Skipped if DEBUG build +# (but it changes nothing, since we always build in multiple parts). +all: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| + +!endif + + +debug: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| + +$(OBJ_S): $(SRC_S) $(SRC_M) + +# Not used here because it excesses the capacity of COMMAND.COM... +libttf.lib: $(LIB_FILES) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(**: = + ) +| + +!if $d(BIGFONTS) +$(TTMEMORY:.c=.obj): $(TTMEMORY) + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| +!endif + + +clean: + -del *.obj + -del extend\*.obj + -del $(ARCH)\*.obj + -del libttf.bak + -del response + +distclean: clean + -del libttf.lib + +!include "$(ARCH)\depend.dos" + +# end of Makefile diff --git a/lib/arch/msdos/Makefile.MS b/lib/arch/msdos/Makefile.MS new file mode 100644 index 0000000..3c793fa --- /dev/null +++ b/lib/arch/msdos/Makefile.MS @@ -0,0 +1,117 @@ +# This file is part of the FreeType project. +# +# It builds the library for Microsoft C for MS-DOS, large model. +# It also works for Visual C++ 1.x 16-bits compiler, but you should +# instead use the Makefile customized for it, Makefile.VC. +# Due to size constraints, it does not try to pack all modules into one. +# +# You will need NMAKE. +# +# Use this file while in the lib directory with the following statement: +# +# nmake /f arch\msdos\Makefile.MS +# +# +# A debug version can be obtained with +# +# nmake DEBUG=1 /f arch\msdos\Makefile.MS +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# nmake BIGFONTS=1 /f arch\msdos\Makefile.MS + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.MS + +CC = cl /nologo +LIB = lib /noignorecase /nologo + +!ifndef DEBUG +CFLAGS = /Ox /AL /W2 /G2 /I$(ARCH) /I. /Iextend +!else +CFLAGS = /Zi /AL /W2 /G2 /I$(ARCH) /I. /Iextend +!endif + + +!ifndef BIGFONTS +CFLAGS = $(CFLAGS) /Za + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +!else +CFLAGS = $(CFLAGS) /DTT_HUGE_PTR=__huge /Ze + +TTFILE = $(ARCH)\hugefile.c +TTMEMORY = $(ARCH)\hugemem.c +!endif + +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces between the file names or at end of line, otherwise +# the substitution for LIB command line will fail. Thank you. +# +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ +extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c extend\ftxsbit.c\ +extend\ftxopen.c extend\ftxgsub.c extend\ftxgpos.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c\ +ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Microsoft's NMAKE does not handle $($(LIB_FILES)), and using +# LIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing LIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# It is commented out below. See Makefile.TC for an application. +.c.obj: + @$(CC) /c /Fo$@ @<< + $(CFLAGS) $*.c +<< +# $(LIB) libttf +-$*.obj + + +!ifndef DEBUG +# Skipped if DEBUG build +# (but it changes nothing, since we always build in multiple parts). +all: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @<&| + +CC = gcc + +CFLAGS = -Wall -O2 -g -ansi -pedantic -I$(ARCH) -I. -Iextend +# CFLAGS = -Wall -ansi -O2 -s -I$(ARCH) -I. -Iextend + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxopen.c \ + extend/ftxgdef.c extend/ftxerr18.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttfile.c ttgload.c ttinterp.c ttload.c \ + ttmemory.c ttmutex.c ttobjs.c ttraster.c ttextend.c +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M libttf.a + + +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) $(CFLAGS) -c -o $@ $(SRC_S) + +libttf.a: $($(LIB_FILES)) + +-del $@ + ar src $@ @$(mktmp $(<:t"\n")\n) + +clean: +-[ + del *.o + del extend\*.o + del $(ARCH)\*.o +] + +distclean: clean +-[ + del dep.end + del libttf.a +] + +# depend: $(SRC_S) $(SRC_M) $(SRC_X) +# $(CC) -E -M @$(mktmp $(<:t"\n")\n) > dep.end + +# ifeq (dep.end,$(wildcard dep.end)) +# include dep.end +# endif + +# end of Makefile.dm diff --git a/lib/arch/msdos/Makefile.gcc b/lib/arch/msdos/Makefile.gcc new file mode 100644 index 0000000..3325538 --- /dev/null +++ b/lib/arch/msdos/Makefile.gcc @@ -0,0 +1,92 @@ +# This file is part of the FreeType project. +# +# It builds the library for emx-gcc or djgpp under MSDOS. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/msdos/Makefile.gcc +# +# If you have the GNU gettext package installed with DJGPP, you can also try +# +# make -f arch/msdos/Makefile.gcc HAVE_GETTEXT + +ARCH = arch/msdos +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +ifndef GETTEXT +GETTEXT=NO_GETTEXT +endif + +ifdef DEBUG +CFLAGS = -Wall -O2 -g -ansi -pedantic -I$(ARCH) -I. -Iextend -D$(GETTEXT) +else +CFLAGS = -Wall -ansi -pedantic -O2 -s -I$(ARCH) -I. -Iextend -D$(GETTEXT) +endif + + +TTFILE = ./ttfile.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxgdef.c \ + extend/ftxopen.c extend/ftxerr18.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M DEBUG=1 libttf.a + +HAVE_GETTEXT: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S GETTEXT=HAVE_GETTEXT \ + libttf.a + +$(OBJ_S): $(SRC_S) $(SRC_M) + +libttf.a: $($(LIB_FILES)) + -del $@ + ar src $@ $^ + +clean: + -del *.o + -del extend\*.o + -del $(ARCH)\*.o + -del response + +distclean: clean + -del dep.end + -del libttf.a + +depend: $(SRS_S) $(SRC_M) $(SRC_X) + $(CC) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/lib/arch/msdos/Makefile.wat b/lib/arch/msdos/Makefile.wat new file mode 100644 index 0000000..e2df1e3 --- /dev/null +++ b/lib/arch/msdos/Makefile.wat @@ -0,0 +1,88 @@ +# This file is part of the FreeType project +# +# This builds the Watcom library with Watcom's wcc386 under DOS +# +# You'll need Watcom's wmake +# +# +# Invoke by "wmake -f arch\msdos\Makefile.wat" while in the "lib" directory +# +# This will build "freetype\lib\libttf.lib" +# + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.wat +FT_MAKE = wmake -h + + +.EXTENSIONS: +.EXTENSIONS: .lib .obj .c .h +.obj:.;.\extend;.\$(ARCH) +.c:.;.\extend;.\$(ARCH) +.h:.;.\extend;.\$(ARCH) + +CC = wcc386 + +CCFLAGS = /otexanl+ /s /w4 /zq /d3 -I$(ARCH) -I. -Iextend + + +# FIXME: should use something like OBJ = $(SRC:.c=.obj) + +SRC_X = ftxgasp.c ftxkern.c ftxpost.c & + ftxcmap.c ftxwidth.c ftxsbit.c ftxerr18.c & + ftxgsub.c ftxgpos.c ftxopen.c ftxgdef.c +OBJS_X = ftxgasp.obj ftxkern.obj ftxpost.obj & + ftxcmap.obj ftxwidth.obj ftxsbit.obj ftxerr18.obj & + ftxgsub.obj ftxgpos.obj ftxopen.obj ftxgdef.obj + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c & + ttfile.c ttgload.c ttinterp.c & + ttload.c ttmemory.c ttmutex.c ttobjs.c ttraster.c & + ttextend.c +OBJS_M = ttapi.obj ttcache.obj ttcalc.obj ttcmap.obj ttdebug.obj & + ttfile.obj ttgload.obj ttinterp.obj & + ttload.obj ttmemory.obj ttmutex.obj ttobjs.obj ttraster.obj & + ttextend.obj $(OBJS_X) + +SRC_S = freetype.c +OBJ_S = freetype.obj +OBJS_S = $(OBJ_S) $(OBJ_X) + + +.c.obj: + $(CC) $(CCFLAGS) $[* /fo=$[*.obj + +libname = libttf +libfile = $(libname).lib +cmdfile = $(libname).lst + + +all: .symbolic + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S $(libfile) + +debug: .symbolic + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M $(libfile) + + +$(libfile): $($(LIB_FILES)) + wlib -q -n $(libfile) @$(cmdfile) + +# is this correct? Know nothing about wmake and the Watcom compiler... +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) $(CCFLAGS) $(SRC_S) /fo=$(OBJ_S) + +$(cmdfile): $($(LIB_FILES)) + @for %i in ($($(LIB_FILES))) do @%append $(cmdfile) +-%i + +clean: .symbolic + @-erase $(OBJ_S) + @-erase $(OBJS_M) + @-erase $(cmdfile) + +distclean: .symbolic clean + @-erase $(libfile) + +new: .symbolic + @-wtouch *.c + +# end of Makefile.wat diff --git a/lib/arch/msdos/depend.dos b/lib/arch/msdos/depend.dos new file mode 100644 index 0000000..0175c97 --- /dev/null +++ b/lib/arch/msdos/depend.dos @@ -0,0 +1,107 @@ +# This dependency file to be used with various MS-DOS compilers +# has been generated automatically with the script `makedep' on +# 03-Sep-1999. + +ttapi.obj: ttapi.c ttconfig.h arch\msdos\ft_conf.h freetype.h fterrid.h \ + ftnameid.h ttengine.h tttypes.h ttmutex.h ttcalc.h ttmemory.h \ + ttcache.h ttfile.h ttdebug.h ttobjs.h tttables.h ttcmap.h ttload.h \ + ttgload.h ttraster.h ttextend.h +ttcache.obj: ttcache.c ttengine.h tttypes.h ttconfig.h \ + arch\msdos\ft_conf.h freetype.h fterrid.h ftnameid.h ttmutex.h \ + ttmemory.h ttcache.h ttobjs.h tttables.h ttcmap.h ttdebug.h +ttcalc.obj: ttcalc.c ttcalc.h ttconfig.h arch\msdos\ft_conf.h freetype.h \ + fterrid.h ftnameid.h ttdebug.h tttypes.h tttables.h +ttcmap.obj: ttcmap.c ttobjs.h ttconfig.h arch\msdos\ft_conf.h ttengine.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmutex.h ttcache.h \ + tttables.h ttcmap.h ttdebug.h ttfile.h ttmemory.h ttload.h +ttdebug.obj: ttdebug.c ttdebug.h ttconfig.h arch\msdos\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h tttables.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h ttcmap.h +ttextend.obj: ttextend.c ttextend.h ttconfig.h arch\msdos\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttmemory.h +ttfile.obj: ttfile.c ttconfig.h arch\msdos\ft_conf.h freetype.h \ + fterrid.h ftnameid.h tttypes.h ttdebug.h ttengine.h ttmutex.h \ + ttmemory.h ttfile.h +ttgload.obj: ttgload.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttdebug.h ttcalc.h ttfile.h \ + ttengine.h ttmutex.h tttables.h ttobjs.h ttcache.h ttcmap.h ttgload.h \ + ttmemory.h tttags.h ttload.h +ttinterp.obj: ttinterp.c freetype.h fterrid.h ftnameid.h tttypes.h \ + ttconfig.h arch\msdos\ft_conf.h ttdebug.h ttcalc.h ttmemory.h \ + ttinterp.h ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h \ + ttcmap.h +ttload.obj: ttload.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttdebug.h ttcalc.h ttfile.h \ + ttengine.h ttmutex.h tttables.h ttobjs.h ttcache.h ttcmap.h \ + ttmemory.h tttags.h ttload.h +ttmemory.obj: ttmemory.c ttdebug.h ttconfig.h arch\msdos\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmemory.h ttengine.h \ + ttmutex.h +ttmutex.obj: ttmutex.c ttmutex.h ttconfig.h arch\msdos\ft_conf.h +ttobjs.obj: ttobjs.c ttobjs.h ttconfig.h arch\msdos\ft_conf.h ttengine.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmutex.h ttcache.h \ + tttables.h ttcmap.h ttfile.h ttdebug.h ttcalc.h ttmemory.h ttload.h \ + ttinterp.h ttextend.h +ttraster.obj: ttraster.c ttraster.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttengine.h tttypes.h ttmutex.h \ + ttdebug.h ttcalc.h ttmemory.h +extend\ftxcmap.obj: extend\ftxcmap.c extend\ftxcmap.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\msdos\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h +extend\ftxerr18.obj: extend\ftxerr18.c ttconfig.h arch\msdos\ft_conf.h \ + extend\ftxerr18.h freetype.h fterrid.h ftnameid.h extend\ftxkern.h \ + extend\ftxpost.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h +extend\ftxgasp.obj: extend\ftxgasp.c extend\ftxgasp.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\msdos\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h +extend\ftxgdef.obj: extend\ftxgdef.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxgpos.obj: extend\ftxgpos.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxgsub.obj: extend\ftxgsub.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxkern.obj: extend\ftxkern.c extend\ftxkern.h freetype.h fterrid.h \ + ftnameid.h ttextend.h ttconfig.h arch\msdos\ft_conf.h tttypes.h \ + ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttdebug.h \ + ttmemory.h ttfile.h ttload.h tttags.h +extend\ftxopen.obj: extend\ftxopen.c tttypes.h ttconfig.h arch\msdos\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxpost.obj: extend\ftxpost.c extend\ftxpost.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\msdos\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttload.h ttfile.h \ + ttdebug.h tttags.h ttmemory.h ttextend.h +extend\ftxsbit.obj: extend\ftxsbit.c extend\ftxsbit.h freetype.h fterrid.h \ + ftnameid.h ttobjs.h ttconfig.h arch\msdos\ft_conf.h ttengine.h \ + tttypes.h ttmutex.h ttcache.h tttables.h ttcmap.h ttfile.h ttdebug.h \ + ttload.h ttmemory.h tttags.h ttextend.h +extend\ftxwidth.obj: extend\ftxwidth.c extend\ftxwidth.h freetype.h fterrid.h \ + ftnameid.h ttdebug.h ttconfig.h arch\msdos\ft_conf.h tttypes.h \ + ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttfile.h \ + tttags.h ttload.h +arch\msdos\freetype.obj: arch\msdos\freetype.c ttapi.c ttconfig.h \ + arch\msdos\ft_conf.h freetype.h fterrid.h ftnameid.h ttengine.h \ + tttypes.h ttmutex.h ttcalc.h ttmemory.h ttcache.h ttfile.h ttdebug.h \ + ttobjs.h tttables.h ttcmap.h ttload.h ttgload.h ttraster.h ttextend.h \ + ttcache.c ttcalc.c ttcmap.c ttdebug.c ttgload.c tttags.h ttinterp.c \ + ttinterp.h ttload.c ttobjs.c ttraster.c arch\msdos\hugefile.c \ + ttfile.c arch\msdos\hugemem.c ttmutex.c ttextend.c +arch\msdos\hugefile.obj: arch\msdos\hugefile.c ttconfig.h arch\msdos\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttfile.c ttdebug.h \ + ttengine.h ttmutex.h ttmemory.h ttfile.h +arch\msdos\hugemem.obj: arch\msdos\hugemem.c ttdebug.h ttconfig.h \ + arch\msdos\ft_conf.h tttypes.h freetype.h fterrid.h ftnameid.h \ + ttmemory.h ttengine.h ttmutex.h diff --git a/lib/arch/msdos/freetype.c b/lib/arch/msdos/freetype.c new file mode 100644 index 0000000..943d5f2 --- /dev/null +++ b/lib/arch/msdos/freetype.c @@ -0,0 +1,39 @@ +/* This file is part of the FreeType project */ + +/* Single object library component for MSDOS. */ +/* Note that low-optimizing 16-bit compilers (such as Borland ones) can't */ +/* successfully compile this file, because it exceeds 64K of code size. */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#ifdef TT_HUGE_PTR +#include "arch/msdos/hugefile.c" +#include "arch/msdos/hugemem.c" +#else +#include "ttfile.c" +#include "ttmemory.c" +#endif +#include "ttmutex.c" + +/* finally, add some extensions */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/msdos/ft_conf.h b/lib/arch/msdos/ft_conf.h new file mode 100644 index 0000000..0199a5c --- /dev/null +++ b/lib/arch/msdos/ft_conf.h @@ -0,0 +1,253 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for MSDOS */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H + +/* Define if you have the header file. */ +#if defined( __EMX__ ) || defined( __DJGPP__ ) || defined( __GO32__ ) +/* some compilers are known to have ; */ +/* add yours if needed, and report to us the update. */ +#define HAVE_UNISTD_H +#else +/* most MS-DOS compilers lack */ +#undef HAVE_UNISTD_H +#endif + +/* Define if you need for console I/O functions. */ +#ifdef __EMX__ +#define HAVE_CONIO_H +#endif + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define if you have the libintl library. */ +#undef HAVE_LIBINTL + +/* DJGPP v.2 may feature the GNU gettext package, with some subtleties. */ +/* The macro HAVE_GETTEXT has to be set in the makefile. */ +#ifdef HAVE_GETTEXT +#define HAVE_LOCALE_H +#define HAVE_LIBINTL_H +#define HAVE_LIBINTL +#define LOCALEDIR "/usr/djgpp/share/locale" +/* Due to a name conflict, gettext is renamed gettext__ in DJGPP */ +#define gettext( str ) gettext__( str ) +#endif + +/* command.com can't pipe stderr into a file; any message would be */ +/* written into the graphics screen. */ +#define HAVE_PRINT_FUNCTION 1 + +#define Print( format, ap ) vfprintf( stdout, (format), (ap) ) + +/* The number of bytes in a int. We use the ANSI header file limits.h */ +/* for determining it since there is no easy way to guess. */ +#include +#if UINT_MAX == 0xFFFF +#define SIZEOF_INT 2 +#elif UINT_MAX == 0xFFFFFFFF +#define SIZEOF_INT 4 +#else +#error "Unsupported number of bytes in `int' type!" +#endif + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/msdos/hugefile.c b/lib/arch/msdos/hugefile.c new file mode 100644 index 0000000..901e0d6 --- /dev/null +++ b/lib/arch/msdos/hugefile.c @@ -0,0 +1,84 @@ +/******************************************************************* + * + * hugefile.c + * + * File I/O Component (body) for dealing with "huge" objects under + * MS-DOS. Relies on the "default" version, with a small hook. + * + * Written by Antoine Leca based on ideas from Dave Hoo. + * Copyright 1999 by Dave Hoo, Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTE + * + * This file #includes the normal version, to avoid discrepancies + * between versions. It uses only ANSI-mandated "tricks", so + * any ANSI-compliant compiler should be able to compile this file. + * + ******************************************************************/ + +#include "ttconfig.h" +#include "tttypes.h" + +/* Here we include , to have the proper definition of fread */ +#include + +/* Then, we divert the use of fread to our version */ +#undef fread +#define fread(ptr, size, n, stream) huge_fread(ptr, size, n, stream) + + LOCAL_FUNC + Long huge_fread ( void *ptr, size_t size, Long n, FILE *stream ); + +/* Now, we include the "normal" version of ttfile.c */ +/* The ANSI/ISO standard mandates that the include of */ +/* there have no bad effects. */ +#include "ttfile.c" + +/* Then, we define our implementation of fread that makes use of */ +/* "huge"-allocated memory. */ + +/******************************************************************* + * + * Function : huge_fread + * + * Description : replacement version of fread that handles + * "huge"-allocated memory. + * + * Input : See the reference for the runtime library function fread + * + * Output : See the reference for the runtime library function fread + * + * Notes : + * + ******************************************************************/ + + LOCAL_DEF + Long huge_fread ( void *ptr, size_t size, Long n, FILE *stream ) + { + char TT_HUGE_PTR * p = (char TT_HUGE_PTR *) ptr; + ULong left = (ULong)n * size; + size_t toRead; + + while ( left ) + { + toRead = (left > 0x8000) ? 0x8000 : left; + if ( (fread)( p, 1, toRead, stream ) != toRead) + return -1; + else + { + left -= (ULong) toRead; + p += toRead; + } + } + return n * size; + } + + +/* END */ diff --git a/lib/arch/msdos/hugemem.c b/lib/arch/msdos/hugemem.c new file mode 100644 index 0000000..aa44c69 --- /dev/null +++ b/lib/arch/msdos/hugemem.c @@ -0,0 +1,496 @@ +/******************************************************************* + * + * hugemem.c + * + * Memory management component (body) + * for dealing with "huge" objects with 16-bit MS-DOS. + * + * Written by Dave Hoo and Antoine Leca. + * Copyright 1999 by Dave Hoo, Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +#ifndef TT_HUGE_PTR +#error "This component needs TT_HUGE_PTR to be #defined." +#endif + +/* ---- Microsoft C compilers support ------------------------------------ */ + +#if defined( M_I86 ) || defined( _M_I86 ) + +#include +#define huge_alloc( size ) _halloc ( size, 1 ) +#define huge_free( block ) _hfree ( block ) + +#endif /* Microsoft compilers */ + +/* ---- Borland C compiler support --------------------------------------- */ + +#ifdef __TURBOC__ + +#include +#define huge_alloc( size ) farmalloc ( size ) +#define huge_free( block ) farfree ( block ) + +#endif + +#if !defined( huge_alloc ) || !defined( huge_free ) +#error "Your compiler is not (yet) supported. Check the source file!" +#endif + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE +#error "This component needs static allocation and is not re-entrant." +#endif + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_memory + + +#ifdef DEBUG_MEMORY + +#include + +#define MAX_TRACKED_BLOCKS 1024 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BLOCKS + 1]; + + static Int num_alloc; + static Int num_free; + static Int num_realloc; /* counts only `real' reallocations + (i.e., an existing buffer will be resized + to a value larger than zero */ + + static Int fail_alloc; + static Int fail_realloc; + static Int fail_free; + +#else + + /* We need a tracing stack of the calls to big chunks of memory, */ + /* in order to call the matching version of free(). */ + +#define MAX_TRACKED_BIGCHUNKS 16 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BIGCHUNKS + 1]; + +#endif /* DEBUG_MEMORY */ + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + Long TTMemory_Allocated; + Long TTMemory_MaxAllocated; +#endif + + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE : The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Alloc( ULong Size, void** P ) + { + Int i; + + + if ( !P ) + return TT_Err_Invalid_Argument; + /* Also see below for another case of "invalid argument". */ + + if ( Size > 0 ) + { + if ( Size > ( UINT_MAX & ~0xFu ) ) + *P = (void*)huge_alloc( Size ); + else + *P = (void*)malloc( Size ); + if ( !*P ) + return TT_Err_Out_Of_Memory; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size; + TTMemory_MaxAllocated += Size; +#endif + +#ifdef DEBUG_MEMORY + + num_alloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_alloc++; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + +#else + + if ( Size > ( UINT_MAX & ~0xFu ) ) + { + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BIGCHUNKS ) + /* We fail badly here. Increase MAX_TRACKED_BIGCHUNKS if needed. */ + return TT_Err_Invalid_Argument; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + } + +#endif /* DEBUG_MEMORY */ + + if ( Size > ( UINT_MAX & ~0xFu ) ) + { + char TT_HUGE_PTR * p = (char TT_HUGE_PTR *) *P; + ULong left = (ULong)Size; + size_t toClear; + + while ( left ) + { + toClear = (left > 0xFF00) ? 0xFF00 : left; + MEM_Set( p, 0, toClear ); + left -= (ULong) toClear; + p += toClear; + } + } + else + MEM_Set( *P, 0, Size ); + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + +/******************************************************************* + * + * Function : TT_Realloc + * + * Description : Reallocates memory from the heap buffer. + * + * Input : Size new size of the memory to be allocated; + * if zero, TT_Free() will be called + * P pointer to a buffer pointer; if *P == NULL, + * TT_Alloc() will be called + * + * Output : Error code. + * + * NOTES : It's not necessary to zero the memory in case the + * reallocated buffer is larger than before -- the + * application has to take care of this. + * + * If the memory request fails, TT_Free() will be + * called on *P, and TT_Err_Out_Of_Memory returned. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Realloc( ULong Size, void** P ) + { + void* Q; + +#ifdef DEBUG_MEMORY + Int i; +#endif + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( !*P ) + return TT_Alloc( Size, P ); + + if ( Size == 0 ) + return TT_Free( P ); + + if ( Size > ( UINT_MAX & ~0xFu ) ) + Q = NULL; /* Do not even try to deal with big chunks of memory. */ + else + Q = (void*)realloc( *P, Size ); + if ( !Q ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + +#ifdef DEBUG_MEMORY + + num_realloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_realloc++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size - pointers[i].size; + if ( Size > pointers[i].size ) + TTMemory_MaxAllocated += Size - pointers[i].size; +#endif + + pointers[i].base = Q; + pointers[i].size = Size; + } +#endif /* DEBUG_MEMORY */ + + *P = Q; + + return TT_Err_Ok; + } + + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Free( void** P ) + { + Int i; + Long Size = 0; + + + if ( !P || !*P ) + return TT_Err_Ok; + +#ifdef DEBUG_MEMORY + + num_free++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_free++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated -= pointers[i].size; +#endif + + Size = pointers[i].size; + pointers[i].base = NULL; + pointers[i].size = 0; + } + +#else + + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != *P ) + i++; + + /* If we did not found the pointer, then this is a "small" chunk. */ + + if ( i < MAX_TRACKED_BIGCHUNKS ) + { + Size = pointers[i].size; + pointers[i].base = NULL; + pointers[i].base = NULL; + } + +#endif /* DEBUG_MEMORY */ + + if ( Size > ( UINT_MAX & ~0xFu ) ) + huge_free( *P ); + else + free( *P ); + + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Init( void ) + { +#ifdef DEBUG_MEMORY + Int i; + + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } + + num_alloc = 0; + num_realloc = 0; + num_free = 0; + + fail_alloc = 0; + fail_realloc = 0; + fail_free = 0; +#else + Int i; + + for ( i = 0; i < MAX_TRACKED_BIGCHUNKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } +#endif + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated = 0; + TTMemory_MaxAllocated = 0; +#endif + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Done( void ) + { +#ifdef DEBUG_MEMORY + Int i, num_leaked, tot_leaked; + + + num_leaked = 0; + tot_leaked = 0; + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + num_leaked ++; + tot_leaked += pointers[i].size; + } + } + + fprintf( stderr, + "%d memory allocations, of which %d failed\n", + num_alloc, + fail_alloc ); + + fprintf( stderr, + "%d memory reallocations, of which %d failed\n", + num_realloc, + fail_realloc ); + + fprintf( stderr, + "%d memory frees, of which %d failed\n", + num_free, + fail_free ); + + if ( num_leaked > 0 ) + { + fprintf( stderr, + "There are %d leaked memory blocks, totalizing %d bytes\n", + num_leaked, tot_leaked ); + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + fprintf( stderr, + "index: %4d (base: $%08lx, size: %08ld)\n", + i, + (long)pointers[i].base, + pointers[i].size ); + } + } + } + else + fprintf( stderr, "No memory leaks !\n" ); + +#endif /* DEBUG_MEMORY */ + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/arch/msdos/makedep b/lib/arch/msdos/makedep new file mode 100644 index 0000000..d566ed8 --- /dev/null +++ b/lib/arch/msdos/makedep @@ -0,0 +1,26 @@ +# makedep +# +# This shell script creates a dependency file necessary for older compilers +# on the MS-DOS platform. + +echo "\ +# This dependency file to be used with various MS-DOS compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.dos + +(cd ../.. + gcc -MM -Iarch/msdos -I. *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.dos + +(cd ../.. + gcc -MM -Iarch/msdos -I. -Iextend extend/*.c | \ + sed -e "s/^\(.*\)\.o:/extend\\\\\1.obj:/" -e "s:/:\\\\:g") >> depend.dos + +(cd ../.. + gcc -MM -Iarch/msdos -I. -Iextend \ + -DTT_HUGE_PTR -Dhuge_alloc -Dhuge_free arch/msdos/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\msdos\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.dos + +# eof diff --git a/lib/arch/os2/Makefile.dm b/lib/arch/os2/Makefile.dm new file mode 100644 index 0000000..a5c18f7 --- /dev/null +++ b/lib/arch/os2/Makefile.dm @@ -0,0 +1,84 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2 +# +# You will need dmake. +# +# Use this file while in the lib directory with the following statement: +# +# dmake -r -f arch/os2/Makefile.dm + +ARCH = arch/os2 +FT_MAKEFILE = $(ARCH)/Makefile.dm +FT_MAKE = dmake -r + +.IMPORT: COMSPEC +SHELL := $(COMSPEC) +SHELLFLAGS := /c +GROUPSHELL := $(SHELL) +GROUPFLAGS := $(SHELLFLAGS) +GROUPSUFFIX := .cmd +SHELLMETAS := *"?<>&| + +CC = gcc + +CFLAGS = -Wall -O2 -g -ansi -pedantic -I$(ARCH) -I. -Iextend +# CFLAGS = -Wall -ansi -O2 -s -I$(ARCH) -I. -Iextend + +TTFILE = $(ARCH)/os2file.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxopen.c \ + extend/ftxgdef.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M libttf.a + + +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) $(CFLAGS) -c -o $@ $(SRC_S) + + +libttf.a: $($(LIB_FILES)) + +-del $@ + ar src $@ @$(mktmp $(<:t"\n")\n) + +clean: + -+del $(subst,/,\ $($(LIB_FILES))) + +distclean: clean + -+del dep.end libttf.a + +# depend: $(SRC_S) $(SRC_M) $(SRC_X) +# $(CC) -E -M @$(mktmp $(<:t"\n")\n) > dep.end + +# ifeq (dep.end,$(wildcard dep.end)) +# include dep.end +# endif + +# end of Makefile.dm diff --git a/lib/arch/os2/Makefile.emx b/lib/arch/os2/Makefile.emx new file mode 100644 index 0000000..4ba9128 --- /dev/null +++ b/lib/arch/os2/Makefile.emx @@ -0,0 +1,91 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/os2/Makefile.emx + +ARCH = arch/os2 +FT_MAKEFILE = $(ARCH)/Makefile.emx + +CC = gcc + +#CFLAGS = -W -Wall -O0 -g -ansi -pedantic -I$(ARCH) -I. -Iextend + +CFLAGS = -Wall -O3 -fno-inline -fomit-frame-pointer \ + -g -ansi -pedantic -I$(ARCH) -I. -Iextend + +#CFLAGS = -Wall -ansi -pedantic -O2 -s -I$(ARCH) -I. -Iextend + +TTFILE = $(ARCH)/os2file.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxopen.c \ + extend/ftxgdef.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + +SRCD_S = $(ARCH)/freetypd.c +OBJD_S = $(SRCD_S:.c=.o) +OBJDS_S = $(OBJD_S) $(OBJS_X) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M libttf.a + +debugger: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJDS_S libttfd.a + +$(OBJ_S): $(SRC_S) $(SRC_M) +$(OBJD_S): $(SRCD_S) $(SRC_M) + +libttf.a: $($(LIB_FILES)) + -del $@ + ar src $@ $^ + +libttfd.a: $(OBJDS) + +libttfd.a: $(OBJDS) + -del $@ + ar src $@ $^ + +clean: + -del $(subst /,\,$(OBJS_S)) + -del $(subst /,\,$(OBJS_M)) + +distclean: clean + -del dep.end + -del libttf.a + +depend: $(SRC_S) $(SRC_M) $(SRC_X) + $(CC) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.emx diff --git a/lib/arch/os2/Makefile.icc b/lib/arch/os2/Makefile.icc new file mode 100644 index 0000000..e633c8d --- /dev/null +++ b/lib/arch/os2/Makefile.icc @@ -0,0 +1,73 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for IBM VisualAge C++ under OS/2. +# +# You will need nmake. +# +# Use this file while in the lib directory with the following statement: +# +# nmake -f arch\os2\Makefile.icc +# + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.icc +FT_MAKE = $(MAKE) -nologo + +CC = icc +CFLAGS = -O+ -Ti- -Tm- -Sa -W3 -Wpro- -Wcnd- -Q+ -Iarch\os2 -I. -Iextend + +# NOTE: Optimizations are discarded, as it seems that Visual Age +# is buggy when producing ttraster.obj. The resulting code +# crashes under some circumstances (performing vertical dropout +# control when rendering smoothed outlines)! + +TTFILE = $(ARCH)\os2file.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c \ + extend\ftxcmap.c extend\ftxwidth.c extend\ftxsbit.c \ + extend\ftxgsub.c extend\ftxgpos.c extend\ftxopen.c \ + extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c \ + ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +all: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_S)" libttf.lib + +debug: + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_M)" libttf.lib + + +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +$(OBJS_X): + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +$(ARCH)\os2file.obj: + $(CC) -C $(CFLAGS) /Fo$@ $*.c + +libttf.lib: $(LIB_FILES) + !ilib /nologo /noignorecase /nobackup $@ +$?,, + +clean: + -del *.obj + -del extend\*.obj + -del arch\os2\*.obj + +distclean: clean + -del libttf.lib + +# end of Makefile.icc diff --git a/lib/arch/os2/Makefile.wat b/lib/arch/os2/Makefile.wat new file mode 100644 index 0000000..4fe8adf --- /dev/null +++ b/lib/arch/os2/Makefile.wat @@ -0,0 +1,88 @@ +# This file is part of the FreeType project. +# +# This builds the Watcom library with Watcom's wcc386 under OS/2. +# +# You'll need Watcom's wmake. +# +# +# Invoke by "wmake -f arch\os2\Makefile.wat" when in the "lib" directory +# +# This will build "freetype\lib\libttf.lib" + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.wat +FT_MAKE = wmake -h + + +.EXTENSIONS: +.EXTENSIONS: .lib .obj .c .h +.obj:.;.\extend;.\$(ARCH) +.c:.;.\extend;.\$(ARCH) +.h:.;.\extend;.\$(ARCH) + +CC = wcc386 + +CCFLAGS = /otexanl+ /s /w5 /zq -Iarch\os2 -I. -Iextend + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +TTFILE_OBJ = ttfile.obj +TTMEMORY_OBJ = ttmemory.obj +TTMUTEX_OBJ = ttmutex.obj + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) +PORT_OBJS = $(TTFILE_OBJ) $(TTMEMORY_OBJ) $(TTMUTEX_OBJ) + +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c & + extend\ftxcmap.c extend\ftxwidth.c extend\ftxsbit.c & + extend\ftxgsub.c extend\ftxgpos.c extend\ftxopen.c & + extend\ftxgdef.c + +OBJS_X = extend\ftxgasp.obj extend\ftxkern.obj extend\ftxpost.obj & + extend\ftxcmap.obj extend\ftxwidth.obj extend\ftxsbit.obj & + extend\ftxgsub.obj extend\ftxgpos.obj extend\ftxopen.obj & + extend\ftxgdef.obj + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c & + ttgload.c ttinterp.c ttload.c ttobjs.c & + ttraster.c ttextend.c $(PORT) + +OBJS_M = ttapi.obj ttcache.obj ttcalc.obj ttcmap.obj & + ttgload.obj ttinterp.obj ttload.obj ttobjs.obj & + ttraster.obj ttextend.obj $(PORT_OBJS) $(OBJS_X) + +SRC_S = freetype.c +OBJ_S = freetype.obj +OBJS_S = $(OBJ_S) $(OBJS_X) + + +.c.obj: + $(CC) $(CCFLAGS) $[* /fo=$[*.obj + +all: .symbolic + $(FT_MAKE) -f $(FT_MAKEFILE) libttf.lib + +debug: .symbolic + $(FT_MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJS_M)" libttf.lib + + +libttf.lib: $(OBJS_M) + wlib -q -n libttf.lib $(OBJS_M) + +# is this correct? Know nothing about wmake and the Watcom compiler... +$(OBJ_S): $(SRC_S) $(SRC_M) + $(CC) $(CCFLAGS) $(SRC_S) /fo=$(OBJ_S) + +clean: .symbolic + @-erase $(OBJS_M) + @-erase *.err + +distclean: .symbolic clean + @-erase libttf.lib + +new: .symbolic + @-wtouch *.c + +# end of Makefile.wat diff --git a/lib/arch/os2/freetype.c b/lib/arch/os2/freetype.c new file mode 100644 index 0000000..7a115cf --- /dev/null +++ b/lib/arch/os2/freetype.c @@ -0,0 +1,32 @@ +/* This file is part of the FreeType project */ + +/* Single file library component for OS/2 */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "os2file.c" +#include "ttmemory.c" +#include "ttmutex.c" + +/* the extensions are compiled separately, but we need to */ +/* include the file ttextend.c if we want to support them */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + +/* END */ diff --git a/lib/arch/os2/ft_conf.h b/lib/arch/os2/ft_conf.h new file mode 100644 index 0000000..c7026c7 --- /dev/null +++ b/lib/arch/os2/ft_conf.h @@ -0,0 +1,239 @@ +/******************************************************************* + * + * ft_conf.h (OS/2 version) + * + * High-level interface specification. + * + * Copyright 1996-1998 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This file is used to contain the definition of several + * configuration-specific macros. + * + ******************************************************************/ + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + + +/**********************************************************************/ +/* */ +/* We begin by a series of macros that are automatically set by the */ +/* 'configure' script on Unix. They must be set manually on OS/2, */ +/* so here they are : */ +/* */ +/**********************************************************************/ + +#define OS2 + +/* Define to empty if the keyword "const" does not work. */ +/* #undef const */ + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you need for console I/O functions. */ +#if defined(__EMX__) || defined(__IBMC__) +#define HAVE_CONIO_H +#endif + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/os2/os2file.c b/lib/arch/os2/os2file.c new file mode 100644 index 0000000..e6003fd --- /dev/null +++ b/lib/arch/os2/os2file.c @@ -0,0 +1,1237 @@ +/******************************************************************* + * + * os2file.c (OS2 version) 2.1 + * + * File I/O Component (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES: + * + * This implementation relies on the OS/2 file API. It was provided + * by the PM FreeType DLL author, Michal Necasek. + * + ******************************************************************/ + +#include "ttconfig.h" + +#include /* !Mike! */ + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttmemory.h" +#include "ttfile.h" /* our prototypes */ + + +/* For now, we don't define additional error messages in the core library */ +/* to report open-on demand errors. Define these errors as standard ones. */ + +#define TT_Err_Could_Not_ReOpen_File TT_Err_Could_Not_Open_File +#define TT_Err_Could_Not_ReSeek_File TT_Err_Could_Not_Open_File + + + /* This definition is mandatory for each file component! */ + EXPORT_FUNC + const TFileFrame TT_Null_FileFrame = { NULL, 0, 0 }; + + +/* It has proven useful to do some bounds checks during development phase. */ +/* They should probably be undefined for speed reasons in a later release. */ + +#if 0 +#define CHECK_FRAME( frame, n ) \ + do { \ + if ( frame.cursor + n > frame.address + frame.size ) \ + Panic( "Frame boundary error!\n" ); \ + } while ( 0 ) +#else +#define CHECK_FRAME( frame, n ) \ + do { \ + } while ( 0 ) +#endif + + + /* Because a stream can be flushed, i.e., its file handle can be */ + /* closed to save system resources, we must keep the stream's file */ + /* pathname to be able to re-open it on demand when it is flushed. */ + + struct _TStream_Rec + { + Bool opened; /* is the stream handle opened ? */ + String* name; /* the file's pathname */ + Long position; /* current pos. within the file */ + + HFILE file; /* file handle !Mike! */ + Long base; /* stream base in file */ + Long size; /* stream size in file */ + }; + + typedef struct _TStream_Rec TStream_Rec; + typedef TStream_Rec* PStream_Rec; + + + /* We support embedded TrueType files by allowing them to be */ + /* inside any file, at any location, hence the 'base' argument. */ + /* Note, however, that the current implementation does not allow you */ + /* to specify a 'base' index when opening a file. */ + /* (will come later) */ + /* I still don't know if this will turn out useful... - DavidT */ + +#define STREAM2REC( x ) ( (TStream_Rec*)HANDLE_Val( x ) ) + + static TT_Error Stream_Activate ( PStream_Rec stream ); + static TT_Error Stream_Deactivate( PStream_Rec stream ); + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /**** ****/ + /**** N O N R E E N T R A N T I M P L E M E N T A T I O N ****/ + /**** ****/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* In non-reentrant builds, we allocate a single block where we'll */ + /* place all the frames smaller than FRAME_CACHE_SIZE, rather than */ + /* allocating a new block on each access. Bigger frames will be */ + /* malloced normally in the heap. */ + /* */ + /* See TT_Access_Frame() and TT_Forget_Frame() for details. */ + +#define FRAME_CACHE_SIZE 2048 + + /* The TFile_Component structure holds all the data that was */ + /* previously declared static or global in this component. */ + /* */ + /* It is accessible through the 'engine.file_component' */ + /* variable in re-entrant builds, or directly through the */ + /* static 'files' variable in other builds. */ + + struct _TFile_Component + { + TMutex lock; /* used by the thread-safe build only */ + Byte* frame_cache; /* frame cache */ + PStream_Rec stream; /* current stream */ + TFileFrame frame; /* current frame */ + }; + + typedef struct _TFile_Component TFile_Component; + + static TFile_Component files; + +#define CUR_Stream files.stream +#define CUR_Frame files.frame + +#define STREAM_VARS /* void */ +#define STREAM_VAR /* void */ + +/* The macro CUR_Stream denotes the current input stream. */ +/* Note that for the re-entrant version, the 'stream' name has been */ +/* chosen according to the macro STREAM_ARGS. */ + +/* The macro CUR_Frame denotes the current file frame. */ +/* Note that for the re-entrant version, the 'frame' name has been */ +/* chosen according to the macro FRAME_ARGS. */ + +/* The macro STREAM_VAR is used when calling public functions */ +/* that need an 'optional' stream argument. */ + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + TT_Error error; + + MUTEX_Create( files.lock ); + files.stream = NULL; + ZERO_Frame( files.frame ); + + if ( ALLOC( files.frame_cache, FRAME_CACHE_SIZE ) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + FREE( files.frame_cache ); + MUTEX_Destroy( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ) + { + MUTEX_Lock( files.lock ); /* lock file mutex */ + + *stream = org_stream; /* copy the stream */ + files.stream = STREAM2REC( org_stream ); /* set current stream */ + + Stream_Activate( files.stream ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : Error code. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + HANDLE_Set( *stream, NULL ); + MUTEX_Release( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( size <= FRAME_CACHE_SIZE ) + { + /* use the cache */ + CUR_Frame.address = files.frame_cache; + CUR_Frame.size = FRAME_CACHE_SIZE; + } + else + { + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + } + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + if ( size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + CUR_Frame.address = NULL; + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * `size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function truncates `size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes, requested; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( size <= FRAME_CACHE_SIZE ) + { + /* use the cache */ + CUR_Frame.address = files.frame_cache; + CUR_Frame.size = FRAME_CACHE_SIZE; + } + else + { + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + } + + requested = size; + readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR ); + if ( size > readBytes ) + size = readBytes; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + if ( requested > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + CUR_Frame.address = NULL; + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Frame.size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + + +#else /* TT_CONFIG_OPTION_THREAD_SAFE */ + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /******** ********/ + /******** R E E N T R A N T I M P L E M E N T A T I O N ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/* a simple macro to access the file component's data */ +#define files ( *((TFile_Component*)engine.file_component) ) + +#define CUR_Stream STREAM2REC( stream ) /* re-entrant macros */ +#define CUR_Frame (*frame) + +#define STREAM_VARS stream, +#define STREAM_VAR stream + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Duplicates a stream for a new usage. + * + * Input : input_stream source stream to duplicate + * copy address of target duplicate stream + * + * Output : error code. + * The target stream is set to NULL in case of failure. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + PStream_Rec rec = STREAM2REC( input_stream ); + + return TT_Open_Stream( rec->name, copy ); + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS int size ) + { + TT_Error error; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * `size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function truncates `size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS int size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR ); + if ( size > readBytes ) + size = readBytes; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + FREE( CUR_Frame.address ); + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /*********** ***********/ + /*********** C O M M O N I M P L E M E N T A T I O N ***********/ + /*********** ***********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/******************************************************************* + * + * Function : Stream_Activate + * + * Description : activates a stream, this will either: + * - open a new file handle if the stream is closed + * - move the stream to the head of the linked list + * + * Input : stream the stream to activate + * + * Output : error condition. + * + * Note : this function is also called with fresh new streams + * created by TT_Open_Stream(). They have their 'size' + * field set to -1. + * + ******************************************************************/ + + static TT_Error Stream_Activate( PStream_Rec stream ) + { + ULONG ulAction; /* !Mike! */ + + if ( !stream->opened ) + { +#if 0 + if ( !(stream->file = fopen( stream->name, "rb" )) ) /* !Mike! */ +#endif + +/* XXX : Strange. GCC/EMX wants an (Byte*) for the file name? */ +#ifdef __EMX__ + + if ( DosOpen( (Byte*)stream->name, &(stream->file), + &ulAction, 0, + 0, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL ) ) + return TT_Err_Could_Not_ReOpen_File; + +#else + + if ( DosOpen( stream->name, &(stream->file), + &ulAction, 0, + 0, OPEN_ACTION_OPEN_IF_EXISTS, + OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL ) ) + return TT_Err_Could_Not_ReOpen_File; + +#endif /* __EMX__ */ + + stream->opened = TRUE; + + /* A newly created stream has a size field of -1 */ + if ( stream->size < 0 ) + { +#if 0 + fseek( stream->file, 0, SEEK_END ); /* !Mike! */ + stream->size = ftell( stream->file ); +#endif + + DosSetFilePtr( stream->file, 0, FILE_END, (ULONG *)&(stream->size) ); +#if 0 + fseek( stream->file, 0, SEEK_SET ); +#endif + + DosSetFilePtr( stream->file, 0, FILE_BEGIN, &ulAction ); + } + + /* Reset cursor in file */ + if ( stream->position ) + { +#if 0 /* !Mike! */ + if ( fseek( stream->file, stream->position, SEEK_SET ) != 0 ) +#endif + + if ( DosSetFilePtr( stream->file, stream->position, + FILE_BEGIN, &ulAction ) ) + { + /* error during seek */ +#if 0 + fclose( stream->file ); /* !Mike! */ +#endif + + DosClose( stream->file ); + stream->opened = FALSE; + return TT_Err_Could_Not_ReSeek_File; + } + } + } + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Stream_DeActivate + * + * Description : deactivates a stream, this will: + * - close its file handle if it was opened + * - remove it from the opened list if necessary + * + * Input : stream the stream to deactivate + * + * Output : Error condition + * + * Note : the function is called whenever a stream is deleted + * (_not_ when a stream handle's is closed due to an + * activation). However, the stream record isn't + * destroyed by it... + * + ******************************************************************/ + + static TT_Error Stream_Deactivate( PStream_Rec stream ) + { + if ( stream->opened ) + { + /* Save its current position within the file */ +#if 0 + stream->position = ftell( stream->file ); /* !Mike! */ +#endif + + DosSetFilePtr( stream->file, 0, FILE_CURRENT, + (ULONG *)&(stream->position) ); +#if 0 + fclose( stream->file ); /* !Mike! */ +#endif + + DosClose( stream->file ); + stream->file = 0; + stream->opened = FALSE; + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : length of stream in bytes. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : Opens the font file and saves the total file size. + * + * Input : error address of stream's error variable + * (re-entrant build only) + * filepathname pathname of the file to open + * stream address of target TT_Stream structure + * + * Output : SUCCESS on sucess, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Open_Stream( const String* filepathname, + TT_Stream* stream ) + { + int len; + TT_Error error; + PStream_Rec stream_rec; + + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + stream_rec = STREAM2REC( *stream ); + + stream_rec->file = NULLHANDLE; /* !Mike! */ + stream_rec->size = -1; + stream_rec->base = 0; + stream_rec->opened = FALSE; + stream_rec->position = 0; + + len = strlen( filepathname ) + 1; + if ( ALLOC( stream_rec->name, len ) ) + goto Fail; + + strncpy( (String*)stream_rec->name, filepathname, len ); + + error = Stream_Activate( stream_rec ); + if ( error ) + goto Fail_Activate; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Fail_Activate: + FREE( stream_rec->name ); + Fail: + FREE( stream_rec ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream address of target TT_Stream structure + * + * Output : SUCCESS (always). + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Stream_Deactivate( rec ); + FREE( rec->name ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + if ( rec ) + { + Stream_Deactivate( rec ); + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Seek_File( STREAM_ARGS long position ) + { + ULONG ibActual; /* !Mike! */ + + + position += CUR_Stream->base; + +#if 0 + if ( fseek( CUR_Stream->file, position, SEEK_SET ) ) /* !Mike! */ +#endif + + if ( DosSetFilePtr( CUR_Stream->file, position, FILE_BEGIN , &ibActual ) ) + return TT_Err_Invalid_File_Offset; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File() + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Skip_File( STREAM_ARGS long distance ) + { + ULONG ibActual; /* !Mike! */ + + +#if 0 + return TT_Seek_File( STREAM_VARS ftell( CUR_Stream->file ) - + CUR_Stream->base + distance ); /* !Mike! */ +#endif + + DosSetFilePtr( CUR_Stream->file, 0, FILE_CURRENT, &ibActual ); + return TT_Seek_File( STREAM_VARS ibActual - CUR_Stream->base + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_File( STREAM_ARGS void* buffer, long count ) + { + ULONG cbActual; /* !Mike! */ + +#if 0 /* !Mike! */ + if ( fread( buffer, 1, count, CUR_Stream->file ) != (unsigned long)count ) +#endif + + DosRead( CUR_Stream->file, buffer, count, &cbActual ); + if ( cbActual != (unsigned long)count ) + return TT_Err_Invalid_File_Read; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_At_File( STREAM_ARGS long position, + void* buffer, + long count ) + { + TT_Error error; + + + if ( ( error = TT_Seek_File( STREAM_VARS position ) ) || + ( error = TT_Read_File( STREAM_VARS buffer, count ) ) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : current file position + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_File_Pos( STREAM_ARG ) + { + ULONG ibActual; /* !Mike! */ + + +#if 0 + return ftell( CUR_Stream->file ) - CUR_Stream->base; /* !Mike! */ +#endif + + DosSetFilePtr( CUR_Stream->file, 0, FILE_CURRENT, &ibActual ); + return ibActual - CUR_Stream->base; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + Byte TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } +#endif + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char. + * + ******************************************************************/ + + EXPORT_FUNC + Char TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short. + * + ******************************************************************/ + + EXPORT_FUNC + short TT_Get_Short( FRAME_ARG ) + { + short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((short)CUR_Frame.cursor[0] << 8) | + (short)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + unsigned short TT_Get_UShort( FRAME_ARG ) + { + unsigned short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((unsigned short)CUR_Frame.cursor[0] << 8) | + (unsigned short)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } +#endif + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long. + * + ******************************************************************/ + + EXPORT_FUNC + long TT_Get_Long( FRAME_ARG ) + { + long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((long)CUR_Frame.cursor[0] << 24) | + ((long)CUR_Frame.cursor[1] << 16) | + ((long)CUR_Frame.cursor[2] << 8 ) | + (long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None + * + * Output : Extracted ulong. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + unsigned long TT_Get_ULong( FRAME_ARG ) + { + unsigned long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((unsigned long)CUR_Frame.cursor[0] << 24) | + ((unsigned long)CUR_Frame.cursor[1] << 16) | + ((unsigned long)CUR_Frame.cursor[2] << 8 ) | + (unsigned long)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } +#endif + + +/* END */ diff --git a/lib/arch/unix/.cvsignore b/lib/arch/unix/.cvsignore new file mode 100644 index 0000000..f3c7a7c --- /dev/null +++ b/lib/arch/unix/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/arch/unix/Makefile.in b/lib/arch/unix/Makefile.in new file mode 100644 index 0000000..321cc7f --- /dev/null +++ b/lib/arch/unix/Makefile.in @@ -0,0 +1,244 @@ +# This file is part of the FreeType project. +# +# lib/arch/unix/Makefile.in + +ARCH = arch/unix +FT_MAKEFILE = $(ARCH)/Makefile + +RM = @RM@ +RMF = @RM@ -f +RMDIR = @RMDIR@ +LN_S = @LN_S@ + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +VPATH = @srcdir@/../.. +srcdir = @srcdir@/../.. + +top_builddir=.. + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = $(top_builddir)/libtool +MKINSTALLDIRS = $(srcdir)/../mkinstalldirs + +version_info = @version_info@ + +include $(top_builddir)/MakeSub + +############### PORTABILITY COMPONENTS ######################## + +# location of memory component +MEMSRC = ttmemory.c + +# location of file component +FILESRC = @TT_FILE_COMPONENT@ + +# location of mutex component +MUTEXSRC = ttmutex.c + +# location of default extensions +FTEXTDIR = $(srcdir)/extend + + +# default extensions sources +EXTSRC = $(FTEXTDIR)/ftxkern.c \ + $(FTEXTDIR)/ftxgasp.c \ + $(FTEXTDIR)/ftxpost.c \ + $(FTEXTDIR)/ftxcmap.c \ + $(FTEXTDIR)/ftxsbit.c \ + $(FTEXTDIR)/ftxwidth.c \ + $(FTEXTDIR)/ftxerr18.c \ + $(FTEXTDIR)/ftxgsub.c \ + $(FTEXTDIR)/ftxgpos.c \ + $(FTEXTDIR)/ftxgdef.c \ + $(FTEXTDIR)/ftxopen.c + +EXTOBJ = ftxkern.lo \ + ftxgasp.lo \ + ftxpost.lo \ + ftxcmap.lo \ + ftxsbit.lo \ + ftxwidth.lo \ + ftxerr18.lo \ + ftxgsub.lo \ + ftxgpos.lo \ + ftxgdef.lo \ + ftxopen.lo + +# all engine sources +SRC_M = $(srcdir)/ttapi.c \ + $(srcdir)/ttcache.c \ + $(srcdir)/ttcalc.c \ + $(srcdir)/ttcmap.c \ + $(srcdir)/ttdebug.c \ + $(srcdir)/ttextend.c \ + $(srcdir)/ttgload.c \ + $(srcdir)/ttinterp.c \ + $(srcdir)/ttload.c \ + $(srcdir)/ttobjs.c \ + $(srcdir)/ttraster.c \ + $(srcdir)/$(FILESRC) \ + $(srcdir)/$(MEMSRC) \ + $(srcdir)/$(MUTEXSRC) +SRC_S = $(srcdir)/$(ARCH)/freetype.c + +# all header files +HEADERS = $(srcdir)/freetype.h \ + $(srcdir)/fterrid.h \ + $(srcdir)/ftnameid.h \ + $(FTEXTDIR)/ftxkern.h \ + $(FTEXTDIR)/ftxgasp.h \ + $(FTEXTDIR)/ftxcmap.h \ + $(FTEXTDIR)/ftxsbit.h \ + $(FTEXTDIR)/ftxpost.h \ + $(FTEXTDIR)/ftxwidth.h \ + $(FTEXTDIR)/ftxerr18.h \ + $(FTEXTDIR)/ftxgsub.h \ + $(FTEXTDIR)/ftxgpos.h \ + $(FTEXTDIR)/ftxgdef.h \ + $(FTEXTDIR)/ftxopen.h + +# all engine objects +OBJ_M = ttapi.lo \ + ttcache.lo \ + ttcalc.lo \ + ttcmap.lo \ + ttdebug.lo \ + ttextend.lo \ + ttgload.lo \ + ttinterp.lo \ + ttload.lo \ + ttobjs.lo \ + ttraster.lo \ + file.lo \ + memory.lo \ + mutex.lo \ + $(EXTOBJ) +OBJ_S = freetype.lo $(EXTOBJ) + + +# include paths +INCLUDES = -I. -I$(top_builddir) -I$(srcdir) -I$(FTEXTDIR) + +# C flags +CFLAGS = @CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +FT_CFLAGS = $(CFLAGS) $(INCLUDES) + +# linker flags +FT_LIBS = @LIBS@ + +# i18n stuff +LOCALEDIR = @LOCALEDIR@ + + +all: do_link + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJ_S)" libttf.la + +debug: do_link + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES="$(OBJ_M)" libttf.la + + +do_link: + -$(RMF) memory.c file.c mutex.c + $(LN_S) $(srcdir)/$(MEMSRC) memory.c + $(LN_S) $(srcdir)/$(FILESRC) file.c + $(LN_S) $(srcdir)/$(MUTEXSRC) mutex.c + + +.SUFFIXES: .lo +.c.lo: + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $< + +ftxkern.lo: $(FTEXTDIR)/ftxkern.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxkern.c + +ftxgasp.lo: $(FTEXTDIR)/ftxgasp.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxgasp.c + +ftxpost.lo: $(FTEXTDIR)/ftxpost.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxpost.c + +ftxcmap.lo: $(FTEXTDIR)/ftxcmap.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxcmap.c + +ftxsbit.lo: $(FTEXTDIR)/ftxsbit.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxsbit.c + +ftxwidth.lo: $(FTEXTDIR)/ftxwidth.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxwidth.c + +ftxerr18.lo: $(FTEXTDIR)/ftxerr18.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) \ + -DLOCALEDIR='"$(LOCALEDIR)"' \ + $(FTEXTDIR)/ftxerr18.c + +ftxgsub.lo: $(FTEXTDIR)/ftxgsub.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxgsub.c + +ftxgpos.lo: $(FTEXTDIR)/ftxgpos.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxgpos.c + +ftxgdef.lo: $(FTEXTDIR)/ftxgdef.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxgdef.c + +ftxopen.lo: $(FTEXTDIR)/ftxopen.c + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) $(FTEXTDIR)/ftxopen.c + +freetype.lo: $(SRC_S) $(SRC_M) + $(LIBTOOL) --mode=compile $(CC) -c $(FT_CFLAGS) \ + -DLOCALEDIR='"$(LOCALEDIR)"' \ + -DTT_MAKE_OPTION_SINGLE_OBJECT \ + $(SRC_S) + +libttf.la: $(LIB_FILES) + $(LIBTOOL) --mode=link $(CC) -o libttf.la $(LIB_FILES) \ + -rpath $(libdir) \ + -version-info $(version_info) $(FT_LIBS) + +install: libttf.la + $(MKINSTALLDIRS) $(libdir) $(includedir)/freetype + $(LIBTOOL) --mode=install $(INSTALL) libttf.la $(libdir) + -for P in $(HEADERS) ; do \ + $(INSTALL_DATA) $$P $(includedir)/freetype ; \ + done + +uninstall: + -$(LIBTOOL) --mode=uninstall $(RM) $(libdir)/libttf.la + -$(RMF) $(includedir)/freetype/* + -$(RMDIR) $(includedir)/freetype + +clean: + -$(RMF) $(OBJ_S) $(OBJ_M) *.o + +distclean: clean + -$(RMF) file.c memory.c mutex.c + -$(RMF) libttf.la + -$(RMF) *.orig *~ core *.core + -$(RMF) $(ARCH)/Makefile + -$(RMF) .libs/* + -$(RMDIR) .libs + +depend: do_link + (echo '/^#.* PUT NO STUFF BELOW/,$$d' ; echo w ; echo q) | \ + ed - $(ARCH)/Makefile + echo '# Dependencies generated by make depend: PUT NO STUFF BELOW' \ + >> $(ARCH)/Makefile + for file in $(SRC_S) $(SRC_M) $(EXTSRC) ; do \ + $(CPP) $(CPPFLAGS) $(INCLUDES) $$file | \ + sed -n -e 's|^# [1-9][0-9]* "\([^/].*\.h\)".*|\1|p' \ + -e 's|^# [1-9][0-9]* "\($(srcdir)/.*\.h\)".*|\1|p' | \ + sed -e 's|/\./|.|g' -e "s/^/`basename $$file .c`.lo: /" ; \ + done | \ + sort -u | \ + awk '{ if (LINE == 1) \ + { line = last = $$1 } \ + else if ($$1 != last) \ + { print line ; line = last = $$1 } \ + line = line " " $$2 } \ + END { print line }' >> $(ARCH)/Makefile + +# Dependencies generated by make depend: PUT NO STUFF BELOW diff --git a/lib/arch/unix/freetype.c b/lib/arch/unix/freetype.c new file mode 100644 index 0000000..9a4860d --- /dev/null +++ b/lib/arch/unix/freetype.c @@ -0,0 +1,27 @@ +/* This file is part of the FreeType project */ + +/* Single object library component for Unix */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* The Makefile creates proper links to following three files */ + +#include "file.c" +#include "memory.c" +#include "mutex.c" + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/unix/ttmmap.c b/lib/arch/unix/ttmmap.c new file mode 100644 index 0000000..aac7c10 --- /dev/null +++ b/lib/arch/unix/ttmmap.c @@ -0,0 +1,1027 @@ +/******************************************************************* + * + * ttmmap.c 2.0 + * + * Memory-Mapped file component ( replaces ttfile.c ). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 2.0 and 1.3 : + * + * - adopted new design/separation introduced in ttfile.c 2.0 + * + ******************************************************************/ + +#include "ttconfig.h" + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#ifndef MAP_FILE +#define MAP_FILE 0x00 +#endif + +/* + * The prototype for munmap() is not provided on SunOS. This needs to + * have a check added later to see if the GNU C library is being used. + * If so, then this prototype is not needed. + */ +#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4) + extern int munmap( caddr_t addr, int len ); +#endif + +#include +#ifdef HAVE_FCNTL_H +#include +#endif + + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttmemory.h" +#include "ttfile.h" /* our prototypes */ + + /* This definition is mandatory for each file component! */ + EXPORT_FUNC + const TFileFrame TT_Null_FileFrame = { NULL, 0, 0 }; + + /* It has proven useful to do some bounds checks during */ + /* development phase. Define DEBUG_FILE when compiling */ + /* this component to enable them. */ + +#ifdef DEBUG_FILE +#define CHECK_FRAME( frame, n ) \ + do { \ + if ( frame.cursor + n > frame.address + frame.size ) \ + Panic( "Frame boundary error!\n" ); \ + } while ( 0 ) +#else +#define CHECK_FRAME( frame, n ) \ + do { \ + } while( 0 ) +#endif + + struct _TFileMap + { + String* base; /* base address of mapped file */ + Int refcount; /* reference count for mmaped region */ + Long size; /* stream size in file */ + Long offset; /* offset in file */ + }; + + typedef struct _TFileMap TFileMap; + +#define MAP_Address( map ) (Byte*)( (map)->base + (map)->offset ) + + /* The stream record structure */ + typedef struct _TStream_Rec + { + TFileMap* map; /* mapped file description */ + Long pos ; /* cursor in mapped file */ + } TStream_Rec; + + typedef TStream_Rec* PStream_Rec; + +#define STREAM2REC( x ) ( (TStream_Rec*)HANDLE_Val( x ) ) + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /**** ****/ + /**** N O N R E E N T R A N T I M P L E M E N T A T I O N ****/ + /**** ****/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* The TFile_Component structure holds all the data that was */ + /* previously declared static or global in this component. */ + /* */ + /* It is accessible through the 'engine.file_component' */ + /* variable in re-entrant builds, or directly through the */ + /* static 'files' variable in other builds. */ + + struct _TFile_Component + { + TMutex lock; /* used by the thread-safe build only */ + PStream_Rec stream; /* current stream */ + TFileFrame frame; /* current frame */ + }; + + typedef struct _TFile_Component TFile_Component; + +/* The macro CUR_Stream denotes the current input stream */ +/* Note that for the re-entrant version, the 'stream' name has been */ +/* chosen according to the macro STREAM_ARGS. */ + +/* The macro CUR_Frame denotes the current file frame */ +/* Note that for the re-entrant version, the 'frame' name has been */ +/* chosen according to the macro FRAME_ARGS. */ + +/* The macro STREAM_VAR is used when calling public functions */ +/* that need an 'optional' stream argument. */ + +#define CUR_Stream files.stream /* thread-safe macros */ +#define CUR_Frame files.frame + +#define STREAM_VARS /* void */ +#define STREAM_VAR /* void */ + + /* the 'files' variable is only defined in non-reentrant builds */ + + static TFile_Component files; + + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + MUTEX_Create( files.lock ); + files.stream = NULL; + ZERO_Frame( files.frame ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + MUTEX_Destroy( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ) + { + MUTEX_Lock( files.lock ); + *stream = org_stream; + files.stream = STREAM2REC( org_stream ); /* set current stream */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream + * + * Output : Error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + HANDLE_Set( *stream, NULL ); + MUTEX_Release( files.lock ); + + return TT_Err_Ok; + } + +#else /* TT_CONFIG_OPTION_THREAD_SAFE */ + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /******** ********/ + /******** R E E N T R A N T I M P L E M E N T A T I O N ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +#define CUR_Stream STREAM2REC( stream ) /* re-entrant macros */ +#define CUR_Frame (*frame) + +#define STREAM_VARS stream, +#define STREAM_VAR stream + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + engine.file_component = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code. The output stream is set to NULL in + * case of Failure. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + TT_Error error; + PStream_Rec stream_rec; + PStream_Rec copy_rec; + + + stream_rec = STREAM2REC( input_stream ); + + if ( ALLOC( copy_rec, sizeof ( TStream_Rec ) ) ) + goto Fail; + + HANDLE_Set( *copy, copy_rec ); + + copy_rec->map->refcount++; + copy_rec->pos = 0; + + return TT_Err_Ok; + + Fail: + HANDLE_Set( *copy, NULL ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /*********** ***********/ + /*********** C O M M O N I M P L E M E N T A T I O N ***********/ + /*********** ***********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/******************************************************************* + * + * Function : AllocateMap + * + * Description : Allocates a new map from the table. + * + * Output : Pointer to new stream rec. NULL in case of failure. + * + ******************************************************************/ + + static + TFileMap* Allocate_Map( void ) + { + TFileMap* result; + + + if ( MEM_Alloc( result, sizeof ( TFileMap ) ) ) + return NULL; + + result->refcount = 1; + return result; + } + + +/******************************************************************* + * + * Function : ReleaseMap + * + * Description : Releases a used map to the table if reference i + * counter reaches zero. + * + * Input : map + * + * Output : None. + * + * Note : Called by TT_Close_File() + * + ******************************************************************/ + + static + void Release_Map ( TFileMap* map ) + { + map->refcount--; + if ( map->refcount <= 0 ) + { + munmap ( (void*)map->base, map->size ); + FREE( map ); + } + } + + +/******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : Opens the font file and saves the total file size. + * + * Input : error address of stream's error variable + * (re-entrant build only). + * filepathname pathname of the file to open + * stream address of target TT_Stream structure + * + * Output : SUCCESS on success, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Open_Stream( const String* filepathname, + TT_Stream* stream ) + { + TT_Error error; + Int file; + PStream_Rec stream_rec; + TFileMap* map; + struct stat stat_buf; + + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + map = Allocate_Map(); + if ( !map ) + { + error = TT_Err_Out_Of_Memory; + goto Memory_Fail; + } + + stream_rec = STREAM2REC( *stream ); + + file = open( (String*)filepathname, O_RDONLY ); + if ( file < 0 ) + goto File_Fail; + + if ( fstat( file, &stat_buf ) < 0 ) + goto Map_Fail; + + map->offset = 0; + map->size = stat_buf.st_size + map->offset; + map->base = mmap( NULL, + map->size, + PROT_READ, + MAP_FILE | MAP_PRIVATE, + file, + 0 ); + + if ( (long)map->base == -1 ) + goto Map_Fail; + + close( file ); + + stream_rec->map = map; + stream_rec->pos = 0; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Map_Fail: + close( file ); + + File_Fail: + error = TT_Err_Could_Not_Open_File; + FREE( map ); + + Memory_Fail: + FREE( *stream ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream + * + * Output : SUCCESS (always) + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Release_Map( rec->map ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Stream( TT_Stream* stream ) + { + /* XXX - DUMMY IMPLEMENTATION */ + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : Length of stream in bytes. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->map->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Seek_File( STREAM_ARGS Long position ) + { + if ( position > CUR_Stream->map->size ) + return TT_Err_Invalid_File_Offset; + + CUR_Stream->pos = position; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Skip_File( STREAM_ARGS Long distance ) + { + return TT_Seek_File( STREAM_VARS CUR_Stream->pos + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_File( STREAM_ARGS void* buffer, Long count ) + { + if ( CUR_Stream->pos + count > CUR_Stream->map->size ) + return TT_Err_Invalid_File_Read; + + MEM_Copy( buffer, + MAP_Address( CUR_Stream->map ) + CUR_Stream->pos, count ); + CUR_Stream->pos += count; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ) + { + TT_Error error; + + + if ( (error = TT_Seek_File( STREAM_VARS position )) || + (error = TT_Read_File( STREAM_VARS buffer, count )) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : current file position + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_File_Pos( STREAM_ARG ) + { + return CUR_Stream->pos; + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : Error code + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that aSize is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Stream->pos + size > CUR_Stream->map->size ) + return TT_Err_Invalid_Frame_Access; + + CUR_Frame.size = size; + CUR_Frame.address = MAP_Address( CUR_Stream->map ) + CUR_Stream->pos; + CUR_Frame.cursor = CUR_Frame.address; + + CUR_Stream->pos += size; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx() + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : Error code + * + * Notes: The function truncates 'size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that aSize is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. The 'overflow' is set to zero. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + readBytes = CUR_Stream->map->size - CUR_Stream->pos; + if ( size > readBytes ) + { + /* There is overflow, we allocate a new block then */ + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + + CUR_Frame.size = size; + + /* copy the valid part */ + MEM_Copy( CUR_Frame.address, + MAP_Address( CUR_Stream->map ) + CUR_Stream->pos, + readBytes ); + } + else + { + CUR_Frame.size = size; + CUR_Frame.address = MAP_Address( CUR_Stream->map ) + CUR_Stream->pos; + } + + CUR_Frame.cursor = CUR_Frame.address; + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + /* If we were using a duplicate in case of overflow, free it now */ + if ( CUR_Frame.address < (Byte*)CUR_Stream->map->base || + CUR_Frame.address >= (Byte*)CUR_Stream->map->base + + CUR_Stream->map->size ) + FREE( CUR_Frame.address ); + + ZERO_Frame( files.frame ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + Byte TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } + +#endif + + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Char TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Short TT_Get_Short( FRAME_ARG ) + { + Short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((Short)CUR_Frame.cursor[0] << 8) | + (Short)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + UShort TT_Get_UShort( FRAME_ARG ) + { + UShort getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = ((UShort)CUR_Frame.cursor[0] << 8) | + (UShort)CUR_Frame.cursor[1]; + + CUR_Frame.cursor += 2; + + return getshort; + } + +#endif + + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Get_Long( FRAME_ARG ) + { + Long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((Long)CUR_Frame.cursor[0] << 24) | + ((Long)CUR_Frame.cursor[1] << 16) | + ((Long)CUR_Frame.cursor[2] << 8 ) | + (Long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None + * + * Output : Extracted ulong + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call.) + * + ******************************************************************/ + +#if 0 + + EXPORT_FUNC + ULong TT_Get_ULong( FRAME_ARG ) + { + ULong getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((ULong)CUR_Frame.cursor[0] << 24) | + ((ULong)CUR_Frame.cursor[1] << 16) | + ((ULong)CUR_Frame.cursor[2] << 8 ) | + (ULong)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } + +#endif + + +/* END */ diff --git a/lib/arch/vms/README b/lib/arch/vms/README new file mode 100644 index 0000000..4107698 --- /dev/null +++ b/lib/arch/vms/README @@ -0,0 +1,20 @@ +This directory contains two files for compiling the FreeType library under +VMS: + + ft_conf.h the configuration file for the FreeType library + descrip.mms a makefile to be used with either MMS or MMK + +The files are such designed that after unpacking of freetype-1.2 one can +give the command + + MMS/DESCR=[.LIB.ARCH.VMS] + +to build the libraries. (Of course, for MMK use `MMK' on the command line +instead of `MMS'.) The makefile contains a `clean' target, but no `install' +target since I'm note sure where to install the library and the include +files. + +I did NOT do the test programs but I tested it with my own programs. + + + Jouk Jansen diff --git a/lib/arch/vms/descrip.mms b/lib/arch/vms/descrip.mms new file mode 100644 index 0000000..9115316 --- /dev/null +++ b/lib/arch/vms/descrip.mms @@ -0,0 +1,155 @@ +# This file is part of the FreeType project. +# +# DESCRIP.MMS: Make file for VMS using MMS or MMK +# Created by Jouk Jansen (joukj@hrem.stm.tudelft.nl) + +ARCH = arch.unix + +CC = cc + +############### PORTABILITY COMPONENTS ######################## + +# location of memory component +MEMSRC = ttmemory.c + +# location of file component +FILESRC = ttfile.c + +# location of mutex component +MUTEXSRC = ttmutex.c + +# location of default extensions +FTEXTDIR = [.lib.extend] + +# default extensions sources +EXTSRC = $(FTEXTDIR)ftxkern.c \ + $(FTEXTDIR)ftxgasp.c \ + $(FTEXTDIR)ftxpost.c \ + $(FTEXTDIR)ftxcmap.c \ + $(FTEXTDIR)ftxsbit.c \ + $(FTEXTDIR)ftxwidth.c \ + $(FTEXTDIR)ftxerr18.c \ + $(FTEXTDIR)ftxgsub.c \ + $(FTEXTDIR)ftxgpos.c \ + $(FTEXTDIR)ftxopen.c \ + $(FTEXTDIR)ftxgdef.c + +EXTOBJ = [.lib]ftxkern.obj, \ + [.lib]ftxgasp.obj, \ + [.lib]ftxpost.obj, \ + [.lib]ftxcmap.obj, \ + [.lib]ftxsbit.obj, \ + [.lib]ftxwidth.obj, \ + [.lib]ftxerr18.obj, \ + [.lib]ftxgsub.obj, \ + [.lib]ftxgpos.obj, \ + [.lib]ftxopen.obj, \ + [.lib]ftxgdef.obj + +# all engine sources +SRC_M = [.lib]ttapi.c \ + [.lib]ttcache.c \ + [.lib]ttcalc.c \ + [.lib]ttcmap.c \ + [.lib]ttdebug.c \ + [.lib]ttextend.c \ + [.lib]ttgload.c \ + [.lib]ttinterp.c \ + [.lib]ttload.c \ + [.lib]ttobjs.c \ + [.lib]ttraster.c \ + [.lib]$(FILESRC) \ + [.lib]$(MEMSRC) \ + [.lib]$(MUTEXSRC) +SRC_S = [.lib.$(ARCH)]freetype.c + +# all header files with path +HEADERS = [.lib]freetype.h \ + [.lib]fterrid.h \ + [.lib]ftnameid.h \ + $(FTEXTDIR)ftxkern.h \ + $(FTEXTDIR)ftxgasp.h \ + $(FTEXTDIR)ftxcmap.h \ + $(FTEXTDIR)ftxsbit.h \ + $(FTEXTDIR)ftxpost.h \ + $(FTEXTDIR)ftxwidth.h \ + $(FTEXTDIR)ftxerr18.h \ + $(FTEXTDIR)ftxgsub.h \ + $(FTEXTDIR)ftxgpos.h \ + $(FTEXTDIR)ftxgdef.h \ + $(FTEXTDIR)ftxopen.h + +# all engine objects +OBJ_M = [.lib]ttapi.obj, \ + [.lib]ttcache.obj, \ + [.lib]ttcalc.obj, \ + [.lib]ttcmap.obj, \ + [.lib]ttdebug.obj, \ + [.lib]ttextend.obj, \ + [.lib]ttgload.obj, \ + [.lib]ttinterp.obj, \ + [.lib]ttload.obj, \ + [.lib]ttobjs.obj, \ + [.lib]ttraster.obj, \ + [.lib]file.obj, \ + [.lib]memory.obj, \ + [.lib]mutex.obj, \ + $(EXTOBJ) +OBJ_S = [.lib]freetype.obj + + +# include paths +INCLUDES = /include=([.lib],[],$(FTEXTDIR)) + +# C flags +CFLAGS = $(INCLUDES)/obj=[.lib] + +all : do_link [.lib]libttf.olb + library/compress [.lib]libttf.olb + +do_link : + if f$search( "[.lib]memory.c" ) .nes. "" then set file/remove [.lib]memory.c; + if f$search( "[.lib]file.c" ) .nes. "" then set file/remove [.lib]file.c; + if f$search( "[.lib]mutex.c" ) .nes. "" then set file/remove [.lib]mutex.c; + if f$search( "[.lib]ft_conf.h" ) .nes. "" then set file/remove [.lib]ft_conf.h; + set file/enter=[.lib]memory.c [.lib]$(MEMSRC) + set file/enter=[.lib]file.c [.lib]$(FILESRC) + set file/enter=[.lib]mutex.c [.lib]$(MUTEXSRC) + set file/enter=[.lib]ft_conf.h [.lib.arch.vms]ft_conf.h + +[.lib]ftxkern.obj : $(FTEXTDIR)ftxkern.c + +[.lib]ftxgasp.obj : $(FTEXTDIR)ftxgasp.c + +[.lib]ftxpost.obj : $(FTEXTDIR)ftxpost.c + +[.lib]ftxcmap.obj : $(FTEXTDIR)ftxcmap.c + +[.lib]ftxsbit.obj : $(FTEXTDIR)ftxsbit.c + +[.lib]ftxwidth.obj : $(FTEXTDIR)ftxwidth.c + +[.lib]ftxerr18.obj : $(FTEXTDIR)ftxerr18.c + +[.lib]ftxgsub.obj : $(FTEXTDIR)ftxgsub.c + +[.lib]ftxgpos.obj : $(FTEXTDIR)ftxgpos.c + +[.lib]ftxgdef.obj : $(FTEXTDIR)ftxgdef.c + +[.lib]ftxopen.obj : $(FTEXTDIR)ftxopen.c + +[.lib]freetype.obj : $(SRC_S) $(SRC_M) + + +[.lib]libttf.olb : $(OBJ_M) + library/create [.lib]libttf.olb $(OBJ_M) + + +clean : + delete [.lib]*.obj;* + delete [.lib]*.olb;* + if f$search( "[.lib]memory.c" ) .nes. "" then set file/remove [.lib]memory.c; + if f$search( "[.lib]file.c" ) .nes. "" then set file/remove [.lib]file.c; + if f$search( "[.lib]mutex.c" ) .nes. "" then set file/remove [.lib]mutex.c; + if f$search( "[.lib]ft_conf.h" ) .nes. "" then set file/remove [.lib]ft_conf.h; diff --git a/lib/arch/vms/ft_conf.h b/lib/arch/vms/ft_conf.h new file mode 100644 index 0000000..b1315e6 --- /dev/null +++ b/lib/arch/vms/ft_conf.h @@ -0,0 +1,215 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for VMS using MMS or MMK */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +/* #undef HAVE_MMAP */ + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LIBINTL_H */ + +/* Define if you have the libintl library. */ +/* #undef HAVE_LIBINTL */ + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #undef HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +/* #undef TT_CONFIG_OPTION_THREAD_SAFE */ + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +/* #undef DEBUG_LEVEL_TRACE */ + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +/* #undef DEBUG_LEVEL_ERROR */ + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/win16/Makefile.BC b/lib/arch/win16/Makefile.BC new file mode 100644 index 0000000..246c127 --- /dev/null +++ b/lib/arch/win16/Makefile.BC @@ -0,0 +1,180 @@ +# This file is part of the FreeType project. +# +# It builds the library for Borland C++ for 16-bit Windows, large model. +# Due to size constraints, it does not try to pack all modules into one. +# +# You will need Borland MAKE. +# Tested with Borland C++ v.4.0 and 5.0. +# +# Use this file while in the lib directory with the following statement: +# +# make -farch/win16/Makefile.BC +# +# +# A DLL version of the library can be built with +# +# make -DDLL -farch/win16/Makefile.BC dll +# +# Debug versions can be obtained with +# +# make -DDEBUG -farch\win16\Makefile.BC +# +# Special versions enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# make -DBIGFONTS -farch/win16/Makefile.BC + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.BC +FT_DLL = ft13_16.dll + +CC = bcc +LIB = tlib /c /e +IMPLIB = implib -c -o + +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig + +# Credits go to Dave Hoo for pointing out that modern +# Borland compilers (from BC++ 3.1 on) can increase the limit on +# the length of identifiers. +!if ! $d(DEBUG) +CFLAGS = -O2 -3 -ml -A -i40 -I$(ARCH);.;extend $(SPURIOUS_WARNINGS) +DLLFLAGS = -ml -WD -lC +!else +CFLAGS = -v -N -ml -A -i40 -I$(ARCH);.;extend $(SPURIOUS_WARNINGS) +DLLFLAGS = -v -ml -WD -lC +!endif + +CFLAGS = $(CFLAGS) -W + +FT_DEF = $(FT_DLL:.dll=.def) +!if $d(DLL) +CFLAGS = $(CFLAGS) -WD +!endif + + +!if $d(BIGFONTS) +CFLAGS = $(CFLAGS) -DTT_HUGE_PTR=__huge + +TTFILE = $(ARCH)\hugefile.c +TTMEMORY = $(ARCH)\hugemem.c +!else +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +!endif +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces before the \ at end of line, +# otherwise the substitution for TLIB command line will fail. +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ + extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c\ + extend\ftxsbit.c extend\ftxgsub.c extend\ftxgpos.c\ + extend\ftxopen.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c\ + ttgload.c ttinterp.c ttload.c ttobjs.c\ + ttraster.c ttextend.c ttdebug.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Borland make does not handle $($(LIB_FILES)), and using +# -DLIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing TLIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# See ../msdos/Makefile.TC for an application. +.c.obj: + @$(CC) -c -o$* @&&| + $(CFLAGS) $< +| + + +!if ! $d(DEBUG) +# Skipped if DEBUG build +# (but it changes nothing, since we always build in multiple parts). +all: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| +!endif + +debug: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| + +$(FT_DEF): $(ARCH)\ttf.def + -copy $(ARCH)\ttf.def $(FT_DEF) + +dll $(FT_DLL): $(OBJS_M) $(FT_DEF) +!if $d(DLL) + $(CC) -e$(FT_DLL) @&&| + $(DLLFLAGS) $(OBJS_M) +| + $(IMPLIB) libttf $(FT_DEF) +!else +# Re-invoke with flag set. Unfortunately, this discards the other flags. + make -DDLL -f$(ARCH)/Makefile.BC dll +!endif + +install: $(FT_DLL) +!if $d(INSTALL_DIR) + copy $(FT_DLL) $(INSTALL_DIR) +!else + copy $(FT_DLL) C:\WINDOWS +!endif + + +$(OBJ_S): $(SRC_S) $(SRC_M) + +# Not used here because it excesses the capacity of COMMAND.COM... +libttf.lib: $(LIB_FILES) + -del libttf.lib + echo -+$(**: =-+)> response + $(LIB) libttf.lib @&&| ++ $(**: = + ) +| + +!if $d(BIGFONTS) +$(TTMEMORY:.c=.obj): $(TTMEMORY) + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| + +$(TTFILE:.c=.obj): $(TTFILE) + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| +!endif + + +clean: + -del *.obj + -del extend\*.obj + -del $(ARCH)\*.obj + -del libttf.bak + -del response + -del *.def + +distclean: clean + -del libttf.lib + -del *.dll + -del $(FT_DEF) + -del C:\WINDOWS\$(FT_DLL) +!if $d(INSTALL_DIR) + -del $(INSTALL_DIR)\$(FT_DLL) +!endif + +!include "$(ARCH)\depend.win" + +# end of Makefile diff --git a/lib/arch/win16/Makefile.MS b/lib/arch/win16/Makefile.MS new file mode 100644 index 0000000..9ff0b67 --- /dev/null +++ b/lib/arch/win16/Makefile.MS @@ -0,0 +1,106 @@ +# This file is part of the FreeType project. +# +# It builds the library for Microsoft C for Windows, large model. +# It also works for Visual C++ 1.x 16-bit compilers, but you should +# instead use the Makefile customized for it, Makefile.VC. +# Due to size constraints, it does not try to pack all modules into one. +# +# You will need NMAKE. +# +# Use this file while in the lib directory with the following statement: +# +# nmake /f arch\win16\Makefile.MS +# +# +# A debug version can be obtained with +# +# nmake DEBUG=1 /f arch\win16\Makefile.MS + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.MS + +CC = cl /nologo +LIB = lib /noignorecase /nologo + +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G2 -I$(ARCH) -I. -Iextend +!else +CFLAGS = /Zi /AL /Za /W2 /G2 -I$(ARCH) -I. -Iextend +!endif + +# Use /Gw instead with Microsoft C version 6 +CFLAGS = $(CFLAGS) /GA + + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces between the file names or at end of line, otherwise +# the substitution for LIB command line will fail. Thank you. +# +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ +extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c extend\ftxsbit.c\ +extend\ftxopen.c extend\ftxgsub.c extend\ftxgpos.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c\ +ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Microsoft's NMAKE does not handle $($(LIB_FILES)), and using +# LIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing LIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# See ..\msdos\Makefile.TC for an application. +.c.obj: + $(CC) /c /Fo$@ @<< + $(CFLAGS) $*.c +<< + + +!ifndef DEBUG +# Skipped if DEBUG build +# (but it changes nothing, since we always build in multiple parts). +all: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @< header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if you need for console I/O functions. */ +#undef HAVE_CONIO_H + +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define if you have the libintl library. */ +#undef HAVE_LIBINTL + +/* command.com can't pipe stderr into a file; any message would be */ +/* written into the graphics screen. */ +#define HAVE_PRINT_FUNCTION 1 + +#define Print( format, ap ) vfprintf( stdout, (format), (ap) ) + +/* The number of bytes in a int. */ +#define SIZEOF_INT 2 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#undef LONG64 +#undef INT64 + +#endif /* FT_CONF_H */ + +/* End of ft_conf.h */ diff --git a/lib/arch/win16/hugefile.c b/lib/arch/win16/hugefile.c new file mode 100644 index 0000000..17b5f59 --- /dev/null +++ b/lib/arch/win16/hugefile.c @@ -0,0 +1,51 @@ +/******************************************************************* + * + * hugefile.c + * + * File I/O Component (body) for dealing with "huge" objects + * under 16-bit Windows. Relies on the "default" version, with + * a small hook. Requires Windows 3.1+. + * + * Written by Antoine Leca based on ideas from Dave Hoo. + * Copyright 1999 by Dave Hoo, Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTE + * + * This file #includes the normal version, to avoid discrepancies + * between versions. It uses only ANSI-mandated "tricks", so + * any ANSI-compliant compiler should be able to compile this file. + * + ******************************************************************/ + +#include "ttconfig.h" +#include "tttypes.h" + +#include + + /* Here we include , to have the proper definition of fread */ +#include + + /* Some compilers define fileno(), some define _fileno()... */ +#ifndef _fileno +#define _fileno(stream) fileno(stream) +#endif + + /* Then, we divert the use of fread to the Windows version */ +#undef fread +#define fread(ptr, size, n, stream) \ + _hread( _fileno(stream), (char TT_HUGE_PTR *) ptr, (ULong)n * size ) + + + /* Now, we include the "normal" version of `ttfile.c' */ + /* The ANSI/ISO standard mandates that the include of */ + /* there have no bad effects. */ +#include "ttfile.c" + +/* END */ diff --git a/lib/arch/win16/hugemem.c b/lib/arch/win16/hugemem.c new file mode 100644 index 0000000..c1abe5f --- /dev/null +++ b/lib/arch/win16/hugemem.c @@ -0,0 +1,539 @@ +/******************************************************************* + * + * hugemem.c + * + * Memory management component (body) + * for dealing with "huge" objects with 16-bit Windows. + * + * Written by Antoine Leca based on ideas from Dave Hoo. + * Copyright 1999 by Dave Hoo, Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +#ifndef TT_HUGE_PTR +#error "This component needs TT_HUGE_PTR to be #defined." +#endif + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE +#error "This component needs static allocation and is not re-entrant." +#endif + + /* If the memory reclaimed is abobve this limit, alloc directly from */ + /* global heap. Else, alloc using malloc (using suballocation). */ +#ifndef MEMORY_MIN_GLOBAL +#define MEMORY_MIN_GLOBAL 4096 +#endif + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_memory + + +#ifdef DEBUG_MEMORY + +#include + +#define MAX_TRACKED_BLOCKS 1024 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BLOCKS + 1]; + + static Int num_alloc; + static Int num_free; + static Int num_realloc; /* counts only `real' reallocations + (i.e., an existing buffer will be resized + to a value larger than zero */ + + static Int fail_alloc; + static Int fail_realloc; + static Int fail_free; + +#else + + /* We need a tracing stack of the calls to big chunks of memory, */ + /* in order to call the matching version of free(). */ + +#define MAX_TRACKED_BIGCHUNKS 64 + + struct TMemRec_ + { + void* base; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BIGCHUNKS + 1]; + +#endif /* DEBUG_MEMORY */ + + +#ifndef TT_CONFIG_REENTRANT + Long TTMemory_Allocated; + Long TTMemory_MaxAllocated; +#endif + + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE : The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Alloc( ULong Size, void** P ) + { + Int i; + + + if ( !P ) + return TT_Err_Invalid_Argument; + /* Also see below for another case of "invalid argument". */ + + if ( Size > 0 ) + { + if ( Size >= MEMORY_MIN_GLOBAL ) + { + HANDLE hMem; + + hMem = GlobalAlloc( GMEM_ZEROINIT, Size ); + if ( !hMem ) + return TT_Err_Out_Of_Memory; + + *P = (void*)GlobalLock( hMem ); + } + else + *P = (void*)malloc( Size ); + + if ( !*P ) + return TT_Err_Out_Of_Memory; + +#ifndef TT_CONFIG_REENTRANT + TTMemory_MaxAllocated += Size; + TTMemory_Allocated += Size; +#endif + +#ifdef DEBUG_MEMORY + + num_alloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_alloc++; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + +#else + + if ( Size >= MEMORY_MIN_GLOBAL ) + { + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BIGCHUNKS ) + /* We fail badly here. Increase MAX_TRACKED_BIGCHUNKS if needed. */ + return TT_Err_Invalid_Argument; + else + pointers[i].base = *P; + } + +#endif /* DEBUG_MEMORY */ + + /* The nice thing about GlobalAlloc is that it zeroes the memory. */ + + if ( Size < MEMORY_MIN_GLOBAL ) + MEM_Set( *P, 0, Size ); + + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + +/******************************************************************* + * + * Function : TT_Realloc + * + * Description : Reallocates memory from the heap buffer. + * + * Input : Size new size of the memory to be allocated; + * if zero, TT_Free() will be called + * P pointer to a buffer pointer; if *P == NULL, + * TT_Alloc() will be called + * + * Output : Error code. + * + * NOTES : It's not necessary to zero the memory in case the + * reallocated buffer is larger than before -- the + * application has to take care of this. + * + * If the memory request fails, TT_Free() will be + * called on *P, and TT_Err_Out_Of_Memory returned. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Realloc( ULong Size, void** P ) + { + ULong oldSize; + void* Q; + Int i; + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( !*P ) + return TT_Alloc( Size, P ); + + if ( Size == 0 ) + return TT_Free( P ); + +#ifdef DEBUG_MEMORY + + num_realloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_realloc++; + else + oldSize = pointers[i].size; + +#else + + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != *P ) + i++; + + /* If we did not found the pointer, then this is a "small" chunk. */ + + if ( i < MAX_TRACKED_BIGCHUNKS ) + { + /* Signal we found a big one. Real size does not matter. */ + oldSize = MEMORY_MIN_GLOBAL; + } + +#endif /* DEBUG_MEMORY */ + + if ( oldSize >= MEMORY_MIN_GLOBAL ) + { + /* Deal with a big chunk. */ + HANDLE hMem, hNewMem; + + hMem = GlobalHandle ( (ULong)*P >> 16 ) & 0xFFFF; + if ( !hMem ) /* Bad call... */ + return TT_Err_Invalid_Argument; + + GlobalUnlock( hMem ); + hNewMem = GlobalReAlloc( hMem, Size, 0 ); + if ( hNewMem ) + *P = (void*)GlobalLock( hNewMem ); + } + if ( Size >= MEMORY_MIN_GLOBAL ) + { + /* A small chunk crosses the limit... */ + + if( TT_Alloc( Size, &Q ) != TT_Err_Ok ) + Q = NULL; /* Failed to create the new block. */ + else + MEM_Copy( Q, *P, oldSize ); + + /* We need to register the new entry. */ +#ifndef DEBUG_MEMORY + + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BIGCHUNKS ) + /* We fail badly here. Increase MAX_TRACKED_BIGCHUNKS if needed. */ + return TT_Err_Invalid_Argument; +#endif /* DEBUG_MEMORY */ + } + else + Q = (void*)realloc( *P, Size ); + + if ( !Q ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + +#ifdef DEBUG_MEMORY + + if ( i < MAX_TRACKED_BLOCKS ) + { +#ifndef TT_CONFIG_REENTRANT + TTMemory_Allocated += Size - pointers[i].size; + if ( Size > pointers[i].size ) + TTMemory_MaxAllocated += Size - pointers[i].size; +#endif + + pointers[i].base = Q; + pointers[i].size = Size; + } +#else + if ( i < MAX_TRACKED_BIGCHUNKS ) + { + pointers[i].base = Q; + } +#endif /* DEBUG_MEMORY */ + + *P = Q; + + return TT_Err_Ok; + } + + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Free( void** P ) + { + Int i; + Long Size = 0; + + + if ( !P || !*P ) + return TT_Err_Ok; + +#ifdef DEBUG_MEMORY + + num_free++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_free++; + else + { +#ifndef TT_CONFIG_REENTRANT + TTMemory_Allocated -= pointers[i].size; +#endif + + Size = pointers[i].size; + pointers[i].base = NULL; + pointers[i].size = 0; + } + +#else + + i = 0; + while ( i < MAX_TRACKED_BIGCHUNKS && pointers[i].base != *P ) + i++; + + /* If we did not found the pointer, then this is a "small" chunk. */ + + if ( i < MAX_TRACKED_BIGCHUNKS ) + { + pointers[i].base = NULL; + /* Signal we found a big one. Real size does not matter. */ + Size = MEMORY_MIN_GLOBAL; + } + +#endif /* DEBUG_MEMORY */ + + if ( Size >= MEMORY_MIN_GLOBAL ) + { + HANDLE hMem; + + hMem = GlobalHandle ( (ULong)*P >> 16 ) & 0xFFFF; + if ( !hMem ) /* Bad call... */ + return TT_Err_Invalid_Argument; + + GlobalUnlock( hMem ); + GlobalFree ( hMem ); + } + else + free( *P ); + + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Init( void ) + { +#ifdef DEBUG_MEMORY + Int i; + + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } + + num_alloc = 0; + num_realloc = 0; + num_free = 0; + + fail_alloc = 0; + fail_realloc = 0; + fail_free = 0; +#else + Int i; + + for ( i = 0; i < MAX_TRACKED_BIGCHUNKS; i++ ) + { + pointers[i].base = NULL; + } +#endif + + +#ifndef TT_CONFIG_REENTRANT + TTMemory_Allocated = 0; + TTMemory_MaxAllocated = 0; +#endif + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Done( void ) + { +#ifdef DEBUG_MEMORY + Int i, num_leaked, tot_leaked; + + + num_leaked = 0; + tot_leaked = 0; + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + num_leaked ++; + tot_leaked += pointers[i].size; + } + } + + fprintf( stderr, + "%d memory allocations, of which %d failed\n", + num_alloc, + fail_alloc ); + + fprintf( stderr, + "%d memory reallocations, of which %d failed\n", + num_realloc, + fail_realloc ); + + fprintf( stderr, + "%d memory frees, of which %d failed\n", + num_free, + fail_free ); + + if ( num_leaked > 0 ) + { + fprintf( stderr, + "There are %d leaked memory blocks, totalizing %d bytes\n", + num_leaked, tot_leaked ); + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + fprintf( stderr, + "index: %4d (base: $%08lx, size: %08ld)\n", + i, + (long)pointers[i].base, + pointers[i].size ); + } + } + } + else + fprintf( stderr, "No memory leaks !\n" ); + +#endif /* DEBUG_MEMORY */ + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/arch/win16/makedef b/lib/arch/win16/makedef new file mode 100644 index 0000000..e248807 --- /dev/null +++ b/lib/arch/win16/makedef @@ -0,0 +1,24 @@ +# makedef +# +# This shell script creates a .DEF file necessary for building as DLL +# on the Windows 16-bit platform. + +echo "\ +; This definition file to be used to built the library as DLL +; has been generated automatically with the script \`makedef' on +; `date +%d-%b-%Y`. + +LIBRARY ft13_16 +DESCRIPTION 'FreeType 1.3 16-bit DLL © 1996-1999 Turner, Wilhelm, Lemberg' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE SINGLE +EXPORTS +" > ttf.def + +(cd ../.. + sed -n -e "/^ *EXPORT_DEF/!d ; n ; s/(.*$//" \ + -e "s/;$//" -e "s/ const / /" -e "s/ *[a-zA-Z][a-zA-Z_\*]* //" \ + -e "s/ *//g" -e "s/^\(.*\)/ _\1/" -e "p" *.h extend/*.h) >> ttf.def + +# eof diff --git a/lib/arch/win16/makedep b/lib/arch/win16/makedep new file mode 100644 index 0000000..594952b --- /dev/null +++ b/lib/arch/win16/makedep @@ -0,0 +1,32 @@ +# makedep +# +# This shell script creates a dependency file necessary for older compilers +# on the Windows 16-bit platform. + +echo "\ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.win + +(cd ../.. + gcc -MM -Iarch/win16 -I. \ + *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.win + +(cd ../.. + gcc -MM -Iarch/win16 -I. -Iextend \ + extend/*.c | \ + sed -e "s/^\(.*\)\.o:/extend\\\\\1.obj:/" -e "s:/:\\\\:g") >> depend.win + +echo "!ifndef __MAKE__" >> depend.win + +(cd ../.. + gcc -MM -Iarch/win16 -I. -Iextend -DTT_HUGE_PTR \ + arch/win16/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\win16\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.win + +echo "!endif" >> depend.win + +# eof diff --git a/lib/arch/win16/ttf.def b/lib/arch/win16/ttf.def new file mode 100644 index 0000000..01276eb --- /dev/null +++ b/lib/arch/win16/ttf.def @@ -0,0 +1,127 @@ +; This definition file to be used to built the library as DLL +; has been generated automatically with the script `makedef' on +; 02-Sep-1999. + +LIBRARY ft13_16 +DESCRIPTION 'FreeType 1.3 16-bit DLL © 1996-1999 Turner, Wilhelm, Lemberg' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE SINGLE +EXPORTS + + _TT_FreeType_Version + _TT_Init_FreeType + _TT_Done_FreeType + _TT_Set_Raster_Gray_Palette + _TT_Open_Face + _TT_Open_Collection + _TT_Get_Face_Properties + _TT_Set_Face_Pointer + _TT_Get_Face_Pointer + _TT_Flush_Face + _TT_Get_Face_Metrics + _TT_Close_Face + _TT_Get_Font_Data + _TT_New_Instance + _TT_Set_Instance_Resolutions + _TT_Set_Instance_CharSize + _TT_Set_Instance_CharSizes + _TT_Set_Instance_PixelSizes + _TT_Set_Instance_Transform_Flags + _TT_Get_Instance_Metrics + _TT_Set_Instance_Pointer + _TT_Get_Instance_Pointer + _TT_Done_Instance + _TT_New_Glyph + _TT_Done_Glyph + _TT_Load_Glyph + _TT_Get_Glyph_Outline + _TT_Get_Glyph_Metrics + _TT_Get_Glyph_Big_Metrics + _TT_Get_Glyph_Bitmap + _TT_Get_Glyph_Pixmap + _TT_New_Outline + _TT_Done_Outline + _TT_Copy_Outline + _TT_Get_Outline_Bitmap + _TT_Get_Outline_Pixmap + _TT_Get_Outline_BBox + _TT_Transform_Outline + _TT_Translate_Outline + _TT_Transform_Vector + _TT_MulDiv + _TT_MulFix + _TT_Get_CharMap_Count + _TT_Get_CharMap_ID + _TT_Get_CharMap + _TT_Char_Index + _TT_Get_Name_Count + _TT_Get_Name_ID + _TT_Get_Name_String + _TT_Register_Extension + _TT_Extension_Get + _TT_Use_Stream + _TT_Done_Stream + _TT_Flush_Stream + _TT_Read_File + _TT_Seek_File + _TT_Skip_File + _TT_Read_At_File + _TT_File_Pos + _TT_Stream_Size + _TT_Null_FileFrame + _TT_Access_Frame + _TT_Check_And_Access_Frame + _TT_Forget_Frame + _TT_Get_Char + _TT_Get_Short + _TT_Get_Long + _TT_LookUp_Table + _TT_Alloc + _TT_Realloc + _TT_Free + _TT_CharMap_First + _TT_CharMap_Next + _TT_CharMap_Last + _TT_ErrToString18 + _TT_Get_Face_Gasp_Flags + _TT_Init_GDEF_Extension + _TT_Load_GDEF_Table + _TT_GDEF_Get_Glyph_Property + _TT_GDEF_Build_ClassDefinition + _TT_Init_GPOS_Extension + _TT_Load_GPOS_Table + _TT_GPOS_Select_Script + _TT_GPOS_Select_Language + _TT_GPOS_Select_Feature + _TT_GPOS_Query_Scripts + _TT_GPOS_Query_Languages + _TT_GPOS_Query_Features + _TT_GPOS_Add_Feature + _TT_GPOS_Clear_Features + _TT_Init_GSUB_Extension + _TT_Load_GSUB_Table + _TT_GSUB_Select_Script + _TT_GSUB_Select_Language + _TT_GSUB_Select_Feature + _TT_GSUB_Query_Scripts + _TT_GSUB_Query_Languages + _TT_GSUB_Query_Features + _TT_GSUB_Add_Feature + _TT_GSUB_Clear_Features + _TT_GSUB_Register_Alternate_Function + _TT_GSUB_Apply_String + _TT_GSUB_Add_String + _TT_Init_Kerning_Extension + _TT_Get_Kerning_Directory + _TT_Load_Kerning_Table + _TT_Init_Post_Extension + _TT_Load_PS_Names + _TT_Get_PS_Name + _TT_Init_SBit_Extension + _TT_Get_Face_Bitmaps + _TT_New_SBit_Image + _TT_Done_SBit_Image + _TT_Get_SBit_Strike + _TT_Load_Glyph_Bitmap + _TT_Get_Face_Widths diff --git a/lib/arch/win32/Makefile.BC b/lib/arch/win32/Makefile.BC new file mode 100644 index 0000000..f83104f --- /dev/null +++ b/lib/arch/win32/Makefile.BC @@ -0,0 +1,161 @@ +# This file is part of the FreeType project. +# +# It builds the library for Borland C++ for Win32. +# +# You will need Borland MAKE. +# Tested with Borland C++ v.5.0 and Borland C++ builder 4.0. +# Does not work with Borland C++ 4.0, since it needs __declspec. +# +# Use this file while in the lib directory with the following statement: +# +# make -farch/win32/Makefile.BC +# +# +# A DLL version of the library can be built with +# +# make -DDLL -farch/win32/Makefile.BC dll +# +# A debug version can be obtained with +# +# make -DDEBUG -farch/win32/Makefile.BC + +ARCH = arch\win32 +FT_MAKEFILE = $(ARCH)\Makefile.BC +FT_DLL = ft13_32.dll + +CC = bcc32 +LIB = tlib /c /e +IMPLIB = implib -c + +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig + +!if ! $d(DEBUG) +CFLAGS = -O2 -A -i40 -I$(ARCH);.;extend $(SPURIOUS_WARNINGS) +DLLFLAGS = -WD +!else +CFLAGS = -v -A -i40 -I$(ARCH);.;extend $(SPURIOUS_WARNINGS) +DLLFLAGS = -v -WD +!endif + +FT_DEF = $(FT_DLL:.dll=.def) +!if $d(DLL) +CFLAGS = $(CFLAGS) \ + -DEXPORT_DEF=__declspec(dllexport) -DEXPORT_FUNC=__declspec(dllexport) +!endif + + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces before the \ at end of line, +# otherwise the substitution for TLIB command line will fail. +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ + extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c\ + extend\ftxsbit.c extend\ftxgsub.c extend\ftxgpos.c\ + extend\ftxopen.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c\ + ttgload.c ttinterp.c ttload.c ttobjs.c\ + ttraster.c ttextend.c ttdebug.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Borland make does not handle $($(LIB_FILES)), and using +# -DLIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing TLIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# See ../msdos/Makefile.TC for an application. +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| + + +!if ! $d(DEBUG) +# Skipped if DEBUG build +all: $(OBJS_S) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_S: = + ) +| + +dll $(FT_DLL): $(OBJS_S) $(FT_DEF) +!if $d(DLL) + $(CC) @&&| + $(DLLFLAGS) -e$(FT_DLL) $(OBJS_S) +| + $(IMPLIB) libttf $(FT_DLL) +!else + $(MAKE) -DDLL -f$(FT_MAKEFILE) dll # Re-invoke with flag set. +!endif +!endif + +debug: $(OBJS_M) + -del libttf.lib + $(LIB) libttf.lib @&&| ++ $(OBJS_M: = + ) +| + +!ifdef DEBUG +dll $(FT_DLL): $(OBJS_M) $(FT_DEF) +!if $d(DLL) + $(CC) @&&| + $(DLLFLAGS) -e$(FT_DLL) $(OBJS_M) +| + $(IMPLIB) libttf $(FT_DLL) +!else + $(MAKE) -DDEBUG -DDLL -f$(FT_MAKEFILE) dll +!endif +!endif + +install: $(FT_DLL) +!ifdef INSTALL_DIR + copy $(FT_DLL) $(INSTALL_DIR) +!else + copy $(FT_DLL) C:\WINDOWS +!endif + +$(OBJ_S): $(SRC_S) $(SRC_M) + +# Not used here because it excesses the capacity of COMMAND.COM... +libttf.lib: $(LIB_FILES) + -del libttf.lib + echo -+$(**: =-+)> response + $(LIB) libttf.lib @&&| ++ $(**: = + ) +| + +$(FT_DEF): $(ARCH)\ttf.def + -copy $(ARCH)\ttf.def $(FT_DEF) + +clean: + -del *.obj + -del extend\*.obj + -del $(ARCH)\*.obj + -del libttf.bak + -del response + -del *.def + -del *.tds + +distclean: clean + -del libttf.lib + -del *.dll + -del $(FT_DEF) + -del C:\WINDOWS\$(FT_DLL) +!if $d(INSTALL_DIR) + -del $(INSTALL_DIR)\$(FT_DLL) +!endif + +!include "$(ARCH)\depend.win" + +# end of Makefile diff --git a/lib/arch/win32/Makefile.CL b/lib/arch/win32/Makefile.CL new file mode 100644 index 0000000..a4145c3 --- /dev/null +++ b/lib/arch/win32/Makefile.CL @@ -0,0 +1,165 @@ +# This file is part of the FreeType project. +# +# It builds the library for Microsoft Visual C++ for 32-bit Windows. +# +# You will need NMAKE. +# +# Use this file while in the lib directory with the following statement: +# +# nmake /f arch\win32\Makefile.CL +# +# +# A DLL version of the library can be built with +# +# nmake DLL=1 /f arch\win32\Makefile.CL dll +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\win32\Makefile.CL + +ARCH = arch\win32 +FT_MAKEFILE = $(ARCH)\Makefile.CL +FT_DLL = ft13_32.dll + +CC = cl /nologo +LIB = lib /nologo +LINK = link /nologo + +CFLAGS = /Za /W2 -I$(ARCH) -I. -Iextend + +!ifndef DEBUG +CFLAGS = $(CFLAGS) /Ox +DLLFLAGS = /RELEASE +!else +CFLAGS = $(CFLAGS) /Zi /Ge +DLLFLAGS = /DEBUG +!endif + +!ifdef DLL +CFLAGS = $(CFLAGS) /GD \ + /DEXPORT_DEF=__declspec(dllexport) /DEXPORT_FUNC=__declspec(dllexport) +!else +CFLAGS = $(CFLAGS) /GA +!endif + + +TTFILE = .\ttfile.c +TTMEMORY = .\ttmemory.c +TTMUTEX = .\ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +# Do not insert spaces between the file names or at end of line, otherwise +# the substitution for LIB command line will fail. Thank you. +# +SRC_X = extend\ftxgasp.c extend\ftxkern.c extend\ftxpost.c\ +extend\ftxcmap.c extend\ftxwidth.c extend\ftxerr18.c extend\ftxsbit.c\ +extend\ftxopen.c extend\ftxgsub.c extend\ftxgpos.c extend\ftxgdef.c +OBJS_X = $(SRC_X:.c=.obj) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c\ +ttgload.c ttinterp.c ttload.c ttobjs.c ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.obj) $(OBJS_X) + +SRC_S = $(ARCH)\freetype.c +OBJ_S = $(SRC_S:.c=.obj) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +# Since Microsoft's NMAKE does not handle $($(LIB_FILES)), and using +# LIB_FILES="$(OBJS_S)" will excess the capacity of COMMAND.COM, we cheat +# by constructing LIB's response file directly in the `all' target. +# +# Another solution, useful during debugging of part of the library, +# would be to include each .obj in the library as soon as it is compiled. +# See ..\msdos\Makefile.TC for an application. +.c.obj: + @$(CC) /c /Fo$@ @<< + $(CFLAGS) $*.c +<< + + +!ifndef DEBUG +# Skipped if DEBUG build +all: $(OBJS_S) + -del libttf.lib + $(LIB) /OUT:libttf.lib @< dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.Min diff --git a/lib/arch/win32/Makefile.VC b/lib/arch/win32/Makefile.VC new file mode 100644 index 0000000..7974aa7 --- /dev/null +++ b/lib/arch/win32/Makefile.VC @@ -0,0 +1,195 @@ +# Visual C++ 2.x, 4.x, 5.0 and 6.0 makefile for freetype +# adapted from suns example makefile (related to the TCL script language) + +# Does not depend on the presence of any environment variables in +# order to compile freetype; all needed information is derived from +# location of the compiler directories. + +# +# Project directories +# +# ROOT = top of source tree +# +# TMPDIR = location where .obj files should be stored during build +# +# TOOLS32 = location of VC++ 32-bit development tools. Note that the +# VC++ 2.0 header files are broken, so you need to use the +# ones that come with the developer network CD's, or later +# versions of VC++. +# + +ROOT = ..\.. +TMPDIR = . +#TOOLS32 = c:\msdev # VC++ 2.x,4.x +#TOOLS32 = c:\Program Files\devstudio\vc # VC++ 5.x +TOOLS32 = c:\Program Files\Microsoft Visual Studio\Vc98 # VC++ 6.x +INSTALLDIR = c:\WINNT\SYSTEM32 + +# Set this to the appropriate value of /MACHINE: for your platform +MACHINE = IX86 + +# Comment the following line to compile with symbols +NODEBUG=1 + + +###################################################################### +# Do not modify below this line +###################################################################### + +TTF = ttf +TTFLIB = $(TTF).lib +TTFDLL = $(TTF).dll + +TTFOBJS = \ + $(TMPDIR)\ttapi.obj \ + $(TMPDIR)\ttcache.obj \ + $(TMPDIR)\ttcalc.obj \ + $(TMPDIR)\ttcmap.obj \ + $(TMPDIR)\ttdebug.obj \ + $(TMPDIR)\ttfile.obj \ + $(TMPDIR)\ttgload.obj \ + $(TMPDIR)\ttinterp.obj \ + $(TMPDIR)\ttload.obj \ + $(TMPDIR)\ttmemory.obj \ + $(TMPDIR)\ttmutex.obj \ + $(TMPDIR)\ttobjs.obj \ + $(TMPDIR)\ttraster.obj \ + $(TMPDIR)\ttextend.obj \ + $(TMPDIR)\ftxcmap.obj \ + $(TMPDIR)\ftxgasp.obj \ + $(TMPDIR)\ftxkern.obj \ + $(TMPDIR)\ftxpost.obj \ + $(TMPDIR)\ftxwidth.obj \ + $(TMPDIR)\ftxerr18.obj + + +PATH=$(TOOLS32)\bin;$(PATH) + +cc32 = "$(TOOLS32)\bin\cl.exe" +link32 = "$(TOOLS32)\bin\link.exe" +include32 = "-I$(TOOLS32)\include" -I$(ROOT)\arch\win32 +CP = copy +RM = del + +TTF_INCLUDES = -I$(ROOT) +TTF_DEFINES = -nologo -D__WIN32__ -D__WIN32DLL__ + +TTF_CFLAGS = $(cdebug) $(cflags) $(cvarsdll) $(include32) \ + $(TTF_INCLUDES) $(TTF_DEFINES) +CON_CFLAGS = $(cdebug) $(cflags) $(cvars) $(include32) -DCONSOLE +DOS_CFLAGS = $(cdebug) $(cflags) $(include16) -AL + +###################################################################### +# Link flags +###################################################################### + +!IFDEF NODEBUG +ldebug = /RELEASE +!ELSE +ldebug = -debug:full -debugtype:cv +!ENDIF + +# declarations common to all linker options +lcommon = /NODEFAULTLIB /RELEASE /NOLOGO + +# declarations for use on Intel i386, i486, and Pentium systems +!IF "$(MACHINE)" == "IX86" +DLLENTRY = @12 +lflags = $(lcommon) /MACHINE:$(MACHINE) +!ELSE +lflags = $(lcommon) /MACHINE:$(MACHINE) +!ENDIF + +conlflags = $(lflags) -subsystem:console -entry:mainCRTStartup +guilflags = $(lflags) -subsystem:windows -entry:WinMainCRTStartup +dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll + +!IF "$(MACHINE)" == "PPC" +libc = libc.lib +libcdll = crtdll.lib +!ELSE +libc = libc.lib oldnames.lib +libcdll = msvcrt.lib oldnames.lib +!ENDIF + +baselibs = kernel32.lib $(optlibs) advapi32.lib +winlibs = $(baselibs) user32.lib gdi32.lib comdlg32.lib winspool.lib + +guilibs = $(libc) $(winlibs) +conlibs = $(libc) $(baselibs) +guilibsdll = $(libcdll) $(winlibs) +conlibsdll = $(libcdll) $(baselibs) + +###################################################################### +# Compile flags +###################################################################### + +!IFDEF NODEBUG +cdebug = -O2 -Gs -GD +!ELSE +cdebug = -Z7 -Od -WX +!ENDIF + +# declarations common to all compiler options +ccommon = -c -W3 -nologo -YX -Dtry=__try -Dexcept=__except + +# NEED BYTEORDER INFORMATION HERE !! +!IF "$(MACHINE)" == "IX86" +cflags = $(ccommon) -D_X86_=1 +!ELSE +!IF "$(MACHINE)" == "MIPS" +cflags = $(ccommon) -D_MIPS_=1 +!ELSE +!IF "$(MACHINE)" == "PPC" +cflags = $(ccommon) -D_PPC_=1 +!ELSE +!IF "$(MACHINE)" == "ALPHA" +cflags = $(ccommon) -D_ALPHA_=1 +!ENDIF +!ENDIF +!ENDIF +!ENDIF + +cvars = -DWIN32 -D_WIN32 +cvarsmt = $(cvars) -D_MT +cvarsdll = $(cvarsmt) -D_DLL + +###################################################################### +# Project specific targets +###################################################################### + +release: $(TTFDLL) +all: $(TTFDLL) + +install: $(TTFDLL) + -@md $(INSTALLDIR) + -@$(CP) $(TTFDLL) $(INSTALLDIR) + + + +$(TTFDLL): $(TTFOBJS) ttf.def + $(link32) $(ldebug) $(dlllflags) \ + $(guilibsdll) -out:$(TTFDLL) -def:ttf.def $(TTFOBJS) + +#ttf.def: $(TTFOBJS) +# ..\..\tcl8.0.4\win\release\dumpexts -o $@ ttf.dll $(TTFOBJS) + + +# +# Implicit rules +# + +{$(ROOT)\extend}.c{$(TMPDIR)}.obj: + $(cc32) $(TTF_CFLAGS) -Fo$(TMPDIR)\ $< + +{$(ROOT)}.c{$(TMPDIR)}.obj: + $(cc32) $(TTF_CFLAGS) -Fo$(TMPDIR)\ $< + + +clean: + -@del *.exp + -@del *.lib + -@del *.dll + -@del $(TMPDIR)\*.obj + -@del *.pch + -@del *.pdb diff --git a/lib/arch/win32/Makefile.gcc b/lib/arch/win32/Makefile.gcc new file mode 100644 index 0000000..68c9f4e --- /dev/null +++ b/lib/arch/win32/Makefile.gcc @@ -0,0 +1,96 @@ +# This file is part of the FreeType project. +# +# It builds the library for gcc under Win32. +# This Makefile will fail with MinGW32 ports of gcc and make under +# bare-bones Windows 9X, because of the limitations of command.com. +# Use Makefile.min instead. +# +# You will need GNU make. +# +# Use this file while in the lib directory with the following statement: +# +# make -f arch/win32/Makefile.gcc +# +# +# If you have the GNU gettext package installed, you can also try +# +# make -f arch/win32/Makefile.gcc HAVE_GETTEXT + +ARCH = arch/win32 +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +ifndef GETTEXT +GETTEXT=NO_GETTEXT +endif + +ifdef DEBUG +CFLAGS = -Wall -O2 -g -ansi -pedantic -I$(ARCH) -I. -Iextend -D$(GETTEXT) +else +CFLAGS = -Wall -ansi -pedantic -O2 -s -I$(ARCH) -I. -Iextend -D$(GETTEXT) +endif + + +TTFILE = ./ttfile.c +TTMEMORY = ./ttmemory.c +TTMUTEX = ./ttmutex.c + +PORT = $(TTFILE) $(TTMEMORY) $(TTMUTEX) + +SRC_X = extend/ftxgasp.c extend/ftxkern.c extend/ftxpost.c \ + extend/ftxcmap.c extend/ftxwidth.c extend/ftxsbit.c \ + extend/ftxgsub.c extend/ftxgpos.c extend/ftxgdef.c \ + extend/ftxopen.c extend/ftxerr18.c +OBJS_X = $(SRC_X:.c=.o) + +SRC_M = ttapi.c ttcache.c ttcalc.c ttcmap.c ttdebug.c \ + ttgload.c ttinterp.c ttload.c ttobjs.c \ + ttraster.c ttextend.c $(PORT) +OBJS_M = $(SRC_M:.c=.o) $(OBJS_X) + +SRC_S = $(ARCH)/freetype.c +OBJ_S = $(SRC_S:.c=.o) +OBJS_S = $(OBJ_S) $(OBJS_X) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +.PHONY: all debug clean distclean depend + + +all: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S libttf.a + +debug: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_M DEBUG=1 libttf.a + +HAVE_GETTEXT: + $(MAKE) -f $(FT_MAKEFILE) LIB_FILES=OBJS_S GETTEXT=HAVE_GETTEXT \ + libttf.a + +$(OBJ_S): $(SRC_S) $(SRC_M) + +libttf.a: $($(LIB_FILES)) + -del $@ + ar src $@ $^ + +clean: + -del *.o + -del extend\*.o + -del $(subst /,\,$(ARCH)/*.o) + -del response + +distclean: clean + -del dep.end + -del libttf.a + +depend: $(SRS_S) $(SRC_M) $(SRC_X) + $(CC) -E -M $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/lib/arch/win32/depend.win b/lib/arch/win32/depend.win new file mode 100644 index 0000000..7fd99bc --- /dev/null +++ b/lib/arch/win32/depend.win @@ -0,0 +1,103 @@ +# This dependency file to be used with various Win32 compilers +# has been generated automatically with the script `makedep' on +# 03-Sep-1999. + +ttapi.obj: ttapi.c ttconfig.h arch\win32\ft_conf.h freetype.h fterrid.h \ + ftnameid.h ttengine.h tttypes.h ttmutex.h ttcalc.h ttmemory.h \ + ttcache.h ttfile.h ttdebug.h ttobjs.h tttables.h ttcmap.h ttload.h \ + ttgload.h ttraster.h ttextend.h +ttcache.obj: ttcache.c ttengine.h tttypes.h ttconfig.h \ + arch\win32\ft_conf.h freetype.h fterrid.h ftnameid.h ttmutex.h \ + ttmemory.h ttcache.h ttobjs.h tttables.h ttcmap.h ttdebug.h +ttcalc.obj: ttcalc.c ttcalc.h ttconfig.h arch\win32\ft_conf.h freetype.h \ + fterrid.h ftnameid.h ttdebug.h tttypes.h tttables.h +ttcmap.obj: ttcmap.c ttobjs.h ttconfig.h arch\win32\ft_conf.h ttengine.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmutex.h ttcache.h \ + tttables.h ttcmap.h ttdebug.h ttfile.h ttmemory.h ttload.h +ttdebug.obj: ttdebug.c ttdebug.h ttconfig.h arch\win32\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h tttables.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h ttcmap.h +ttextend.obj: ttextend.c ttextend.h ttconfig.h arch\win32\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttmemory.h +ttfile.obj: ttfile.c ttconfig.h arch\win32\ft_conf.h freetype.h \ + fterrid.h ftnameid.h tttypes.h ttdebug.h ttengine.h ttmutex.h \ + ttmemory.h ttfile.h +ttgload.obj: ttgload.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttdebug.h ttcalc.h ttfile.h \ + ttengine.h ttmutex.h tttables.h ttobjs.h ttcache.h ttcmap.h ttgload.h \ + ttmemory.h tttags.h ttload.h +ttinterp.obj: ttinterp.c freetype.h fterrid.h ftnameid.h tttypes.h \ + ttconfig.h arch\win32\ft_conf.h ttdebug.h ttcalc.h ttmemory.h \ + ttinterp.h ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h \ + ttcmap.h +ttload.obj: ttload.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttdebug.h ttcalc.h ttfile.h \ + ttengine.h ttmutex.h tttables.h ttobjs.h ttcache.h ttcmap.h \ + ttmemory.h tttags.h ttload.h +ttmemory.obj: ttmemory.c ttdebug.h ttconfig.h arch\win32\ft_conf.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmemory.h ttengine.h \ + ttmutex.h +ttmutex.obj: ttmutex.c ttmutex.h ttconfig.h arch\win32\ft_conf.h +ttobjs.obj: ttobjs.c ttobjs.h ttconfig.h arch\win32\ft_conf.h ttengine.h \ + tttypes.h freetype.h fterrid.h ftnameid.h ttmutex.h ttcache.h \ + tttables.h ttcmap.h ttfile.h ttdebug.h ttcalc.h ttmemory.h ttload.h \ + ttinterp.h ttextend.h +ttraster.obj: ttraster.c ttraster.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttengine.h tttypes.h ttmutex.h \ + ttdebug.h ttcalc.h ttmemory.h +extend\ftxcmap.obj: extend\ftxcmap.c extend\ftxcmap.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\win32\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h +extend\ftxerr18.obj: extend\ftxerr18.c ttconfig.h arch\win32\ft_conf.h \ + extend\ftxerr18.h freetype.h fterrid.h ftnameid.h extend\ftxkern.h \ + extend\ftxpost.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h +extend\ftxgasp.obj: extend\ftxgasp.c extend\ftxgasp.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\win32\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h +extend\ftxgdef.obj: extend\ftxgdef.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxgpos.obj: extend\ftxgpos.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxgsub.obj: extend\ftxgsub.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h tttags.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxkern.obj: extend\ftxkern.c extend\ftxkern.h freetype.h fterrid.h \ + ftnameid.h ttextend.h ttconfig.h arch\win32\ft_conf.h tttypes.h \ + ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttdebug.h \ + ttmemory.h ttfile.h ttload.h tttags.h +extend\ftxopen.obj: extend\ftxopen.c tttypes.h ttconfig.h arch\win32\ft_conf.h \ + freetype.h fterrid.h ftnameid.h ttload.h ttobjs.h ttengine.h \ + ttmutex.h ttcache.h tttables.h ttcmap.h ttextend.h ttmemory.h \ + ttfile.h ttdebug.h extend\ftxopen.h extend\ftxgdef.h extend\ftxgsub.h \ + extend\ftxgpos.h extend\ftxopenf.h +extend\ftxpost.obj: extend\ftxpost.c extend\ftxpost.h freetype.h fterrid.h \ + ftnameid.h tttypes.h ttconfig.h arch\win32\ft_conf.h ttobjs.h \ + ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttload.h ttfile.h \ + ttdebug.h tttags.h ttmemory.h ttextend.h +extend\ftxsbit.obj: extend\ftxsbit.c extend\ftxsbit.h freetype.h fterrid.h \ + ftnameid.h ttobjs.h ttconfig.h arch\win32\ft_conf.h ttengine.h \ + tttypes.h ttmutex.h ttcache.h tttables.h ttcmap.h ttfile.h ttdebug.h \ + ttload.h ttmemory.h tttags.h ttextend.h +extend\ftxwidth.obj: extend\ftxwidth.c extend\ftxwidth.h freetype.h fterrid.h \ + ftnameid.h ttdebug.h ttconfig.h arch\win32\ft_conf.h tttypes.h \ + ttobjs.h ttengine.h ttmutex.h ttcache.h tttables.h ttcmap.h ttfile.h \ + tttags.h ttload.h +!ifndef __MAKE__ +arch\win32\freetype.obj: arch\win32\freetype.c ttapi.c ttconfig.h \ + arch\win32\ft_conf.h freetype.h fterrid.h ftnameid.h ttengine.h \ + tttypes.h ttmutex.h ttcalc.h ttmemory.h ttcache.h ttfile.h ttdebug.h \ + ttobjs.h tttables.h ttcmap.h ttload.h ttgload.h ttraster.h ttextend.h \ + ttcache.c ttcalc.c ttcmap.c ttdebug.c ttgload.c tttags.h ttinterp.c \ + ttinterp.h ttload.c ttobjs.c ttraster.c ttfile.c ttmemory.c ttmutex.c \ + ttextend.c +!endif diff --git a/lib/arch/win32/freetype.c b/lib/arch/win32/freetype.c new file mode 100644 index 0000000..8c391a7 --- /dev/null +++ b/lib/arch/win32/freetype.c @@ -0,0 +1,42 @@ +/* This file is part of the FreeType project */ + +/* single object library component for Win32 */ +#define TT_MAKE_OPTION_SINGLE_OBJECT + +/* Note, you should define the EXPORT_DEF and EXPORT_FUNC macros */ +/* here if you want to build a Win32 DLL. If undefined, the */ +/* macros default to "extern"/"" (nothing), which is suitable */ +/* for static libraries. See `ttconfig.h' for details. */ + +/* The macro EXPORT_DEF is placed before each high-level API */ +/* function declaration, and EXPORT_FUNC before each definition */ +/* (body). You can then use it to take any compiler-specific */ +/* pragma for DLL-exported symbols */ + +/* first include common core components */ + +#include "ttapi.c" +#include "ttcache.c" +#include "ttcalc.c" +#include "ttcmap.c" +#include "ttdebug.c" +#include "ttgload.c" +#include "ttinterp.c" +#include "ttload.c" +#include "ttobjs.c" +#include "ttraster.c" + +/* then system-specific (or ANSI) components */ + +#include "ttfile.c" +#include "ttmemory.c" +#include "ttmutex.c" + +/* finally, add some extensions */ + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.c" +#endif + + +/* END */ diff --git a/lib/arch/win32/freetype.dsp b/lib/arch/win32/freetype.dsp new file mode 100644 index 0000000..b04390b --- /dev/null +++ b/lib/arch/win32/freetype.dsp @@ -0,0 +1,104 @@ +# Microsoft Developer Studio Project File - Name="freetype" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=freetype - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "freetype.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "freetype.mak" CFG="freetype - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "freetype - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "freetype - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe + +!IF "$(CFG)" == "freetype - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O1 /I "." /I "..\.." /I "..\..\extend" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c +# SUBTRACT CPP /YX +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "freetype - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /Zi /O1 /I "." /I "..\.." /I "..\..\extend" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c +# SUBTRACT CPP /YX +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "freetype - Win32 Release" +# Name "freetype - Win32 Debug" +# Begin Source File + +SOURCE=.\freetype.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\Ftxcmap.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\ftxerr18.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\Ftxgasp.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\Ftxkern.c +# End Source File +# Begin Source File + +SOURCE=..\..\Extend\ftxpost.c +# End Source File +# End Target +# End Project diff --git a/lib/arch/win32/freetype.dsw b/lib/arch/win32/freetype.dsw new file mode 100644 index 0000000..e21f7cd --- /dev/null +++ b/lib/arch/win32/freetype.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "freetype"=.\freetype.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lib/arch/win32/freetype.ide b/lib/arch/win32/freetype.ide new file mode 100644 index 0000000000000000000000000000000000000000..f5c4043e5723a9165e1ea4f6478b6d4a324a69a1 GIT binary patch literal 35542 zcmeHwdtg=7neRF$uagk+1_A^);2}l~F+4<6RPqF32r&tYh(KN>!H~q{fQT=|=U5e_ z*0GOqtaY5JLmg`^wG88UTc=|?*4mC^t<&47FTnSJzXqNH{wwf(;J*Pgf&UKt58!Wr z9|Hdq_!028z~2Es2Ab@Mi2$R(G+;U~1DFZS0>*&Zz#QN-U@mYvFb|jyEC3b)i-5(z z65tHrOyDeFDR4G$4sb583^)%sAGiP*2QCCI0w#b@!lw^_r{Q-w@N{4W@C@J*;F-Wm z;8I`}@GM|8a2aqpa0PHB@ND2J;5oq6z;l7;0nZ1n0bT&S5O@)AEwBby3#&i zz;(d&zzx7A;KjgZ;6`8za4~QbuoZX-unpJ_+zh-Fco}dD@N(c*;1$4az$<~;rZH`+)<%-N37WgTOt&uOP1;1^x-}G2ov932)zPOhRgbHX4+h zsTmn*DBnNQJDRMjsuG?`(ctrxn5wF6_}{xf**ny;ZC7&t$naRw>Z=q>sd%sI9UW3$ zdZd7QF+p!%=h%qy(sKpWp9#FZqod1KJAXBW>BOuOl_`*_#}$?;SyPaeS51yZU^^rmc6+@V?%7 zd60F6q;IYC!anaA%G)_O7{9{jzcM~F+|xT2-!(eCC*COmS61x76$(d6HDJvB zE{-F*LX`Pf)3&bN$jrr;$v5R4dq=y58j`j{E zTRYY}Y{##Su% z`=q$c5H%iiGPCKL!8&xRqe-ck37I`=d=&l5@HK9Xc!?ZbOVyL&}fv&=w!z7@tct_1k%F6}@|Qs@27!EcBz{pQPJvsq@czOI#OQ)|TF zwehjuK|B=n_5{0ln2IlpCx_$wv0VE=&WIJ#(Fcz9_6>|BgZWe`GiK$%yp(-l+q#C1 z_|mrCzV_Zxq}P~H@vUBF);@0~#vbbH9gQdZd(}a$vYlh`&Y}3G<_7pHT0}>s%*=fq ztiR6Q<{`M}EDCS6%;0_AnWkKLtVwEC|1K8(^)lP{`KwHT{nL18E)qRu^2FflLBBIH z>iXb>JV|I=6m!J3y+iHY7}k?~NR#?dDNh>8!#P)Z^KfSmvZE&s?zm;QWwcVBNPOP8 z#$z1?YiGRMa>sX3dy)9JQl4OZnR#Y?@8HM|H#&~SS1j)uNapl+W1{7?_qaUqs0_!B z@$m_H8q#ChGTCcjplASi5{OR47Is4fJf< zn;hAjZ0$_;+w$y?Cr6*>Jf}liNPll<4;l-La*PQa?d`Tsv2yxe^>ijXyE?}(&-se0 zk9-nUD3*E7$bM_DLY`1Hj^kNd-452o9SuDL$zinJJ6xXeDOQ2y%Xp;Ec4Lyh3VF)) zdGduPUankYC_|eM@+9mS*#@W!sd384QzlQ!zAm((T|?e;5uczH*yq#^B=Hn7-fx@d z74oF*^X7>y%P$QMQPw9ujVoyS;^mf8dHA%hfai1THyVpP0*Rh7d7Afm;CI&^_k2_) zPx<5GMmZa${YrWI_v4C8-QLl$;nDGF`my9+g{%_zyf#gi-=^t%E}yxQpx~#;a%%Z= zr9pwu7*ZCPKESx`G(=aKtVZ~JNEdii2UjT+sAEI-@X$EVoj+X3P*8u!D_%Puu5>7H z-Y))>lgpUH!c!qDAwG{ye|!Ke)?=e{L#~!6*k`%!VfC4-C<<6xVLKb=@|$9-QdU}g zzG7E@hB`;D_3L$BHp{SDR%CqMna=mx0dmKEcC7r6zf4wde17C<&*(nuUzx1xjEmdX z<=SkStoDqH>mKo*m$(X~AZgx(oO5~0)gcA0Pi&}f*ipBxdBdKOVK=X-l+`1j2lWtL z>bkw1qdm>TeU1?;Z}h)XR+)U>8K&Ga#66ifgrt7A%4(F)yUI*p9UShH;)_>Q!KX9W z!LeW4*gH1X+1KlOb84`8$CWJwNoRN8ppks7kQFbDi=u2jf9i&Zb`A8QZ=sHatcv-3 zxu&}hbqEZ>c_3HK6tG68^9_vS)KMWTYJPkno-;MWkPTvue66zT=JT!MxF5(T%er^8 zGdX}-yg4~AIFP)S6M1j4W@qvSE1EX_T)|Ut>33@pm9m=W#}%2H_Qsa;bTNj5+-g2X zTRmI_RG5Z2ezJG}*>>%xT2|XM4r`1P)`_@Q#b+KJSGj_yz_#m|1dsNiTwzpT9klCT z9UV2T8>;HWr)pV&RGuvKCzi+4hE*N~TLxUMRPgzeNmrU~Y)#0Drq7pcb|rU^1Z$_!Q03c$wVcsweY;$NRS4SUI@_3Mw_a9hl`qXKHFf80!voQ}wwjIc#tqF4?c4YW zQPWbtt+wv$ZFq=p-dx|XZ43)cLw(S~G}g;1uj_EpMF59}s6?KKQKpnyoqvZ5&UAnmHt`Mxdm=9vg z2%j7uSLPKm0{Xa?%Y1sr@p1KDA()?ocpM?$8;*}F{0baPweI#g##bF5cL5ZFb$qmw zPl3LF+$m59^4V2#pO3o<3clTrj=Gw<^$qAvo^f`$w;w#)rIl)@79({9bYt#?;1R@|_pBYf4eOQn31jh)ig zx(#+SnVxFd(en9cxi;kQ3(1}g2HU@J{M`Lgm`p$SdpI`dOW9P*PFX5`?j?bLbfDAv z!(BB6>@AM>2hL!qShgAh|1SQN$*!5tpKj`h>)l+tT6X9BIMroyc3VSRTYET`n_gP^wzw0;-fxpqUY3@=h`22pK(Z@*?`hfeKe(q>1Ov;Z5J^62Q{M`Lk zn3R8PZx{Kmb^P2ZSD1`{7`v9_-{bhXtFAB^{}|R*$Zz*_t7Qk?=huG3PwzDYJ;{Cu zY>x5iRG}$NfBk>@`{lq;+85Hkmv$;`etKB033qm8H~3GL~dCW^`rT znDK>-?_~Tcqbjp0b64h}%!e{hWWJjDVdl)N^Rh0@+L!fI)=OFMWaY$m#SXGcNgAX_*CKRg}*B-FRCrtU372JQ$?>AeNZ&NxT*L+@dL$A6~9#cPH|qzc_q6_ zj+gwTzKbi5n8FOYf%^aF}bmn(vzB4m#)~Z?CXWc&QiCM4Cnp3*H z^pVmZl%6V`Gkg2&M`r(E_Nm!(=G4yFJ?H406La32lQVbu+^usD&3%0CPv(9&cTrhW z*=X7EvR{;C&a0Yt>Ac(L9iR8hc{ArX&hMIkbpDC?@669x(6Zp@f)fkgT#yrA9^V>2 z6n{MalX!IDl7(9r-nH<=!gm(VS=6-Xz@o<&y>LOADaFG~)Et`eM#&>mG<<98g+(!} zDMfJKm_fWsB(HNx?5hzQ7nOUb9zSb9p3yv?$ahAZwmi9Bxe05`bYZ&^^5*e z_vH5TVeRjPU+ou6VLxFQQ|j5*bZGwA^b~^U#c}$IrqG9VX2irzp5}-1`)TLz4^iXj zlhs=c-XD(BTQa3y#!Rl43dZZ50p6F!>76-+-h^RH={SGs-*|nq!1JSV`bwwJSBYol zsF`P0L}r^EJ7ivZ!SeHW?7$;tT?6Q4HEk_aWYa$zyf2T_J149+h8=sfuUune*jH7W zx!~g4j(9eezAC@P#15IJw4sO%i%QdXYX zR%ZSLnFXE9GW<1}O!)+v(>)pfnoOo* zg3KA741Y}~vt)t{M+IBfXW|#%$mH9Hc#~k}U}P!ogu(JwBIY#VCC3{WX*i06fo1qy zCbc}3`H^c^vt4`pg==paF8ncjdO(^B{}y4E_X33J&rEke*lwk|xcG>puc99%EOz|m zpda64%vWKLknZlYU!r`m3(s)jGDl0@{ckzBe{u91jvjY3*YV{$s{Kg9h5rhCv@^?v zpL25a5oY?HaN);68UAw@e$&yPx%B*#3xCbgZ#sIK)BBMN|J3pSqodPZd^YGg(7)7$ zS2$Yb=vj^~0%b|Qhanlmo6WReJNgGs>B>mdEHP)xb(LJtk?U%?o-5b$iC!OsN9sN&7V{o(w{8^y0L4W7&f9$AnzGk`v z9g150`yAcx=w495^^V@|=&dfk%h7|5-sR}Ej^5_zRiK2=xbQuW-s$KSj`o8RdR=&z zqkWEk&c%1T@O_RRb@YBmA8_;!9qn=SN=LUldce_ZKneFcI_B@(+%m6DR^FP=sgP{l9i$PCy7cHT^f& zalKxUVOCTvt2Y1YZu|!*EA)p9$Bp^5yRRenlj*pRruKPf;1Fmw_-|&oz?hfa{o5S9 zRp?st04VkT*xkR|(YqY|jH53)`a?%wa`Z=z{=Luw^9m{K-QvPOA%(wpNZ6RqIr<3lVAt?3!JM@sg=E6Un20s9=I{G>&+%&Jb z@Xs9mlH>m(_2K_Rj{XrTpwSgr(uJ>c^lDJ{xF5KJz0=+QjSK5sqZ;FvU5nQF$qL-D z^N?luHGb~09Cz&8g}=s+!MxuZp>%y@Eq1iIi#zvI1_aJ$h`^fg#PU7*C)8s`T5?%3GQSrTYpc2JC&sTUL;--TgY!lNVy|O z%5O)$p1e1~??(!*xFf+`x!0hF-;pq$J7=Wa{d%D7aDuyAw8Pyi@^N=+{lFaw?mqE8 zcb5t-Kb+w1(c-O#6Wkqo2Ku@Cle6n^g1b8%NDp^!_9M*QnXYJEg1avtAf!Fm z;O09L+#Q(>{`H`h9fuR#-8i`QjzkkE{o)S9`CINtaED&%9j1N6@K+Dgo-5z)-1V22CHM_b&dF5?uKrI}-@_Ys~bvJ)1Kgvw)1V8F< zhdvxM{FQ_cdGc*j{SAi`-O$|vI+YJvo>~r{R1dV?XdB|nH|xADuZ9V}F;{F|U58(` zt}cemkI^nP-T&3TY26CfJ?$sL<*s#bsyeJ~NZXE0`}zrK-{8`I5Z?xAxokq(*)F(J z-@2v!zr0-R8e0?W_roII1(xU5O?Ynoj5(A(Bz=kX|KbV$v&5`?Gk$UHU*#`@{N0|s z<=F@xuJ#Lq&@Ei{Dw1Q_(faeIkF`3|4yHYt_Hx=sX%*=m=?BvvO@BH4qx6c5l^HuT zuFtqX<>YG!OJ zc~mrT1=g4();Onu4uPhdm7BRj8UY`_m&KgxGWc(8kC@cbmEeV!7@PiPf2oxN2})yQGAm z&Si*=;~sTZO`?-?9|fy313H(d)VU&{lM9*_d_QNYLQtzS6FOI>)OohV@=2Y-i<|~u z=UjJ(#Olm~PJWv_dD``hWt6iN!ese5pK%UsImV##T+h#^*RveUL*b@dSg2bdmJl*s`U0Dl9K>BXrOxjmm1_~(Pq`^{o<2e6H0Z3EQfDn< z>VWu+OXlf~5$hEa?D;8qhn2!~uvkBH5m!H@&IZIZ0(Yj+c?RRg>6{Lo>!#GX9x)q$ zSBc!@`ME^mg87*TolR5fycjXfz}+cyo*B?->qb6wZuE3Mw}ExztWe!30M90m$Eo+) zV=H1V0d^uHf^u9M(RxnZ0x^HzQ}etKacxuTY)4E7uq%bmYEf<1NNrk*pc9=Nfc=$e zVp^7m(ozhb%X}Wu;rA_D5OX>365f|O+3q-~TOhVfNWRn`Yqtb(J3O6h#O}(F-5KEN z^mv?7FAuvA(@jJK^YAP$52;%qwnBwKt=*Z38}M{KFLuu{yK#p%ZQY&)o~t|_RY4wp zCyE_8vj>P5{zGk$x&>lq3$gXk+AT#K#u9+!^To{PbImaB@TRpp8$2UEkLWPM!&4Nn z>t;rQJ-BbvtL>D!1!Aj(1j~00;;!>_9ud21%=Ng#o7V1J@Z8|>SXEfC!X2L6a3knV zz(GVr3fS({E_DmU&J$7^DBm)~^>{j86uTG7cdNW0 z{NDC6pmzhS#crDP$(Dz@1!A?9%GKIE4RQB)I-eH1O(DAp@ErDdRE6f%5yadFtkDRM zQnx^Cy?0OB=3>Mh^>n@`cAG35WCn?x!STj9dVzV zR3}d!!2_N7L!jssE>+;`+^DxeZ5~!Y=YyWk>K2yWCOO4~H?7?>!1H;JM^)&zx?e!d z7l8|01jkbg)GZK`tu%Mn>Rf`jFHNeGr>9WoL!Y3t)#)R#I?sg8Kb}-4>lk%@`4egh~M{+I z#C=0_euVzvNwM1@-z)Q`wR;wLp7wZDg`PU|O~f1riru)zl2Z3Xuy(5v_bpH7yJB~< ze7nq>*6uR!Jmc}GCZ2Lb_%_H1;6%IBJrS(k<%r`MId@bLVc z@$=_@#vPuh^Bf|63F_BF?T4vbAa<#cf+5N*V8Z#O~#CGLLWf>~TDz0vCR( z%+q_m3r3#cqvgBQ8+WK%Ahtz?Ky7+gA?|NHyAO-qD?)b98ONh4Xg7FT&_uh`EfCwP zLZH^}YQ()Hb~)~pwlbf$hx)E_$ML8N_FZg8KN4wU9%e*DOSC?3PlUR$PL3zhZH#kZ z?Vg7?o@r$BxkK#k4B0(@9FNLtU#+JhJ;w-)P5$^!-2$;4mde%IU4uBDpJeSG5xZUT zZ87iJdUXMKc(&5`dUXnSc-j)@6+Cf?`8B@I4;-2vA#x7y`?h4th8ONh4)b7_I{S@#Z zBaqKNP`5x#=9DhN=5sCLcovn-!+NpXAF^9Fj>m}$55H4B2f{qX>SjiWU2VVAEfAAu zRI@P9e(Mp(Gp}qupA@@Sh3qzf$9_%BvaqWBeAbh)q^%SN=N{B;?aDK!6SV1VL|guV94KXXT)7ff(nq3fAs=#ASIp-xj;0A-fyE z6Z3dfUduNdF*!hKqvPySw?J$}g+Q&{CdB1>I(N1+y?aA;F9y$ak4IIg-8{tP1FvMn zIJ?v>5F4{puGVfd;tD;TcX!b4bs@VO!Bgb%s0y`Pj2M3Zy`2$-SUG2*2~f8{Y@ela zwRT$&SL*3Z-%PtVhU{(v&uouJRjB?sh?xt7WXLXc3&gIsRIb);E8^yPIG%Q@VQ7ybanLZ=o`_M zX?LdmJgpjQo_~h*&Ui*L&Kt99G1(pHl0p|l30OLURON)S~0TaN*z;fW}zzX0Qz$L&l zft5hQk?k?8J=1IH#9WC4NNlDA`20lR`l*#+D(wg(5y4Arsf5_i6AC;T=1Q7Z|0Pl{ zG30Lmxc+JFFc(psWWMV&jI3jem}mMi?sL8{7}`8@!BUbEH&&u|Mc#fl{`(GF`_ z@NBoBOi3UREK}CX;F)g$w%Ck7ASlCH%(LKP!t#rvA6^{ zo)fs<0r^W ztqeyMo(4M!#IE%EUX8Uf9EF1C?`Z7g)XH$wl1_diQ%v_9{3t8KQ7(f6!$gS5TBzat zSHa3~RLq=0W=L2k%5W5&HigX9BE$Kvg0;g@H+U9{#)8Ihs1Ja1RRt@EL%2{1$@W zE$|xyeiy)Z`1!uJg>qBS6O}#nOtUr8#0Pr-ZTx)TNxTOzh_8wGMJi4Vft4m$$;4YS zdGhrU-|FWZ5`4>nZ!z#K1-^yAw+y1-O9Q3@Gk}@EEFi(Y_dpJwf~@Z={B4bi-RHfF zV0ozFD*>K=X*aQ>As$+IG{Cc<*u*{?;-LpTr&n#w+G%3iN&{9FQwm^Zu>*#Yz6j)BDjlp957U8 zn*L*1rXD$)C5Sf=-P3tgczF6Kd5u>Z5|GOnGv6V_XuBy38&SUh2KQqzifomw`q)-J{Vzr2t)eK zs*e)JrI!*S<)wFeKwmz7uZ2F=tuXldD53f&LG=AAKuG&WFL*M+wzejNe3GUkO60Zw7uJgFd#OF!=f?q53F6^!3d|NcB<2 z%h1QR7zSS-B~%}4g{>J{UrGb|7UK6Y)K|9JF!=f?q57CZMBl$T2&sR}iI<^|Ej$dq zK1!%QmLSpBSB8-4V@bUaee4aw;OnD=>YIn(L|@;0gj64EdTC??ysy47>Z7Hd(5HQBQ0J}R*Y-vULIrk%_v716!VAD$ zOjk;Q+kpL%W07YfA4Ou(=IEB_m!f|beK-0a(KTu7)9y}t5Gx;Vr&Xq}PQO0=V{EE% z?IC7XndO18=+V2Ml(AtZ`j(hsAIm<*LYaB8o8QJ_84e@Vs(=*ZIikz~cQ#&ox8oGY zr?6yB$X;UWpL_Ol#9nql>f}S2Vs9FH;o|{&kFNfjNPPkJrr|B6MW9%f1jc}Ti-T`J z@J$516~G;O?v``sn!Csgf!qmQ4CHPecdWR3R1M^=3U@fT+rX87uEKLgoU7AZDXs-_ z1(mCrTv_BQA6MMC`sJ-e!RKSgVGlW#n{h!fG#%q}V<63pXC5y> zTBqYwOpeG{sRME*&)v)=K<*ZXHRXl!Ts5(b^CZuyNu^3Iwf6I2y*6O~IhW_$%Px6;iT#e+;no6s;^Ha31`O?0^YrtG3v+qAsSDDfFwID_N zS|II{})UBSN~K} zM~w1tU0h~sGDoa(sf#KZu0g6vQ*nBzO)y^joYSREOqK$bu1FzW;Yl+eg6UW3Gg3&O z@rlw)Qb;fPMCmhANT2zM(v>O7zEaAbyDMB#)%_sNcP;y+W*2Jc#2Vj-5?qQ?MyJb4 zbE@{lK1$mYS7z&gVJlVPdg4l#^`y%6S$;dB#;_)>ac70<>Uvk>I1fEb>Z-O*^+8Ly zIz?YyEqygt(!)~AQb;WmDX#OYlzO>5B=vrWoxO7Yg}wy;xaO}?>fwrz6yw%k28?ntZijTYRzWf)=H7GYXeqFZJiyGVyxOaTcqsU=T=H<%c{@}QKdLTTqQF^ zuH%RMa&iSdJ||@R)_}+7h;3@I;E&R)Q?!)T(o$G{+_9T1m(C5@d@*42T(KFPQ)n*n znJ4(HM4vR5uwsXQ+(l4NHJ8p$G3uQ!qaJq@!nw2*_xJ{nYSZ#v6Y}Bhfahz(2WnF( z_56ZRJ7GLMXFIvTwUhC)0=0Kx$ezjdpARn-dmNR*_AW|c?;^3so`}7WN~*oJA<6a5 z9z9(vlG^*Iq^7YZB*}P9W6h*CRkAikuUG4OJ)1imFZgW2*1)>O@@9+YPHK4nT>aB} zP#4Zg=O5d1o#Z6zKv)W==T2GYu*!&klSwtCkZPDxsxd_lHcAfC7WaPCOD(l^A$vyx zwPf7{dz$a-Q}iF}-4mvL4}tkU)tI#*WShQetK1;AIV%f$+!T^Ja_e7sQcV-2)Z>d& zF)-lbY=8)uT&K~P^vqr#?PvxYMnYIu2YJvd4JsudWn( zeAZVf&7JKbspkS-Zl55fxw9iA6|}WOq`2oFwzV@Pm3YJN8+VFSa12meogt~9txl1e ztQB>Iqy_`Fx@iwv^lq^iT))v=xhf=ecfiZ5CP=B5gDJcm6fgM(2j9rB;Cs0z zWH0FD9OaHo% z)UiO`UN=EX^Y;1_z3%nW>*`Y--_i-^%&W{n@)qzU|HK54m1G z3$yBpJE^yX>^;Bdt6r~ri`etu3o0{u+VO2>4fcO+>G16pzG)Iq=jlo%={5Lbl&8`V z?A6FAR>3e&vkHcJY7Ig6hUh!35D9n?02rAE0 zu?Sjoc!~`{<9Xr|LF0L%6G7v7Y8Js>jr;|6hLxYE;{?Mz*@>X?JpG2C{5&a&pz%B* zC>Z8xTLgQ>nf#%!{%seH=P6u4exAk^46hA^YeM1LP?)E61?72aS1{ZV3iA}NU_4Lr z3WnE*!aUt87|&C_g5irpVV?RGjOXcJ!7xt>3Wi%l;Y&hco&Xl)Zx4leI#w{Ar(^}g zJROUm<;l~r2=XARGy~@X)l;-G6uEGmyaFbql;J zqEdHt$RXJ?{0hAle$Nw?Au}ErS1($jXdV}!S{-keFtp3 z)ZviSd-MHt9TqA3rq_6>BO$555M9RL;HD2nzkW|lCeOvd5l)ldw%#EWVsaO8M zU)4V|OB4yve8ZUK!NGf^P<6h3+FH-hBtMO8w3rW3O<9qly zk+N@7jhA{LB=zW0U+MvovhPe;snxgPi5l z`hvS3?KPOYKpvFw`#@_!p8=)ZDMu@J+4wF{@;?kpKi&bQz2-iHnXoZm0A=_iP=1f! z(r?30f>Q4(Q0lE5u=4vrsqbk=PdQq>+uk2?^cX1Re+3GYrUM59HGw_^N`0?^(*Hbs z>`7Yh=mAHcbo7^wmf_|4M(}lklK(+a`thm@=i)_r-me8^x{kQ;_dsdS4BPlspbU>V z`naQSfzr>W5zBYb(c_N33re|iynIhP+d%2hBQE@!qj{s2Z@r_396bq2zjE-gC;eUz z%J2h@z6DCXbMT@*X{)2RJ9^U5Q;t^bwfVanl>867@S84Ny3hL22Fmz59evi(_Z?k= zm;4#O)6oY&>EA0ZoP!toneKW}@*QyDr(O6R7f#?Me#UQg^av>Be&E99fQ?_}=%AyI zIQp8SdDmIKdPfg9`Xngx>vt}^@_Ng++tG&|ebv!iyzI|(G=b8ugN`0|_uqHnB{$mm zouKD|?+Y%Bp8_u7<;KL#TXgk+qilaw)K%yeXBW4pB_kGz>l zz6HGV!1v)x@Ct8zQXZQTh?#fY*wYj@~eS#)wgXjgq zD{%z=!7I@OeowUbaQO$*u%J%h2m&Ag0w4eaAOHd&00JNY0w4eaATS;TaQ|;S;&@swF3`(#kzS!! zX^vi_OZ56_4WZq0NFXEb{!Rqr{_V#h2fTZM-VZ{&YMC!6YbV9O>6*!{){-hLt3p8) zZYVoj)y=9Z;|KyE00JNY0w4eaAOHd&00JNY0wD102;lzTvtxf2dVYi6q_^m8dWSC4 z0vWV;76yeeJS74dTKz?Jh5LVs1dbp80w4eaAOHd&00JNY0w4eaATVwOaQ|=IB6>1^ z-lZ#amENQG=>z(ZKBA9L)*R~Rnt*@*PbT|as_c}@_wL^<8`q55#+|~lQ7W%}x9^Xg&vr?(WXbE%OrCU-HWv0Rp zn`XZkBYDJJJ4Rx4P0z~J*ZYx-eKOq*n$a8PY(Pl%UFWs*uQaD#LDgOJ-J` z&UMX4De*jq;$7Ey$SfYApI7?OOn_2uXAx~=I`E%UaGa(0?%Ixce871s-ZR}M z;~SiHgVUG8**JPtiRVoeEA0*&YO)a3M6I$BZAN!9Sam0960E|LGznJah$geS&>OKF zM+heNST7}V?u#YX6I&#+t)rr2bF*zTH(;1in@}r77lwrroYHVEH_Coaqe*k_G#+Xt zGs2A7=)~ITIObkVSNmdcF%oVz<3`hEUB^Ar*%3qbuP$1Vn&w&&=aysdx0^bV2*v}c z(rM(7?52pIPL$!idmx4$qp?h@rL`lX>Ple}U-?36ZxvVl>{h zE=ChK=yPHw_S$mMXy&|6N28H+%#NiqqX25G2!Ks*%4;+t=xv)bS6-eYhb;Pvvm+$l zD%DsKUAbmo^cB;Uw*>Weg7u{lh4WOS8LUB#NQFW-FBE5uX5hSD6a+&fN*~zmKG*JJ zQ|YA!m|Gh{1JGKAr|6zi65C8!X z009sH0T2KI5C8!X009sHf#U=o|AFWKA7_%J&(|nNdAd$Zv`huML7&oRbdzq;=d?m! z(3kX8l3*mx*NZgeJ^$ZD{!fpM&Qw7Dk4W#5d0kP-T*&|NlhuZ&kH|oI5=mWRe~QS> zLH^HB@}8g{WZjKOyopR1LjDi(f1>}t8~HynNmY|oA+yzx{}Yj>cQ*2W68H5M4ub#) mfB*IltF%T%Dp8p#w4MmB;iOL>L;nJe{V~@7 literal 0 HcmV?d00001 diff --git a/lib/arch/win32/ft_conf.h b/lib/arch/win32/ft_conf.h new file mode 100644 index 0000000..63819dd --- /dev/null +++ b/lib/arch/win32/ft_conf.h @@ -0,0 +1,210 @@ +/* This file is part of the FreeType project */ + +/* ft_conf.h for Win32 */ + + +/* we need the following because there are some typedefs in this file */ + +#ifndef FT_CONF_H +#define FT_CONF_H + +#ifndef WIN32 +#define WIN32 +#endif + +/* Define to empty if the 'const' keyword does not work. */ +/* #undef const */ + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE + +/* Define if you have the valloc function. */ +#undef HAVE_VALLOC + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* The number of bytes in a long. */ +#define SIZEOF_LONG 4 + +/**********************************************************************/ +/* */ +/* The following configuration macros can be tweaked manually by */ +/* a developer to turn on or off certain features or options in the */ +/* TrueType engine. This may be useful to tune it for specific */ +/* purposes.. */ +/* */ +/**********************************************************************/ + + +/*************************************************************************/ +/* Define this if the underlying operating system uses a different */ +/* character width than 8bit for file names. You must then also supply */ +/* a typedef declaration for defining 'TT_Text'. Default is off. */ + +/* #define HAVE_TT_TEXT */ + + +/*************************************************************************/ +/* Define this if you want to generate code to support engine extensions */ +/* Default is on, but if you're satisfied by the basic services provided */ +/* by the engine and need no extensions, undefine this configuration */ +/* macro to save a few more bytes. */ + +#define TT_CONFIG_OPTION_EXTEND_ENGINE + + +/*************************************************************************/ +/* Define this if you want to generate code to support gray-scaling, */ +/* a.k.a. font-smoothing or anti-aliasing. Default is on, but you can */ +/* disable it if you don't need it. */ + +#define TT_CONFIG_OPTION_GRAY_SCALING + + +/*************************************************************************/ +/* Define this if you want to completely disable the use of the bytecode */ +/* interpreter. Doing so will produce a much smaller library, but the */ +/* quality of the rendered glyphs will enormously suffer from this. */ +/* */ +/* This switch was introduced due to the Apple patents issue which */ +/* emerged recently on the FreeType lists. We still do not have Apple's */ +/* opinion on the subject and will change this as soon as we have. */ + +#undef TT_CONFIG_OPTION_NO_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to use a big 'switch' statement within the */ +/* bytecode interpreter. Because some non-optimizing compilers are not */ +/* able to produce jump tables from such statements, undefining this */ +/* configuration macro will generate the appropriate C jump table in */ +/* ttinterp.c. If you use an optimizing compiler, you should leave it */ +/* defined for better performance and code compactness.. */ + +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the TrueType */ +/* bytecode interpreter. This will produce much bigger code, which */ +/* _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_INTERPRETER + + +/*************************************************************************/ +/* Define this if you want to build a 'static' version of the scan-line */ +/* converter (the component which in charge of converting outlines into */ +/* bitmaps). This will produce a bigger object file for "ttraster.c", */ +/* which _may_ be faster on some architectures.. */ +/* */ +/* Do NOT DEFINE THIS is you build a thread-safe version of the engine */ +/* */ +#undef TT_CONFIG_OPTION_STATIC_RASTER + + +/*************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +#undef TT_CONFIG_OPTION_THREAD_SAFE + + +/**********************************************************************/ +/* */ +/* The following macros are used to define the debug level, as well */ +/* as individual tracing levels for each component. There are */ +/* currently three modes of operation : */ +/* */ +/* - trace mode (define DEBUG_LEVEL_TRACE) */ +/* */ +/* The engine prints all error messages, as well as tracing */ +/* ones, filtered by each component's level */ +/* */ +/* - debug mode (define DEBUG_LEVEL_ERROR) */ +/* */ +/* Disable tracing, but keeps error output and assertion */ +/* checks. */ +/* */ +/* - release mode (don't define anything) */ +/* */ +/* Don't include error-checking or tracing code in the */ +/* engine's code. Ideal for releases. */ +/* */ +/* NOTE : */ +/* */ +/* Each component's tracing level is defined in its own source. */ +/* */ +/**********************************************************************/ + +/* Define if you want to use the tracing debug mode */ +#undef DEBUG_LEVEL_TRACE + +/* Define if you want to use the error debug mode - ignored if */ +/* DEBUG_LEVEL_TRACE is defined */ +#undef DEBUG_LEVEL_ERROR + + +/**************************************************************************/ +/* Definition of various integer sizes. These types are used by ttcalc */ +/* and ttinterp (for the 64-bit integers) only.. */ + +#if SIZEOF_INT == 4 + + typedef signed int TT_Int32; + typedef unsigned int TT_Word32; + +#elif SIZEOF_LONG == 4 + + typedef signed long TT_Int32; + typedef unsigned long TT_Word32; + +#else +#error "no 32bit type found" +#endif + +#if SIZEOF_LONG == 8 + +/* LONG64 must be defined when a 64-bit type is available */ +/* INT64 must then be defined to this type.. */ +#define LONG64 +#define INT64 long + +#else + +/* GCC provides the non-ANSI 'long long' 64-bit type. You can activate */ +/* by defining the TT_USE_LONG_LONG macro in 'ft_conf.h'. Note that this */ +/* will produce many -ansi warnings during library compilation. */ +#ifdef TT_USE_LONG_LONG + +#define LONG64 +#define INT64 long long + +#endif /* TT_USE_LONG_LONG */ +#endif + +#endif /* FT_CONF_H */ + + +/* END */ diff --git a/lib/arch/win32/makedef b/lib/arch/win32/makedef new file mode 100644 index 0000000..4f91819 --- /dev/null +++ b/lib/arch/win32/makedef @@ -0,0 +1,24 @@ +# makedef +# +# This shell script creates a .DEF file necessary for building as DLL +# on the Windows 32-bit platform. + +echo "\ +; This definition file to be used to built the library as DLL +; has been generated automatically with the script \`makedef' on +; `date +%d-%b-%Y`. + +LIBRARY ft13_32 +DESCRIPTION 'FreeType 1.3 32-bit DLL © 1996-1999 Turner, Wilhelm, Lemberg' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +EXPORTS +" > ttf.def + +(cd ../.. + sed -n -e "/^ *EXPORT_DEF/!d ; n ; s/(.*$//" \ + -e "s/;$//" -e "s/ const / /" -e "s/ *[a-zA-Z][a-zA-Z_\*]* //" \ + -e "s/ *//g" -e "s/^/ /" -e "p" *.h extend/*.h) >> ttf.def + +# eof diff --git a/lib/arch/win32/makedep b/lib/arch/win32/makedep new file mode 100644 index 0000000..34ade91 --- /dev/null +++ b/lib/arch/win32/makedep @@ -0,0 +1,29 @@ +# makedep +# +# This shell script creates a dependency file necessary for some compilers +# on the Win32 platform. + +echo "\ +# This dependency file to be used with various Win32 compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.win + +(cd ../.. + gcc -MM -Iarch/win32 -I. *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.win + +(cd ../.. + gcc -MM -Iarch/win32 -I. -Iextend extend/*.c | \ + sed -e "s/^\(.*\)\.o:/extend\\\\\1.obj:/" -e "s:/:\\\\:g") >> depend.win + +echo "!ifndef __MAKE__" >> depend.win + +(cd ../.. + gcc -MM -Iarch/win32 -I. -Iextend arch/win32/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\win32\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.win + +echo "!endif" >> depend.win + +# eof diff --git a/lib/arch/win32/ttf.def b/lib/arch/win32/ttf.def new file mode 100644 index 0000000..f833c07 --- /dev/null +++ b/lib/arch/win32/ttf.def @@ -0,0 +1,127 @@ +; This definition file to be used to built the library as DLL +; has been generated automatically with the script `makedef' on +; 03-Sep-1999. + +LIBRARY ft13_32 +DESCRIPTION 'FreeType 1.3 32-bit DLL © 1996-1999 Turner, Wilhelm, Lemberg' +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +EXPORTS + + TT_FreeType_Version + TT_Init_FreeType + TT_Done_FreeType + TT_Set_Raster_Gray_Palette + TT_Open_Face + TT_Open_Collection + TT_Get_Face_Properties + TT_Set_Face_Pointer + TT_Get_Face_Pointer + TT_Flush_Face + TT_Get_Face_Metrics + TT_Close_Face + TT_Get_Font_Data + TT_New_Instance + TT_Set_Instance_Resolutions + TT_Set_Instance_CharSize + TT_Set_Instance_CharSizes + TT_Set_Instance_PixelSizes + TT_Set_Instance_Transform_Flags + TT_Get_Instance_Metrics + TT_Set_Instance_Pointer + TT_Get_Instance_Pointer + TT_Done_Instance + TT_New_Glyph + TT_Done_Glyph + TT_Load_Glyph + TT_Get_Glyph_Outline + TT_Get_Glyph_Metrics + TT_Get_Glyph_Big_Metrics + TT_Get_Glyph_Bitmap + TT_Get_Glyph_Pixmap + TT_New_Outline + TT_Done_Outline + TT_Copy_Outline + TT_Get_Outline_Bitmap + TT_Get_Outline_Pixmap + TT_Get_Outline_BBox + TT_Transform_Outline + TT_Translate_Outline + TT_Transform_Vector + TT_MulDiv + TT_MulFix + TT_Get_CharMap_Count + TT_Get_CharMap_ID + TT_Get_CharMap + TT_Char_Index + TT_Get_Name_Count + TT_Get_Name_ID + TT_Get_Name_String + TT_Register_Extension + TT_Extension_Get + TT_Use_Stream + TT_Done_Stream + TT_Flush_Stream + TT_Read_File + TT_Seek_File + TT_Skip_File + TT_Read_At_File + TT_File_Pos + TT_Stream_Size + TT_Null_FileFrame + TT_Access_Frame + TT_Check_And_Access_Frame + TT_Forget_Frame + TT_Get_Char + TT_Get_Short + TT_Get_Long + TT_LookUp_Table + TT_Alloc + TT_Realloc + TT_Free + TT_CharMap_First + TT_CharMap_Next + TT_CharMap_Last + TT_ErrToString18 + TT_Get_Face_Gasp_Flags + TT_Init_GDEF_Extension + TT_Load_GDEF_Table + TT_GDEF_Get_Glyph_Property + TT_GDEF_Build_ClassDefinition + TT_Init_GPOS_Extension + TT_Load_GPOS_Table + TT_GPOS_Select_Script + TT_GPOS_Select_Language + TT_GPOS_Select_Feature + TT_GPOS_Query_Scripts + TT_GPOS_Query_Languages + TT_GPOS_Query_Features + TT_GPOS_Add_Feature + TT_GPOS_Clear_Features + TT_Init_GSUB_Extension + TT_Load_GSUB_Table + TT_GSUB_Select_Script + TT_GSUB_Select_Language + TT_GSUB_Select_Feature + TT_GSUB_Query_Scripts + TT_GSUB_Query_Languages + TT_GSUB_Query_Features + TT_GSUB_Add_Feature + TT_GSUB_Clear_Features + TT_GSUB_Register_Alternate_Function + TT_GSUB_Apply_String + TT_GSUB_Add_String + TT_Init_Kerning_Extension + TT_Get_Kerning_Directory + TT_Load_Kerning_Table + TT_Init_Post_Extension + TT_Load_PS_Names + TT_Get_PS_Name + TT_Init_SBit_Extension + TT_Get_Face_Bitmaps + TT_New_SBit_Image + TT_Done_SBit_Image + TT_Get_SBit_Strike + TT_Load_Glyph_Bitmap + TT_Get_Face_Widths diff --git a/lib/extend/ftxcmap.c b/lib/extend/ftxcmap.c new file mode 100644 index 0000000..d44136e --- /dev/null +++ b/lib/extend/ftxcmap.c @@ -0,0 +1,347 @@ +/******************************************************************* + * + * ftxcmap.h 1.0 + * + * API extension for iterating over Cmaps + * + * Copyright 1996-1999 by Juliusz Chroboczek, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + ******************************************************************/ + +#include "ftxcmap.h" + +#include "tttypes.h" +#include "ttobjs.h" +#include "tttables.h" + +static Long charmap_first4 ( PCMap4, UShort* ); +static Long charmap_next4 ( PCMap4, UShort, UShort* ); +static Long charmap_last4 ( PCMap4, UShort* ); +static UShort charmap_find_id4( PCMap4, UShort, TCMap4Segment*, UShort ); + + +/******************************************************************* + * + * Function : TT_CharMap_First + * + * Description : Returns the first valid character code in a + * given character map. Also returns the corresponding + * glyph index. + * + * Input : charMap handle to the target character map + * id address where the glyph index will be + * be returned in case of success + * + * Output : First valid character code. -1 in case of failure. + * + * Notes : + * + ******************************************************************/ + +EXPORT_FUNC +TT_Long TT_CharMap_First( TT_CharMap charMap, + TT_UShort* id ) +{ + PCMapTable cmap; + UShort i, c; + + + if ( !( cmap = HANDLE_CharMap( charMap ) ) ) + return -1; + + switch ( cmap->format ) + { + case 0: + if ( id ) + *id = cmap->c.cmap0.glyphIdArray[0]; + return 0; + + case 4: + return charmap_first4( &cmap->c.cmap4, id ); + + case 6: + if ( cmap->c.cmap6.entryCount < 1 ) + return -1; + + if ( id ) + *id = cmap->c.cmap6.glyphIdArray[0]; + return cmap->c.cmap6.firstCode; + + default: + /* Now loop from 0 to 65535. We can't use a simple "for' on */ + /* 16-bits systems, hence the "strange" loop here.. */ + i = 0; + do + { + c = TT_Char_Index( charMap, i ); + if ( c > 0 ) + { + if ( id ) + *id = c; + return i; + } + i++; + } while ( i != 0 ); /* because i is UShort! */ + + return -1; + } +} + + +static Long charmap_first4( PCMap4 cmap4, + UShort* id ) +{ + UShort firstCode; + + + if ( cmap4->segCountX2 / 2 < 1 ) + return -1; + + firstCode = cmap4->segments[0].startCount; + + if ( id ) + *id = charmap_find_id4( cmap4, firstCode, &(cmap4->segments[0]), 0 ); + + return firstCode; +} + + +/******************************************************************* + * + * Function : TT_CharMap_Next + * + * Description : Returns the next valid character code in a given + * charMap. + * + * Input : charMap handle to the target char. map + * index starting character code + * id address where the glyph index of the next + * character will be returned + * + * Output : Next valid character code after 'index'. -1 in case + * of failure. + * + * Notes : + * + ******************************************************************/ + +EXPORT_FUNC +TT_Long TT_CharMap_Next( TT_CharMap charMap, + TT_UShort index, + TT_UShort* id ) +{ + PCMapTable cmap; + UShort i, c; + + + cmap = HANDLE_CharMap( charMap ); + if ( !cmap ) + return -1; + + switch ( cmap->format ) + { + case 0: + if ( index < 255 ) + { + if ( id ) + *id = cmap->c.cmap0.glyphIdArray[index + 1]; + return index + 1; + } + else + return -1; + + case 4: + return charmap_next4( &cmap->c.cmap4, index, id ); + + case 6: + { + UShort firstCode = cmap->c.cmap6.firstCode; + + + if ( index + 1 < firstCode + cmap->c.cmap6.entryCount ) + { + if ( id ) + *id = cmap->c.cmap6.glyphIdArray[index + 1 - firstCode]; + return index + 1; + } + else + return -1; + } + + default: + /* Now loop from 0 to 65535. We can't use a simple "for" on */ + /* 16-bits systems, hence the "strange" loop here.. */ + i = 0; + do + { + c = TT_Char_Index( charMap, i ); + if ( c > 0 ) + { + if ( id ) + *id = c; + return i; + } + i++; + } while ( i != 0 ); /* because i is UShort! */ + + return -1; + } +} + + +static Long charmap_next4( PCMap4 cmap4, + UShort charCode, + UShort* id) +{ + UShort segCount, nextCode; + UShort i; + TCMap4Segment seg4; + + + if ( charCode == 0xFFFF ) + return -1; /* get it out of the way now */ + + segCount = cmap4->segCountX2 / 2; + + for ( i = 0; i < segCount; i++ ) + if ( charCode < cmap4->segments[i].endCount ) + break; + + /* Safety check - even though the last endCount should be 0xFFFF */ + if ( i >= segCount ) + return -1; + + seg4 = cmap4->segments[i]; + + if ( charCode < seg4.startCount ) + nextCode = seg4.startCount; + else + nextCode = charCode + 1; + + if ( id ) + *id = charmap_find_id4( cmap4, nextCode, &seg4, i ); + + return nextCode; +} + + +static UShort +charmap_find_id4( PCMap4 cmap4, + UShort charCode, + TCMap4Segment* seg4, + UShort i ) +{ + UShort index1; + + + if ( seg4->idRangeOffset == 0 ) + return (charCode + seg4->idDelta) & 0xFFFF; + else + { + index1 = seg4->idRangeOffset / 2 + charCode-seg4->startCount - + ( cmap4->segCountX2 / 2 - i ); + + if ( index1 >= cmap4->numGlyphId || cmap4->glyphIdArray[index1] == 0 ) + return 0; + else + return (cmap4->glyphIdArray[index1] + seg4->idDelta) & 0xFFFF; + } +} + + +/******************************************************************* + * + * Function : TT_CharMap_Last + * + * Description : Returns the last valid character code in a + * given character map. Also returns the corresponding + * glyph index. + * + * Input : charMap handle to the target character map + * id address where the glyph index will be + * be returned in case of success + * + * Output : Last valid character code. -1 in case of failure. + * + * Notes : + * + ******************************************************************/ + +EXPORT_FUNC +TT_Long TT_CharMap_Last( TT_CharMap charMap, + TT_UShort* id ) +{ + PCMapTable cmap; + UShort i, c; + + + if ( !( cmap = HANDLE_CharMap( charMap ) ) ) + return -1; + + switch ( cmap->format ) + { + case 0: + if ( id ) + *id = cmap->c.cmap0.glyphIdArray[255]; + return 255; + + case 4: + return charmap_last4( &cmap->c.cmap4, id ); + + case 6: + if ( cmap->c.cmap6.entryCount < 1 ) + return -1; + + if ( id ) + *id = cmap->c.cmap6.glyphIdArray[cmap->c.cmap6.entryCount - 1]; + return cmap->c.cmap6.firstCode + cmap->c.cmap6.entryCount - 1; + + default: + i = 65535; + do + { + c = TT_Char_Index( charMap, i ); + if ( c > 0 ) + { + if ( id ) + *id = c; + return i; + } + i--; + } while ( i != 0 ); + + return -1; + } +} + + +static Long charmap_last4( PCMap4 cmap4, + UShort* id ) +{ + UShort lastCode; + + + if ( cmap4->segCountX2 / 2 < 1 ) + return -1; + + lastCode = cmap4->segments[cmap4->segCountX2 / 2 - 1].endCount; + + if ( id ) + *id = charmap_find_id4( cmap4, + lastCode, + &(cmap4->segments[cmap4->segCountX2 / 2 - 1]), + 0 ); + + return lastCode; +} + + +/* END */ diff --git a/lib/extend/ftxcmap.h b/lib/extend/ftxcmap.h new file mode 100644 index 0000000..38ed8e1 --- /dev/null +++ b/lib/extend/ftxcmap.h @@ -0,0 +1,60 @@ +/******************************************************************* + * + * ftxcmap.h 1.0 + * + * API extension for iterating over Cmaps + * + * Copyright 1996-1999 by Juliusz Chroboczek, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + ******************************************************************/ + +#ifndef FTXCMAP_H +#define FTXCMAP_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* Find the first entry of a Cmap. Its glyph index is returned */ + /* in the "id" field, while the function returns the first valid */ + /* character code in the Cmap. It returns -1 in case of failure. */ + + EXPORT_DEF + TT_Long TT_CharMap_First( TT_CharMap charMap, + TT_UShort* id ); + + + /* Find the next entry of Cmap. Same return conventions. */ + + EXPORT_DEF + TT_Long TT_CharMap_Next( TT_CharMap charMap, + TT_UShort startId, + TT_UShort* id ); + + /* Find the last entry of a Cmap. Its glyph index is returned */ + /* in the "id" field, while the function returns the last valid */ + /* character code in the Cmap. It returns -1 in case of failure. */ + + EXPORT_DEF + TT_Long TT_CharMap_Last( TT_CharMap charMap, + TT_UShort* id ); + + +#ifdef __cplusplus +} +#endif + +#endif /* FTXCMAP_H */ + + +/* END */ diff --git a/lib/extend/ftxerr18.c b/lib/extend/ftxerr18.c new file mode 100644 index 0000000..ac8934a --- /dev/null +++ b/lib/extend/ftxerr18.c @@ -0,0 +1,241 @@ +/****************************************************************************/ +/* */ +/* Erwin Dieterich, 15. 10. 1997 */ +/* - 15. 08. 1999 */ +/* */ +/* TT_ErrToString: translate error codes to character strings */ +/* */ +/* This extension provides internationalized error strings from the */ +/* various error messages. It uses the "gettext" package if available */ +/* or returns English/American message strings if not. */ +/* */ +/* If you do not want to use it, or if you encounter some problems */ +/* compiling this file, try to disable nls support when invoking */ +/* ./configure (on Unix). */ +/* */ +/* */ +/****************************************************************************/ + +#include "ttconfig.h" + +#include "ftxerr18.h" +#include "ftxkern.h" +#include "ftxpost.h" +#include "ftxopen.h" + +#ifdef HAVE_LOCALE_H +#include +#endif + +#ifdef HAVE_LIBINTL_H +#include +#undef _ +#define _( String ) dgettext( "freetype", String ) +#else +#define _( String ) ( String ) +#endif + + +EXPORT_FUNC +TT_String* TT_ErrToString18( TT_Error error ) +{ + + switch ( error ) + { + /* ----- high-level API error codes ----- */ + case TT_Err_Ok: + return _( "Successful function call, no error." ); + + case TT_Err_Invalid_Face_Handle: + return _( "Invalid face handle." ); + case TT_Err_Invalid_Instance_Handle: + return _( "Invalid instance handle." ); + case TT_Err_Invalid_Glyph_Handle: + return _( "Invalid glyph handle." ); + case TT_Err_Invalid_CharMap_Handle: + return _( "Invalid charmap handle." ); + case TT_Err_Invalid_Result_Address: + return _( "Invalid result address." ); + case TT_Err_Invalid_Glyph_Index: + return _( "Invalid glyph index." ); + case TT_Err_Invalid_Argument: + return _( "Invalid argument." ); + case TT_Err_Could_Not_Open_File: + return _( "Could not open file." ); + case TT_Err_File_Is_Not_Collection: + return _( "File is not a TrueType collection." ); + + case TT_Err_Table_Missing: + return _( "Mandatory table missing." ); + case TT_Err_Invalid_Horiz_Metrics: + return _( "Invalid horizontal metrics (hmtx table broken)." ); + case TT_Err_Invalid_CharMap_Format: + return _( "Invalid charmap format." ); + case TT_Err_Invalid_PPem: + return _( "Invalid ppem value." ); + case TT_Err_Invalid_Vert_Metrics: + return _( "Invalid vertical metrics (vmtx table broken)." ); + + case TT_Err_Invalid_File_Format: + return _( "Invalid file format." ); + + case TT_Err_Invalid_Engine: + return _( "Invalid engine." ); + case TT_Err_Too_Many_Extensions: + return _( "Too many extensions." ); + case TT_Err_Extensions_Unsupported: + return _( "Extensions unsupported." ); + case TT_Err_Invalid_Extension_Id: + return _( "Invalid extension id." ); + + case TT_Err_No_Vertical_Data: + return _( "No vertical data in font." ); + + case TT_Err_Max_Profile_Missing: + return _( "Maximum Profile (maxp) table missing." ); + case TT_Err_Header_Table_Missing: + return _( "Font Header (head) table missing." ); + case TT_Err_Horiz_Header_Missing: + return _( "Horizontal Header (hhea) table missing." ); + case TT_Err_Locations_Missing: + return _( "Index to Location (loca) table missing." ); + case TT_Err_Name_Table_Missing: + return _( "Naming (name) table missing." ); + case TT_Err_CMap_Table_Missing: + return _( "Character to Glyph Index Mapping (cmap) tables missing." ); + case TT_Err_Hmtx_Table_Missing: + return _( "Horizontal Metrics (hmtx) table missing." ); + case TT_Err_OS2_Table_Missing: + return _( "OS/2 table missing." ); + case TT_Err_Post_Table_Missing: + return _( "PostScript (post) table missing." ); + case TT_Err_Glyf_Table_Missing: + return _( "Glyph (glyf) table missing." ); + + + /* ----- memory component error codes ----- */ + case TT_Err_Out_Of_Memory: + return _( "Out of memory." ); + + + /* ----- file component error codes ----- */ + case TT_Err_Invalid_File_Offset: + return _( "Invalid file offset." ); + case TT_Err_Invalid_File_Read: + return _( "Invalid file read." ); + case TT_Err_Invalid_Frame_Access: + return _( "Invalid frame access." ); + + + /* ----- glyph loader error codes ----- */ + case TT_Err_Too_Many_Points: + return _( "Too many points." ); + case TT_Err_Too_Many_Contours: + return _( "Too many contours." ); + case TT_Err_Invalid_Composite: + return _( "Invalid composite glyph." ); + case TT_Err_Too_Many_Ins: + return _( "Too many instructions." ); + + + /* ----- byte-code interpreter error codes ----- */ + case TT_Err_Invalid_Opcode: + return _( "Invalid opcode." ); + case TT_Err_Too_Few_Arguments: + return _( "Too few arguments." ); + case TT_Err_Stack_Overflow: + return _( "Stack overflow." ); + case TT_Err_Code_Overflow: + return _( "Code overflow." ); + case TT_Err_Bad_Argument: + return _( "Bad argument." ); + case TT_Err_Divide_By_Zero: + return _( "Divide by zero." ); + case TT_Err_Storage_Overflow: + return _( "Storage overflow." ); + case TT_Err_Cvt_Overflow: + return _( "Control Value (cvt) table overflow." ); + case TT_Err_Invalid_Reference: + return _( "Invalid reference." ); + case TT_Err_Invalid_Distance: + return _( "Invalid distance." ); + case TT_Err_Interpolate_Twilight: + return _( "Interpolate twilight points." ); + case TT_Err_Debug_OpCode: + return _( "`DEBUG' opcode found." ); + case TT_Err_ENDF_In_Exec_Stream: + return _( "`ENDF' in byte-code stream." ); + case TT_Err_Out_Of_CodeRanges: + return _( "Out of code ranges." ); + case TT_Err_Nested_DEFS: + return _( "Nested function definitions." ); + case TT_Err_Invalid_CodeRange: + return _( "Invalid code range." ); + case TT_Err_Invalid_Displacement: + return _( "Invalid displacement." ); + case TT_Err_Execution_Too_Long: + return _( "Endless loop encountered while executing instructions." ); + + + /* ----- internal failure error codes ----- */ + case TT_Err_Nested_Frame_Access: + return _( "Nested frame access." ); + case TT_Err_Invalid_Cache_List: + return _( "Invalid cache list." ); + case TT_Err_Could_Not_Find_Context: + return _( "Could not find context." ); + case TT_Err_Unlisted_Object: + return _( "Unlisted object." ); + + + /* ----- scan-line converter error codes ----- */ + case TT_Err_Raster_Pool_Overflow: + return _( "Raster pool overflow." ); + case TT_Err_Raster_Negative_Height: + return _( "Raster: negative height encountered." ); + case TT_Err_Raster_Invalid_Value: + return _( "Raster: invalid value." ); + case TT_Err_Raster_Not_Initialized: + return _( "Raster not initialized." ); + + + /* ----- engine extensions error codes ----- */ + case TT_Err_Invalid_Kerning_Table_Format: + return _( "Invalid kerning (kern) table format." ); + case TT_Err_Invalid_Kerning_Table: + return _( "Invalid kerning (kern) table." ); + case TT_Err_Invalid_Post_Table_Format: + return _( "Invalid PostScript (post) table format." ); + case TT_Err_Invalid_Post_Table: + return _( "Invalid PostScript (post) table." ); + + + /* ----- TrueType Open extension error codes ----- */ + + case TTO_Err_Invalid_SubTable_Format: + return _( "Invalid TrueType Open subtable format." ); + case TTO_Err_Invalid_SubTable: + return _( "Invalid TrueType Open subtable." ); + case TTO_Err_Not_Covered: + return _( "Glyph(s) not covered by lookup." ); + case TTO_Err_Too_Many_Nested_Contexts: + return _( "Too many nested context substitutions." ); + case TTO_Err_Invalid_GSUB_SubTable_Format: + return _( "Invalid glyph substitution (GSUB) table format." ); + case TTO_Err_Invalid_GSUB_SubTable: + return _( "Invalid glyph substitution (GSUB) table." ); + case TTO_Err_Invalid_GPOS_SubTable_Format: + return _( "Invalid glyph positioning (GPOS) table format." ); + case TTO_Err_Invalid_GPOS_SubTable: + return _( "Invalid glyph positioning (GPOS) table." ); + + + default: + ; + } + + return _( "Invalid Error Number." ); +} + + +/* END */ diff --git a/lib/extend/ftxerr18.h b/lib/extend/ftxerr18.h new file mode 100644 index 0000000..3ad060b --- /dev/null +++ b/lib/extend/ftxerr18.h @@ -0,0 +1,38 @@ +/****************************************************************************/ +/* */ +/* Erwin Dieterich, 15. 10. 1997 */ +/* - 15. 08. 1999 */ +/* */ +/* TT_ErrToString: translate error codes to character strings */ +/* */ +/* This extension provides internationalized error strings from the */ +/* various error messages. It uses the "gettext" package where available */ +/* or returns english/american message strings if not. */ +/* */ +/* If you do not want to use it, or if you encounter some problems */ +/* compiling this file, try to disable nls support by configuring */ +/* FreeType with ./configure --disable-nls */ +/* */ +/* */ +/****************************************************************************/ + +#ifndef FTXERR18_H +#define FTXERR18_H + +#include "freetype.h" + +#ifdef __cplusplus + extern "C" { +#endif + + EXPORT_DEF + TT_String* TT_ErrToString18( TT_Error i ); + +#ifdef __cplusplus + } +#endif + +#endif /* FTXERR18_H */ + + +/* END */ diff --git a/lib/extend/ftxgasp.c b/lib/extend/ftxgasp.c new file mode 100644 index 0000000..b2bc083 --- /dev/null +++ b/lib/extend/ftxgasp.c @@ -0,0 +1,69 @@ +/******************************************************************* + * + * ftxgasp.c 1.0 + * + * Gasp table support API extension body + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The gasp table is currently loaded by the core engine, but the + * standard API doesn't give access to it. This file is used to + * demonstrate the use of a simple API extension. + * + ******************************************************************/ + +#include "ftxgasp.h" + +#include "tttypes.h" +#include "ttobjs.h" +#include "tttables.h" + + + EXPORT_FUNC + TT_Error TT_Get_Face_Gasp_Flags( TT_Face face, + TT_UShort point_size, + TT_Bool* grid_fit, + TT_Bool* smooth_font ) + { + PFace faze = HANDLE_Face( face ); + UShort i, flag; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( faze->gasp.numRanges == 0 || !faze->gasp.gaspRanges ) + return TT_Err_Table_Missing; + + for ( i = 0; i < faze->gasp.numRanges; i++ ) + { + if ( point_size <= faze->gasp.gaspRanges[i].maxPPEM ) + { + flag = faze->gasp.gaspRanges[i].gaspFlag; + + *grid_fit = ( (flag & GASP_GRIDFIT) != 0 ); + *smooth_font = ( (flag & GASP_DOGRAY ) != 0 ); + + return TT_Err_Ok; + } + } + + /* for very large fonts we enable font smoothing and discard */ + /* grid fitting */ + + *grid_fit = 0; + *smooth_font = 1; + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/extend/ftxgasp.h b/lib/extend/ftxgasp.h new file mode 100644 index 0000000..a0dde72 --- /dev/null +++ b/lib/extend/ftxgasp.h @@ -0,0 +1,53 @@ +/******************************************************************* + * + * ftxgasp.h 1.0 + * + * Gasp table support API extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The gasp table is currently loaded by the core engine, but the + * standard API doesn't give access to it. This file is used to + * demonstrate the use of a simple API extension. + * + ******************************************************************/ + +#ifndef FTXGASP_H +#define FTXGASP_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + /* This function returns for a given 'point_size' the values of the */ + /* gasp flags 'grid_fit' and 'smooth_font'. The returned values */ + /* are booleans (where 0 = NO, and 1 = YES). */ + + /* Note that this function will return TT_Err_Table_Missing if */ + /* the font file doesn't contain any gasp table. */ + + EXPORT_DEF + TT_Error TT_Get_Face_Gasp_Flags( TT_Face face, + TT_UShort point_size, + TT_Bool* grid_fit, + TT_Bool* smooth_font ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXGASP_H */ + + +/* END */ diff --git a/lib/extend/ftxgdef.c b/lib/extend/ftxgdef.c new file mode 100644 index 0000000..9f94e96 --- /dev/null +++ b/lib/extend/ftxgdef.c @@ -0,0 +1,1099 @@ +/******************************************************************* + * + * ftxgdef.c + * + * TrueType Open GDEF table support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "tttypes.h" +#include "tttags.h" +#include "ttload.h" +#include "ttextend.h" +#include "ttmemory.h" +#include "ttfile.h" + +#include "ftxopen.h" +#include "ftxopenf.h" + + +#define GDEF_ID Build_Extension_ID( 'G', 'D', 'E', 'F' ) + + + static TT_Error Load_AttachList( TTO_AttachList* al, + PFace input ); + static TT_Error Load_LigCaretList( TTO_LigCaretList* lcl, + PFace input ); + + static void Free_AttachList( TTO_AttachList* al ); + static void Free_LigCaretList( TTO_LigCaretList* lcl ); + + static void Free_NewGlyphClasses( TTO_GDEFHeader* gdef ); + + + + /********************** + * Extension Functions + **********************/ + + + static TT_Error GDEF_Create( void* ext, + PFace face ) + { + DEFINE_LOAD_LOCALS( face->stream ); + + TTO_GDEFHeader* gdef = (TTO_GDEFHeader*)ext; + Long table; + + + /* by convention */ + + if ( !gdef ) + return TT_Err_Ok; + + /* a null offset indicates that there is no GDEF table */ + + gdef->offset = 0; + + /* we store the start offset and the size of the subtable */ + + table = TT_LookUp_Table( face, TTAG_GDEF ); + if ( table < 0 ) + return TT_Err_Ok; /* The table is optional */ + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + gdef->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */ + gdef->Version = GET_ULong(); + + FORGET_Frame(); + + gdef->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error GDEF_Destroy( void* ext, + PFace face ) + { + TTO_GDEFHeader* gdef = (TTO_GDEFHeader*)ext; + + + /* by convention */ + + if ( !gdef ) + return TT_Err_Ok; + + if ( gdef->loaded ) + { + Free_LigCaretList( &gdef->LigCaretList ); + Free_AttachList( &gdef->AttachList ); + Free_ClassDefinition( &gdef->GlyphClassDef ); + Free_ClassDefinition( &gdef->MarkAttachClassDef ); + + Free_NewGlyphClasses( gdef ); + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_GDEF_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + return TT_Register_Extension( _engine, + GDEF_ID, + sizeof ( TTO_GDEFHeader ), + GDEF_Create, + GDEF_Destroy ); + } + + + EXPORT_FUNC + TT_Error TT_Load_GDEF_Table( TT_Face face, + TTO_GDEFHeader* retptr ) + { + ULong cur_offset, new_offset, base_offset; + + TT_Error error; + TT_Stream stream; + TTO_GDEFHeader* gdef; + + PFace faze = HANDLE_Face( face ); + + + if ( !retptr ) + return TT_Err_Invalid_Argument; + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, GDEF_ID, (void**)&gdef ); + if ( error ) + return error; + + if ( gdef->offset == 0 ) + return TT_Err_Table_Missing; /* no GDEF table; nothing to do */ + + /* now access stream */ + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + base_offset = gdef->offset; + + /* skip version */ + + if ( FILE_Seek( base_offset + 4L ) || + ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + /* all GDEF subtables are optional */ + + if ( new_offset ) + { + new_offset += base_offset; + + /* only classes 1-4 are allowed here */ + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &gdef->GlyphClassDef, 5, + faze ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + } + else + gdef->GlyphClassDef.loaded = FALSE; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_AttachList( &gdef->AttachList, + faze ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + gdef->AttachList.loaded = FALSE; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigCaretList( &gdef->LigCaretList, + faze ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + else + gdef->LigCaretList.loaded = FALSE; + + /* OpenType 1.2 has introduced the `MarkAttachClassDef' field. We + first have to scan the LookupFlag values to find out whether we + must load it or not. Here we only store the current file offset. */ + + gdef->MarkAttachClassDef_offset = FILE_Pos(); + gdef->MarkAttachClassDef.loaded = FALSE; + + gdef->LastGlyph = 0; + gdef->NewGlyphClasses = NULL; + gdef->loaded = TRUE; + + *retptr = *gdef; + DONE_Stream( stream ); + + return TT_Err_Ok; + + Fail2: + Free_AttachList( &gdef->AttachList ); + + Fail1: + Free_ClassDefinition( &gdef->GlyphClassDef ); + + /* release stream */ + + DONE_Stream( stream ); + + return error; + } + + + + /******************************* + * AttachList related functions + *******************************/ + + + /* AttachPoint */ + + static TT_Error Load_AttachPoint( TTO_AttachPoint* ap, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* pi; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ap->PointCount = GET_UShort(); + + FORGET_Frame(); + + ap->PointIndex = NULL; + + if ( count ) + { + if ( ALLOC_ARRAY( ap->PointIndex, count, UShort ) ) + return error; + + pi = ap->PointIndex; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( pi ); + return error; + } + + for ( n = 0; n < count; n++ ) + pi[n] = GET_UShort(); + + FORGET_Frame(); + } + + return TT_Err_Ok; + } + + + static void Free_AttachPoint( TTO_AttachPoint* ap ) + { + FREE( ap->PointIndex ); + } + + + /* AttachList */ + + static TT_Error Load_AttachList( TTO_AttachList* al, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_AttachPoint* ap; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &al->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = al->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + al->AttachPoint = NULL; + + if ( ALLOC_ARRAY( al->AttachPoint, count, TTO_AttachPoint ) ) + goto Fail2; + + ap = al->AttachPoint; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_AttachPoint( &ap[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + al->loaded = TRUE; + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_AttachPoint( &ap[n] ); + + FREE( ap ); + + Fail2: + Free_Coverage( &al->Coverage ); + return error; + } + + + static void Free_AttachList( TTO_AttachList* al ) + { + UShort n, count; + + TTO_AttachPoint* ap; + + + if ( !al->loaded ) + return; + + if ( al->AttachPoint ) + { + count = al->GlyphCount; + ap = al->AttachPoint; + + for ( n = 0; n < count; n++ ) + Free_AttachPoint( &ap[n] ); + + FREE( ap ); + } + + Free_Coverage( &al->Coverage ); + } + + + + /********************************* + * LigCaretList related functions + *********************************/ + + + /* CaretValueFormat1 */ + /* CaretValueFormat2 */ + /* CaretValueFormat3 */ + /* CaretValueFormat4 */ + + static TT_Error Load_CaretValue( TTO_CaretValue* cv, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + cv->CaretValueFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( cv->CaretValueFormat ) + { + case 1: + if ( ACCESS_Frame( 2L ) ) + return error; + + cv->cvf.cvf1.Coordinate = GET_Short(); + + FORGET_Frame(); + + break; + + case 2: + if ( ACCESS_Frame( 2L ) ) + return error; + + cv->cvf.cvf2.CaretValuePoint = GET_UShort(); + + FORGET_Frame(); + + break; + + case 3: + if ( ACCESS_Frame( 4L ) ) + return error; + + cv->cvf.cvf3.Coordinate = GET_Short(); + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &cv->cvf.cvf3.Device, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + break; + + case 4: + if ( ACCESS_Frame( 2L ) ) + return error; + + cv->cvf.cvf4.IdCaretValue = GET_UShort(); + + FORGET_Frame(); + break; + + default: + return TTO_Err_Invalid_GDEF_SubTable_Format; + } + + return TT_Err_Ok; + } + + + static void Free_CaretValue( TTO_CaretValue* cv ) + { + if ( cv->CaretValueFormat == 3 ) + Free_Device( &cv->cvf.cvf3.Device ); + } + + + /* LigGlyph */ + + static TT_Error Load_LigGlyph( TTO_LigGlyph* lg, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_CaretValue* cv; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = lg->CaretCount = GET_UShort(); + + FORGET_Frame(); + + lg->CaretValue = NULL; + + if ( ALLOC_ARRAY( lg->CaretValue, count, TTO_CaretValue ) ) + return error; + + cv = lg->CaretValue; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_CaretValue( &cv[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_CaretValue( &cv[n] ); + + FREE( cv ); + return error; + } + + + static void Free_LigGlyph( TTO_LigGlyph* lg ) + { + UShort n, count; + + TTO_CaretValue* cv; + + + if ( lg->CaretValue ) + { + count = lg->CaretCount; + cv = lg->CaretValue; + + for ( n = 0; n < count; n++ ) + Free_CaretValue( &cv[n] ); + + FREE( cv ); + } + } + + + /* LigCaretList */ + + static TT_Error Load_LigCaretList( TTO_LigCaretList* lcl, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_LigGlyph* lg; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &lcl->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = lcl->LigGlyphCount = GET_UShort(); + + FORGET_Frame(); + + lcl->LigGlyph = NULL; + + if ( ALLOC_ARRAY( lcl->LigGlyph, count, TTO_LigGlyph ) ) + goto Fail2; + + lg = lcl->LigGlyph; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigGlyph( &lg[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + lcl->loaded = TRUE; + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_LigGlyph( &lg[n] ); + + FREE( lg ); + + Fail2: + Free_Coverage( &lcl->Coverage ); + return error; + } + + + static void Free_LigCaretList( TTO_LigCaretList* lcl ) + { + UShort n, count; + + TTO_LigGlyph* lg; + + + if ( !lcl->loaded ) + return; + + if ( lcl->LigGlyph ) + { + count = lcl->LigGlyphCount; + lg = lcl->LigGlyph; + + for ( n = 0; n < count; n++ ) + Free_LigGlyph( &lg[n] ); + + FREE( lg ); + } + + Free_Coverage( &lcl->Coverage ); + } + + + + /*********** + * GDEF API + ***********/ + + + static UShort Get_New_Class( TTO_GDEFHeader* gdef, + UShort glyphID, + UShort index ) + { + UShort glyph_index, array_index; + UShort byte, bits; + + TTO_ClassRangeRecord* gcrr; + UShort** ngc; + + + if ( glyphID >= gdef->LastGlyph ) + return 0; + + gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord; + ngc = gdef->NewGlyphClasses; + + if ( glyphID < gcrr[index].Start ) + { + array_index = 0; + if ( index == 0 ) + glyph_index = glyphID; + else + glyph_index = glyphID - gcrr[index - 1].End - 1; + } + else + { + array_index = index + 1; + glyph_index = glyphID - gcrr[index].End - 1; + } + + byte = ngc[array_index][glyph_index / 4 + 1]; + bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 ); + + return bits & 0x000F; + } + + + EXPORT_FUNC + TT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef, + TT_UShort glyphID, + TT_UShort* property ) + { + UShort class, index; + + TT_Error error; + + + if ( !gdef || !property ) + return TT_Err_Invalid_Argument; + + /* first, we check for mark attach classes */ + + if ( gdef->MarkAttachClassDef.loaded ) + { + error = Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + if ( !error ) + { + *property = class << 8; + return TT_Err_Ok; + } + } + + error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + + /* if we have a constructed class table, check whether additional + values have been assigned */ + + if ( error == TTO_Err_Not_Covered && gdef->NewGlyphClasses ) + class = Get_New_Class( gdef, glyphID, index ); + + switch ( class ) + { + case UNCLASSIFIED_GLYPH: + *property = 0; + break; + + case SIMPLE_GLYPH: + *property = TTO_BASE_GLYPH; + break; + + case LIGATURE_GLYPH: + *property = TTO_LIGATURE; + break; + + case MARK_GLYPH: + *property = TTO_MARK; + break; + + case COMPONENT_GLYPH: + *property = TTO_COMPONENT; + break; + } + + return TT_Err_Ok; + } + + + static TT_Error Make_ClassRange( TTO_ClassDefinition* cd, + UShort start, + UShort end, + UShort class ) + { + TT_Error error; + UShort index; + + TTO_ClassDefFormat2* cdf2; + TTO_ClassRangeRecord* crr; + + + cdf2 = &cd->cd.cd2; + + cdf2->ClassRangeCount++; + + if ( REALLOC_ARRAY( cdf2->ClassRangeRecord, cdf2->ClassRangeCount, + TTO_ClassRangeRecord ) ) + return error; + + crr = cdf2->ClassRangeRecord; + index = cdf2->ClassRangeCount - 1; + + crr[index].Start = start; + crr[index].End = end; + crr[index].Class = class; + + cd->Defined[class] = TRUE; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef, + TT_UShort num_glyphs, + TT_UShort glyph_count, + TT_UShort* glyph_array, + TT_UShort* class_array ) + { + UShort start, curr_glyph, curr_class; + UShort n, count; + TT_Error error; + + TTO_ClassDefinition* gcd; + TTO_ClassRangeRecord* gcrr; + UShort** ngc; + + + if ( !gdef || !glyph_array || !class_array ) + return TT_Err_Invalid_Argument; + + gcd = &gdef->GlyphClassDef; + + /* We build a format 2 table */ + + gcd->ClassFormat = 2; + + /* A GlyphClassDef table contains at most 5 different class values */ + + if ( ALLOC_ARRAY( gcd->Defined, 5, Bool ) ) + return error; + + gcd->cd.cd2.ClassRangeCount = 0; + gcd->cd.cd2.ClassRangeRecord = NULL; + + start = glyph_array[0]; + curr_class = class_array[0]; + curr_glyph = start; + + if ( curr_class >= 5 ) + { + error = TT_Err_Invalid_Argument; + goto Fail4; + } + + glyph_count--; + + for ( n = 0; n <= glyph_count; n++ ) + { + if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] ) + { + if ( n == glyph_count ) + { + if ( ( error = Make_ClassRange( gcd, start, + curr_glyph, + curr_class ) ) != TT_Err_Ok ) + goto Fail3; + } + else + { + if ( curr_glyph == 0xFFFF ) + { + error = TT_Err_Invalid_Argument; + goto Fail3; + } + else + curr_glyph++; + } + } + else + { + if ( ( error = Make_ClassRange( gcd, start, + curr_glyph - 1, + curr_class ) ) != TT_Err_Ok ) + goto Fail3; + + if ( curr_glyph > glyph_array[n] ) + { + error = TT_Err_Invalid_Argument; + goto Fail3; + } + + start = glyph_array[n]; + curr_class = class_array[n]; + curr_glyph = start; + + if ( curr_class >= 5 ) + { + error = TT_Err_Invalid_Argument; + goto Fail3; + } + + if ( n == glyph_count ) + { + if ( ( error = Make_ClassRange( gcd, start, + curr_glyph, + curr_class ) ) != TT_Err_Ok ) + goto Fail3; + } + else + { + if ( curr_glyph == 0xFFFF ) + { + error = TT_Err_Invalid_Argument; + goto Fail3; + } + else + curr_glyph++; + } + } + } + + /* now prepare the arrays for class values assigned during the lookup + process */ + + if ( ALLOC_ARRAY( gdef->NewGlyphClasses, + gcd->cd.cd2.ClassRangeCount + 1, UShort* ) ) + goto Fail2; + + count = gcd->cd.cd2.ClassRangeCount; + gcrr = gcd->cd.cd2.ClassRangeRecord; + ngc = gdef->NewGlyphClasses; + + /* We allocate arrays for all glyphs not covered by the class range + records. Each element holds four class values. */ + + if ( gcrr[0].Start ) + { + if ( ALLOC_ARRAY( ngc[0], gcrr[0].Start / 4 + 1, UShort ) ) + goto Fail1; + } + + for ( n = 1; n < count; n++ ) + { + if ( gcrr[n].Start - gcrr[n - 1].End > 1 ) + if ( ALLOC_ARRAY( ngc[n], + ( gcrr[n].Start - gcrr[n - 1].End - 1 ) / 4 + 1, + UShort ) ) + goto Fail1; + } + + if ( gcrr[count - 1].End != num_glyphs - 1 ) + { + if ( ALLOC_ARRAY( ngc[count], + ( num_glyphs - gcrr[count - 1].End - 1 ) / 4 + 1, + UShort ) ) + goto Fail1; + } + + gdef->LastGlyph = num_glyphs - 1; + + gdef->MarkAttachClassDef_offset = 0L; + gdef->MarkAttachClassDef.loaded = FALSE; + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + FREE( ngc[n] ); + + Fail2: + FREE( gdef->NewGlyphClasses ); + + Fail3: + FREE( gcd->cd.cd2.ClassRangeRecord ); + + Fail4: + FREE( gcd->Defined ); + return error; + } + + + static void Free_NewGlyphClasses( TTO_GDEFHeader* gdef ) + { + UShort** ngc; + UShort n, count; + + + if ( gdef->NewGlyphClasses ) + { + count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1; + ngc = gdef->NewGlyphClasses; + + for ( n = 0; n < count; n++ ) + FREE( ngc[n] ); + + FREE( ngc ); + } + } + + + TT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef, + UShort glyphID, + UShort property ) + { + TT_Error error; + UShort class, new_class, index; + UShort byte, bits, mask; + UShort array_index, glyph_index; + + TTO_ClassRangeRecord* gcrr; + UShort** ngc; + + + error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + + /* we don't accept glyphs covered in `GlyphClassDef' */ + + if ( !error ) + return TTO_Err_Not_Covered; + + switch ( property ) + { + case 0: + new_class = UNCLASSIFIED_GLYPH; + break; + + case TTO_BASE_GLYPH: + new_class = SIMPLE_GLYPH; + break; + + case TTO_LIGATURE: + new_class = LIGATURE_GLYPH; + break; + + case TTO_MARK: + new_class = MARK_GLYPH; + break; + + case TTO_COMPONENT: + new_class = COMPONENT_GLYPH; + break; + + default: + return TT_Err_Invalid_Argument; + } + + gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord; + ngc = gdef->NewGlyphClasses; + + if ( glyphID < gcrr[index].Start ) + { + array_index = 0; + if ( index == 0 ) + glyph_index = glyphID; + else + glyph_index = glyphID - gcrr[index - 1].End - 1; + } + else + { + array_index = index + 1; + glyph_index = glyphID - gcrr[index].End - 1; + } + + byte = ngc[array_index][glyph_index / 4 + 1]; + bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 ); + class = bits & 0x000F; + + /* we don't overwrite existing entries */ + + if ( !class ) + { + bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 ); + mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) ); + + ngc[array_index][glyph_index / 4 + 1] &= mask; + ngc[array_index][glyph_index / 4 + 1] |= bits; + } + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/extend/ftxgdef.h b/lib/extend/ftxgdef.h new file mode 100644 index 0000000..3387232 --- /dev/null +++ b/lib/extend/ftxgdef.h @@ -0,0 +1,216 @@ +/******************************************************************* + * + * ftxgdef.h + * + * TrueType Open GDEF table support + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FTXOPEN_H +#error "Don't include this file! Use ftxopen.h instead." +#endif + +#ifndef FTXGDEF_H +#define FTXGDEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define TTO_Err_Invalid_GDEF_SubTable_Format 0x1030 +#define TTO_Err_Invalid_GDEF_SubTable 0x1031 + + +/* GDEF glyph classes */ + +#define UNCLASSIFIED_GLYPH 0 +#define SIMPLE_GLYPH 1 +#define LIGATURE_GLYPH 2 +#define MARK_GLYPH 3 +#define COMPONENT_GLYPH 4 + +/* GDEF glyph properties, corresponding to class values 1-4. Note that + TTO_COMPONENT has no corresponding flag in the LookupFlag field. */ + +#define TTO_BASE_GLYPH 0x0002 +#define TTO_LIGATURE 0x0004 +#define TTO_MARK 0x0008 +#define TTO_COMPONENT 0x0010 + + + /* Attachment related structures */ + + struct TTO_AttachPoint_ + { + TT_UShort PointCount; /* size of the PointIndex array */ + TT_UShort* PointIndex; /* array of contour points */ + }; + + typedef struct TTO_AttachPoint_ TTO_AttachPoint; + + + struct TTO_AttachList_ + { + TT_Bool loaded; + + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort GlyphCount; /* number of glyphs with + attachments */ + TTO_AttachPoint* AttachPoint; /* array of AttachPoint tables */ + }; + + typedef struct TTO_AttachList_ TTO_AttachList; + + + /* Ligature Caret related structures */ + + struct TTO_CaretValueFormat1_ + { + TT_Short Coordinate; /* x or y value (in design units) */ + }; + + typedef struct TTO_CaretValueFormat1_ TTO_CaretValueFormat1; + + + struct TTO_CaretValueFormat2_ + { + TT_UShort CaretValuePoint; /* contour point index on glyph */ + }; + + typedef struct TTO_CaretValueFormat2_ TTO_CaretValueFormat2; + + + struct TTO_CaretValueFormat3_ + { + TT_Short Coordinate; /* x or y value (in design units) */ + TTO_Device Device; /* Device table for x or y value */ + }; + + typedef struct TTO_CaretValueFormat3_ TTO_CaretValueFormat3; + + + struct TTO_CaretValueFormat4_ + { + TT_UShort IdCaretValue; /* metric ID */ + }; + + typedef struct TTO_CaretValueFormat4_ TTO_CaretValueFormat4; + + + struct TTO_CaretValue_ + { + TT_UShort CaretValueFormat; /* 1, 2, 3, or 4 */ + + union + { + TTO_CaretValueFormat1 cvf1; + TTO_CaretValueFormat2 cvf2; + TTO_CaretValueFormat3 cvf3; + TTO_CaretValueFormat4 cvf4; + } cvf; + }; + + typedef struct TTO_CaretValue_ TTO_CaretValue; + + + struct TTO_LigGlyph_ + { + TT_Bool loaded; + + TT_UShort CaretCount; /* number of caret values */ + TTO_CaretValue* CaretValue; /* array of caret values */ + }; + + typedef struct TTO_LigGlyph_ TTO_LigGlyph; + + + struct TTO_LigCaretList_ + { + TT_Bool loaded; + + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort LigGlyphCount; /* number of ligature glyphs */ + TTO_LigGlyph* LigGlyph; /* array of LigGlyph tables */ + }; + + typedef struct TTO_LigCaretList_ TTO_LigCaretList; + + + /* The `NewGlyphClasses' field is not defined in the TTO specification. + We use it for fonts with a constructed `GlyphClassDef' structure + (i.e., which don't have a GDEF table) to collect glyph classes + assigned during the lookup process. The number of arrays in this + pointer array is GlyphClassDef->cd.cd2.ClassRangeCount+1; the nth + array then contains the glyph class values of the glyphs not covered + by the ClassRangeRecords structures with index n-1 and n. We store + glyph class values for four glyphs in a single array element. + + `LastGlyph' is identical to the number of glyphs minus one in the + font; we need it only if `NewGlyphClasses' is not NULL (to have an + upper bound for the last array). + + Note that we first store the file offset to the `MarkAttachClassDef' + field (which has been introduced in OpenType 1.2) -- since the + `Version' field value hasn't been increased to indicate that we have + one more field for some obscure reason, we must parse the GSUB table + to find out whether class values refer to this table. Only then we + can finally load the MarkAttachClassDef structure if necessary. */ + + struct TTO_GDEFHeader_ + { + TT_Bool loaded; + TT_ULong offset; + + TT_Fixed Version; + + TTO_ClassDefinition GlyphClassDef; + TTO_AttachList AttachList; + TTO_LigCaretList LigCaretList; + TT_ULong MarkAttachClassDef_offset; + TTO_ClassDefinition MarkAttachClassDef; /* new in OT 1.2 */ + + TT_UShort LastGlyph; + TT_UShort** NewGlyphClasses; + }; + + typedef struct TTO_GDEFHeader_ TTO_GDEFHeader; + + + /* finally, the GDEF API */ + + EXPORT_DEF + TT_Error TT_Init_GDEF_Extension( TT_Engine engine ); + + EXPORT_DEF + TT_Error TT_Load_GDEF_Table( TT_Face face, + TTO_GDEFHeader* gdef ); + + EXPORT_DEF + TT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef, + TT_UShort glyphID, + TT_UShort* property ); + EXPORT_DEF + TT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef, + TT_UShort num_glyphs, + TT_UShort glyph_count, + TT_UShort* glyph_array, + TT_UShort* class_array ); + + +#ifdef __cplusplus +} +#endif + +#endif /* FTXGDEF_H */ + + +/* END */ diff --git a/lib/extend/ftxgpos.c b/lib/extend/ftxgpos.c new file mode 100644 index 0000000..76a52b7 --- /dev/null +++ b/lib/extend/ftxgpos.c @@ -0,0 +1,4045 @@ +/******************************************************************* + * + * ftxgpos.c + * + * TrueType Open GPOS table support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +/* XXX There is *a lot* of duplicated code (cf. formats 7 and 8), but + I don't care currently. I believe that it would be possible to + save about 50% of TTO code by carefully designing the structures, + sharing as much as possible with extensive use of macros. This + is something for a volunteer :-) */ + +#include "tttypes.h" +#include "tttags.h" +#include "ttload.h" +#include "ttextend.h" +#include "ttmemory.h" +#include "ttfile.h" + +#include "ftxopen.h" +#include "ftxopenf.h" + + +#define GPOS_ID Build_Extension_ID( 'G', 'P', 'O', 'S' ) + + + + /********************** + * Extension Functions + **********************/ + + + static TT_Error GPOS_Create( void* ext, + PFace face ) + { + DEFINE_LOAD_LOCALS( face->stream ); + + TTO_GPOSHeader* gpos = (TTO_GPOSHeader*)ext; + Long table; + + + /* by convention */ + + if ( !gpos ) + return TT_Err_Ok; + + /* a null offset indicates that there is no GPOS table */ + + gpos->offset = 0; + + /* we store the start offset and the size of the subtable */ + + table = TT_LookUp_Table( face, TTAG_GPOS ); + if ( table < 0 ) + return TT_Err_Ok; /* The table is optional */ + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + gpos->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */ + gpos->Version = GET_ULong(); + + FORGET_Frame(); + + gpos->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error GPOS_Destroy( void* ext, + PFace face ) + { + TTO_GPOSHeader* gpos = (TTO_GPOSHeader*)ext; + + + /* by convention */ + + if ( !gpos ) + return TT_Err_Ok; + + if ( gpos->loaded ) + { + Free_LookupList( &gpos->LookupList, GPOS ); + Free_FeatureList( &gpos->FeatureList ); + Free_ScriptList( &gpos->ScriptList ); + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_GPOS_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + return TT_Register_Extension( _engine, + GPOS_ID, + sizeof ( TTO_GPOSHeader ), + GPOS_Create, + GPOS_Destroy ); + } + + + EXPORT_FUNC + TT_Error TT_Load_GPOS_Table( TT_Face face, + TTO_GPOSHeader* retptr, + TTO_GDEFHeader* gdef ) + { + ULong cur_offset, new_offset, base_offset; + + TT_UShort i, num_lookups; + TT_Error error; + TT_Stream stream; + TTO_GPOSHeader* gpos; + TTO_Lookup* lo; + + PFace faze = HANDLE_Face( face ); + + + if ( !retptr ) + return TT_Err_Invalid_Argument; + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, GPOS_ID, (void**)&gpos ); + if ( error ) + return error; + + if ( gpos->offset == 0 ) + return TT_Err_Table_Missing; /* no GPOS table; nothing to do */ + + /* now access stream */ + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + base_offset = gpos->offset; + + /* skip version */ + + if ( FILE_Seek( base_offset + 4L ) || + ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ScriptList( &gpos->ScriptList, + faze ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_FeatureList( &gpos->FeatureList, + faze ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LookupList( &gpos->LookupList, + faze, GPOS ) ) != TT_Err_Ok ) + goto Fail2; + + gpos->gdef = gdef; /* can be NULL */ + + /* We now check the LookupFlags for values larger than 0xFF to find + out whether we need to load the `MarkAttachClassDef' field of the + GDEF table -- this hack is necessary for OpenType 1.2 tables since + the version field of the GDEF table hasn't been incremented. + + For constructed GDEF tables, we only load it if + `MarkAttachClassDef_offset' is not zero (nevertheless, a build of + a constructed mark attach table is not supported currently). */ + + if ( gdef && + gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded ) + { + lo = gpos->LookupList.Lookup; + num_lookups = gpos->LookupList.LookupCount; + + for ( i = 0; i < num_lookups; i++ ) + { + if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS ) + { + if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) || + ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( !new_offset ) + return TTO_Err_Invalid_GDEF_SubTable; + + new_offset += base_offset; + + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef, + 256, faze ) ) != TT_Err_Ok ) + goto Fail1; + + break; + } + } + } + + gpos->loaded = TRUE; + *retptr = *gpos; + DONE_Stream( stream ); + + return TT_Err_Ok; + + Fail1: + Free_LookupList( &gpos->LookupList, GPOS ); + + Fail2: + Free_FeatureList( &gpos->FeatureList ); + + Fail3: + Free_ScriptList( &gpos->ScriptList ); + + /* release stream */ + + DONE_Stream( stream ); + + return error; + } + + + + /***************************** + * SubTable related functions + *****************************/ + + /* shared tables */ + + /* ValueRecord */ + + static TT_Error Load_ValueRecord( TTO_ValueRecord* vr, + TT_UShort format, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( format & HAVE_X_PLACEMENT ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + vr->XPlacement = GET_Short(); + + FORGET_Frame(); + } + else + vr->XPlacement = 0; + + if ( format & HAVE_Y_PLACEMENT ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + vr->YPlacement = GET_Short(); + + FORGET_Frame(); + } + else + vr->YPlacement = 0; + + if ( format & HAVE_X_ADVANCE ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + vr->XAdvance = GET_Short(); + + FORGET_Frame(); + } + else + vr->XAdvance = 0; + + if ( format & HAVE_Y_ADVANCE ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + vr->YAdvance = GET_Short(); + + FORGET_Frame(); + } + else + vr->YAdvance = 0; + + if ( format & HAVE_X_PLACEMENT_DEVICE ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &vr->XPlacementDevice, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + } + else + { + vr->XPlacementDevice.StartSize = 0; + vr->XPlacementDevice.EndSize = 0; + vr->XPlacementDevice.DeltaValue = NULL; + } + + if ( format & HAVE_Y_PLACEMENT_DEVICE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &vr->YPlacementDevice, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + } + else + { + vr->YPlacementDevice.StartSize = 0; + vr->YPlacementDevice.EndSize = 0; + vr->YPlacementDevice.DeltaValue = NULL; + } + + if ( format & HAVE_X_ADVANCE_DEVICE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &vr->XAdvanceDevice, + input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + else + { + vr->XAdvanceDevice.StartSize = 0; + vr->XAdvanceDevice.EndSize = 0; + vr->XAdvanceDevice.DeltaValue = NULL; + } + + if ( format & HAVE_Y_ADVANCE_DEVICE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &vr->YAdvanceDevice, + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + vr->YAdvanceDevice.StartSize = 0; + vr->YAdvanceDevice.EndSize = 0; + vr->YAdvanceDevice.DeltaValue = NULL; + } + + if ( format & HAVE_X_ID_PLACEMENT ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + vr->XIdPlacement = GET_UShort(); + + FORGET_Frame(); + } + else + vr->XIdPlacement = 0; + + if ( format & HAVE_Y_ID_PLACEMENT ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + vr->YIdPlacement = GET_UShort(); + + FORGET_Frame(); + } + else + vr->YIdPlacement = 0; + + if ( format & HAVE_X_ID_ADVANCE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + vr->XIdAdvance = GET_UShort(); + + FORGET_Frame(); + } + else + vr->XIdAdvance = 0; + + if ( format & HAVE_Y_ID_ADVANCE ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + vr->YIdAdvance = GET_UShort(); + + FORGET_Frame(); + } + else + vr->YIdAdvance = 0; + + return TT_Err_Ok; + + Fail1: + Free_Device( &vr->YAdvanceDevice ); + + Fail2: + Free_Device( &vr->XAdvanceDevice ); + + Fail3: + Free_Device( &vr->YPlacementDevice ); + return error; + } + + + static void Free_ValueRecord( TTO_ValueRecord* vr, + UShort format ) + { + if ( format & HAVE_Y_ADVANCE_DEVICE ) + Free_Device( &vr->YAdvanceDevice ); + if ( format & HAVE_X_ADVANCE_DEVICE ) + Free_Device( &vr->XAdvanceDevice ); + if ( format & HAVE_Y_PLACEMENT_DEVICE ) + Free_Device( &vr->YPlacementDevice ); + if ( format & HAVE_X_PLACEMENT_DEVICE ) + Free_Device( &vr->XPlacementDevice ); + } + + + /* AnchorFormat1 */ + /* AnchorFormat2 */ + /* AnchorFormat3 */ + /* AnchorFormat4 */ + + static TT_Error Load_Anchor( TTO_Anchor* an, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + an->PosFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( an->PosFormat ) + { + case 1: + if ( ACCESS_Frame( 4L ) ) + return error; + + an->af.af1.XCoordinate = GET_Short(); + an->af.af1.YCoordinate = GET_Short(); + + FORGET_Frame(); + break; + + case 2: + if ( ACCESS_Frame( 6L ) ) + return error; + + an->af.af2.XCoordinate = GET_Short(); + an->af.af2.YCoordinate = GET_Short(); + an->af.af2.AnchorPoint = GET_UShort(); + + FORGET_Frame(); + break; + + case 3: + if ( ACCESS_Frame( 6L ) ) + return error; + + an->af.af3.XCoordinate = GET_Short(); + an->af.af3.YCoordinate = GET_Short(); + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &an->af.af3.XDeviceTable, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + } + else + { + an->af.af3.XDeviceTable.StartSize = 0; + an->af.af3.XDeviceTable.EndSize = 0; + an->af.af3.XDeviceTable.DeltaValue = 0; + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Device( &an->af.af3.YDeviceTable, + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + else + { + an->af.af3.YDeviceTable.StartSize = 0; + an->af.af3.YDeviceTable.EndSize = 0; + an->af.af3.YDeviceTable.DeltaValue = 0; + } + break; + + case 4: + if ( ACCESS_Frame( 4L ) ) + return error; + + an->af.af4.XIdAnchor = GET_UShort(); + an->af.af4.YIdAnchor = GET_UShort(); + + FORGET_Frame(); + break; + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; + + Fail: + Free_Device( &an->af.af3.XDeviceTable ); + return error; + } + + + static void Free_Anchor( TTO_Anchor* an ) + { + if ( an->PosFormat == 3 ) + { + Free_Device( &an->af.af3.YDeviceTable ); + Free_Device( &an->af.af3.XDeviceTable ); + } + } + + + /* MarkArray */ + + static TT_Error Load_MarkArray ( TTO_MarkArray* ma, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_MarkRecord* mr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ma->MarkCount = GET_UShort(); + + FORGET_Frame(); + + ma->MarkRecord = NULL; + + if ( ALLOC_ARRAY( ma->MarkRecord, count, TTO_MarkRecord ) ) + return error; + + mr = ma->MarkRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 4L ) ) + goto Fail; + + mr[n].Class = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &mr[n].MarkAnchor, input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_Anchor( &mr[n].MarkAnchor ); + + FREE( mr ); + return error; + } + + + static void Free_MarkArray( TTO_MarkArray* ma ) + { + UShort n, count; + + TTO_MarkRecord* mr; + + + if ( ma->MarkRecord ) + { + count = ma->MarkCount; + mr = ma->MarkRecord; + + for ( n = 0; n < count; n++ ) + Free_Anchor( &mr[n].MarkAnchor ); + + FREE( mr ); + } + } + + + /* LookupType 1 */ + + /* SinglePosFormat1 */ + /* SinglePosFormat2 */ + + TT_Error Load_SinglePos( TTO_SinglePos* sp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count, format; + ULong cur_offset, new_offset, base_offset; + + TTO_ValueRecord* v; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 6L ) ) + return error; + + sp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + format = sp->ValueFormat = GET_UShort(); + + FORGET_Frame(); + + if ( !format ) + return TTO_Err_Invalid_GPOS_SubTable; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &sp->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + switch ( sp->PosFormat ) + { + case 1: + error = Load_ValueRecord( &sp->spf.spf1.Value, format, input ); + if ( error ) + goto Fail2; + break; + + case 2: + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = sp->spf.spf2.ValueCount = GET_UShort(); + + FORGET_Frame(); + + sp->spf.spf2.Value = NULL; + + if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, TTO_ValueRecord ) ) + goto Fail2; + + v = sp->spf.spf2.Value; + + for ( n = 0; n < count; n++ ) + { + error = Load_ValueRecord( &v[n], format, input ); + if ( error ) + goto Fail1; + } + break; + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ValueRecord( &v[n], format ); + + FREE( v ); + + Fail2: + Free_Coverage( &sp->Coverage ); + return error; + } + + + void Free_SinglePos( TTO_SinglePos* sp ) + { + UShort n, count, format; + + TTO_ValueRecord* v; + + + format = sp->ValueFormat; + + switch ( sp->PosFormat ) + { + case 1: + Free_ValueRecord( &sp->spf.spf1.Value, format ); + break; + + case 2: + if ( sp->spf.spf2.Value ) + { + count = sp->spf.spf2.ValueCount; + v = sp->spf.spf2.Value; + + for ( n = 0; n < count; n++ ) + Free_ValueRecord( &v[n], format ); + + FREE( v ); + } + break; + } + + Free_Coverage( &sp->Coverage ); + } + + + /* LookupType 2 */ + + /* PairSet */ + + static TT_Error Load_PairSet ( TTO_PairSet* ps, + UShort format1, + UShort format2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + TTO_PairValueRecord* pvr; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ps->PairValueCount = GET_UShort(); + + FORGET_Frame(); + + ps->PairValueRecord = NULL; + + if ( ALLOC_ARRAY( ps->PairValueRecord, count, TTO_PairValueRecord ) ) + return error; + + pvr = ps->PairValueRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + pvr[n].SecondGlyph = GET_UShort(); + + FORGET_Frame(); + + if ( format1 ) + { + error = Load_ValueRecord( &pvr[n].Value1, format1, input ); + if ( error ) + goto Fail; + } + if ( format2 ) + { + error = Load_ValueRecord( &pvr[n].Value2, format2, input ); + if ( error ) + goto Fail; + } + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + { + if ( format1 ) + Free_ValueRecord( &pvr[n].Value1, format1 ); + if ( format2 ) + Free_ValueRecord( &pvr[n].Value2, format2 ); + } + + FREE( pvr ); + return error; + } + + + static void Free_PairSet( TTO_PairSet* ps, + UShort format1, + UShort format2 ) + { + UShort n, count; + + TTO_PairValueRecord* pvr; + + + if ( ps->PairValueRecord ) + { + count = ps->PairValueCount; + pvr = ps->PairValueRecord; + + for ( n = 0; n < count; n++ ) + { + if ( format1 ) + Free_ValueRecord( &pvr[n].Value1, format1 ); + if ( format2 ) + Free_ValueRecord( &pvr[n].Value2, format2 ); + } + + FREE( pvr ); + } + } + + + /* PairPosFormat1 */ + + static TT_Error Load_PairPosFormat1( TTO_PairPosFormat1* ppf1, + UShort format1, + UShort format2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PairSet* ps; + + + base_offset = FILE_Pos() - 8L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ppf1->PairSetCount = GET_UShort(); + + FORGET_Frame(); + + ppf1->PairSet = NULL; + + if ( ALLOC_ARRAY( ppf1->PairSet, count, TTO_PairSet ) ) + goto Fail; + + ps = ppf1->PairSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PairSet( &ps[n], format1, + format2, input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_PairSet( &ps[n], format1, format2 ); + + FREE( ps ); + return error; + } + + + static void Free_PairPosFormat1( TTO_PairPosFormat1* ppf1, + UShort format1, + UShort format2 ) + { + UShort n, count; + + TTO_PairSet* ps; + + + if ( ppf1->PairSet ) + { + count = ppf1->PairSetCount; + ps = ppf1->PairSet; + + for ( n = 0; n < count; n++ ) + Free_PairSet( &ps[n], format1, format2 ); + + FREE( ps ); + } + } + + + /* PairPosFormat2 */ + + static TT_Error Load_PairPosFormat2( TTO_PairPosFormat2* ppf2, + UShort format1, + UShort format2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort m, n, count1, count2; + ULong cur_offset, new_offset1, new_offset2, base_offset; + + TTO_Class1Record* c1r; + TTO_Class2Record* c2r; + + + base_offset = FILE_Pos() - 8L; + + if ( ACCESS_Frame( 8L ) ) + return error; + + new_offset1 = GET_UShort() + base_offset; + new_offset2 = GET_UShort() + base_offset; + + /* `Class1Count' and `Class2Count' are the upper limits for class + values, thus we read it now to make additional safety checks. */ + + count1 = ppf2->Class1Count = GET_UShort(); + count2 = ppf2->Class2Count = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset1 ) || + ( error = Load_ClassDefinition( &ppf2->ClassDef1, count1, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset2 ) || + ( error = Load_ClassDefinition( &ppf2->ClassDef2, count2, + input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + + ppf2->Class1Record = NULL; + + if ( ALLOC_ARRAY( ppf2->Class1Record, count1, TTO_Class1Record ) ) + goto Fail1; + + c1r = ppf2->Class1Record; + + for ( m = 0; m < count1; m++ ) + { + c1r[m].Class2Record = NULL; + + if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, TTO_Class2Record ) ) + goto Fail1; + + c2r = c1r[m].Class2Record; + + for ( n = 0; n < count2; n++ ) + { + if ( format1 ) + { + Load_ValueRecord( &c2r[n].Value1, format1, input ); + if ( error ) + goto Fail1; + } + if ( format2 ) + { + Load_ValueRecord( &c2r[n].Value2, format2, input ); + if ( error ) + goto Fail1; + } + } + } + + return TT_Err_Ok; + + Fail1: + for ( m = 0; m < count1; m++ ) + { + c2r = c1r[m].Class2Record; + + for ( n = 0; n < count2; n++ ) + { + if ( format1 ) + Free_ValueRecord( &c2r[n].Value1, format1 ); + if ( format2 ) + Free_ValueRecord( &c2r[n].Value2, format2 ); + } + + FREE( c2r ); + } + + FREE( c1r ); + + Free_ClassDefinition( &ppf2->ClassDef2 ); + + Fail2: + Free_ClassDefinition( &ppf2->ClassDef1 ); + return error; + } + + + static void Free_PairPosFormat2( TTO_PairPosFormat2* ppf2, + UShort format1, + UShort format2 ) + { + UShort m, n, count1, count2; + + TTO_Class1Record* c1r; + TTO_Class2Record* c2r; + + + if ( ppf2->Class1Record ) + { + c1r = ppf2->Class1Record; + count1 = ppf2->Class1Count; + count2 = ppf2->Class2Count; + + for ( m = 0; m < count1; m++ ) + { + c2r = c1r[m].Class2Record; + + for ( n = 0; n < count2; n++ ) + { + if ( format1 ) + Free_ValueRecord( &c2r[n].Value1, format1 ); + if ( format2 ) + Free_ValueRecord( &c2r[n].Value2, format2 ); + } + + FREE( c2r ); + } + + FREE( c1r ); + + Free_ClassDefinition( &ppf2->ClassDef2 ); + Free_ClassDefinition( &ppf2->ClassDef1 ); + } + } + + + TT_Error Load_PairPos( TTO_PairPos* pp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort format1, format2; + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 8L ) ) + return error; + + pp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + format1 = pp->ValueFormat1 = GET_UShort(); + format2 = pp->ValueFormat2 = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &pp->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + switch ( pp->PosFormat ) + { + case 1: + error = Load_PairPosFormat1( &pp->ppf.ppf1, format1, format2, input ); + if ( error ) + goto Fail; + break; + + case 2: + error = Load_PairPosFormat2( &pp->ppf.ppf2, format1, format2, input ); + if ( error ) + goto Fail; + break; + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; + + Fail: + Free_Coverage( &pp->Coverage ); + return error; + } + + + void Free_PairPos( TTO_PairPos* pp ) + { + UShort format1, format2; + + + format1 = pp->ValueFormat1; + format2 = pp->ValueFormat2; + + switch ( pp->PosFormat ) + { + case 1: + Free_PairPosFormat1( &pp->ppf.ppf1, format1, format2 ); + break; + + case 2: + Free_PairPosFormat2( &pp->ppf.ppf2, format1, format2 ); + break; + } + + Free_Coverage( &pp->Coverage ); + } + + + /* LookupType 3 */ + + /* CursivePosFormat1 */ + + TT_Error Load_CursivePos( TTO_CursivePos* cp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_EntryExitRecord* eer; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + cp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &cp->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = cp->EntryExitCount = GET_UShort(); + + FORGET_Frame(); + + cp->EntryExitRecord = NULL; + + if ( ALLOC_ARRAY( cp->EntryExitRecord, count, TTO_EntryExitRecord ) ) + goto Fail2; + + eer = cp->EntryExitRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &eer[n].EntryAnchor, + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + eer[n].EntryAnchor.PosFormat = 0; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &eer[n].ExitAnchor, + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + eer[n].ExitAnchor.PosFormat = 0; + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + { + Free_Anchor( &eer[n].EntryAnchor ); + Free_Anchor( &eer[n].ExitAnchor ); + } + + FREE( eer ); + + Fail2: + Free_Coverage( &cp->Coverage ); + return error; + } + + + void Free_CursivePos( TTO_CursivePos* cp ) + { + UShort n, count; + + TTO_EntryExitRecord* eer; + + + if ( cp->EntryExitRecord ) + { + count = cp->EntryExitCount; + eer = cp->EntryExitRecord; + + for ( n = 0; n < count; n++ ) + { + Free_Anchor( &eer[n].EntryAnchor ); + Free_Anchor( &eer[n].ExitAnchor ); + } + + FREE( eer ); + } + + Free_Coverage( &cp->Coverage ); + } + + + /* LookupType 4 */ + + /* BaseArray */ + + static TT_Error Load_BaseArray( TTO_BaseArray* ba, + UShort num_classes, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort m, n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_BaseRecord* br; + TTO_Anchor* ban; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ba->BaseCount = GET_UShort(); + + FORGET_Frame(); + + ba->BaseRecord = NULL; + + if ( ALLOC_ARRAY( ba->BaseRecord, count, TTO_BaseRecord ) ) + return error; + + br = ba->BaseRecord; + + for ( m = 0; m < count; m++ ) + { + br[m].BaseAnchor = NULL; + + if ( ALLOC_ARRAY( br[m].BaseAnchor, num_classes, TTO_Anchor ) ) + goto Fail; + + ban = br[m].BaseAnchor; + + for ( n = 0; n < num_classes; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &ban[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + } + + return TT_Err_Ok; + + Fail: + for ( m = 0; m < count; m++ ) + { + ban = br[m].BaseAnchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &ban[n] ); + + FREE( ban ); + } + + FREE( br ); + return error; + } + + + static void Free_BaseArray( TTO_BaseArray* ba, + UShort num_classes ) + { + UShort m, n, count; + + TTO_BaseRecord* br; + TTO_Anchor* ban; + + + if ( ba->BaseRecord ) + { + count = ba->BaseCount; + br = ba->BaseRecord; + + for ( m = 0; m < count; m++ ) + { + ban = br[m].BaseAnchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &ban[n] ); + + FREE( ban ); + } + + FREE( br ); + } + } + + + /* MarkBasePosFormat1 */ + + TT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + mbp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mbp->MarkCoverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mbp->BaseCoverage, input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail2; + + mbp->ClassCount = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_MarkArray( &mbp->MarkArray, input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount, + input ) ) != TT_Err_Ok ) + goto Fail1; + + return TT_Err_Ok; + + Fail1: + Free_MarkArray( &mbp->MarkArray ); + + Fail2: + Free_Coverage( &mbp->BaseCoverage ); + + Fail3: + Free_Coverage( &mbp->MarkCoverage ); + return error; + } + + + void Free_MarkBasePos( TTO_MarkBasePos* mbp ) + { + Free_BaseArray( &mbp->BaseArray, mbp->ClassCount ); + Free_MarkArray( &mbp->MarkArray ); + Free_Coverage( &mbp->BaseCoverage ); + Free_Coverage( &mbp->MarkCoverage ); + } + + + /* LookupType 5 */ + + /* LigatureAttach */ + + static TT_Error Load_LigatureAttach( TTO_LigatureAttach* lat, + UShort num_classes, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort m, n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ComponentRecord* cr; + TTO_Anchor* lan; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = lat->ComponentCount = GET_UShort(); + + FORGET_Frame(); + + lat->ComponentRecord = NULL; + + if ( ALLOC_ARRAY( lat->ComponentRecord, count, TTO_ComponentRecord ) ) + return error; + + cr = lat->ComponentRecord; + + for ( m = 0; m < count; m++ ) + { + cr[m].LigatureAnchor = NULL; + + if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, TTO_Anchor ) ) + goto Fail; + + lan = cr[m].LigatureAnchor; + + for ( n = 0; n < num_classes; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( new_offset ) + { + new_offset += base_offset; + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &lan[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + else + lan[n].PosFormat = 0; + } + } + + return TT_Err_Ok; + + Fail: + for ( m = 0; m < count; m++ ) + { + lan = cr[m].LigatureAnchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &lan[n] ); + + FREE( lan ); + } + + FREE( cr ); + return error; + } + + + static void Free_LigatureAttach( TTO_LigatureAttach* lat, + UShort num_classes ) + { + UShort m, n, count; + + TTO_ComponentRecord* cr; + TTO_Anchor* lan; + + + if ( lat->ComponentRecord ) + { + count = lat->ComponentCount; + cr = lat->ComponentRecord; + + for ( m = 0; m < count; m++ ) + { + lan = cr[m].LigatureAnchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &lan[n] ); + + FREE( lan ); + } + + FREE( cr ); + } + } + + + /* LigatureArray */ + + static TT_Error Load_LigatureArray( TTO_LigatureArray* la, + UShort num_classes, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_LigatureAttach* lat; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = la->LigatureCount = GET_UShort(); + + FORGET_Frame(); + + la->LigatureAttach = NULL; + + if ( ALLOC_ARRAY( la->LigatureAttach, count, TTO_LigatureAttach ) ) + return error; + + lat = la->LigatureAttach; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigatureAttach( &lat[n], num_classes, + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_LigatureAttach( &lat[n], num_classes ); + + FREE( lat ); + return error; + } + + + static void Free_LigatureArray( TTO_LigatureArray* la, + UShort num_classes ) + { + UShort n, count; + + TTO_LigatureAttach* lat; + + + if ( la->LigatureAttach ) + { + count = la->LigatureCount; + lat = la->LigatureAttach; + + for ( n = 0; n < count; n++ ) + Free_LigatureAttach( &lat[n], num_classes ); + + FREE( lat ); + } + } + + + /* MarkLigPosFormat1 */ + + TT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + mlp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mlp->MarkCoverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mlp->LigatureCoverage, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail2; + + mlp->ClassCount = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_MarkArray( &mlp->MarkArray, input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, + input ) ) != TT_Err_Ok ) + goto Fail1; + + return TT_Err_Ok; + + Fail1: + Free_MarkArray( &mlp->MarkArray ); + + Fail2: + Free_Coverage( &mlp->LigatureCoverage ); + + Fail3: + Free_Coverage( &mlp->MarkCoverage ); + return error; + } + + + void Free_MarkLigPos( TTO_MarkLigPos* mlp ) + { + Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount ); + Free_MarkArray( &mlp->MarkArray ); + Free_Coverage( &mlp->LigatureCoverage ); + Free_Coverage( &mlp->MarkCoverage ); + } + + + /* LookupType 6 */ + + /* Mark2Array */ + + static TT_Error Load_Mark2Array( TTO_Mark2Array* m2a, + UShort num_classes, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort m, n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Mark2Record* m2r; + TTO_Anchor* m2an; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = m2a->Mark2Count = GET_UShort(); + + FORGET_Frame(); + + m2a->Mark2Record = NULL; + + if ( ALLOC_ARRAY( m2a->Mark2Record, count, TTO_Mark2Record ) ) + return error; + + m2r = m2a->Mark2Record; + + for ( m = 0; m < count; m++ ) + { + m2r[m].Mark2Anchor = NULL; + + if ( ALLOC_ARRAY( m2r[m].Mark2Anchor, num_classes, TTO_Anchor ) ) + goto Fail; + + m2an = m2r[m].Mark2Anchor; + + for ( n = 0; n < num_classes; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Anchor( &m2an[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + } + + return TT_Err_Ok; + + Fail: + for ( m = 0; m < count; m++ ) + { + m2an = m2r[m].Mark2Anchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &m2an[n] ); + + FREE( m2an ); + } + + FREE( m2r ); + return error; + } + + + static void Free_Mark2Array( TTO_Mark2Array* m2a, + UShort num_classes ) + { + UShort m, n, count; + + TTO_Mark2Record* m2r; + TTO_Anchor* m2an; + + + if ( m2a->Mark2Record ) + { + count = m2a->Mark2Count; + m2r = m2a->Mark2Record; + + for ( m = 0; m < count; m++ ) + { + m2an = m2r[m].Mark2Anchor; + + for ( n = 0; n < num_classes; n++ ) + Free_Anchor( &m2an[n] ); + + FREE( m2an ); + } + + FREE( m2r ); + } + } + + + /* MarkMarkPosFormat1 */ + + TT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + ULong cur_offset, new_offset, base_offset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + mmp->PosFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mmp->Mark1Coverage, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &mmp->Mark2Coverage, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail2; + + mmp->ClassCount = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_MarkArray( &mmp->Mark1Array, input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount, + input ) ) != TT_Err_Ok ) + goto Fail1; + + return TT_Err_Ok; + + Fail1: + Free_MarkArray( &mmp->Mark1Array ); + + Fail2: + Free_Coverage( &mmp->Mark2Coverage ); + + Fail3: + Free_Coverage( &mmp->Mark1Coverage ); + return error; + } + + + void Free_MarkMarkPos( TTO_MarkMarkPos* mmp ) + { + Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount ); + Free_MarkArray( &mmp->Mark1Array ); + Free_Coverage( &mmp->Mark2Coverage ); + Free_Coverage( &mmp->Mark1Coverage ); + } + + + /* LookupType 7 */ + + /* PosRule */ + + static TT_Error Load_PosRule( TTO_PosRule* pr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* i; + + TTO_PosLookupRecord* plr; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + pr->GlyphCount = GET_UShort(); + pr->PosCount = GET_UShort(); + + FORGET_Frame(); + + pr->Input = NULL; + + count = pr->GlyphCount - 1; /* only GlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( pr->Input, count, UShort ) ) + return error; + + i = pr->Input; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + i[n] = GET_UShort(); + + FORGET_Frame(); + + pr->PosLookupRecord = NULL; + + count = pr->PosCount; + + if ( ALLOC_ARRAY( pr->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = pr->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + FREE( i ); + return error; + } + + + static void Free_PosRule( TTO_PosRule* pr ) + { + FREE( pr->PosLookupRecord ); + FREE( pr->Input ); + } + + + /* PosRuleSet */ + + static TT_Error Load_PosRuleSet( TTO_PosRuleSet* prs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PosRule* pr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = prs->PosRuleCount = GET_UShort(); + + FORGET_Frame(); + + prs->PosRule = NULL; + + if ( ALLOC_ARRAY( prs->PosRule, count, TTO_PosRule ) ) + return error; + + pr = prs->PosRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PosRule( &pr[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_PosRule( &pr[n] ); + + FREE( pr ); + return error; + } + + + static void Free_PosRuleSet( TTO_PosRuleSet* prs ) + { + UShort n, count; + + TTO_PosRule* pr; + + + if ( prs->PosRule ) + { + count = prs->PosRuleCount; + pr = prs->PosRule; + + for ( n = 0; n < count; n++ ) + Free_PosRule( &pr[n] ); + + FREE( pr ); + } + } + + + /* ContextPosFormat1 */ + + static TT_Error Load_ContextPos1( TTO_ContextPosFormat1* cpf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PosRuleSet* prs; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &cpf1->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = cpf1->PosRuleSetCount = GET_UShort(); + + FORGET_Frame(); + + cpf1->PosRuleSet = NULL; + + if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, TTO_PosRuleSet ) ) + goto Fail2; + + prs = cpf1->PosRuleSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PosRuleSet( &prs[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_PosRuleSet( &prs[n] ); + + FREE( prs ); + + Fail2: + Free_Coverage( &cpf1->Coverage ); + return error; + } + + + static void Free_Context1( TTO_ContextPosFormat1* cpf1 ) + { + UShort n, count; + + TTO_PosRuleSet* prs; + + + if ( cpf1->PosRuleSet ) + { + count = cpf1->PosRuleSetCount; + prs = cpf1->PosRuleSet; + + for ( n = 0; n < count; n++ ) + Free_PosRuleSet( &prs[n] ); + + FREE( prs ); + } + + Free_Coverage( &cpf1->Coverage ); + } + + + /* PosClassRule */ + + static TT_Error Load_PosClassRule( TTO_ContextPosFormat2* cpf2, + TTO_PosClassRule* pcr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* c; + TTO_PosLookupRecord* plr; + Bool* d; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + pcr->GlyphCount = GET_UShort(); + pcr->PosCount = GET_UShort(); + + FORGET_Frame(); + + if ( pcr->GlyphCount > cpf2->MaxContextLength ) + cpf2->MaxContextLength = pcr->GlyphCount; + + pcr->Class = NULL; + + count = pcr->GlyphCount - 1; /* only GlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( pcr->Class, count, UShort ) ) + return error; + + c = pcr->Class; + d = cpf2->ClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + { + c[n] = GET_UShort(); + + /* We check whether the specific class is used at all. If not, + class 0 is used instead. */ + + if ( !d[c[n]] ) + c[n] = 0; + } + + FORGET_Frame(); + + pcr->PosLookupRecord = NULL; + + count = pcr->PosCount; + + if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = pcr->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + FREE( c ); + return error; + } + + + static void Free_PosClassRule( TTO_PosClassRule* pcr ) + { + FREE( pcr->PosLookupRecord ); + FREE( pcr->Class ); + } + + + /* PosClassSet */ + + static TT_Error Load_PosClassSet( TTO_ContextPosFormat2* cpf2, + TTO_PosClassSet* pcs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PosClassRule* pcr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = pcs->PosClassRuleCount = GET_UShort(); + + FORGET_Frame(); + + pcs->PosClassRule = NULL; + + if ( ALLOC_ARRAY( pcs->PosClassRule, count, TTO_PosClassRule ) ) + return error; + + pcr = pcs->PosClassRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PosClassRule( cpf2, &pcr[n], + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_PosClassRule( &pcr[n] ); + + FREE( pcr ); + return error; + } + + + static void Free_PosClassSet( TTO_PosClassSet* pcs ) + { + UShort n, count; + + TTO_PosClassRule* pcr; + + + if ( pcs->PosClassRule ) + { + count = pcs->PosClassRuleCount; + pcr = pcs->PosClassRule; + + for ( n = 0; n < count; n++ ) + Free_PosClassRule( &pcr[n] ); + + FREE( pcr ); + } + } + + + /* ContextPosFormat2 */ + + static TT_Error Load_ContextPos2( TTO_ContextPosFormat2* cpf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_PosClassSet* pcs; + + + base_offset = FILE_Pos() - 2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &cpf2->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + /* `PosClassSetCount' is the upper limit for class values, thus we + read it now to make an additional safety check. */ + + count = cpf2->PosClassSetCount = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &cpf2->ClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + cpf2->PosClassSet = NULL; + cpf2->MaxContextLength = 0; + + if ( ALLOC_ARRAY( cpf2->PosClassSet, count, TTO_PosClassSet ) ) + goto Fail2; + + pcs = cpf2->PosClassSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_PosClassSet( cpf2, &pcs[n], + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a PosClassSet table with no entries */ + + cpf2->PosClassSet[n].PosClassRuleCount = 0; + cpf2->PosClassSet[n].PosClassRule = NULL; + } + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_PosClassSet( &pcs[n] ); + + FREE( pcs ); + + Fail2: + Free_ClassDefinition( &cpf2->ClassDef ); + + Fail3: + Free_Coverage( &cpf2->Coverage ); + return error; + } + + + static void Free_Context2( TTO_ContextPosFormat2* cpf2 ) + { + UShort n, count; + + TTO_PosClassSet* pcs; + + + if ( cpf2->PosClassSet ) + { + count = cpf2->PosClassSetCount; + pcs = cpf2->PosClassSet; + + for ( n = 0; n < count; n++ ) + Free_PosClassSet( &pcs[n] ); + + FREE( pcs ); + } + + Free_ClassDefinition( &cpf2->ClassDef ); + Free_Coverage( &cpf2->Coverage ); + } + + + /* ContextPosFormat3 */ + + static TT_Error Load_ContextPos3( TTO_ContextPosFormat3* cpf3, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Coverage* c; + TTO_PosLookupRecord* plr; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 4L ) ) + return error; + + cpf3->GlyphCount = GET_UShort(); + cpf3->PosCount = GET_UShort(); + + FORGET_Frame(); + + cpf3->Coverage = NULL; + + count = cpf3->GlyphCount; + + if ( ALLOC_ARRAY( cpf3->Coverage, count, TTO_Coverage ) ) + return error; + + c = cpf3->Coverage; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &c[n], input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + + cpf3->PosLookupRecord = NULL; + + count = cpf3->PosCount; + + if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = cpf3->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + return error; + } + + + static void Free_Context3( TTO_ContextPosFormat3* cpf3 ) + { + UShort n, count; + + TTO_Coverage* c; + + + FREE( cpf3->PosLookupRecord ); + + if ( cpf3->Coverage ) + { + count = cpf3->GlyphCount; + c = cpf3->Coverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + } + + + /* ContextPos */ + + TT_Error Load_ContextPos( TTO_ContextPos* cp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cp->PosFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( cp->PosFormat ) + { + case 1: + return Load_ContextPos1( &cp->cpf.cpf1, input ); + + case 2: + return Load_ContextPos2( &cp->cpf.cpf2, input ); + + case 3: + return Load_ContextPos3( &cp->cpf.cpf3, input ); + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_ContextPos( TTO_ContextPos* cp ) + { + switch ( cp->PosFormat ) + { + case 1: + Free_Context1( &cp->cpf.cpf1 ); + break; + + case 2: + Free_Context2( &cp->cpf.cpf2 ); + break; + + case 3: + Free_Context3( &cp->cpf.cpf3 ); + break; + } + } + + + /* LookupType 8 */ + + /* ChainPosRule */ + + static TT_Error Load_ChainPosRule( TTO_ChainPosRule* cpr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* b; + UShort* i; + UShort* l; + + TTO_PosLookupRecord* plr; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cpr->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + cpr->Backtrack = NULL; + + count = cpr->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( cpr->Backtrack, count, UShort ) ) + return error; + + b = cpr->Backtrack; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail4; + + for ( n = 0; n < count; n++ ) + b[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + cpr->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + cpr->Input = NULL; + + count = cpr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( cpr->Input, count, UShort ) ) + goto Fail4; + + i = cpr->Input; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail3; + + for ( n = 0; n < count; n++ ) + i[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + cpr->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + cpr->Lookahead = NULL; + + count = cpr->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( cpr->Lookahead, count, UShort ) ) + goto Fail3; + + l = cpr->Lookahead; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + l[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + cpr->PosCount = GET_UShort(); + + FORGET_Frame(); + + cpr->PosLookupRecord = NULL; + + count = cpr->PosCount; + + if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = cpr->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + FREE( l ); + + Fail3: + FREE( i ); + + Fail4: + FREE( b ); + return error; + } + + + static void Free_ChainPosRule( TTO_ChainPosRule* cpr ) + { + FREE( cpr->PosLookupRecord ); + FREE( cpr->Lookahead ); + FREE( cpr->Input ); + FREE( cpr->Backtrack ); + } + + + /* ChainPosRuleSet */ + + static TT_Error Load_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainPosRule* cpr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cprs->ChainPosRuleCount = GET_UShort(); + + FORGET_Frame(); + + cprs->ChainPosRule = NULL; + + if ( ALLOC_ARRAY( cprs->ChainPosRule, count, TTO_ChainPosRule ) ) + return error; + + cpr = cprs->ChainPosRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainPosRule( &cpr[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_ChainPosRule( &cpr[n] ); + + FREE( cpr ); + return error; + } + + + static void Free_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs ) + { + UShort n, count; + + TTO_ChainPosRule* cpr; + + + if ( cprs->ChainPosRule ) + { + count = cprs->ChainPosRuleCount; + cpr = cprs->ChainPosRule; + + for ( n = 0; n < count; n++ ) + Free_ChainPosRule( &cpr[n] ); + + FREE( cpr ); + } + } + + + /* ChainContextPosFormat1 */ + + static TT_Error Load_ChainContextPos1( TTO_ChainContextPosFormat1* ccpf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainPosRuleSet* cprs; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ccpf1->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ccpf1->ChainPosRuleSetCount = GET_UShort(); + + FORGET_Frame(); + + ccpf1->ChainPosRuleSet = NULL; + + if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, TTO_ChainPosRuleSet ) ) + goto Fail2; + + cprs = ccpf1->ChainPosRuleSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainPosRuleSet( &cprs[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ChainPosRuleSet( &cprs[n] ); + + FREE( cprs ); + + Fail2: + Free_Coverage( &ccpf1->Coverage ); + return error; + } + + + static void Free_ChainContext1( TTO_ChainContextPosFormat1* ccpf1 ) + { + UShort n, count; + + TTO_ChainPosRuleSet* cprs; + + + if ( ccpf1->ChainPosRuleSet ) + { + count = ccpf1->ChainPosRuleSetCount; + cprs = ccpf1->ChainPosRuleSet; + + for ( n = 0; n < count; n++ ) + Free_ChainPosRuleSet( &cprs[n] ); + + FREE( cprs ); + } + + Free_Coverage( &ccpf1->Coverage ); + } + + + /* ChainPosClassRule */ + + static TT_Error Load_ChainPosClassRule( + TTO_ChainContextPosFormat2* ccpf2, + TTO_ChainPosClassRule* cpcr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* b; + UShort* i; + UShort* l; + TTO_PosLookupRecord* plr; + Bool* d; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cpcr->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength ) + ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount; + + cpcr->Backtrack = NULL; + + count = cpcr->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( cpcr->Backtrack, count, UShort ) ) + return error; + + b = cpcr->Backtrack; + d = ccpf2->BacktrackClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail4; + + for ( n = 0; n < count; n++ ) + { + b[n] = GET_UShort(); + + /* We check whether the specific class is used at all. If not, + class 0 is used instead. */ + + if ( !d[b[n]] ) + b[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + cpcr->InputGlyphCount = GET_UShort(); + + if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength ) + ccpf2->MaxInputLength = cpcr->InputGlyphCount; + + FORGET_Frame(); + + cpcr->Input = NULL; + + count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( cpcr->Input, count, UShort ) ) + goto Fail4; + + i = cpcr->Input; + d = ccpf2->InputClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail3; + + for ( n = 0; n < count; n++ ) + { + i[n] = GET_UShort(); + + if ( !d[i[n]] ) + i[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + cpcr->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength ) + ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount; + + cpcr->Lookahead = NULL; + + count = cpcr->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( cpcr->Lookahead, count, UShort ) ) + goto Fail3; + + l = cpcr->Lookahead; + d = ccpf2->LookaheadClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + { + l[n] = GET_UShort(); + + if ( !d[l[n]] ) + l[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + cpcr->PosCount = GET_UShort(); + + FORGET_Frame(); + + cpcr->PosLookupRecord = NULL; + + count = cpcr->PosCount; + + if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = cpcr->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + FREE( l ); + + Fail3: + FREE( i ); + + Fail4: + FREE( b ); + return error; + } + + + static void Free_ChainPosClassRule( TTO_ChainPosClassRule* cpcr ) + { + FREE( cpcr->PosLookupRecord ); + FREE( cpcr->Lookahead ); + FREE( cpcr->Input ); + FREE( cpcr->Backtrack ); + } + + + /* PosClassSet */ + + static TT_Error Load_ChainPosClassSet( + TTO_ChainContextPosFormat2* ccpf2, + TTO_ChainPosClassSet* cpcs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainPosClassRule* cpcr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cpcs->ChainPosClassRuleCount = GET_UShort(); + + FORGET_Frame(); + + cpcs->ChainPosClassRule = NULL; + + if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count, + TTO_ChainPosClassRule ) ) + return error; + + cpcr = cpcs->ChainPosClassRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n], + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_ChainPosClassRule( &cpcr[n] ); + + FREE( cpcr ); + return error; + } + + + static void Free_ChainPosClassSet( TTO_ChainPosClassSet* cpcs ) + { + UShort n, count; + + TTO_ChainPosClassRule* cpcr; + + + if ( cpcs->ChainPosClassRule ) + { + count = cpcs->ChainPosClassRuleCount; + cpcr = cpcs->ChainPosClassRule; + + for ( n = 0; n < count; n++ ) + Free_ChainPosClassRule( &cpcr[n] ); + + FREE( cpcr ); + } + } + + + /* ChainContextPosFormat2 */ + + static TT_Error Load_ChainContextPos2( TTO_ChainContextPosFormat2* ccpf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + ULong backtrack_offset, input_offset, lookahead_offset; + + TTO_ChainPosClassSet* cpcs; + + + base_offset = FILE_Pos() - 2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ccpf2->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 8L ) ) + goto Fail5; + + backtrack_offset = GET_UShort() + base_offset; + input_offset = GET_UShort() + base_offset; + lookahead_offset = GET_UShort() + base_offset; + + /* `ChainPosClassSetCount' is the upper limit for input class values, + thus we read it now to make an additional safety check. */ + + count = ccpf2->ChainPosClassSetCount = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( backtrack_offset ) || + ( error = Load_ClassDefinition( &ccpf2->BacktrackClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail5; + if ( FILE_Seek( input_offset ) || + ( error = Load_ClassDefinition( &ccpf2->InputClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail4; + if ( FILE_Seek( lookahead_offset ) || + ( error = Load_ClassDefinition( &ccpf2->LookaheadClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + ccpf2->ChainPosClassSet = NULL; + ccpf2->MaxBacktrackLength = 0; + ccpf2->MaxInputLength = 0; + ccpf2->MaxLookaheadLength = 0; + + if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, TTO_ChainPosClassSet ) ) + goto Fail2; + + cpcs = ccpf2->ChainPosClassSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n], + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a ChainPosClassSet table with no entries */ + + ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0; + ccpf2->ChainPosClassSet[n].ChainPosClassRule = NULL; + } + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ChainPosClassSet( &cpcs[n] ); + + FREE( cpcs ); + + Fail2: + Free_ClassDefinition( &ccpf2->LookaheadClassDef ); + + Fail3: + Free_ClassDefinition( &ccpf2->InputClassDef ); + + Fail4: + Free_ClassDefinition( &ccpf2->BacktrackClassDef ); + + Fail5: + Free_Coverage( &ccpf2->Coverage ); + return error; + } + + + static void Free_ChainContext2( TTO_ChainContextPosFormat2* ccpf2 ) + { + UShort n, count; + + TTO_ChainPosClassSet* cpcs; + + + if ( ccpf2->ChainPosClassSet ) + { + count = ccpf2->ChainPosClassSetCount; + cpcs = ccpf2->ChainPosClassSet; + + for ( n = 0; n < count; n++ ) + Free_ChainPosClassSet( &cpcs[n] ); + + FREE( cpcs ); + } + + Free_ClassDefinition( &ccpf2->LookaheadClassDef ); + Free_ClassDefinition( &ccpf2->InputClassDef ); + Free_ClassDefinition( &ccpf2->BacktrackClassDef ); + + Free_Coverage( &ccpf2->Coverage ); + } + + + /* ChainContextPosFormat3 */ + + static TT_Error Load_ChainContextPos3( TTO_ChainContextPosFormat3* ccpf3, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort backtrack_count, input_count, lookahead_count; + ULong cur_offset, new_offset, base_offset; + + TTO_Coverage* b; + TTO_Coverage* i; + TTO_Coverage* l; + TTO_PosLookupRecord* plr; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + ccpf3->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccpf3->BacktrackCoverage = NULL; + + backtrack_count = ccpf3->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count, + TTO_Coverage ) ) + return error; + + b = ccpf3->BacktrackCoverage; + + for ( n = 0; n < backtrack_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &b[n], input ) ) != TT_Err_Ok ) + goto Fail4; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + ccpf3->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccpf3->InputCoverage = NULL; + + input_count = ccpf3->InputGlyphCount; + + if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, TTO_Coverage ) ) + goto Fail4; + + i = ccpf3->InputCoverage; + + for ( n = 0; n < input_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &i[n], input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + ccpf3->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccpf3->LookaheadCoverage = NULL; + + lookahead_count = ccpf3->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count, + TTO_Coverage ) ) + goto Fail3; + + l = ccpf3->LookaheadCoverage; + + for ( n = 0; n < lookahead_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &l[n], input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + ccpf3->PosCount = GET_UShort(); + + FORGET_Frame(); + + ccpf3->PosLookupRecord = NULL; + + count = ccpf3->PosCount; + + if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, TTO_PosLookupRecord ) ) + goto Fail2; + + plr = ccpf3->PosLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + plr[n].SequenceIndex = GET_UShort(); + plr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( plr ); + + Fail2: + for ( n = 0; n < lookahead_count; n++ ) + Free_Coverage( &l[n] ); + + FREE( l ); + + Fail3: + for ( n = 0; n < input_count; n++ ) + Free_Coverage( &i[n] ); + + FREE( i ); + + Fail4: + for ( n = 0; n < backtrack_count; n++ ) + Free_Coverage( &b[n] ); + + FREE( b ); + return error; + } + + + static void Free_ChainContext3( TTO_ChainContextPosFormat3* ccpf3 ) + { + UShort n, count; + + TTO_Coverage* c; + + + FREE( ccpf3->PosLookupRecord ); + + if ( ccpf3->LookaheadCoverage ) + { + count = ccpf3->LookaheadGlyphCount; + c = ccpf3->LookaheadCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + + if ( ccpf3->InputCoverage ) + { + count = ccpf3->InputGlyphCount; + c = ccpf3->InputCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + + if ( ccpf3->BacktrackCoverage ) + { + count = ccpf3->BacktrackGlyphCount; + c = ccpf3->BacktrackCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + } + + + /* ChainContextPos */ + + TT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + ccp->PosFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( ccp->PosFormat ) + { + case 1: + return Load_ChainContextPos1( &ccp->ccpf.ccpf1, input ); + + case 2: + return Load_ChainContextPos2( &ccp->ccpf.ccpf2, input ); + + case 3: + return Load_ChainContextPos3( &ccp->ccpf.ccpf3, input ); + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_ChainContextPos( TTO_ChainContextPos* ccp ) + { + switch ( ccp->PosFormat ) + { + case 1: + Free_ChainContext1( &ccp->ccpf.ccpf1 ); + break; + + case 2: + Free_ChainContext2( &ccp->ccpf.ccpf2 ); + break; + + case 3: + Free_ChainContext3( &ccp->ccpf.ccpf3 ); + break; + } + } + + + + /*********** + * GPOS API + ***********/ + + + EXPORT_FUNC + TT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos, + TT_ULong script_tag, + TT_UShort* script_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + + + if ( !gpos || !script_index ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + for ( n = 0; n < sl->ScriptCount; n++ ) + if ( script_tag == sr[n].ScriptTag ) + { + *script_index = n; + + return TT_Err_Ok; + } + + return TTO_Err_Not_Covered; + } + + + EXPORT_FUNC + TT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + + + if ( !gpos || !language_index || !req_feature_index ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + for ( n = 0; n < s->LangSysCount; n++ ) + if ( language_tag == lsr[n].LangSysTag ) + { + *language_index = n; + *req_feature_index = lsr[n].LangSys.ReqFeatureIndex; + + return TT_Err_Ok; + } + + return TTO_Err_Not_Covered; + } + + + /* selecting 0xFFFF for language_index asks for the values of the + default language (DefaultLangSys) */ + + EXPORT_FUNC + TT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + TTO_LangSys* ls; + UShort* fi; + + TTO_FeatureList* fl; + TTO_FeatureRecord* fr; + + + if ( !gpos || !feature_index ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + fl = &gpos->FeatureList; + fr = fl->FeatureRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( language_index == 0xFFFF ) + ls = &s->DefaultLangSys; + else + { + if ( language_index >= s->LangSysCount ) + return TT_Err_Invalid_Argument; + + ls = &lsr[language_index].LangSys; + } + + fi = ls->FeatureIndex; + + for ( n = 0; n < ls->FeatureCount; n++ ) + { + if ( fi[n] >= fl->FeatureCount ) + return TTO_Err_Invalid_GPOS_SubTable_Format; + + if ( feature_tag == fr[fi[n]].FeatureTag ) + { + *feature_index = fi[n]; + + return TT_Err_Ok; + } + } + + return TTO_Err_Not_Covered; + } + + + /* The next three functions return a null-terminated list */ + + EXPORT_FUNC + TT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos, + TT_ULong** script_tag_list ) + { + UShort n; + TT_Error error; + ULong* stl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + + + if ( !gpos || !script_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, ULong ) ) + return error; + + for ( n = 0; n < sl->ScriptCount; n++ ) + stl[n] = sr[n].ScriptTag; + stl[n] = 0; + + *script_tag_list = stl; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos, + TT_UShort script_index, + TT_ULong** language_tag_list ) + { + UShort n; + TT_Error error; + ULong* ltl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + + + if ( !gpos || !language_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, ULong ) ) + return error; + + for ( n = 0; n < s->LangSysCount; n++ ) + ltl[n] = lsr[n].LangSysTag; + ltl[n] = 0; + + *language_tag_list = ltl; + + return TT_Err_Ok; + } + + + /* selecting 0xFFFF for language_index asks for the values of the + default language (DefaultLangSys) */ + + EXPORT_FUNC + TT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ) + { + UShort n; + TT_Error error; + ULong* ftl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + TTO_LangSys* ls; + UShort* fi; + + TTO_FeatureList* fl; + TTO_FeatureRecord* fr; + + + if ( !gpos || !feature_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gpos->ScriptList; + sr = sl->ScriptRecord; + + fl = &gpos->FeatureList; + fr = fl->FeatureRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( language_index == 0xFFFF ) + ls = &s->DefaultLangSys; + else + { + if ( language_index >= s->LangSysCount ) + return TT_Err_Invalid_Argument; + + ls = &lsr[language_index].LangSys; + } + + fi = ls->FeatureIndex; + + if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, ULong ) ) + return error; + + for ( n = 0; n < ls->FeatureCount; n++ ) + { + if ( fi[n] >= fl->FeatureCount ) + { + FREE( ftl ); + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + ftl[n] = fr[fi[n]].FeatureTag; + } + ftl[n] = 0; + + *feature_tag_list = ftl; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos, + TT_UShort feature_index, + TT_UShort property ) + { + UShort i; + + TTO_Feature feature; + UShort* properties; + UShort* index; + + + if ( !gpos || + feature_index >= gpos->FeatureList.FeatureCount ) + return TT_Err_Invalid_Argument; + + properties = gpos->LookupList.Properties; + + feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; + index = feature.LookupListIndex; + + for ( i = 0; i < feature.LookupListCount; i++ ) + properties[index[i]] |= property; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos ) + { + UShort i; + + UShort* properties; + + + if ( !gpos ) + return TT_Err_Invalid_Argument; + + properties = gpos->LookupList.Properties; + + for ( i = 0; i < gpos->LookupList.LookupCount; i++ ) + properties[i] = 0; + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/extend/ftxgpos.h b/lib/extend/ftxgpos.h new file mode 100644 index 0000000..d289c88 --- /dev/null +++ b/lib/extend/ftxgpos.h @@ -0,0 +1,767 @@ +/******************************************************************* + * + * ftxgpos.h + * + * TrueType Open GPOS table support + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FTXOPEN_H +#error "Don't include this file! Use ftxopen.h instead." +#endif + +#ifndef FTXGPOS_H +#define FTXGPOS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define TTO_Err_Invalid_GPOS_SubTable_Format 0x1020 +#define TTO_Err_Invalid_GPOS_SubTable 0x1021 + + +/* Lookup types for glyph positioning */ + +#define GPOS_LOOKUP_SINGLE 1 +#define GPOS_LOOKUP_PAIR 2 +#define GPOS_LOOKUP_CURSIVE 3 +#define GPOS_LOOKUP_MARKBASE 4 +#define GPOS_LOOKUP_MARKLIG 5 +#define GPOS_LOOKUP_MARKMARK 6 +#define GPOS_LOOKUP_CONTEXT 7 +#define GPOS_LOOKUP_CHAIN 8 + + + struct TTO_GPOSHeader_ + { + TT_Bool loaded; + TT_ULong offset; + + TT_Fixed Version; + + TTO_ScriptList ScriptList; + TTO_FeatureList FeatureList; + TTO_LookupList LookupList; + + TTO_GDEFHeader* gdef; + }; + + typedef struct TTO_GPOSHeader_ TTO_GPOSHeader; + + + /* shared tables */ + + struct TTO_ValueRecord_ + { + TT_Short XPlacement; /* horizontal adjustment for + placement */ + TT_Short YPlacement; /* vertical adjustment for + placement */ + TT_Short XAdvance; /* horizontal adjustment for + advance */ + TT_Short YAdvance; /* vertical adjustment for + advance */ + TTO_Device XPlacementDevice; /* device table for horizontal + placement */ + TTO_Device YPlacementDevice; /* device table for vertical + placement */ + TTO_Device XAdvanceDevice; /* device table for horizontal + advance */ + TTO_Device YAdvanceDevice; /* device table for vertical + advance */ + TT_UShort XIdPlacement; /* horizontal placement metric ID */ + TT_UShort YIdPlacement; /* vertical placement metric ID */ + TT_UShort XIdAdvance; /* horizontal advance metric ID */ + TT_UShort YIdAdvance; /* vertical advance metric ID */ + }; + + typedef struct TTO_ValueRecord_ TTO_ValueRecord; + + +/* Mask values to scan the value format of the ValueRecord structure. + We always expand compressed ValueRecords of the font. */ + +#define HAVE_X_PLACEMENT 0x0001 +#define HAVE_Y_PLACEMENT 0x0002 +#define HAVE_X_ADVANCE 0x0004 +#define HAVE_Y_ADVANCE 0x0008 +#define HAVE_X_PLACEMENT_DEVICE 0x0010 +#define HAVE_Y_PLACEMENT_DEVICE 0x0020 +#define HAVE_X_ADVANCE_DEVICE 0x0040 +#define HAVE_Y_ADVANCE_DEVICE 0x0080 +#define HAVE_X_ID_PLACEMENT 0x0100 +#define HAVE_Y_ID_PLACEMENT 0x0200 +#define HAVE_X_ID_ADVANCE 0x0400 +#define HAVE_Y_ID_ADVANCE 0x0800 + + + struct TTO_AnchorFormat1_ + { + TT_Short XCoordinate; /* horizontal value */ + TT_Short YCoordinate; /* vertical value */ + }; + + typedef struct TTO_AnchorFormat1_ TTO_AnchorFormat1; + + + struct TTO_AnchorFormat2_ + { + TT_Short XCoordinate; /* horizontal value */ + TT_Short YCoordinate; /* vertical value */ + TT_UShort AnchorPoint; /* index to glyph contour point */ + }; + + typedef struct TTO_AnchorFormat2_ TTO_AnchorFormat2; + + + struct TTO_AnchorFormat3_ + { + TT_Short XCoordinate; /* horizontal value */ + TT_Short YCoordinate; /* vertical value */ + TTO_Device XDeviceTable; /* device table for X coordinate */ + TTO_Device YDeviceTable; /* device table for Y coordinate */ + }; + + typedef struct TTO_AnchorFormat3_ TTO_AnchorFormat3; + + + struct TTO_AnchorFormat4_ + { + TT_UShort XIdAnchor; /* horizontal metric ID */ + TT_UShort YIdAnchor; /* vertical metric ID */ + }; + + typedef struct TTO_AnchorFormat4_ TTO_AnchorFormat4; + + + struct TTO_Anchor_ + { + TT_UShort PosFormat; /* 1, 2, 3, or 4 -- 0 indicates + that there is no Anchor table */ + + union + { + TTO_AnchorFormat1 af1; + TTO_AnchorFormat2 af2; + TTO_AnchorFormat3 af3; + TTO_AnchorFormat4 af4; + } af; + }; + + typedef struct TTO_Anchor_ TTO_Anchor; + + + struct TTO_MarkRecord_ + { + TT_UShort Class; /* mark class */ + TTO_Anchor MarkAnchor; /* anchor table */ + }; + + typedef struct TTO_MarkRecord_ TTO_MarkRecord; + + + struct TTO_MarkArray_ + { + TT_UShort MarkCount; /* number of MarkRecord tables */ + TTO_MarkRecord* MarkRecord; /* array of MarkRecord tables */ + }; + + typedef struct TTO_MarkArray_ TTO_MarkArray; + + + /* LookupType 1 */ + + struct TTO_SinglePosFormat1_ + { + TTO_ValueRecord Value; /* ValueRecord for all covered + glyphs */ + }; + + typedef struct TTO_SinglePosFormat1_ TTO_SinglePosFormat1; + + + struct TTO_SinglePosFormat2_ + { + TT_UShort ValueCount; /* number of ValueRecord tables */ + TTO_ValueRecord* Value; /* array of ValueRecord tables */ + }; + + typedef struct TTO_SinglePosFormat2_ TTO_SinglePosFormat2; + + + struct TTO_SinglePos_ + { + TT_UShort PosFormat; /* 1 or 2 */ + TTO_Coverage Coverage; /* Coverage table */ + + TT_UShort ValueFormat; /* format of ValueRecord table */ + + union + { + TTO_SinglePosFormat1 spf1; + TTO_SinglePosFormat2 spf2; + } spf; + }; + + typedef struct TTO_SinglePos_ TTO_SinglePos; + + + /* LookupType 2 */ + + struct TTO_PairValueRecord_ + { + TT_UShort SecondGlyph; /* glyph ID for second glyph */ + TTO_ValueRecord Value1; /* pos. data for first glyph */ + TTO_ValueRecord Value2; /* pos. data for second glyph */ + }; + + typedef struct TTO_PairValueRecord_ TTO_PairValueRecord; + + + struct TTO_PairSet_ + { + TT_UShort PairValueCount; + /* number of PairValueRecord tables */ + TTO_PairValueRecord* PairValueRecord; + /* array of PairValueRecord tables */ + }; + + typedef struct TTO_PairSet_ TTO_PairSet; + + + struct TTO_PairPosFormat1_ + { + TT_UShort PairSetCount; /* number of PairSet tables */ + TTO_PairSet* PairSet; /* array of PairSet tables */ + }; + + typedef struct TTO_PairPosFormat1_ TTO_PairPosFormat1; + + + struct TTO_Class2Record_ + { + TTO_ValueRecord Value1; /* pos. data for first glyph */ + TTO_ValueRecord Value2; /* pos. data for second glyph */ + }; + + typedef struct TTO_Class2Record_ TTO_Class2Record; + + + struct TTO_Class1Record_ + { + TTO_Class2Record* Class2Record; /* array of Class2Record tables */ + }; + + typedef struct TTO_Class1Record_ TTO_Class1Record; + + + struct TTO_PairPosFormat2_ + { + TTO_ClassDefinition ClassDef1; /* class def. for first glyph */ + TTO_ClassDefinition ClassDef2; /* class def. for second glyph */ + TT_UShort Class1Count; /* number of classes in ClassDef1 + table */ + TT_UShort Class2Count; /* number of classes in ClassDef2 + table */ + TTO_Class1Record* Class1Record; /* array of Class1Record tables */ + }; + + typedef struct TTO_PairPosFormat2_ TTO_PairPosFormat2; + + + struct TTO_PairPos_ + { + TT_UShort PosFormat; /* 1 or 2 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort ValueFormat1; /* format of ValueRecord table + for first glyph */ + TT_UShort ValueFormat2; /* format of ValueRecord table + for second glyph */ + + union + { + TTO_PairPosFormat1 ppf1; + TTO_PairPosFormat2 ppf2; + } ppf; + }; + + typedef struct TTO_PairPos_ TTO_PairPos; + + + /* LookupType 3 */ + + struct TTO_EntryExitRecord_ + { + TTO_Anchor EntryAnchor; /* entry Anchor table */ + TTO_Anchor ExitAnchor; /* exit Anchor table */ + }; + + + typedef struct TTO_EntryExitRecord_ TTO_EntryExitRecord; + + struct TTO_CursivePos_ + { + TT_UShort PosFormat; /* always 1 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort EntryExitCount; + /* number of EntryExitRecord tables */ + TTO_EntryExitRecord* EntryExitRecord; + /* array of EntryExitRecord tables */ + }; + + typedef struct TTO_CursivePos_ TTO_CursivePos; + + + /* LookupType 4 */ + + struct TTO_BaseRecord_ + { + TTO_Anchor* BaseAnchor; /* array of base glyph anchor + tables */ + }; + + typedef struct TTO_BaseRecord_ TTO_BaseRecord; + + + struct TTO_BaseArray_ + { + TT_UShort BaseCount; /* number of BaseRecord tables */ + TTO_BaseRecord* BaseRecord; /* array of BaseRecord tables */ + }; + + typedef struct TTO_BaseArray_ TTO_BaseArray; + + + struct TTO_MarkBasePos_ + { + TT_UShort PosFormat; /* always 1 */ + TTO_Coverage MarkCoverage; /* mark glyph coverage table */ + TTO_Coverage BaseCoverage; /* base glyph coverage table */ + TT_UShort ClassCount; /* number of mark classes */ + TTO_MarkArray MarkArray; /* mark array table */ + TTO_BaseArray BaseArray; /* base array table */ + }; + + typedef struct TTO_MarkBasePos_ TTO_MarkBasePos; + + + /* LookupType 5 */ + + struct TTO_ComponentRecord_ + { + TTO_Anchor* LigatureAnchor; /* array of ligature glyph anchor + tables */ + }; + + typedef struct TTO_ComponentRecord_ TTO_ComponentRecord; + + + struct TTO_LigatureAttach_ + { + TT_UShort ComponentCount; + /* number of ComponentRecord tables */ + TTO_ComponentRecord* ComponentRecord; + /* array of ComponentRecord tables */ + }; + + typedef struct TTO_LigatureAttach_ TTO_LigatureAttach; + + + struct TTO_LigatureArray_ + { + TT_UShort LigatureCount; /* number of LigatureAttach tables */ + TTO_LigatureAttach* LigatureAttach; + /* array of LigatureAttach tables */ + }; + + typedef struct TTO_LigatureArray_ TTO_LigatureArray; + + + struct TTO_MarkLigPos_ + { + TT_UShort PosFormat; /* always 1 */ + TTO_Coverage MarkCoverage; /* mark glyph coverage table */ + TTO_Coverage LigatureCoverage; + /* ligature glyph coverage table */ + TT_UShort ClassCount; /* number of mark classes */ + TTO_MarkArray MarkArray; /* mark array table */ + TTO_LigatureArray LigatureArray; /* ligature array table */ + }; + + typedef struct TTO_MarkLigPos_ TTO_MarkLigPos; + + + /* LookupType 6 */ + + struct TTO_Mark2Record_ + { + TTO_Anchor* Mark2Anchor; /* array of mark glyph anchor + tables */ + }; + + typedef struct TTO_Mark2Record_ TTO_Mark2Record; + + + struct TTO_Mark2Array_ + { + TT_UShort Mark2Count; /* number of Mark2Record tables */ + TTO_Mark2Record* Mark2Record; /* array of Mark2Record tables */ + }; + + typedef struct TTO_Mark2Array_ TTO_Mark2Array; + + + struct TTO_MarkMarkPos_ + { + TT_UShort PosFormat; /* always 1 */ + TTO_Coverage Mark1Coverage; /* first mark glyph coverage table */ + TTO_Coverage Mark2Coverage; /* second mark glyph coverave table */ + TT_UShort ClassCount; /* number of combining mark classes */ + TTO_MarkArray Mark1Array; /* MarkArray table for first mark */ + TTO_Mark2Array Mark2Array; /* MarkArray table for second mark */ + }; + + typedef struct TTO_MarkMarkPos_ TTO_MarkMarkPos; + + + /* needed by both lookup type 7 and 8 */ + + struct TTO_PosLookupRecord_ + { + TT_UShort SequenceIndex; /* index into current + glyph sequence */ + TT_UShort LookupListIndex; /* Lookup to apply to that pos. */ + }; + + typedef struct TTO_PosLookupRecord_ TTO_PosLookupRecord; + + + /* LookupType 7 */ + + struct TTO_PosRule_ + { + TT_UShort GlyphCount; /* total number of input glyphs */ + TT_UShort PosCount; /* number of PosLookupRecord tables */ + TT_UShort* Input; /* array of input glyph IDs */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of PosLookupRecord tables */ + }; + + typedef struct TTO_PosRule_ TTO_PosRule; + + + struct TTO_PosRuleSet_ + { + TT_UShort PosRuleCount; /* number of PosRule tables */ + TTO_PosRule* PosRule; /* array of PosRule tables */ + }; + + typedef struct TTO_PosRuleSet_ TTO_PosRuleSet; + + + struct TTO_ContextPosFormat1_ + { + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort PosRuleSetCount; /* number of PosRuleSet tables */ + TTO_PosRuleSet* PosRuleSet; /* array of PosRuleSet tables */ + }; + + typedef struct TTO_ContextPosFormat1_ TTO_ContextPosFormat1; + + + struct TTO_PosClassRule_ + { + TT_UShort GlyphCount; /* total number of context classes */ + TT_UShort PosCount; /* number of PosLookupRecord tables */ + TT_UShort* Class; /* array of classes */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of PosLookupRecord tables */ + }; + + typedef struct TTO_PosClassRule_ TTO_PosClassRule; + + + struct TTO_PosClassSet_ + { + TT_UShort PosClassRuleCount; + /* number of PosClassRule tables */ + TTO_PosClassRule* PosClassRule; /* array of PosClassRule tables */ + }; + + typedef struct TTO_PosClassSet_ TTO_PosClassSet; + + + /* The `MaxContextLength' field is not defined in the TTO specification + but simplifies the implementation of this format. It holds the + maximal context length used in the context rules. */ + + struct TTO_ContextPosFormat2_ + { + TT_UShort MaxContextLength; + /* maximal context length */ + TTO_Coverage Coverage; /* Coverage table */ + TTO_ClassDefinition ClassDef; /* ClassDef table */ + TT_UShort PosClassSetCount; + /* number of PosClassSet tables */ + TTO_PosClassSet* PosClassSet; /* array of PosClassSet tables */ + }; + + typedef struct TTO_ContextPosFormat2_ TTO_ContextPosFormat2; + + + struct TTO_ContextPosFormat3_ + { + TT_UShort GlyphCount; /* number of input glyphs */ + TT_UShort PosCount; /* number of PosLookupRecord tables */ + TTO_Coverage* Coverage; /* array of Coverage tables */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of PosLookupRecord tables */ + }; + + typedef struct TTO_ContextPosFormat3_ TTO_ContextPosFormat3; + + + struct TTO_ContextPos_ + { + TT_UShort PosFormat; /* 1, 2, or 3 */ + + union + { + TTO_ContextPosFormat1 cpf1; + TTO_ContextPosFormat2 cpf2; + TTO_ContextPosFormat3 cpf3; + } cpf; + }; + + typedef struct TTO_ContextPos_ TTO_ContextPos; + + + /* LookupType 8 */ + + struct TTO_ChainPosRule_ + { + TT_UShort BacktrackGlyphCount; + /* total number of backtrack glyphs */ + TT_UShort* Backtrack; /* array of backtrack glyph IDs */ + TT_UShort InputGlyphCount; + /* total number of input glyphs */ + TT_UShort* Input; /* array of input glyph IDs */ + TT_UShort LookaheadGlyphCount; + /* total number of lookahead glyphs */ + TT_UShort* Lookahead; /* array of lookahead glyph IDs */ + TT_UShort PosCount; /* number of PosLookupRecords */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of PosLookupRecords */ + }; + + typedef struct TTO_ChainPosRule_ TTO_ChainPosRule; + + + struct TTO_ChainPosRuleSet_ + { + TT_UShort ChainPosRuleCount; + /* number of ChainPosRule tables */ + TTO_ChainPosRule* ChainPosRule; /* array of ChainPosRule tables */ + }; + + typedef struct TTO_ChainPosRuleSet_ TTO_ChainPosRuleSet; + + + struct TTO_ChainContextPosFormat1_ + { + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort ChainPosRuleSetCount; + /* number of ChainPosRuleSet tables */ + TTO_ChainPosRuleSet* ChainPosRuleSet; + /* array of ChainPosRuleSet tables */ + }; + + typedef struct TTO_ChainContextPosFormat1_ TTO_ChainContextPosFormat1; + + + struct TTO_ChainPosClassRule_ + { + TT_UShort BacktrackGlyphCount; + /* total number of backtrack + classes */ + TT_UShort* Backtrack; /* array of backtrack classes */ + TT_UShort InputGlyphCount; + /* total number of context classes */ + TT_UShort* Input; /* array of context classes */ + TT_UShort LookaheadGlyphCount; + /* total number of lookahead + classes */ + TT_UShort* Lookahead; /* array of lookahead classes */ + TT_UShort PosCount; /* number of PosLookupRecords */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ChainPosClassRule_ TTO_ChainPosClassRule; + + + struct TTO_ChainPosClassSet_ + { + TT_UShort ChainPosClassRuleCount; + /* number of ChainPosClassRule + tables */ + TTO_ChainPosClassRule* ChainPosClassRule; + /* array of ChainPosClassRule + tables */ + }; + + typedef struct TTO_ChainPosClassSet_ TTO_ChainPosClassSet; + + + /* The `MaxXXXLength' fields are not defined in the TTO specification + but simplifies the implementation of this format. It holds the + maximal context length used in the specific context rules. */ + + struct TTO_ChainContextPosFormat2_ + { + TTO_Coverage Coverage; /* Coverage table */ + + TT_UShort MaxBacktrackLength; + /* maximal backtrack length */ + TTO_ClassDefinition BacktrackClassDef; + /* BacktrackClassDef table */ + TT_UShort MaxInputLength; + /* maximal input length */ + TTO_ClassDefinition InputClassDef; + /* InputClassDef table */ + TT_UShort MaxLookaheadLength; + /* maximal lookahead length */ + TTO_ClassDefinition LookaheadClassDef; + /* LookaheadClassDef table */ + + TT_UShort ChainPosClassSetCount; + /* number of ChainPosClassSet + tables */ + TTO_ChainPosClassSet* ChainPosClassSet; + /* array of ChainPosClassSet + tables */ + }; + + typedef struct TTO_ChainContextPosFormat2_ TTO_ChainContextPosFormat2; + + + struct TTO_ChainContextPosFormat3_ + { + TT_UShort BacktrackGlyphCount; + /* number of backtrack glyphs */ + TTO_Coverage* BacktrackCoverage; + /* array of backtrack Coverage + tables */ + TT_UShort InputGlyphCount; + /* number of input glyphs */ + TTO_Coverage* InputCoverage; + /* array of input coverage + tables */ + TT_UShort LookaheadGlyphCount; + /* number of lookahead glyphs */ + TTO_Coverage* LookaheadCoverage; + /* array of lookahead coverage + tables */ + TT_UShort PosCount; /* number of PosLookupRecords */ + TTO_PosLookupRecord* PosLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ChainContextPosFormat3_ TTO_ChainContextPosFormat3; + + + struct TTO_ChainContextPos_ + { + TT_UShort PosFormat; /* 1, 2, or 3 */ + + union + { + TTO_ChainContextPosFormat1 ccpf1; + TTO_ChainContextPosFormat2 ccpf2; + TTO_ChainContextPosFormat3 ccpf3; + } ccpf; + }; + + typedef struct TTO_ChainContextPos_ TTO_ChainContextPos; + + + union TTO_GPOS_SubTable_ + { + TTO_SinglePos single; + TTO_PairPos pair; + TTO_CursivePos cursive; + TTO_MarkBasePos markbase; + TTO_MarkLigPos marklig; + TTO_MarkMarkPos markmark; + TTO_ContextPos context; + TTO_ChainContextPos chain; + }; + + typedef union TTO_GPOS_SubTable_ TTO_GPOS_SubTable; + + + /* finally, the GPOS API */ + + EXPORT_DEF + TT_Error TT_Init_GPOS_Extension( TT_Engine engine ); + + EXPORT_DEF + TT_Error TT_Load_GPOS_Table( TT_Face face, + TTO_GPOSHeader* gpos, + TTO_GDEFHeader* gdef ); + + EXPORT_DEF + TT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos, + TT_ULong script_tag, + TT_UShort* script_index ); + EXPORT_DEF + TT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ); + EXPORT_DEF + TT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ); + + EXPORT_DEF + TT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos, + TT_ULong** script_tag_list ); + EXPORT_DEF + TT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos, + TT_UShort script_index, + TT_ULong** language_tag_list ); + EXPORT_DEF + TT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ); + + EXPORT_DEF + TT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos, + TT_UShort feature_index, + TT_UShort property ); + EXPORT_DEF + TT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXGPOS_H */ + + +/* END */ diff --git a/lib/extend/ftxgsub.c b/lib/extend/ftxgsub.c new file mode 100644 index 0000000..81930c8 --- /dev/null +++ b/lib/extend/ftxgsub.c @@ -0,0 +1,4307 @@ +/******************************************************************* + * + * ftxgsub.c + * + * TrueType Open GSUB table support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +/* XXX There is *a lot* of duplicated code (cf. formats 5 and 6), but + I don't care currently. I believe that it would be possible to + save about 50% of TTO code by carefully designing the structures, + sharing as much as possible with extensive use of macros. This + is something for a volunteer :-) */ + +#include "tttypes.h" +#include "tttags.h" +#include "ttload.h" +#include "ttextend.h" +#include "ttmemory.h" +#include "ttfile.h" + +#include "ftxopen.h" +#include "ftxopenf.h" + + +#define GSUB_ID Build_Extension_ID( 'G', 'S', 'U', 'B' ) + + +#define ADD_String( in, num_in, out, num_out, data ) \ + ( ( error = TT_GSUB_Add_String( (in), (num_in), \ + (out), (num_out), \ + (data) ) ) != TT_Err_Ok ) + +#define CHECK_Property( gdef, index, flags, property ) \ + ( ( error = Check_Property( (gdef), (index), (flags), \ + (property) ) ) != TT_Err_Ok ) + + + static TT_Error Do_Glyph_Lookup( TTO_GSUBHeader* gsub, + UShort lookup_index, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort context_length, + int nesting_level ); + + + + /********************** + * Auxiliary functions + **********************/ + + + /* The following function copies `num_out' elements from `data' to + `out', advancing the array pointer in the `in' structure by `num_in' + elements and in `out' by `num_out' elements. If the string (resp. + the properties) array in `out' is empty or too small, it allocates + resp. reallocates the string (and properties) array. Finally, it + sets the `length' field of `out' equal to `pos' of the `out' + structure. + + The properties (if defined) for all replaced glyphs are taken from + the glyph at position `in->pos'. */ + + EXPORT_FUNC + TT_Error TT_GSUB_Add_String( TTO_GSUB_String* in, + UShort num_in, + TTO_GSUB_String* out, + UShort num_out, + UShort* data ) + { + TT_Error error; + UShort i; + UShort p_in; + UShort* p_out; + + + /* sanity check */ + + if ( !in || !out || + in->length == 0 || in->pos >= in->length || + in->length < in->pos + num_in ) + return TT_Err_Invalid_Argument; + + if ( out->pos + num_out >= out->allocated ) + { + ULong size = out->pos + num_out + 256L; + + + /* The following works because all fields in `out' must be + initialized to zero (including the `string' field) for the + first use. */ + + if ( REALLOC( out->string, size * sizeof ( UShort ) ) ) + return error; + if ( in->properties ) + if ( REALLOC( out->properties, size * sizeof ( UShort ) ) ) + return error; + out->allocated = size; + } + + if ( num_out ) + { + MEM_Copy( &out->string[out->pos], data, num_out * sizeof ( UShort ) ); + if ( in->properties ) + { + p_in = in->properties[in->pos]; + p_out = out->properties; + + for ( i = out->pos; i < out->pos + num_out; i++ ) + p_out[i] = p_in; + } + } + + in->pos += num_in; + out->pos += num_out; + + out->length = out->pos; + + return TT_Err_Ok; + } + + + static TT_Error Check_Property( TTO_GDEFHeader* gdef, + UShort index, + UShort flags, + UShort* property ) + { + TT_Error error; + + + if ( gdef ) + { + error = TT_GDEF_Get_Glyph_Property( gdef, index, property ); + if ( error ) + return error; + + /* This is OpenType 1.2 */ + + if ( flags & IGNORE_SPECIAL_MARKS ) + if ( (flags & 0xFF00) != *property ) + return TTO_Err_Not_Covered; + + if ( flags & *property ) + return TTO_Err_Not_Covered; + } + + return TT_Err_Ok; + } + + + + /********************** + * Extension Functions + **********************/ + + + static TT_Error GSUB_Create( void* ext, + PFace face ) + { + DEFINE_LOAD_LOCALS( face->stream ); + + TTO_GSUBHeader* gsub = (TTO_GSUBHeader*)ext; + Long table; + + + /* by convention */ + + if ( !gsub ) + return TT_Err_Ok; + + /* a null offset indicates that there is no GSUB table */ + + gsub->offset = 0; + + /* we store the start offset and the size of the subtable */ + + table = TT_LookUp_Table( face, TTAG_GSUB ); + if ( table < 0 ) + return TT_Err_Ok; /* The table is optional */ + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + gsub->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */ + gsub->Version = GET_ULong(); + + FORGET_Frame(); + + gsub->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error GSUB_Destroy( void* ext, + PFace face ) + { + TTO_GSUBHeader* gsub = (TTO_GSUBHeader*)ext; + + + /* by convention */ + + if ( !gsub ) + return TT_Err_Ok; + + if ( gsub->loaded ) + { + Free_LookupList( &gsub->LookupList, GSUB ); + Free_FeatureList( &gsub->FeatureList ); + Free_ScriptList( &gsub->ScriptList ); + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_GSUB_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + return TT_Register_Extension( _engine, + GSUB_ID, + sizeof ( TTO_GSUBHeader ), + GSUB_Create, + GSUB_Destroy ); + } + + + EXPORT_FUNC + TT_Error TT_Load_GSUB_Table( TT_Face face, + TTO_GSUBHeader* retptr, + TTO_GDEFHeader* gdef ) + { + ULong cur_offset, new_offset, base_offset; + + TT_UShort i, num_lookups; + TT_Error error; + TT_Stream stream; + TTO_GSUBHeader* gsub; + TTO_Lookup* lo; + + PFace faze = HANDLE_Face( face ); + + + if ( !retptr ) + return TT_Err_Invalid_Argument; + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, GSUB_ID, (void**)&gsub ); + if ( error ) + return error; + + if ( gsub->offset == 0 ) + return TT_Err_Table_Missing; /* no GSUB table; nothing to do */ + + /* now access stream */ + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + base_offset = gsub->offset; + + /* skip version */ + + if ( FILE_Seek( base_offset + 4L ) || + ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ScriptList( &gsub->ScriptList, + faze ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_FeatureList( &gsub->FeatureList, + faze ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LookupList( &gsub->LookupList, + faze, GSUB ) ) != TT_Err_Ok ) + goto Fail2; + + gsub->gdef = gdef; /* can be NULL */ + + /* We now check the LookupFlags for values larger than 0xFF to find + out whether we need to load the `MarkAttachClassDef' field of the + GDEF table -- this hack is necessary for OpenType 1.2 tables since + the version field of the GDEF table hasn't been incremented. + + For constructed GDEF tables, we only load it if + `MarkAttachClassDef_offset' is not zero (nevertheless, a build of + a constructed mark attach table is not supported currently). */ + + if ( gdef && + gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded ) + { + lo = gsub->LookupList.Lookup; + num_lookups = gsub->LookupList.LookupCount; + + for ( i = 0; i < num_lookups; i++ ) + { + if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS ) + { + if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) || + ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort(); + + FORGET_Frame(); + + if ( !new_offset ) + return TTO_Err_Invalid_GDEF_SubTable; + + new_offset += base_offset; + + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef, + 256, faze ) ) != TT_Err_Ok ) + goto Fail1; + + break; + } + } + } + + gsub->loaded = TRUE; + *retptr = *gsub; + DONE_Stream( stream ); + + return TT_Err_Ok; + + Fail1: + Free_LookupList( &gsub->LookupList, GSUB ); + + Fail2: + Free_FeatureList( &gsub->FeatureList ); + + Fail3: + Free_ScriptList( &gsub->ScriptList ); + + /* release stream */ + + DONE_Stream( stream ); + + return error; + } + + + + /***************************** + * SubTable related functions + *****************************/ + + + /* LookupType 1 */ + + /* SingleSubstFormat1 */ + /* SingleSubstFormat2 */ + + TT_Error Load_SingleSubst( TTO_SingleSubst* ss, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + UShort* s; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + ss->SubstFormat = GET_UShort(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ss->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + switch ( ss->SubstFormat ) + { + case 1: + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + ss->ssf.ssf1.DeltaGlyphID = GET_UShort(); + + FORGET_Frame(); + + break; + + case 2: + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ss->ssf.ssf2.GlyphCount = GET_UShort(); + + FORGET_Frame(); + + ss->ssf.ssf2.Substitute = NULL; + + if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, UShort ) ) + goto Fail2; + + s = ss->ssf.ssf2.Substitute; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + s[n] = GET_UShort(); + + FORGET_Frame(); + + break; + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; + + Fail1: + FREE( s ); + + Fail2: + Free_Coverage( &ss->Coverage ); + return error; + } + + + void Free_SingleSubst( TTO_SingleSubst* ss ) + { + switch ( ss->SubstFormat ) + { + case 1: + break; + + case 2: + FREE( ss->ssf.ssf2.Substitute ); + break; + } + + Free_Coverage( &ss->Coverage ); + } + + + static TT_Error Lookup_SingleSubst( TTO_SingleSubst* ss, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + TTO_GDEFHeader* gdef ) + { + UShort index, value[1], property; + TT_Error error; + + + if ( context_length != 0xFFFF && context_length < 1 ) + return TTO_Err_Not_Covered; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &ss->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + switch ( ss->SubstFormat ) + { + case 1: + value[0] = ( in->string[in->pos] + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF; + if ( ADD_String( in, 1, out, 1, value ) ) + return error; + break; + + case 2: + if ( index >= ss->ssf.ssf2.GlyphCount ) + return TTO_Err_Invalid_GSUB_SubTable; + value[0] = ss->ssf.ssf2.Substitute[index]; + if ( ADD_String( in, 1, out, 1, value ) ) + return error; + break; + + default: + return TTO_Err_Invalid_GSUB_SubTable; + } + + if ( gdef && gdef->NewGlyphClasses ) + { + /* we inherit the old glyph class to the substituted glyph */ + + error = Add_Glyph_Property( gdef, value[0], property ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + + return TT_Err_Ok; + } + + + /* LookupType 2 */ + + /* Sequence */ + + static TT_Error Load_Sequence( TTO_Sequence* s, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* sub; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = s->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + s->Substitute = NULL; + + if ( count ) + { + if ( ALLOC_ARRAY( s->Substitute, count, UShort ) ) + return error; + + sub = s->Substitute; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( sub ); + return error; + } + + for ( n = 0; n < count; n++ ) + sub[n] = GET_UShort(); + + FORGET_Frame(); + } + + return TT_Err_Ok; + } + + + static void Free_Sequence( TTO_Sequence* s ) + { + FREE( s->Substitute ); + } + + + /* MultipleSubstFormat1 */ + + TT_Error Load_MultipleSubst( TTO_MultipleSubst* ms, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Sequence* s; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + ms->SubstFormat = GET_UShort(); /* should be 1 */ + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ms->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ms->SequenceCount = GET_UShort(); + + FORGET_Frame(); + + ms->Sequence = NULL; + + if ( ALLOC_ARRAY( ms->Sequence, count, TTO_Sequence ) ) + goto Fail2; + + s = ms->Sequence; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Sequence( &s[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_Sequence( &s[n] ); + + FREE( s ); + + Fail2: + Free_Coverage( &ms->Coverage ); + return error; + } + + + void Free_MultipleSubst( TTO_MultipleSubst* ms ) + { + UShort n, count; + + TTO_Sequence* s; + + + if ( ms->Sequence ) + { + count = ms->SequenceCount; + s = ms->Sequence; + + for ( n = 0; n < count; n++ ) + Free_Sequence( &s[n] ); + + FREE( s ); + } + + Free_Coverage( &ms->Coverage ); + } + + + static TT_Error Lookup_MultipleSubst( TTO_MultipleSubst* ms, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + TTO_GDEFHeader* gdef ) + { + TT_Error error; + UShort index, property, n, count; + UShort* s; + + + if ( context_length != 0xFFFF && context_length < 1 ) + return TTO_Err_Not_Covered; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &ms->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + if ( index >= ms->SequenceCount ) + return TTO_Err_Invalid_GSUB_SubTable; + + count = ms->Sequence[index].GlyphCount; + s = ms->Sequence[index].Substitute; + + if ( ADD_String( in, 1, out, count, s ) ) + return error; + + if ( gdef && gdef->NewGlyphClasses ) + { + /* this is a guess only ... */ + + if ( property == TTO_LIGATURE ) + property = TTO_BASE_GLYPH; + + for ( n = 0; n < count; n++ ) + { + error = Add_Glyph_Property( gdef, s[n], property ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + } + + return TT_Err_Ok; + } + + + /* LookupType 3 */ + + /* AlternateSet */ + + static TT_Error Load_AlternateSet( TTO_AlternateSet* as, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* a; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = as->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + as->Alternate = NULL; + + if ( ALLOC_ARRAY( as->Alternate, count, UShort ) ) + return error; + + a = as->Alternate; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( a ); + return error; + } + + for ( n = 0; n < count; n++ ) + a[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_AlternateSet( TTO_AlternateSet* as ) + { + FREE( as->Alternate ); + } + + + /* AlternateSubstFormat1 */ + + TT_Error Load_AlternateSubst( TTO_AlternateSubst* as, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_AlternateSet* aset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + as->SubstFormat = GET_UShort(); /* should be 1 */ + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &as->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = as->AlternateSetCount = GET_UShort(); + + FORGET_Frame(); + + as->AlternateSet = NULL; + + if ( ALLOC_ARRAY( as->AlternateSet, count, TTO_AlternateSet ) ) + goto Fail2; + + aset = as->AlternateSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_AlternateSet( &aset[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_AlternateSet( &aset[n] ); + + FREE( aset ); + + Fail2: + Free_Coverage( &as->Coverage ); + return error; + } + + + void Free_AlternateSubst( TTO_AlternateSubst* as ) + { + UShort n, count; + + TTO_AlternateSet* aset; + + + if ( as->AlternateSet ) + { + count = as->AlternateSetCount; + aset = as->AlternateSet; + + for ( n = 0; n < count; n++ ) + Free_AlternateSet( &aset[n] ); + + FREE( aset ); + } + + Free_Coverage( &as->Coverage ); + } + + + static TT_Error Lookup_AlternateSubst( TTO_GSUBHeader* gsub, + TTO_AlternateSubst* as, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + TTO_GDEFHeader* gdef ) + { + TT_Error error; + UShort index, alt_index, property; + + TTO_AlternateSet aset; + + + if ( context_length != 0xFFFF && context_length < 1 ) + return TTO_Err_Not_Covered; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &as->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + aset = as->AlternateSet[index]; + + /* we use a user-defined callback function to get the alternate index */ + + if ( gsub->alt ) + alt_index = (gsub->alt)( out->pos, in->string[in->pos], + aset.GlyphCount, aset.Alternate, + gsub->data ); + else + alt_index = 0; + + if ( ADD_String( in, 1, out, 1, &aset.Alternate[alt_index] ) ) + return error; + + if ( gdef && gdef->NewGlyphClasses ) + { + /* we inherit the old glyph class to the substituted glyph */ + + error = Add_Glyph_Property( gdef, aset.Alternate[alt_index], + property ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + + return TT_Err_Ok; + } + + + /* LookupType 4 */ + + /* Ligature */ + + static TT_Error Load_Ligature( TTO_Ligature* l, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* c; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + l->LigGlyph = GET_UShort(); + l->ComponentCount = GET_UShort(); + + FORGET_Frame(); + + l->Component = NULL; + + count = l->ComponentCount - 1; /* only ComponentCount - 1 elements */ + + if ( ALLOC_ARRAY( l->Component, count, UShort ) ) + return error; + + c = l->Component; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( c ); + return error; + } + + for ( n = 0; n < count; n++ ) + c[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_Ligature( TTO_Ligature* l ) + { + FREE( l->Component ); + } + + + /* LigatureSet */ + + static TT_Error Load_LigatureSet( TTO_LigatureSet* ls, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Ligature* l; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ls->LigatureCount = GET_UShort(); + + FORGET_Frame(); + + ls->Ligature = NULL; + + if ( ALLOC_ARRAY( ls->Ligature, count, TTO_Ligature ) ) + return error; + + l = ls->Ligature; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Ligature( &l[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_Ligature( &l[n] ); + + FREE( l ); + return error; + } + + + static void Free_LigatureSet( TTO_LigatureSet* ls ) + { + UShort n, count; + + TTO_Ligature* l; + + + if ( ls->Ligature ) + { + count = ls->LigatureCount; + l = ls->Ligature; + + for ( n = 0; n < count; n++ ) + Free_Ligature( &l[n] ); + + FREE( l ); + } + } + + + /* LigatureSubstFormat1 */ + + TT_Error Load_LigatureSubst( TTO_LigatureSubst* ls, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_LigatureSet* lset; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 4L ) ) + return error; + + ls->SubstFormat = GET_UShort(); /* should be 1 */ + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ls->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ls->LigatureSetCount = GET_UShort(); + + FORGET_Frame(); + + ls->LigatureSet = NULL; + + if ( ALLOC_ARRAY( ls->LigatureSet, count, TTO_LigatureSet ) ) + goto Fail2; + + lset = ls->LigatureSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LigatureSet( &lset[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_LigatureSet( &lset[n] ); + + FREE( lset ); + + Fail2: + Free_Coverage( &ls->Coverage ); + return error; + } + + + void Free_LigatureSubst( TTO_LigatureSubst* ls ) + { + UShort n, count; + + TTO_LigatureSet* lset; + + + if ( ls->LigatureSet ) + { + count = ls->LigatureSetCount; + lset = ls->LigatureSet; + + for ( n = 0; n < count; n++ ) + Free_LigatureSet( &lset[n] ); + + FREE( lset ); + } + + Free_Coverage( &ls->Coverage ); + } + + + static TT_Error Lookup_LigatureSubst( TTO_LigatureSubst* ls, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + TTO_GDEFHeader* gdef ) + { + UShort index, property; + TT_Error error; + UShort numlig, i, j; + UShort* s_in; + UShort* c; + + TTO_Ligature* lig; + + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &ls->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + if ( index >= ls->LigatureSetCount ) + return TTO_Err_Invalid_GSUB_SubTable; + + lig = ls->LigatureSet[index].Ligature; + + for ( numlig = ls->LigatureSet[index].LigatureCount; + numlig; + numlig--, lig++ ) + { + if ( in->pos + lig->ComponentCount > in->length ) + continue; /* Not enough glyphs in input */ + + s_in = &in->string[in->pos]; + c = lig->Component; + + if ( context_length != 0xFFFF && context_length < lig->ComponentCount ) + break; + + for ( i = 1, j = 1; i < lig->ComponentCount; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( in->pos + j < in->length ) + j++; + else + break; + } + + if ( s_in[j] != c[i - 1] ) + break; + } + + if ( i == lig->ComponentCount ) + { + if ( ADD_String( in, lig->ComponentCount, out, 1, &lig->LigGlyph ) ) + return error; + + if ( gdef && gdef->NewGlyphClasses ) + { + /* this is just a guess ... */ + + error = Add_Glyph_Property( gdef, lig->LigGlyph, TTO_LIGATURE ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + + return TT_Err_Ok; + } + } + + return TTO_Err_Not_Covered; + } + + + /* Do the actual substitution for a context substitution (either format + 5 or 6). This is only called after we've determined that the input + matches the subrule. */ + + static TT_Error Do_ContextSubst( TTO_GSUBHeader* gsub, + UShort GlyphCount, + UShort SubstCount, + TTO_SubstLookupRecord* subst, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + int nesting_level ) + { + TT_Error error; + UShort i, old_pos; + + + i = 0; + + while ( i < GlyphCount ) + { + if ( SubstCount && i == subst->SequenceIndex ) + { + old_pos = in->pos; + + /* Do a substitution */ + + error = Do_Glyph_Lookup( gsub, subst->LookupListIndex, in, out, + GlyphCount, nesting_level ); + + subst++; + SubstCount--; + i += in->pos - old_pos; + + if ( error == TTO_Err_Not_Covered ) + { + /* XXX "can't happen" -- but don't count on it */ + + if ( ADD_String( in, 1, out, 1, &in->string[in->pos] ) ) + return error; + i++; + } + else if ( error ) + return error; + } + else + { + /* No substitution for this index */ + + if ( ADD_String( in, 1, out, 1, &in->string[in->pos] ) ) + return error; + i++; + } + } + + return TT_Err_Ok; + } + + + /* LookupType 5 */ + + /* SubRule */ + + static TT_Error Load_SubRule( TTO_SubRule* sr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* i; + + TTO_SubstLookupRecord* slr; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + sr->GlyphCount = GET_UShort(); + sr->SubstCount = GET_UShort(); + + FORGET_Frame(); + + sr->Input = NULL; + + count = sr->GlyphCount - 1; /* only GlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( sr->Input, count, UShort ) ) + return error; + + i = sr->Input; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + i[n] = GET_UShort(); + + FORGET_Frame(); + + sr->SubstLookupRecord = NULL; + + count = sr->SubstCount; + + if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = sr->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + FREE( i ); + return error; + } + + + static void Free_SubRule( TTO_SubRule* sr ) + { + FREE( sr->SubstLookupRecord ); + FREE( sr->Input ); + } + + + /* SubRuleSet */ + + static TT_Error Load_SubRuleSet( TTO_SubRuleSet* srs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubRule* sr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = srs->SubRuleCount = GET_UShort(); + + FORGET_Frame(); + + srs->SubRule = NULL; + + if ( ALLOC_ARRAY( srs->SubRule, count, TTO_SubRule ) ) + return error; + + sr = srs->SubRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubRule( &sr[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_SubRule( &sr[n] ); + + FREE( sr ); + return error; + } + + + static void Free_SubRuleSet( TTO_SubRuleSet* srs ) + { + UShort n, count; + + TTO_SubRule* sr; + + + if ( srs->SubRule ) + { + count = srs->SubRuleCount; + sr = srs->SubRule; + + for ( n = 0; n < count; n++ ) + Free_SubRule( &sr[n] ); + + FREE( sr ); + } + } + + + /* ContextSubstFormat1 */ + + static TT_Error Load_ContextSubst1( TTO_ContextSubstFormat1* csf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubRuleSet* srs; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &csf1->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = csf1->SubRuleSetCount = GET_UShort(); + + FORGET_Frame(); + + csf1->SubRuleSet = NULL; + + if ( ALLOC_ARRAY( csf1->SubRuleSet, count, TTO_SubRuleSet ) ) + goto Fail2; + + srs = csf1->SubRuleSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubRuleSet( &srs[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_SubRuleSet( &srs[n] ); + + FREE( srs ); + + Fail2: + Free_Coverage( &csf1->Coverage ); + return error; + } + + + static void Free_Context1( TTO_ContextSubstFormat1* csf1 ) + { + UShort n, count; + + TTO_SubRuleSet* srs; + + + if ( csf1->SubRuleSet ) + { + count = csf1->SubRuleSetCount; + srs = csf1->SubRuleSet; + + for ( n = 0; n < count; n++ ) + Free_SubRuleSet( &srs[n] ); + + FREE( srs ); + } + + Free_Coverage( &csf1->Coverage ); + } + + + /* SubClassRule */ + + static TT_Error Load_SubClassRule( TTO_ContextSubstFormat2* csf2, + TTO_SubClassRule* scr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* c; + TTO_SubstLookupRecord* slr; + Bool* d; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + scr->GlyphCount = GET_UShort(); + scr->SubstCount = GET_UShort(); + + if ( scr->GlyphCount > csf2->MaxContextLength ) + csf2->MaxContextLength = scr->GlyphCount; + + FORGET_Frame(); + + scr->Class = NULL; + + count = scr->GlyphCount - 1; /* only GlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( scr->Class, count, UShort ) ) + return error; + + c = scr->Class; + d = csf2->ClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + { + c[n] = GET_UShort(); + + /* We check whether the specific class is used at all. If not, + class 0 is used instead. */ + + if ( !d[c[n]] ) + c[n] = 0; + } + + FORGET_Frame(); + + scr->SubstLookupRecord = NULL; + + count = scr->SubstCount; + + if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = scr->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + FREE( c ); + return error; + } + + + static void Free_SubClassRule( TTO_SubClassRule* scr ) + { + FREE( scr->SubstLookupRecord ); + FREE( scr->Class ); + } + + + /* SubClassSet */ + + static TT_Error Load_SubClassSet( TTO_ContextSubstFormat2* csf2, + TTO_SubClassSet* scs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubClassRule* scr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = scs->SubClassRuleCount = GET_UShort(); + + FORGET_Frame(); + + scs->SubClassRule = NULL; + + if ( ALLOC_ARRAY( scs->SubClassRule, count, TTO_SubClassRule ) ) + return error; + + scr = scs->SubClassRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubClassRule( csf2, &scr[n], + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_SubClassRule( &scr[n] ); + + FREE( scr ); + return error; + } + + + static void Free_SubClassSet( TTO_SubClassSet* scs ) + { + UShort n, count; + + TTO_SubClassRule* scr; + + + if ( scs->SubClassRule ) + { + count = scs->SubClassRuleCount; + scr = scs->SubClassRule; + + for ( n = 0; n < count; n++ ) + Free_SubClassRule( &scr[n] ); + + FREE( scr ); + } + } + + + /* ContextSubstFormat2 */ + + static TT_Error Load_ContextSubst2( TTO_ContextSubstFormat2* csf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubClassSet* scs; + + + base_offset = FILE_Pos() - 2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &csf2->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 4L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + /* `SubClassSetCount' is the upper limit for class values, thus we + read it now to make an additional safety check. */ + + count = csf2->SubClassSetCount = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ClassDefinition( &csf2->ClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + csf2->SubClassSet = NULL; + csf2->MaxContextLength = 0; + + if ( ALLOC_ARRAY( csf2->SubClassSet, count, TTO_SubClassSet ) ) + goto Fail2; + + scs = csf2->SubClassSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubClassSet( csf2, &scs[n], + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a SubClassSet table with no entries */ + + csf2->SubClassSet[n].SubClassRuleCount = 0; + csf2->SubClassSet[n].SubClassRule = NULL; + } + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_SubClassSet( &scs[n] ); + + FREE( scs ); + + Fail2: + Free_ClassDefinition( &csf2->ClassDef ); + + Fail3: + Free_Coverage( &csf2->Coverage ); + return error; + } + + + static void Free_Context2( TTO_ContextSubstFormat2* csf2 ) + { + UShort n, count; + + TTO_SubClassSet* scs; + + + if ( csf2->SubClassSet ) + { + count = csf2->SubClassSetCount; + scs = csf2->SubClassSet; + + for ( n = 0; n < count; n++ ) + Free_SubClassSet( &scs[n] ); + + FREE( scs ); + } + + Free_ClassDefinition( &csf2->ClassDef ); + Free_Coverage( &csf2->Coverage ); + } + + + /* ContextSubstFormat3 */ + + static TT_Error Load_ContextSubst3( TTO_ContextSubstFormat3* csf3, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Coverage* c; + TTO_SubstLookupRecord* slr; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 4L ) ) + return error; + + csf3->GlyphCount = GET_UShort(); + csf3->SubstCount = GET_UShort(); + + FORGET_Frame(); + + csf3->Coverage = NULL; + + count = csf3->GlyphCount; + + if ( ALLOC_ARRAY( csf3->Coverage, count, TTO_Coverage ) ) + return error; + + c = csf3->Coverage; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &c[n], input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + + csf3->SubstLookupRecord = NULL; + + count = csf3->SubstCount; + + if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count, + TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = csf3->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + return error; + } + + + static void Free_Context3( TTO_ContextSubstFormat3* csf3 ) + { + UShort n, count; + + TTO_Coverage* c; + + + FREE( csf3->SubstLookupRecord ); + + if ( csf3->Coverage ) + { + count = csf3->GlyphCount; + c = csf3->Coverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + } + + + /* ContextSubst */ + + TT_Error Load_ContextSubst( TTO_ContextSubst* cs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cs->SubstFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( cs->SubstFormat ) + { + case 1: + return Load_ContextSubst1( &cs->csf.csf1, input ); + + case 2: + return Load_ContextSubst2( &cs->csf.csf2, input ); + + case 3: + return Load_ContextSubst3( &cs->csf.csf3, input ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_ContextSubst( TTO_ContextSubst* cs ) + { + switch ( cs->SubstFormat ) + { + case 1: + Free_Context1( &cs->csf.csf1 ); + break; + + case 2: + Free_Context2( &cs->csf.csf2 ); + break; + + case 3: + Free_Context3( &cs->csf.csf3 ); + break; + } + } + + + static TT_Error Lookup_ContextSubst1( + TTO_GSUBHeader* gsub, + TTO_ContextSubstFormat1* csf1, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, property; + UShort i, j, k, numsr; + TT_Error error; + UShort* s_in; + + TTO_SubRule* sr; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &csf1->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + sr = csf1->SubRuleSet[index].SubRule; + numsr = csf1->SubRuleSet[index].SubRuleCount; + + for ( k = 0; k < numsr; k++ ) + { + if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount ) + continue; + + if ( in->pos + sr[k].GlyphCount > in->length ) + continue; /* context is too long */ + + s_in = &in->string[in->pos]; + + for ( i = 1, j = 1; i < sr[k].GlyphCount; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( in->pos + j < in->length ) + j++; + else + break; + } + + if ( s_in[j] != sr[k].Input[i - 1] ) + break; + } + + if ( i == sr[k].GlyphCount ) + return Do_ContextSubst( gsub, sr[k].GlyphCount, + sr[k].SubstCount, sr[k].SubstLookupRecord, + in, out, + nesting_level ); + } + + return TTO_Err_Not_Covered; + } + + + static TT_Error Lookup_ContextSubst2( + TTO_GSUBHeader* gsub, + TTO_ContextSubstFormat2* csf2, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, property; + TT_Error error; + UShort i, j, k, known_classes; + + UShort* classes; + UShort* s_in; + UShort* cl; + + TTO_SubClassSet* scs; + TTO_SubClassRule* sr; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, UShort ) ) + return error; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + /* Note: The coverage table in format 2 doesn't give an index into + anything. It just lets us know whether or not we need to + do any lookup at all. */ + + error = Coverage_Index( &csf2->Coverage, in->string[in->pos], &index ); + if ( error ) + goto End; + + error = Get_Class( &csf2->ClassDef, in->string[in->pos], + &classes[0], NULL ); + if ( error ) + goto End; + known_classes = 0; + + scs = &csf2->SubClassSet[classes[0]]; + if ( !scs ) + { + error = TTO_Err_Invalid_GSUB_SubTable; + goto End; + } + + for ( k = 0; k < scs->SubClassRuleCount; k++ ) + { + sr = &scs->SubClassRule[k]; + + if ( context_length != 0xFFFF && context_length < sr->GlyphCount ) + continue; + + if ( in->pos + sr->GlyphCount > in->length ) + continue; /* context is too long */ + + s_in = &in->string[in->pos]; + cl = sr->Class; + + /* Start at 1 because [0] is implied */ + + for ( i = 1, j = 1; i < sr->GlyphCount; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( in->pos + j < in->length ) + j++; + else + break; + } + + if ( i > known_classes ) + { + /* Keeps us from having to do this for each rule */ + + error = Get_Class( &csf2->ClassDef, s_in[j], &classes[i], NULL ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + known_classes = i; + } + + if ( cl[i - 1] != classes[i] ) + break; + } + + if ( i == sr->GlyphCount ) + { + error = Do_ContextSubst( gsub, sr->GlyphCount, + sr->SubstCount, sr->SubstLookupRecord, + in, out, + nesting_level ); + goto End; + } + } + + error = TTO_Err_Not_Covered; + + End: + FREE( classes ); + return error; + } + + + static TT_Error Lookup_ContextSubst3( + TTO_GSUBHeader* gsub, + TTO_ContextSubstFormat3* csf3, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + TT_Error error; + UShort index, i, j, property; + UShort* s_in; + + TTO_Coverage* c; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + if ( context_length != 0xFFFF && context_length < csf3->GlyphCount ) + return TTO_Err_Not_Covered; + + if ( in->pos + csf3->GlyphCount > in->length ) + return TTO_Err_Not_Covered; /* context is too long */ + + s_in = &in->string[in->pos]; + c = csf3->Coverage; + + for ( i = 1, j = 1; i < csf3->GlyphCount; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( in->pos + j < in->length ) + j++; + else + return TTO_Err_Not_Covered; + } + + error = Coverage_Index( &c[i], s_in[j], &index ); + if ( error ) + return error; + } + + return Do_ContextSubst( gsub, csf3->GlyphCount, + csf3->SubstCount, csf3->SubstLookupRecord, + in, out, + nesting_level ); + } + + + static TT_Error Lookup_ContextSubst( TTO_GSUBHeader* gsub, + TTO_ContextSubst* cs, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + switch ( cs->SubstFormat ) + { + case 1: + return Lookup_ContextSubst1( gsub, &cs->csf.csf1, in, out, + flags, context_length, nesting_level ); + + case 2: + return Lookup_ContextSubst2( gsub, &cs->csf.csf2, in, out, + flags, context_length, nesting_level ); + + case 3: + return Lookup_ContextSubst3( gsub, &cs->csf.csf3, in, out, + flags, context_length, nesting_level ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + /* LookupType 6 */ + + /* ChainSubRule */ + + static TT_Error Load_ChainSubRule( TTO_ChainSubRule* csr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort* b; + UShort* i; + UShort* l; + + TTO_SubstLookupRecord* slr; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + csr->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + csr->Backtrack = NULL; + + count = csr->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( csr->Backtrack, count, UShort ) ) + return error; + + b = csr->Backtrack; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail4; + + for ( n = 0; n < count; n++ ) + b[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + csr->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + csr->Input = NULL; + + count = csr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( csr->Input, count, UShort ) ) + goto Fail4; + + i = csr->Input; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail3; + + for ( n = 0; n < count; n++ ) + i[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + csr->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + csr->Lookahead = NULL; + + count = csr->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( csr->Lookahead, count, UShort ) ) + goto Fail3; + + l = csr->Lookahead; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + l[n] = GET_UShort(); + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + csr->SubstCount = GET_UShort(); + + FORGET_Frame(); + + csr->SubstLookupRecord = NULL; + + count = csr->SubstCount; + + if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = csr->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + FREE( l ); + + Fail3: + FREE( i ); + + Fail4: + FREE( b ); + return error; + } + + + static void Free_ChainSubRule( TTO_ChainSubRule* csr ) + { + FREE( csr->SubstLookupRecord ); + FREE( csr->Lookahead ); + FREE( csr->Input ); + FREE( csr->Backtrack ); + } + + + /* ChainSubRuleSet */ + + static TT_Error Load_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainSubRule* csr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = csrs->ChainSubRuleCount = GET_UShort(); + + FORGET_Frame(); + + csrs->ChainSubRule = NULL; + + if ( ALLOC_ARRAY( csrs->ChainSubRule, count, TTO_ChainSubRule ) ) + return error; + + csr = csrs->ChainSubRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainSubRule( &csr[n], input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_ChainSubRule( &csr[n] ); + + FREE( csr ); + return error; + } + + + static void Free_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs ) + { + UShort n, count; + + TTO_ChainSubRule* csr; + + + if ( csrs->ChainSubRule ) + { + count = csrs->ChainSubRuleCount; + csr = csrs->ChainSubRule; + + for ( n = 0; n < count; n++ ) + Free_ChainSubRule( &csr[n] ); + + FREE( csr ); + } + } + + + /* ChainContextSubstFormat1 */ + + static TT_Error Load_ChainContextSubst1( + TTO_ChainContextSubstFormat1* ccsf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainSubRuleSet* csrs; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ccsf1->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = ccsf1->ChainSubRuleSetCount = GET_UShort(); + + FORGET_Frame(); + + ccsf1->ChainSubRuleSet = NULL; + + if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, TTO_ChainSubRuleSet ) ) + goto Fail2; + + csrs = ccsf1->ChainSubRuleSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainSubRuleSet( &csrs[n], input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ChainSubRuleSet( &csrs[n] ); + + FREE( csrs ); + + Fail2: + Free_Coverage( &ccsf1->Coverage ); + return error; + } + + + static void Free_ChainContext1( TTO_ChainContextSubstFormat1* ccsf1 ) + { + UShort n, count; + + TTO_ChainSubRuleSet* csrs; + + + if ( ccsf1->ChainSubRuleSet ) + { + count = ccsf1->ChainSubRuleSetCount; + csrs = ccsf1->ChainSubRuleSet; + + for ( n = 0; n < count; n++ ) + Free_ChainSubRuleSet( &csrs[n] ); + + FREE( csrs ); + } + + Free_Coverage( &ccsf1->Coverage ); + } + + + /* ChainSubClassRule */ + + static TT_Error Load_ChainSubClassRule( + TTO_ChainContextSubstFormat2* ccsf2, + TTO_ChainSubClassRule* cscr, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* b; + UShort* i; + UShort* l; + TTO_SubstLookupRecord* slr; + Bool* d; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + cscr->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength ) + ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount; + + cscr->Backtrack = NULL; + + count = cscr->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( cscr->Backtrack, count, UShort ) ) + return error; + + b = cscr->Backtrack; + d = ccsf2->BacktrackClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail4; + + for ( n = 0; n < count; n++ ) + { + b[n] = GET_UShort(); + + /* We check whether the specific class is used at all. If not, + class 0 is used instead. */ + + if ( !d[b[n]] ) + b[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + cscr->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cscr->InputGlyphCount > ccsf2->MaxInputLength ) + ccsf2->MaxInputLength = cscr->InputGlyphCount; + + cscr->Input = NULL; + + count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ + + if ( ALLOC_ARRAY( cscr->Input, count, UShort ) ) + goto Fail4; + + i = cscr->Input; + d = ccsf2->InputClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail3; + + for ( n = 0; n < count; n++ ) + { + i[n] = GET_UShort(); + + if ( !d[i[n]] ) + i[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + cscr->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength ) + ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount; + + cscr->Lookahead = NULL; + + count = cscr->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( cscr->Lookahead, count, UShort ) ) + goto Fail3; + + l = cscr->Lookahead; + d = ccsf2->LookaheadClassDef.Defined; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail2; + + for ( n = 0; n < count; n++ ) + { + l[n] = GET_UShort(); + + if ( !d[l[n]] ) + l[n] = 0; + } + + FORGET_Frame(); + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + cscr->SubstCount = GET_UShort(); + + FORGET_Frame(); + + cscr->SubstLookupRecord = NULL; + + count = cscr->SubstCount; + + if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count, + TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = cscr->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + FREE( l ); + + Fail3: + FREE( i ); + + Fail4: + FREE( b ); + return error; + } + + + static void Free_ChainSubClassRule( TTO_ChainSubClassRule* cscr ) + { + FREE( cscr->SubstLookupRecord ); + FREE( cscr->Lookahead ); + FREE( cscr->Input ); + FREE( cscr->Backtrack ); + } + + + /* SubClassSet */ + + static TT_Error Load_ChainSubClassSet( + TTO_ChainContextSubstFormat2* ccsf2, + TTO_ChainSubClassSet* cscs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ChainSubClassRule* cscr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cscs->ChainSubClassRuleCount = GET_UShort(); + + FORGET_Frame(); + + cscs->ChainSubClassRule = NULL; + + if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count, + TTO_ChainSubClassRule ) ) + return error; + + cscr = cscs->ChainSubClassRule; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainSubClassRule( ccsf2, &cscr[n], + input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_ChainSubClassRule( &cscr[n] ); + + FREE( cscr ); + return error; + } + + + static void Free_ChainSubClassSet( TTO_ChainSubClassSet* cscs ) + { + UShort n, count; + + TTO_ChainSubClassRule* cscr; + + + if ( cscs->ChainSubClassRule ) + { + count = cscs->ChainSubClassRuleCount; + cscr = cscs->ChainSubClassRule; + + for ( n = 0; n < count; n++ ) + Free_ChainSubClassRule( &cscr[n] ); + + FREE( cscr ); + } + } + + + /* ChainContextSubstFormat2 */ + + static TT_Error Load_ChainContextSubst2( + TTO_ChainContextSubstFormat2* ccsf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + ULong backtrack_offset, input_offset, lookahead_offset; + + TTO_ChainSubClassSet* cscs; + + + base_offset = FILE_Pos() - 2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &ccsf2->Coverage, input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + + if ( ACCESS_Frame( 8L ) ) + goto Fail5; + + backtrack_offset = GET_UShort() + base_offset; + input_offset = GET_UShort() + base_offset; + lookahead_offset = GET_UShort() + base_offset; + + /* `ChainSubClassSetCount' is the upper limit for input class values, + thus we read it now to make an additional safety check. */ + + count = ccsf2->ChainSubClassSetCount = GET_UShort(); + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( backtrack_offset ) || + ( error = Load_ClassDefinition( &ccsf2->BacktrackClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail5; + if ( FILE_Seek( input_offset ) || + ( error = Load_ClassDefinition( &ccsf2->InputClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail4; + if ( FILE_Seek( lookahead_offset ) || + ( error = Load_ClassDefinition( &ccsf2->LookaheadClassDef, count, + input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + + ccsf2->ChainSubClassSet = NULL; + ccsf2->MaxBacktrackLength = 0; + ccsf2->MaxInputLength = 0; + ccsf2->MaxLookaheadLength = 0; + + if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, TTO_ChainSubClassSet ) ) + goto Fail2; + + cscs = ccsf2->ChainSubClassSet; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_ChainSubClassSet( ccsf2, &cscs[n], + input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a ChainSubClassSet table with no entries */ + + ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0; + ccsf2->ChainSubClassSet[n].ChainSubClassRule = NULL; + } + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_ChainSubClassSet( &cscs[n] ); + + FREE( cscs ); + + Fail2: + Free_ClassDefinition( &ccsf2->LookaheadClassDef ); + + Fail3: + Free_ClassDefinition( &ccsf2->InputClassDef ); + + Fail4: + Free_ClassDefinition( &ccsf2->BacktrackClassDef ); + + Fail5: + Free_Coverage( &ccsf2->Coverage ); + return error; + } + + + static void Free_ChainContext2( TTO_ChainContextSubstFormat2* ccsf2 ) + { + UShort n, count; + + TTO_ChainSubClassSet* cscs; + + + if ( ccsf2->ChainSubClassSet ) + { + count = ccsf2->ChainSubClassSetCount; + cscs = ccsf2->ChainSubClassSet; + + for ( n = 0; n < count; n++ ) + Free_ChainSubClassSet( &cscs[n] ); + + FREE( cscs ); + } + + Free_ClassDefinition( &ccsf2->LookaheadClassDef ); + Free_ClassDefinition( &ccsf2->InputClassDef ); + Free_ClassDefinition( &ccsf2->BacktrackClassDef ); + + Free_Coverage( &ccsf2->Coverage ); + } + + + /* ChainContextSubstFormat3 */ + + static TT_Error Load_ChainContextSubst3( + TTO_ChainContextSubstFormat3* ccsf3, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + UShort backtrack_count, input_count, lookahead_count; + ULong cur_offset, new_offset, base_offset; + + TTO_Coverage* b; + TTO_Coverage* i; + TTO_Coverage* l; + TTO_SubstLookupRecord* slr; + + + base_offset = FILE_Pos() - 2L; + + if ( ACCESS_Frame( 2L ) ) + return error; + + ccsf3->BacktrackGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccsf3->BacktrackCoverage = NULL; + + backtrack_count = ccsf3->BacktrackGlyphCount; + + if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count, + TTO_Coverage ) ) + return error; + + b = ccsf3->BacktrackCoverage; + + for ( n = 0; n < backtrack_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &b[n], input ) ) != TT_Err_Ok ) + goto Fail4; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail4; + + ccsf3->InputGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccsf3->InputCoverage = NULL; + + input_count = ccsf3->InputGlyphCount; + + if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, TTO_Coverage ) ) + goto Fail4; + + i = ccsf3->InputCoverage; + + for ( n = 0; n < input_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &i[n], input ) ) != TT_Err_Ok ) + goto Fail3; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail3; + + ccsf3->LookaheadGlyphCount = GET_UShort(); + + FORGET_Frame(); + + ccsf3->LookaheadCoverage = NULL; + + lookahead_count = ccsf3->LookaheadGlyphCount; + + if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count, + TTO_Coverage ) ) + goto Fail3; + + l = ccsf3->LookaheadCoverage; + + for ( n = 0; n < lookahead_count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Coverage( &l[n], input ) ) != TT_Err_Ok ) + goto Fail2; + (void)FILE_Seek( cur_offset ); + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + ccsf3->SubstCount = GET_UShort(); + + FORGET_Frame(); + + ccsf3->SubstLookupRecord = NULL; + + count = ccsf3->SubstCount; + + if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count, + TTO_SubstLookupRecord ) ) + goto Fail2; + + slr = ccsf3->SubstLookupRecord; + + if ( ACCESS_Frame( count * 4L ) ) + goto Fail1; + + for ( n = 0; n < count; n++ ) + { + slr[n].SequenceIndex = GET_UShort(); + slr[n].LookupListIndex = GET_UShort(); + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail1: + FREE( slr ); + + Fail2: + for ( n = 0; n < lookahead_count; n++ ) + Free_Coverage( &l[n] ); + + FREE( l ); + + Fail3: + for ( n = 0; n < input_count; n++ ) + Free_Coverage( &i[n] ); + + FREE( i ); + + Fail4: + for ( n = 0; n < backtrack_count; n++ ) + Free_Coverage( &b[n] ); + + FREE( b ); + return error; + } + + + static void Free_ChainContext3( TTO_ChainContextSubstFormat3* ccsf3 ) + { + UShort n, count; + + TTO_Coverage* c; + + + FREE( ccsf3->SubstLookupRecord ); + + if ( ccsf3->LookaheadCoverage ) + { + count = ccsf3->LookaheadGlyphCount; + c = ccsf3->LookaheadCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + + if ( ccsf3->InputCoverage ) + { + count = ccsf3->InputGlyphCount; + c = ccsf3->InputCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + + if ( ccsf3->BacktrackCoverage ) + { + count = ccsf3->BacktrackGlyphCount; + c = ccsf3->BacktrackCoverage; + + for ( n = 0; n < count; n++ ) + Free_Coverage( &c[n] ); + + FREE( c ); + } + } + + + /* ChainContextSubst */ + + TT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + ccs->SubstFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( ccs->SubstFormat ) + { + case 1: + return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, input ); + + case 2: + return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, input ); + + case 3: + return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, input ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_ChainContextSubst( TTO_ChainContextSubst* ccs ) + { + switch ( ccs->SubstFormat ) + { + case 1: + Free_ChainContext1( &ccs->ccsf.ccsf1 ); + break; + + case 2: + Free_ChainContext2( &ccs->ccsf.ccsf2 ); + break; + + case 3: + Free_ChainContext3( &ccs->ccsf.ccsf3 ); + break; + } + } + + + static TT_Error Lookup_ChainContextSubst1( + TTO_GSUBHeader* gsub, + TTO_ChainContextSubstFormat1* ccsf1, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, property; + UShort i, j, k, num_csr, curr_pos; + UShort bgc, igc, lgc; + TT_Error error; + UShort* s_in; + + TTO_ChainSubRule* csr; + TTO_ChainSubRule curr_csr; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + error = Coverage_Index( &ccsf1->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + csr = ccsf1->ChainSubRuleSet[index].ChainSubRule; + num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount; + + for ( k = 0; k < num_csr; k++ ) + { + curr_csr = csr[k]; + bgc = curr_csr.BacktrackGlyphCount; + igc = curr_csr.InputGlyphCount; + lgc = curr_csr.LookaheadGlyphCount; + + if ( context_length != 0xFFFF && context_length < igc ) + continue; + + /* check whether context is too long; it is a first guess only */ + + if ( bgc > in->pos || in->pos + igc + lgc > in->length ) + continue; + + if ( bgc ) + { + /* Since we don't know in advance the number of glyphs to inspect, + we search backwards for matches in the backtrack glyph array */ + + curr_pos = 0; + s_in = &in->string[curr_pos]; + + for ( i = bgc, j = in->pos - 1; i > 0; i--, j-- ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( j > curr_pos ) + j--; + else + break; + } + + if ( s_in[j] != curr_csr.Backtrack[i - 1] ) + break; + } + + if ( i != 0 ) + continue; + } + + curr_pos = in->pos; + s_in = &in->string[curr_pos]; + + /* Start at 1 because [0] is implied */ + + for ( i = 1, j = 1; i < igc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + break; + } + + if ( s_in[j] != curr_csr.Input[i - 1] ) + break; + } + + if ( i != igc ) + continue; + + /* we are starting to check for lookahead glyphs right after the + last context glyph */ + + curr_pos = j; + s_in = &in->string[curr_pos]; + + for ( i = 0, j = 0; i < lgc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + break; + } + + if ( s_in[j] != curr_csr.Lookahead[i] ) + break; + } + + if ( i == lgc ) + return Do_ContextSubst( gsub, igc, + curr_csr.SubstCount, + curr_csr.SubstLookupRecord, + in, out, + nesting_level ); + } + + return TTO_Err_Not_Covered; + } + + + static TT_Error Lookup_ChainContextSubst2( + TTO_GSUBHeader* gsub, + TTO_ChainContextSubstFormat2* ccsf2, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, property; + TT_Error error; + UShort i, j, k, curr_pos; + UShort bgc, igc, lgc; + UShort known_backtrack_classes, + known_input_classes, + known_lookahead_classes; + + UShort* backtrack_classes; + UShort* input_classes; + UShort* lookahead_classes; + + UShort* s_in; + + UShort* bc; + UShort* ic; + UShort* lc; + + TTO_ChainSubClassSet* cscs; + TTO_ChainSubClassRule ccsr; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + /* Note: The coverage table in format 2 doesn't give an index into + anything. It just lets us know whether or not we need to + do any lookup at all. */ + + error = Coverage_Index( &ccsf2->Coverage, in->string[in->pos], &index ); + if ( error ) + return error; + + if ( ALLOC_ARRAY( backtrack_classes, ccsf2->MaxBacktrackLength, UShort ) ) + return error; + known_backtrack_classes = 0; + + if ( ALLOC_ARRAY( input_classes, ccsf2->MaxInputLength, UShort ) ) + goto End3; + known_input_classes = 1; + + if ( ALLOC_ARRAY( lookahead_classes, ccsf2->MaxLookaheadLength, UShort ) ) + goto End2; + known_lookahead_classes = 0; + + error = Get_Class( &ccsf2->InputClassDef, in->string[in->pos], + &input_classes[0], NULL ); + if ( error ) + goto End1; + + cscs = &ccsf2->ChainSubClassSet[input_classes[0]]; + if ( !cscs ) + { + error = TTO_Err_Invalid_GSUB_SubTable; + goto End1; + } + + for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ ) + { + ccsr = cscs->ChainSubClassRule[k]; + bgc = ccsr.BacktrackGlyphCount; + igc = ccsr.InputGlyphCount; + lgc = ccsr.LookaheadGlyphCount; + + if ( context_length != 0xFFFF && context_length < igc ) + continue; + + /* check whether context is too long; it is a first guess only */ + + if ( bgc > in->pos || in->pos + igc + lgc > in->length ) + continue; + + if ( bgc ) + { + /* Since we don't know in advance the number of glyphs to inspect, + we search backwards for matches in the backtrack glyph array. + Note that `known_backtrack_classes' starts at index 0. */ + + curr_pos = 0; + s_in = &in->string[curr_pos]; + bc = ccsr.Backtrack; + + for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( j > curr_pos ) + j--; + else + break; + } + + if ( i >= known_backtrack_classes ) + { + /* Keeps us from having to do this for each rule */ + + error = Get_Class( &ccsf2->BacktrackClassDef, s_in[j], + &backtrack_classes[i], NULL ); + if ( error && error != TTO_Err_Not_Covered ) + goto End1; + known_backtrack_classes = i; + } + + if ( bc[bgc - 1 - i] != backtrack_classes[i] ) + break; + } + + if ( i != bgc ) + continue; + } + + curr_pos = in->pos; + s_in = &in->string[curr_pos]; + ic = ccsr.Input; + + /* Start at 1 because [0] is implied */ + + for ( i = 1, j = 1; i < igc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + goto End1; + + if ( curr_pos + j < in->length ) + j++; + else + break; + } + + if ( i >= known_input_classes ) + { + error = Get_Class( &ccsf2->InputClassDef, s_in[j], + &input_classes[i], NULL ); + if ( error && error != TTO_Err_Not_Covered ) + goto End1; + known_input_classes = i; + } + + if ( ic[i - 1] != input_classes[i] ) + break; + } + + if ( i != igc ) + continue; + + /* we are starting to check for lookahead glyphs right after the + last context glyph */ + + curr_pos = j; + s_in = &in->string[curr_pos]; + lc = ccsr.Lookahead; + + for ( i = 0, j = 0; i < lgc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + break; + } + + if ( i >= known_lookahead_classes ) + { + error = Get_Class( &ccsf2->LookaheadClassDef, s_in[j], + &lookahead_classes[i], NULL ); + if ( error && error != TTO_Err_Not_Covered ) + goto End1; + known_lookahead_classes = i; + } + + if ( lc[i] != lookahead_classes[i] ) + break; + } + + if ( i == lgc ) + { + error = Do_ContextSubst( gsub, igc, + ccsr.SubstCount, + ccsr.SubstLookupRecord, + in, out, + nesting_level ); + goto End1; + } + } + + error = TTO_Err_Not_Covered; + + End1: + FREE( lookahead_classes ); + + End2: + FREE( input_classes ); + + End3: + FREE( backtrack_classes ); + return error; + } + + + static TT_Error Lookup_ChainContextSubst3( + TTO_GSUBHeader* gsub, + TTO_ChainContextSubstFormat3* ccsf3, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + UShort index, i, j, curr_pos, property; + UShort bgc, igc, lgc; + TT_Error error; + UShort* s_in; + + TTO_Coverage* bc; + TTO_Coverage* ic; + TTO_Coverage* lc; + TTO_GDEFHeader* gdef; + + + gdef = gsub->gdef; + + if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) ) + return error; + + bgc = ccsf3->BacktrackGlyphCount; + igc = ccsf3->InputGlyphCount; + lgc = ccsf3->LookaheadGlyphCount; + + if ( context_length != 0xFFFF && context_length < igc ) + return TTO_Err_Not_Covered; + + /* check whether context is too long; it is a first guess only */ + + if ( bgc > in->pos || in->pos + igc + lgc > in->length ) + return TTO_Err_Not_Covered; + + if ( bgc ) + { + /* Since we don't know in advance the number of glyphs to inspect, + we search backwards for matches in the backtrack glyph array */ + + curr_pos = 0; + s_in = &in->string[curr_pos]; + bc = ccsf3->BacktrackCoverage; + + for ( i = bgc, j = in->pos - 1; i > 0; i--, j-- ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( j > curr_pos ) + j--; + else + return TTO_Err_Not_Covered; + } + + error = Coverage_Index( &bc[i - 1], s_in[j], &index ); + if ( error ) + return error; + } + } + + curr_pos = in->pos; + s_in = &in->string[curr_pos]; + ic = ccsf3->InputCoverage; + + /* Start at 1 because [0] is implied */ + + for ( i = 1, j = 1; i < igc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + return TTO_Err_Not_Covered; + } + + error = Coverage_Index( &ic[i], s_in[j], &index ); + if ( error ) + return error; + } + + /* we are starting for lookahead glyphs right after the last context + glyph */ + + curr_pos = j; + s_in = &in->string[curr_pos]; + lc = ccsf3->LookaheadCoverage; + + for ( i = 0, j = 0; i < lgc; i++, j++ ) + { + while ( CHECK_Property( gdef, s_in[j], flags, &property ) ) + { + if ( error && error != TTO_Err_Not_Covered ) + return error; + + if ( curr_pos + j < in->length ) + j++; + else + return TTO_Err_Not_Covered; + } + + error = Coverage_Index( &lc[i], s_in[j], &index ); + if ( error ) + return error; + } + + return Do_ContextSubst( gsub, igc, + ccsf3->SubstCount, + ccsf3->SubstLookupRecord, + in, out, + nesting_level ); + } + + + static TT_Error Lookup_ChainContextSubst( + TTO_GSUBHeader* gsub, + TTO_ChainContextSubst* ccs, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort flags, + UShort context_length, + int nesting_level ) + { + switch ( ccs->SubstFormat ) + { + case 1: + return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, in, out, + flags, context_length, + nesting_level ); + + case 2: + return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, in, out, + flags, context_length, + nesting_level ); + + case 3: + return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, in, out, + flags, context_length, + nesting_level ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + + /*********** + * GSUB API + ***********/ + + + EXPORT_FUNC + TT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub, + TT_ULong script_tag, + TT_UShort* script_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + + + if ( !gsub || !script_index ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + for ( n = 0; n < sl->ScriptCount; n++ ) + if ( script_tag == sr[n].ScriptTag ) + { + *script_index = n; + + return TT_Err_Ok; + } + + return TTO_Err_Not_Covered; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + + + if ( !gsub || !language_index || !req_feature_index ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + for ( n = 0; n < s->LangSysCount; n++ ) + if ( language_tag == lsr[n].LangSysTag ) + { + *language_index = n; + *req_feature_index = lsr[n].LangSys.ReqFeatureIndex; + + return TT_Err_Ok; + } + + return TTO_Err_Not_Covered; + } + + + /* selecting 0xFFFF for language_index asks for the values of the + default language (DefaultLangSys) */ + + EXPORT_FUNC + TT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ) + { + UShort n; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + TTO_LangSys* ls; + UShort* fi; + + TTO_FeatureList* fl; + TTO_FeatureRecord* fr; + + + if ( !gsub || !feature_index ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + fl = &gsub->FeatureList; + fr = fl->FeatureRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( language_index == 0xFFFF ) + ls = &s->DefaultLangSys; + else + { + if ( language_index >= s->LangSysCount ) + return TT_Err_Invalid_Argument; + + ls = &lsr[language_index].LangSys; + } + + fi = ls->FeatureIndex; + + for ( n = 0; n < ls->FeatureCount; n++ ) + { + if ( fi[n] >= fl->FeatureCount ) + return TTO_Err_Invalid_GSUB_SubTable_Format; + + if ( feature_tag == fr[fi[n]].FeatureTag ) + { + *feature_index = fi[n]; + + return TT_Err_Ok; + } + } + + return TTO_Err_Not_Covered; + } + + + /* The next three functions return a null-terminated list */ + + EXPORT_FUNC + TT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub, + TT_ULong** script_tag_list ) + { + UShort n; + TT_Error error; + ULong* stl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + + + if ( !gsub || !script_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, ULong ) ) + return error; + + for ( n = 0; n < sl->ScriptCount; n++ ) + stl[n] = sr[n].ScriptTag; + stl[n] = 0; + + *script_tag_list = stl; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_ULong** language_tag_list ) + { + UShort n; + TT_Error error; + ULong* ltl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + + + if ( !gsub || !language_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, ULong ) ) + return error; + + for ( n = 0; n < s->LangSysCount; n++ ) + ltl[n] = lsr[n].LangSysTag; + ltl[n] = 0; + + *language_tag_list = ltl; + + return TT_Err_Ok; + } + + + /* selecting 0xFFFF for language_index asks for the values of the + default language (DefaultLangSys) */ + + EXPORT_FUNC + TT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ) + { + UShort n; + TT_Error error; + ULong* ftl; + + TTO_ScriptList* sl; + TTO_ScriptRecord* sr; + TTO_Script* s; + TTO_LangSysRecord* lsr; + TTO_LangSys* ls; + UShort* fi; + + TTO_FeatureList* fl; + TTO_FeatureRecord* fr; + + + if ( !gsub || !feature_tag_list ) + return TT_Err_Invalid_Argument; + + sl = &gsub->ScriptList; + sr = sl->ScriptRecord; + + fl = &gsub->FeatureList; + fr = fl->FeatureRecord; + + if ( script_index >= sl->ScriptCount ) + return TT_Err_Invalid_Argument; + + s = &sr[script_index].Script; + lsr = s->LangSysRecord; + + if ( language_index == 0xFFFF ) + ls = &s->DefaultLangSys; + else + { + if ( language_index >= s->LangSysCount ) + return TT_Err_Invalid_Argument; + + ls = &lsr[language_index].LangSys; + } + + fi = ls->FeatureIndex; + + if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, ULong ) ) + return error; + + for ( n = 0; n < ls->FeatureCount; n++ ) + { + if ( fi[n] >= fl->FeatureCount ) + { + FREE( ftl ); + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + ftl[n] = fr[fi[n]].FeatureTag; + } + ftl[n] = 0; + + *feature_tag_list = ftl; + + return TT_Err_Ok; + } + + + /* Do an individual subtable lookup. Returns TT_Err_Ok if substitution + has been done, or TTO_Err_Not_Covered if not. */ + + static TT_Error Do_Glyph_Lookup( TTO_GSUBHeader* gsub, + UShort lookup_index, + TTO_GSUB_String* in, + TTO_GSUB_String* out, + UShort context_length, + int nesting_level ) + { + TT_Error error = TT_Err_Ok; + UShort i, flags; + TTO_Lookup* lo; + + + nesting_level++; + + if ( nesting_level > TTO_MAX_NESTING_LEVEL ) + return TTO_Err_Too_Many_Nested_Contexts; + + lo = &gsub->LookupList.Lookup[lookup_index]; + flags = lo->LookupFlag; + + for ( i = 0; i < lo->SubTableCount; i++ ) + { + switch ( lo->LookupType ) + { + case GSUB_LOOKUP_SINGLE: + error = Lookup_SingleSubst( &lo->SubTable[i].st.gsub.single, + in, out, + flags, context_length, gsub->gdef ); + break; + + case GSUB_LOOKUP_MULTIPLE: + error = Lookup_MultipleSubst( &lo->SubTable[i].st.gsub.multiple, + in, out, + flags, context_length, gsub->gdef ); + break; + + case GSUB_LOOKUP_ALTERNATE: + error = Lookup_AlternateSubst( gsub, + &lo->SubTable[i].st.gsub.alternate, + in, out, + flags, context_length, gsub->gdef ); + break; + + case GSUB_LOOKUP_LIGATURE: + error = Lookup_LigatureSubst( &lo->SubTable[i].st.gsub.ligature, + in, out, + flags, context_length, gsub->gdef ); + break; + + case GSUB_LOOKUP_CONTEXT: + error = Lookup_ContextSubst( gsub, &lo->SubTable[i].st.gsub.context, + in, out, + flags, context_length, nesting_level ); + break; + + case GSUB_LOOKUP_CHAIN: + error = Lookup_ChainContextSubst( gsub, + &lo->SubTable[i].st.gsub.chain, + in, out, + flags, context_length, + nesting_level ); + break; + } + + /* Check whether we have a successful substitution or an error other + than TTO_Err_Not_Covered */ + + if ( error != TTO_Err_Not_Covered ) + return error; + } + + return TTO_Err_Not_Covered; + } + + + /* apply one lookup to the input string object */ + + static TT_Error Do_String_Lookup( TTO_GSUBHeader* gsub, + UShort lookup_index, + TTO_GSUB_String* in, + TTO_GSUB_String* out ) + { + TT_Error error = TTO_Err_Not_Covered; + + UShort* properties = gsub->LookupList.Properties; + UShort* p_in = in->properties; + UShort* s_in = in->string; + + int nesting_level = 0; + + + while ( in->pos < in->length ) + { + if ( ~p_in[in->pos] & properties[lookup_index] ) + { + /* 0xFFFF indicates that we don't have a context length yet */ + error = Do_Glyph_Lookup( gsub, lookup_index, in, out, + 0xFFFF, nesting_level ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + } + else + error = TTO_Err_Not_Covered; + + if ( error == TTO_Err_Not_Covered ) + if ( ADD_String( in, 1, out, 1, &s_in[in->pos] ) ) + return error; + } + + return error; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub, + TT_UShort feature_index, + TT_UShort property ) + { + UShort i; + + TTO_Feature feature; + UShort* properties; + UShort* index; + + + if ( !gsub || + feature_index >= gsub->FeatureList.FeatureCount ) + return TT_Err_Invalid_Argument; + + properties = gsub->LookupList.Properties; + + feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; + index = feature.LookupListIndex; + + for ( i = 0; i < feature.LookupListCount; i++ ) + properties[index[i]] |= property; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub ) + { + UShort i; + + UShort* properties; + + + if ( !gsub ) + return TT_Err_Invalid_Argument; + + properties = gsub->LookupList.Properties; + + for ( i = 0; i < gsub->LookupList.LookupCount; i++ ) + properties[i] = 0; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub, + TTO_AltFunction alt, + void* data ) + { + if ( !gsub ) + return TT_Err_Invalid_Argument; + + gsub->alt = alt; + gsub->data = data; + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub, + TTO_GSUB_String* in, + TTO_GSUB_String* out ) + { + TT_Error error = TTO_Err_Not_Covered; + UShort j; + + TTO_GSUB_String tmp1; + TTO_GSUB_String* ptmp1; + TTO_GSUB_String tmp2; + TTO_GSUB_String* ptmp2; + TTO_GSUB_String* t; + + UShort* properties; + + + if ( !gsub || + !in || !out || in->length == 0 || in->pos >= in->length ) + return TT_Err_Invalid_Argument; + + properties = gsub->LookupList.Properties; + + tmp1.length = in->length; + tmp1.allocated = in->length; + tmp1.pos = in->pos; + + if ( ALLOC_ARRAY( tmp1.string, tmp1.length, UShort ) ) + return error; + MEM_Copy( tmp1.string, in->string, in->length * sizeof ( UShort ) ); + + /* make sure that we always have a `properties' array in the string + object */ + + if ( ALLOC_ARRAY( tmp1.properties, tmp1.length, UShort ) ) + return error; + if ( in->properties ) + MEM_Copy( tmp1.properties, in->properties, + in->length * sizeof( UShort ) ); + + tmp2.allocated = 0; + tmp2.pos = 0; + tmp2.string = NULL; + tmp2.properties = NULL; + + ptmp1 = &tmp1; + ptmp2 = &tmp2; + + for ( j = 0; j < gsub->LookupList.LookupCount; j++ ) + if ( properties[j] ) + { + error = Do_String_Lookup( gsub, j, ptmp1, ptmp2 ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + + /* flipping `in' and `out', preparing for the next loop */ + + ptmp1->pos = in->pos; + ptmp2->length = ptmp2->pos; + ptmp2->pos = in->pos; + + t = ptmp2; + ptmp2 = ptmp1; + ptmp1 = t; + } + + out->length = ptmp1->length; + out->pos = 0; + out->allocated = ptmp1->allocated; + out->string = ptmp1->string; + + if ( in->properties ) + out->properties = ptmp1->properties; + else + { + free( ptmp1->properties ); + out->properties = NULL; + } + + free( ptmp2->string ); + free( ptmp2->properties ); + + return error; + } + + +/* END */ diff --git a/lib/extend/ftxgsub.h b/lib/extend/ftxgsub.h new file mode 100644 index 0000000..b444c92 --- /dev/null +++ b/lib/extend/ftxgsub.h @@ -0,0 +1,581 @@ +/******************************************************************* + * + * ftxgsub.h + * + * TrueType Open GSUB table support + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FTXOPEN_H +#error "Don't include this file! Use ftxopen.h instead." +#endif + +#ifndef FTXGSUB_H +#define FTXGSUB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define TTO_Err_Invalid_GSUB_SubTable_Format 0x1010 +#define TTO_Err_Invalid_GSUB_SubTable 0x1011 + + +/* Lookup types for glyph substitution */ + +#define GSUB_LOOKUP_SINGLE 1 +#define GSUB_LOOKUP_MULTIPLE 2 +#define GSUB_LOOKUP_ALTERNATE 3 +#define GSUB_LOOKUP_LIGATURE 4 +#define GSUB_LOOKUP_CONTEXT 5 +#define GSUB_LOOKUP_CHAIN 6 + + +/* Use this if a feature applies to all glyphs */ + +#define ALL_GLYPHS 0xFFFF + + + /* A pointer to a function which selects the alternate glyph. `pos' is + the position of the glyph with index `glyphID', `num_alternates' + gives the number of alternates in the `alternates' array. `data' + points to the user-defined structure specified during a call to + TT_GSUB_Register_Alternate_Function(). The function must return an + index into the `alternates' array. */ + + typedef TT_UShort (*TTO_AltFunction)(TT_ULong pos, + TT_UShort glyphID, + TT_UShort num_alternates, + TT_UShort* alternates, + void* data ); + + + struct TTO_GSUBHeader_ + { + TT_Bool loaded; + TT_ULong offset; + + TT_Fixed Version; + + TTO_ScriptList ScriptList; + TTO_FeatureList FeatureList; + TTO_LookupList LookupList; + + TTO_GDEFHeader* gdef; + + /* the next two fields are used for an alternate substitution callback + function to select the proper alternate glyph. */ + + TTO_AltFunction alt; + void* data; + }; + + typedef struct TTO_GSUBHeader_ TTO_GSUBHeader; + + + /* LookupType 1 */ + + struct TTO_SingleSubstFormat1_ + { + TT_Short DeltaGlyphID; /* constant added to get + substitution glyph index */ + }; + + typedef struct TTO_SingleSubstFormat1_ TTO_SingleSubstFormat1; + + + struct TTO_SingleSubstFormat2_ + { + TT_UShort GlyphCount; /* number of glyph IDs in + Substitute array */ + TT_UShort* Substitute; /* array of substitute glyph IDs */ + }; + + typedef struct TTO_SingleSubstFormat2_ TTO_SingleSubstFormat2; + + + struct TTO_SingleSubst_ + { + TT_UShort SubstFormat; /* 1 or 2 */ + TTO_Coverage Coverage; /* Coverage table */ + + union + { + TTO_SingleSubstFormat1 ssf1; + TTO_SingleSubstFormat2 ssf2; + } ssf; + }; + + typedef struct TTO_SingleSubst_ TTO_SingleSubst; + + + /* LookupType 2 */ + + struct TTO_Sequence_ + { + TT_UShort GlyphCount; /* number of glyph IDs in the + Substitute array */ + TT_UShort* Substitute; /* string of glyph IDs to + substitute */ + }; + + typedef struct TTO_Sequence_ TTO_Sequence; + + + struct TTO_MultipleSubst_ + { + TT_UShort SubstFormat; /* always 1 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort SequenceCount; /* number of Sequence tables */ + TTO_Sequence* Sequence; /* array of Sequence tables */ + }; + + typedef struct TTO_MultipleSubst_ TTO_MultipleSubst; + + + /* LookupType 3 */ + + struct TTO_AlternateSet_ + { + TT_UShort GlyphCount; /* number of glyph IDs in the + Alternate array */ + TT_UShort* Alternate; /* array of alternate glyph IDs */ + }; + + typedef struct TTO_AlternateSet_ TTO_AlternateSet; + + + struct TTO_AlternateSubst_ + { + TT_UShort SubstFormat; /* always 1 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort AlternateSetCount; + /* number of AlternateSet tables */ + TTO_AlternateSet* AlternateSet; /* array of AlternateSet tables */ + }; + + typedef struct TTO_AlternateSubst_ TTO_AlternateSubst; + + + /* LookupType 4 */ + + struct TTO_Ligature_ + { + TT_UShort LigGlyph; /* glyphID of ligature + to substitute */ + TT_UShort ComponentCount; /* number of components in ligature */ + TT_UShort* Component; /* array of component glyph IDs */ + }; + + typedef struct TTO_Ligature_ TTO_Ligature; + + + struct TTO_LigatureSet_ + { + TT_UShort LigatureCount; /* number of Ligature tables */ + TTO_Ligature* Ligature; /* array of Ligature tables */ + }; + + typedef struct TTO_LigatureSet_ TTO_LigatureSet; + + + struct TTO_LigatureSubst_ + { + TT_UShort SubstFormat; /* always 1 */ + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort LigatureSetCount; /* number of LigatureSet tables */ + TTO_LigatureSet* LigatureSet; /* array of LigatureSet tables */ + }; + + typedef struct TTO_LigatureSubst_ TTO_LigatureSubst; + + + /* needed by both lookup type 5 and 6 */ + + struct TTO_SubstLookupRecord_ + { + TT_UShort SequenceIndex; /* index into current + glyph sequence */ + TT_UShort LookupListIndex; /* Lookup to apply to that pos. */ + }; + + typedef struct TTO_SubstLookupRecord_ TTO_SubstLookupRecord; + + + /* LookupType 5 */ + + struct TTO_SubRule_ + { + TT_UShort GlyphCount; /* total number of input glyphs */ + TT_UShort SubstCount; /* number of SubstLookupRecord + tables */ + TT_UShort* Input; /* array of input glyph IDs */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of SubstLookupRecord + tables */ + }; + + typedef struct TTO_SubRule_ TTO_SubRule; + + + struct TTO_SubRuleSet_ + { + TT_UShort SubRuleCount; /* number of SubRule tables */ + TTO_SubRule* SubRule; /* array of SubRule tables */ + }; + + typedef struct TTO_SubRuleSet_ TTO_SubRuleSet; + + + struct TTO_ContextSubstFormat1_ + { + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort SubRuleSetCount; /* number of SubRuleSet tables */ + TTO_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */ + }; + + typedef struct TTO_ContextSubstFormat1_ TTO_ContextSubstFormat1; + + + struct TTO_SubClassRule_ + { + TT_UShort GlyphCount; /* total number of context classes */ + TT_UShort SubstCount; /* number of SubstLookupRecord + tables */ + TT_UShort* Class; /* array of classes */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of SubstLookupRecord + tables */ + }; + + typedef struct TTO_SubClassRule_ TTO_SubClassRule; + + + struct TTO_SubClassSet_ + { + TT_UShort SubClassRuleCount; + /* number of SubClassRule tables */ + TTO_SubClassRule* SubClassRule; /* array of SubClassRule tables */ + }; + + typedef struct TTO_SubClassSet_ TTO_SubClassSet; + + + /* The `MaxContextLength' field is not defined in the TTO specification + but simplifies the implementation of this format. It holds the + maximal context length used in the context rules. */ + + struct TTO_ContextSubstFormat2_ + { + TT_UShort MaxContextLength; + /* maximal context length */ + TTO_Coverage Coverage; /* Coverage table */ + TTO_ClassDefinition ClassDef; /* ClassDef table */ + TT_UShort SubClassSetCount; + /* number of SubClassSet tables */ + TTO_SubClassSet* SubClassSet; /* array of SubClassSet tables */ + }; + + typedef struct TTO_ContextSubstFormat2_ TTO_ContextSubstFormat2; + + + struct TTO_ContextSubstFormat3_ + { + TT_UShort GlyphCount; /* number of input glyphs */ + TT_UShort SubstCount; /* number of SubstLookupRecords */ + TTO_Coverage* Coverage; /* array of Coverage tables */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ContextSubstFormat3_ TTO_ContextSubstFormat3; + + + struct TTO_ContextSubst_ + { + TT_UShort SubstFormat; /* 1, 2, or 3 */ + + union + { + TTO_ContextSubstFormat1 csf1; + TTO_ContextSubstFormat2 csf2; + TTO_ContextSubstFormat3 csf3; + } csf; + }; + + typedef struct TTO_ContextSubst_ TTO_ContextSubst; + + + /* LookupType 6 */ + + struct TTO_ChainSubRule_ + { + TT_UShort BacktrackGlyphCount; + /* total number of backtrack glyphs */ + TT_UShort* Backtrack; /* array of backtrack glyph IDs */ + TT_UShort InputGlyphCount; + /* total number of input glyphs */ + TT_UShort* Input; /* array of input glyph IDs */ + TT_UShort LookaheadGlyphCount; + /* total number of lookahead glyphs */ + TT_UShort* Lookahead; /* array of lookahead glyph IDs */ + TT_UShort SubstCount; /* number of SubstLookupRecords */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of SubstLookupRecords */ + }; + + typedef struct TTO_ChainSubRule_ TTO_ChainSubRule; + + + struct TTO_ChainSubRuleSet_ + { + TT_UShort ChainSubRuleCount; + /* number of ChainSubRule tables */ + TTO_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */ + }; + + typedef struct TTO_ChainSubRuleSet_ TTO_ChainSubRuleSet; + + + struct TTO_ChainContextSubstFormat1_ + { + TTO_Coverage Coverage; /* Coverage table */ + TT_UShort ChainSubRuleSetCount; + /* number of ChainSubRuleSet tables */ + TTO_ChainSubRuleSet* ChainSubRuleSet; + /* array of ChainSubRuleSet tables */ + }; + + typedef struct TTO_ChainContextSubstFormat1_ TTO_ChainContextSubstFormat1; + + + struct TTO_ChainSubClassRule_ + { + TT_UShort BacktrackGlyphCount; + /* total number of backtrack + classes */ + TT_UShort* Backtrack; /* array of backtrack classes */ + TT_UShort InputGlyphCount; + /* total number of context classes */ + TT_UShort* Input; /* array of context classes */ + TT_UShort LookaheadGlyphCount; + /* total number of lookahead + classes */ + TT_UShort* Lookahead; /* array of lookahead classes */ + TT_UShort SubstCount; /* number of SubstLookupRecords */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ChainSubClassRule_ TTO_ChainSubClassRule; + + + struct TTO_ChainSubClassSet_ + { + TT_UShort ChainSubClassRuleCount; + /* number of ChainSubClassRule + tables */ + TTO_ChainSubClassRule* ChainSubClassRule; + /* array of ChainSubClassRule + tables */ + }; + + typedef struct TTO_ChainSubClassSet_ TTO_ChainSubClassSet; + + + /* The `MaxXXXLength' fields are not defined in the TTO specification + but simplifies the implementation of this format. It holds the + maximal context length used in the specific context rules. */ + + struct TTO_ChainContextSubstFormat2_ + { + TTO_Coverage Coverage; /* Coverage table */ + + TT_UShort MaxBacktrackLength; + /* maximal backtrack length */ + TTO_ClassDefinition BacktrackClassDef; + /* BacktrackClassDef table */ + TT_UShort MaxInputLength; + /* maximal input length */ + TTO_ClassDefinition InputClassDef; + /* InputClassDef table */ + TT_UShort MaxLookaheadLength; + /* maximal lookahead length */ + TTO_ClassDefinition LookaheadClassDef; + /* LookaheadClassDef table */ + + TT_UShort ChainSubClassSetCount; + /* number of ChainSubClassSet + tables */ + TTO_ChainSubClassSet* ChainSubClassSet; + /* array of ChainSubClassSet + tables */ + }; + + typedef struct TTO_ChainContextSubstFormat2_ TTO_ChainContextSubstFormat2; + + + struct TTO_ChainContextSubstFormat3_ + { + TT_UShort BacktrackGlyphCount; + /* number of backtrack glyphs */ + TTO_Coverage* BacktrackCoverage; + /* array of backtrack Coverage + tables */ + TT_UShort InputGlyphCount; + /* number of input glyphs */ + TTO_Coverage* InputCoverage; + /* array of input coverage + tables */ + TT_UShort LookaheadGlyphCount; + /* number of lookahead glyphs */ + TTO_Coverage* LookaheadCoverage; + /* array of lookahead coverage + tables */ + TT_UShort SubstCount; /* number of SubstLookupRecords */ + TTO_SubstLookupRecord* SubstLookupRecord; + /* array of substitution lookups */ + }; + + typedef struct TTO_ChainContextSubstFormat3_ TTO_ChainContextSubstFormat3; + + + struct TTO_ChainContextSubst_ + { + TT_UShort SubstFormat; /* 1, 2, or 3 */ + + union + { + TTO_ChainContextSubstFormat1 ccsf1; + TTO_ChainContextSubstFormat2 ccsf2; + TTO_ChainContextSubstFormat3 ccsf3; + } ccsf; + }; + + typedef struct TTO_ChainContextSubst_ TTO_ChainContextSubst; + + + union TTO_GSUB_SubTable_ + { + TTO_SingleSubst single; + TTO_MultipleSubst multiple; + TTO_AlternateSubst alternate; + TTO_LigatureSubst ligature; + TTO_ContextSubst context; + TTO_ChainContextSubst chain; + }; + + typedef union TTO_GSUB_SubTable_ TTO_GSUB_SubTable; + + + /* A simple string object. It can both `send' and `receive' data. + In case of sending, `length' and `pos' will be used. In case of + receiving, `pos' points to the first free slot, and `allocated' + specifies the amount of allocated memory (and the `length' field + will be ignored). The routine TT_Add_String() will increase the + amount of memory if necessary. After end of receive, `length' + should be set to the value of `pos', and `pos' will be set to zero. + + `properties' (which is treated as a bit field) gives the glyph's + properties: If a certain bit is set for a glyph, the feature which + has the same bit set in its property value is applied. + + NEVER modify any elements of the structure! You should rather copy + its contents if necessary. + + TT_Add_String() will also handle allocation; you should use + free() in case you want to destroy the arrays in the object. */ + + struct TTO_GSUB_String_ + { + TT_ULong length; + TT_ULong pos; + TT_ULong allocated; + TT_UShort* string; + TT_UShort* properties; + }; + + typedef struct TTO_GSUB_String_ TTO_GSUB_String; + + + /* finally, the GSUB API */ + + EXPORT_DEF + TT_Error TT_Init_GSUB_Extension( TT_Engine engine ); + + EXPORT_DEF + TT_Error TT_Load_GSUB_Table( TT_Face face, + TTO_GSUBHeader* gsub, + TTO_GDEFHeader* gdef ); + + EXPORT_DEF + TT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub, + TT_ULong script_tag, + TT_UShort* script_index ); + EXPORT_DEF + TT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub, + TT_ULong language_tag, + TT_UShort script_index, + TT_UShort* language_index, + TT_UShort* req_feature_index ); + EXPORT_DEF + TT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub, + TT_ULong feature_tag, + TT_UShort script_index, + TT_UShort language_index, + TT_UShort* feature_index ); + + EXPORT_DEF + TT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub, + TT_ULong** script_tag_list ); + EXPORT_DEF + TT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_ULong** language_tag_list ); + EXPORT_DEF + TT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub, + TT_UShort script_index, + TT_UShort language_index, + TT_ULong** feature_tag_list ); + + EXPORT_DEF + TT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub, + TT_UShort feature_index, + TT_UShort property ); + EXPORT_DEF + TT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub ); + + EXPORT_DEF + TT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub, + TTO_AltFunction alt, + void* data ); + + EXPORT_DEF + TT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub, + TTO_GSUB_String* in, + TTO_GSUB_String* out ); + + EXPORT_DEF + TT_Error TT_GSUB_Add_String( TTO_GSUB_String* in, + TT_UShort num_in, + TTO_GSUB_String* out, + TT_UShort num_out, + TT_UShort* data ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXGSUB_H */ + + +/* END */ diff --git a/lib/extend/ftxkern.c b/lib/extend/ftxkern.c new file mode 100644 index 0000000..e2704ae --- /dev/null +++ b/lib/extend/ftxkern.c @@ -0,0 +1,564 @@ +/******************************************************************* + * + * ftxkern.c 1.0 + * + * Kerning support extension. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The kerning support is currently part of the engine extensions. + * + ******************************************************************/ + +#include "ftxkern.h" + +#include "ttextend.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttfile.h" +#include "ttobjs.h" +#include "ttload.h" /* For the macros */ +#include "tttags.h" + +/* Required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_any + +#define KERNING_ID Build_Extension_ID( 'k', 'e', 'r', 'n' ) + + +/******************************************************************* + * + * Function : SubTable_Load_0 + * + * Description : Loads a format 0 kerning subtable data. + * + * Input : kern0 pointer to the kerning subtable + * + * Output : error code + * + * Notes : - Assumes that the stream is already `used' + * + * - the file cursor must be set by the caller + * + * - in case of error, the function _must_ destroy + * the data it allocates! + * + ******************************************************************/ + + static TT_Error Subtable_Load_0( TT_Kern_0* kern0, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort num_pairs, n; + + + if ( ACCESS_Frame( 8L ) ) + return error; + + num_pairs = GET_UShort(); + kern0->nPairs = 0; + kern0->searchRange = GET_UShort(); + kern0->entrySelector = GET_UShort(); + kern0->rangeShift = GET_UShort(); + + /* we only set kern0->nPairs if the subtable has been loaded */ + + FORGET_Frame(); + + if ( ALLOC_ARRAY( kern0->pairs, num_pairs, TT_Kern_0_Pair ) ) + return error; + + if ( ACCESS_Frame( num_pairs * 6L ) ) + goto Fail; + + for ( n = 0; n < num_pairs; n++ ) + { + kern0->pairs[n].left = GET_UShort(); + kern0->pairs[n].right = GET_UShort(); + kern0->pairs[n].value = GET_UShort(); + + if ( kern0->pairs[n].left >= input->numGlyphs || + kern0->pairs[n].right >= input->numGlyphs ) + { + FORGET_Frame(); + error = TT_Err_Invalid_Kerning_Table; + goto Fail; + } + } + + FORGET_Frame(); + + /* we're ok, set the pairs count */ + kern0->nPairs = num_pairs; + + return TT_Err_Ok; + + Fail: + FREE( kern0->pairs ); + return error; + } + + +/******************************************************************* + * + * Function : SubTable_Load_2 + * + * Description : Loads a format 2 kerning subtable data. + * + * Input : kern2 pointer to the kerning subtable + * length subtable length. This is required as + * the subheader doesn't give any indication + * of the size of the `array' table. + * + * Output : error code + * + * Notes : - Assumes that the stream is already `used' + * + * - the file cursor must be set by the caller + * + * - in case of error, the function _must_ destroy + * the data it allocates! + * + ******************************************************************/ + + static TT_Error Subtable_Load_2( TT_Kern_2* kern2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + Long table_base; + + UShort left_offset, right_offset, array_offset; + ULong array_size; + UShort left_max, right_max, n; + + + /* record the table offset */ + table_base = FILE_Pos(); + + if ( ACCESS_Frame( 8L ) ) + return error; + + kern2->rowWidth = GET_UShort(); + left_offset = GET_UShort(); + right_offset = GET_UShort(); + array_offset = GET_UShort(); + + FORGET_Frame(); + + /* first load left and right glyph classes */ + + if ( FILE_Seek( table_base + left_offset ) || + ACCESS_Frame( 4L ) ) + return error; + + kern2->leftClass.firstGlyph = GET_UShort(); + kern2->leftClass.nGlyphs = GET_UShort(); + + FORGET_Frame(); + + if ( ALLOC_ARRAY( kern2->leftClass.classes, + kern2->leftClass.nGlyphs, + UShort ) ) + return error; + + /* load left offsets */ + + if ( ACCESS_Frame( kern2->leftClass.nGlyphs * 2L ) ) + goto Fail_Left; + + for ( n = 0; n < kern2->leftClass.nGlyphs; n++ ) + kern2->leftClass.classes[n] = GET_UShort(); + + FORGET_Frame(); + + /* right class */ + + if ( FILE_Seek( table_base + right_offset ) || + ACCESS_Frame( 4L ) ) + goto Fail_Left; + + kern2->rightClass.firstGlyph = GET_UShort(); + kern2->rightClass.nGlyphs = GET_UShort(); + + FORGET_Frame(); + + if ( ALLOC_ARRAY( kern2->rightClass.classes, + kern2->rightClass.nGlyphs, + UShort ) ) + goto Fail_Left; + + /* load right offsets */ + + if ( ACCESS_Frame( kern2->rightClass.nGlyphs * 2L ) ) + goto Fail_Right; + + for ( n = 0; n < kern2->rightClass.nGlyphs; n++ ) + kern2->rightClass.classes[n] = GET_UShort(); + + FORGET_Frame(); + + /* Now load the kerning array. We don't have its size, we */ + /* must compute it from what we know. */ + + /* We thus compute the maximum left and right offsets and */ + /* add them to get the array size. */ + + left_max = right_max = 0; + + for ( n = 0; n < kern2->leftClass.nGlyphs; n++ ) + left_max = MAX( left_max, kern2->leftClass.classes[n] ); + + for ( n = 0; n < kern2->rightClass.nGlyphs; n++ ) + right_max = MAX( right_max, kern2->leftClass.classes[n] ); + + array_size = left_max + right_max + 2; + + if ( ALLOC( kern2->array, array_size ) ) + goto Fail_Right; + + if ( ACCESS_Frame( array_size ) ) + goto Fail_Array; + + for ( n = 0; n < array_size/2; n++ ) + kern2->array[n] = GET_Short(); + + FORGET_Frame(); + + /* we're good now */ + + return TT_Err_Ok; + + Fail_Array: + FREE( kern2->array ); + + Fail_Right: + FREE( kern2->rightClass.classes ); + kern2->rightClass.nGlyphs = 0; + + Fail_Left: + FREE( kern2->leftClass.classes ); + kern2->leftClass.nGlyphs = 0; + + return error; + } + + +/******************************************************************* + * + * Function : Kerning_Create + * + * Description : Creates the kerning directory if a face is + * loaded. The tables however are loaded on + * demand to save space. + * + * Input : face pointer to the parent face object + * kern pointer to the extension's kerning field + * + * Output : error code + * + * Notes : as in all constructors, the memory allocated isn't + * released in case of failure. Rather, the task is left + * to the destructor (which is called if an error + * occurs during the loading of a face). + * + ******************************************************************/ + + static TT_Error Kerning_Create( void* ext, + PFace face ) + { + DEFINE_LOAD_LOCALS( face->stream ); + + TT_Kerning* kern = (TT_Kerning*)ext; + UShort num_tables; + Long table; + + TT_Kern_Subtable* sub; + + + /* by convention */ + if ( !kern ) + return TT_Err_Ok; + + /* Now load the kerning directory. We're called from the face */ + /* constructor. We thus need not use the stream. */ + + kern->version = 0; + kern->nTables = 0; + kern->tables = NULL; + + table = TT_LookUp_Table( face, TTAG_kern ); + if ( table < 0 ) + return TT_Err_Ok; /* The table is optional */ + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + kern->version = GET_UShort(); + num_tables = GET_UShort(); + + FORGET_Frame(); + + /* we don't set kern->nTables until we have allocated the array */ + + if ( ALLOC_ARRAY( kern->tables, num_tables, TT_Kern_Subtable ) ) + return error; + + kern->nTables = num_tables; + + /* now load the directory entries, but do _not_ load the tables ! */ + + sub = kern->tables; + + for ( table = 0; table < num_tables; table++ ) + { + if ( ACCESS_Frame( 6L ) ) + return error; + + sub->loaded = FALSE; /* redundant, but good to see */ + sub->version = GET_UShort(); + sub->length = GET_UShort() - 6; /* substract header length */ + sub->format = GET_Byte(); + sub->coverage = GET_Byte(); + + FORGET_Frame(); + + sub->offset = FILE_Pos(); + + /* now skip to the next table */ + + if ( FILE_Skip( sub->length ) ) + return error; + + sub++; + } + + /* that's fine, leave now */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Kerning_Destroy + * + * Description : Destroys all kerning information. + * + * Input : kern pointer to the extension's kerning field + * + * Output : error code + * + * Notes : This function is a destructor; it must be able + * to destroy partially built tables. + * + ******************************************************************/ + + static TT_Error Kerning_Destroy( void* ext, + PFace face ) + { + TT_Kerning* kern = (TT_Kerning*)ext; + TT_Kern_Subtable* sub; + UShort n; + + + /* by convention */ + if ( !kern ) + return TT_Err_Ok; + + if ( kern->nTables == 0 ) + return TT_Err_Ok; /* no tables to release */ + + /* scan the table directory and release loaded entries */ + + sub = kern->tables; + for ( n = 0; n < kern->nTables; n++ ) + { + if ( sub->loaded ) + { + switch ( sub->format ) + { + case 0: + FREE( sub->t.kern0.pairs ); + sub->t.kern0.nPairs = 0; + sub->t.kern0.searchRange = 0; + sub->t.kern0.entrySelector = 0; + sub->t.kern0.rangeShift = 0; + break; + + case 2: + FREE( sub->t.kern2.leftClass.classes ); + sub->t.kern2.leftClass.firstGlyph = 0; + sub->t.kern2.leftClass.nGlyphs = 0; + + FREE( sub->t.kern2.rightClass.classes ); + sub->t.kern2.rightClass.firstGlyph = 0; + sub->t.kern2.rightClass.nGlyphs = 0; + + FREE( sub->t.kern2.array ); + sub->t.kern2.rowWidth = 0; + break; + + default: + ; /* invalid subtable format - do nothing */ + } + + sub->loaded = FALSE; + sub->version = 0; + sub->offset = 0; + sub->length = 0; + sub->coverage = 0; + sub->format = 0; + } + sub++; + } + + FREE( kern->tables ); + kern->nTables = 0; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Kerning_Directory + * + * Description : Returns a given face's kerning directory. + * + * Input : face handle to the face object + * directory pointer to client's target directory + * + * Output : error code + * + * Notes : The kerning table directory is loaded with the face + * through the extension constructor. However, the kerning + * tables themselves are only loaded on demand, as they + * may represent a lot of data, unneeded by most uses of + * the engine. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Kerning_Directory( TT_Face face, + TT_Kerning* directory ) + { + PFace faze = HANDLE_Face( face ); + TT_Error error; + TT_Kerning* kerning; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + /* copy directory header */ + error = TT_Extension_Get( faze, KERNING_ID, (void**)&kerning ); + if ( !error ) + *directory = *kerning; + + return error; + } + + +/******************************************************************* + * + * Function : TT_Load_Kerning_Table + * + * Description : Loads a kerning table intro memory. + * + * Input : face face handle + * kern_index index in the face's kerning directory + * + * Output : error code + * + * Notes : + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Load_Kerning_Table( TT_Face face, + TT_UShort kern_index ) + { + TT_Error error; + TT_Stream stream; + + TT_Kerning* kern; + TT_Kern_Subtable* sub; + + + PFace faze = HANDLE_Face( face ); + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, KERNING_ID, (void**)&kern ); + if ( error ) + return error; + + if ( kern->nTables == 0 ) + return TT_Err_Table_Missing; + + if ( kern_index >= kern->nTables ) + return TT_Err_Invalid_Argument; + + sub = kern->tables + kern_index; + + if ( sub->format != 0 && sub->format != 2 ) + return TT_Err_Invalid_Kerning_Table_Format; + + /* now access stream */ + if ( USE_Stream( faze->stream, stream ) ) + return error; + + if ( FILE_Seek( sub->offset ) ) + goto Fail; + + if ( sub->format == 0 ) + error = Subtable_Load_0( &sub->t.kern0, faze ); + else if ( sub->format == 2 ) + error = Subtable_Load_2( &sub->t.kern2, faze ); + + if ( !error ) + sub->loaded = TRUE; + + Fail: + /* release stream */ + DONE_Stream( stream ); + + return error; + } + + + EXPORT_FUNC + TT_Error TT_Init_Kerning_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + error = TT_Register_Extension( _engine, + KERNING_ID, + sizeof ( TT_Kerning ), + Kerning_Create, + Kerning_Destroy ); + return error; + } + + +/* END */ diff --git a/lib/extend/ftxkern.h b/lib/extend/ftxkern.h new file mode 100644 index 0000000..06e221e --- /dev/null +++ b/lib/extend/ftxkern.h @@ -0,0 +1,181 @@ +/******************************************************************* + * + * ftxkern.h 1.0 + * + * High-Level API Kerning extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The kerning support is currently part of the engine extensions. + * + * This file should _not_ depend on engine internal types. + * + ******************************************************************/ + +#ifndef FTXKERN_H +#define FTXKERN_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* The kerning support in FreeType is minimal. This means that */ + /* we do not try to interpret the kerning data in any way to */ + /* `cook' it for a user application. This API lets you access */ + /* directly the kerning tables found in the TrueType file; it's */ + /* up to the client application to apply its own processing on */ + /* these. */ + + /* The reason for this is that we generally do not encourage */ + /* feature-bloat of the core engine. Moreover, not all */ + /* libraries or font servers really need kerning data, or all */ + /* formats of this data. */ + + /************** kerning error codes *****************************/ + + /* we choose the class 0x0A for our errors, this should not */ + /* match with any error code class used in any other extension */ + +#define TT_Err_Invalid_Kerning_Table_Format 0x0A00 +#define TT_Err_Invalid_Kerning_Table 0x0A01 + + + /********** structures definitions ******************************/ + + /* Remember that all types and function are accessible by client */ + /* applications in this section, and thus should have the `TT_' */ + /* prefix. */ + + /* format 0 kerning pair */ + + struct TT_Kern_0_Pair_ + { + TT_UShort left; /* index of left glyph in pair */ + TT_UShort right; /* index of right glyph in pair */ + TT_FWord value; /* kerning value */ + }; + + typedef struct TT_Kern_0_Pair_ TT_Kern_0_Pair; + + + /* format 0 kerning subtable */ + + struct TT_Kern_0_ + { + TT_UShort nPairs; /* number of kerning pairs */ + + TT_UShort searchRange; /* these values are defined by the TT spec */ + TT_UShort entrySelector; /* for table searchs. */ + TT_UShort rangeShift; + + TT_Kern_0_Pair* pairs; /* a table of nPairs `pairs' */ + }; + + typedef struct TT_Kern_0_ TT_Kern_0; + + + /* format 2 kerning glyph class */ + + struct TT_Kern_2_Class_ + { + TT_UShort firstGlyph; /* first glyph in range */ + TT_UShort nGlyphs; /* number of glyphs in range */ + TT_UShort* classes; /* a table giving for each ranged glyph */ + /* its class offset in the subtable pairs */ + /* two-dimensional array */ + }; + + typedef struct TT_Kern_2_Class_ TT_Kern_2_Class; + + + /* format 2 kerning subtable */ + + struct TT_Kern_2_ + { + TT_UShort rowWidth; /* length of one row in bytes */ + TT_Kern_2_Class leftClass; /* left class table */ + TT_Kern_2_Class rightClass; /* right class table */ + TT_FWord* array; /* 2-dimensional kerning values array */ + }; + + typedef struct TT_Kern_2_ TT_Kern_2; + + + /* kerning subtable */ + + struct TT_Kern_Subtable_ + { + TT_Bool loaded; /* boolean; indicates whether the table is */ + /* loaded */ + TT_UShort version; /* table version number */ + TT_Long offset; /* file offset of table */ + TT_UShort length; /* length of table, _excluding_ header */ + TT_Byte coverage; /* lower 8 bit of the coverage table entry */ + TT_Byte format; /* the subtable format, as found in the */ + /* higher 8 bits of the coverage table entry */ + union + { + TT_Kern_0 kern0; + TT_Kern_2 kern2; + } t; + }; + + typedef struct TT_Kern_Subtable_ TT_Kern_Subtable; + + + struct TT_Kerning_ + { + TT_UShort version; /* kern table version number. starts at 0 */ + TT_UShort nTables; /* number of tables */ + + TT_Kern_Subtable* tables; /* the kerning sub-tables */ + }; + + typedef struct TT_Kerning_ TT_Kerning; + + + + /***************** high-level API extension **************************/ + + /* Initialize Kerning extension, must be called after */ + /* TT_Init_FreeType(). There is no need for a finalizer */ + EXPORT_DEF + TT_Error TT_Init_Kerning_Extension( TT_Engine engine ); + + /* Note on the implemented mechanism: */ + + /* The kerning table directory is loaded with the face through the */ + /* extension constructor. However, the tables will only be loaded */ + /* on demand, as they may represent a lot of data, unnecessary to */ + /* most applications. */ + + /* Queries a pointer to the kerning directory for the face object */ + EXPORT_DEF + TT_Error TT_Get_Kerning_Directory( TT_Face face, + TT_Kerning* directory ); + + /* Load the kerning table number `kern_index' in the kerning */ + /* directory. The table will stay in memory until the `face' */ + /* face is destroyed. */ + EXPORT_DEF + TT_Error TT_Load_Kerning_Table( TT_Face face, + TT_UShort kern_index ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXKERN_H */ + + +/* END */ diff --git a/lib/extend/ftxopen.c b/lib/extend/ftxopen.c new file mode 100644 index 0000000..efe0c0f --- /dev/null +++ b/lib/extend/ftxopen.c @@ -0,0 +1,1439 @@ +/******************************************************************* + * + * ftxopen.c + * + * TrueType Open common table support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "tttypes.h" +#include "ttload.h" +#include "ttextend.h" +#include "ttmemory.h" +#include "ttfile.h" + +#include "ftxopen.h" +#include "ftxopenf.h" + + + /*************************** + * Script related functions + ***************************/ + + + /* LangSys */ + + static TT_Error Load_LangSys( TTO_LangSys* ls, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* fi; + + + if ( ACCESS_Frame( 6L ) ) + return error; + + ls->LookupOrderOffset = GET_UShort(); /* should be 0 */ + ls->ReqFeatureIndex = GET_UShort(); + count = ls->FeatureCount = GET_UShort(); + + FORGET_Frame(); + + ls->FeatureIndex = NULL; + + if ( ALLOC_ARRAY( ls->FeatureIndex, count, UShort ) ) + return error; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( ls->FeatureIndex ); + return error; + } + + fi = ls->FeatureIndex; + + for ( n = 0; n < count; n++ ) + fi[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_LangSys( TTO_LangSys* ls ) + { + FREE( ls->FeatureIndex ); + } + + + /* Script */ + + static TT_Error Load_Script( TTO_Script* s, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_LangSysRecord* lsr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + if ( new_offset != base_offset ) /* not a NULL offset */ + { + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LangSys( &s->DefaultLangSys, + input ) ) != TT_Err_Ok ) + return error; + (void)FILE_Seek( cur_offset ); + } + else + { + /* we create a DefaultLangSys table with no entries */ + + s->DefaultLangSys.LookupOrderOffset = 0; + s->DefaultLangSys.ReqFeatureIndex = 0xFFFF; + s->DefaultLangSys.FeatureCount = 0; + s->DefaultLangSys.FeatureIndex = NULL; + } + + if ( ACCESS_Frame( 2L ) ) + goto Fail2; + + count = s->LangSysCount = GET_UShort(); + + /* safety check; otherwise the official handling of TrueType Open + fonts won't work */ + + if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 ) + { + error = TTO_Err_Invalid_SubTable; + goto Fail2; + } + + FORGET_Frame(); + + s->LangSysRecord = NULL; + + if ( ALLOC_ARRAY( s->LangSysRecord, count, TTO_LangSysRecord ) ) + goto Fail2; + + lsr = s->LangSysRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 6L ) ) + goto Fail1; + + lsr[n].LangSysTag = GET_ULong(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_LangSys( &lsr[n].LangSys, input ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + for ( n = 0; n < count; n++ ) + Free_LangSys( &lsr[n].LangSys ); + + FREE( s->LangSysRecord ); + + Fail2: + Free_LangSys( &s->DefaultLangSys ); + return error; + } + + + static void Free_Script( TTO_Script* s ) + { + UShort n, count; + + TTO_LangSysRecord* lsr; + + + Free_LangSys( &s->DefaultLangSys ); + + if ( s->LangSysRecord ) + { + count = s->LangSysCount; + lsr = s->LangSysRecord; + + for ( n = 0; n < count; n++ ) + Free_LangSys( &lsr[n].LangSys ); + + FREE( lsr ); + } + } + + + /* ScriptList */ + + TT_Error Load_ScriptList( TTO_ScriptList* sl, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_ScriptRecord* sr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = sl->ScriptCount = GET_UShort(); + + FORGET_Frame(); + + sl->ScriptRecord = NULL; + + if ( ALLOC_ARRAY( sl->ScriptRecord, count, TTO_ScriptRecord ) ) + return error; + + sr = sl->ScriptRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 6L ) ) + goto Fail; + + sr[n].ScriptTag = GET_ULong(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Script( &sr[n].Script, input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_Script( &sr[n].Script ); + + FREE( sl->ScriptRecord ); + return error; + } + + + void Free_ScriptList( TTO_ScriptList* sl ) + { + UShort n, count; + + TTO_ScriptRecord* sr; + + + if ( sl->ScriptRecord ) + { + count = sl->ScriptCount; + sr = sl->ScriptRecord; + + for ( n = 0; n < count; n++ ) + Free_Script( &sr[n].Script ); + + FREE( sr ); + } + } + + + + /********************************* + * Feature List related functions + *********************************/ + + + /* Feature */ + + static TT_Error Load_Feature( TTO_Feature* f, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* lli; + + + if ( ACCESS_Frame( 4L ) ) + return error; + + f->FeatureParams = GET_UShort(); /* should be 0 */ + count = f->LookupListCount = GET_UShort(); + + FORGET_Frame(); + + f->LookupListIndex = NULL; + + if ( ALLOC_ARRAY( f->LookupListIndex, count, UShort ) ) + return error; + + lli = f->LookupListIndex; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( f->LookupListIndex ); + return error; + } + + for ( n = 0; n < count; n++ ) + lli[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_Feature( TTO_Feature* f ) + { + FREE( f->LookupListIndex ); + } + + + /* FeatureList */ + + TT_Error Load_FeatureList( TTO_FeatureList* fl, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_FeatureRecord* fr; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = fl->FeatureCount = GET_UShort(); + + FORGET_Frame(); + + fl->FeatureRecord = NULL; + + if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) ) + return error; + + fr = fl->FeatureRecord; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 6L ) ) + goto Fail; + + fr[n].FeatureTag = GET_ULong(); + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Feature( &fr[n].Feature, input ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_Feature( &fr[n].Feature ); + + FREE( fl->FeatureRecord ); + return error; + } + + + void Free_FeatureList( TTO_FeatureList* fl ) + { + UShort n, count; + + TTO_FeatureRecord* fr; + + + if ( fl->FeatureRecord ) + { + count = fl->FeatureCount; + fr = fl->FeatureRecord; + + for ( n = 0; n < count; n++ ) + Free_Feature( &fr[n].Feature ); + + FREE( fr ); + } + } + + + + /******************************** + * Lookup List related functions + ********************************/ + + /* the subroutines of the following two functions are defined in + ftxgsub.c and ftxgpos.c respectively */ + + + /* SubTable */ + + static TT_Error Load_SubTable( TTO_SubTable* st, + PFace input, + TTO_Type table_type, + UShort lookup_type ) + { + if ( table_type == GSUB ) + switch ( lookup_type ) + { + case GSUB_LOOKUP_SINGLE: + return Load_SingleSubst( &st->st.gsub.single, input ); + + case GSUB_LOOKUP_MULTIPLE: + return Load_MultipleSubst( &st->st.gsub.multiple, input ); + + case GSUB_LOOKUP_ALTERNATE: + return Load_AlternateSubst( &st->st.gsub.alternate, input ); + + case GSUB_LOOKUP_LIGATURE: + return Load_LigatureSubst( &st->st.gsub.ligature, input ); + + case GSUB_LOOKUP_CONTEXT: + return Load_ContextSubst( &st->st.gsub.context, input ); + + case GSUB_LOOKUP_CHAIN: + return Load_ChainContextSubst( &st->st.gsub.chain, input ); + + default: + return TTO_Err_Invalid_GSUB_SubTable_Format; + } + else + switch ( lookup_type ) + { + case GPOS_LOOKUP_SINGLE: + return Load_SinglePos( &st->st.gpos.single, input ); + + case GPOS_LOOKUP_PAIR: + return Load_PairPos( &st->st.gpos.pair, input ); + + case GPOS_LOOKUP_CURSIVE: + return Load_CursivePos( &st->st.gpos.cursive, input ); + + case GPOS_LOOKUP_MARKBASE: + return Load_MarkBasePos( &st->st.gpos.markbase, input ); + + case GPOS_LOOKUP_MARKLIG: + return Load_MarkLigPos( &st->st.gpos.marklig, input ); + + case GPOS_LOOKUP_MARKMARK: + return Load_MarkMarkPos( &st->st.gpos.markmark, input ); + + case GPOS_LOOKUP_CONTEXT: + return Load_ContextPos( &st->st.gpos.context, input ); + + case GPOS_LOOKUP_CHAIN: + return Load_ChainContextPos ( &st->st.gpos.chain, input ); + + default: + return TTO_Err_Invalid_GPOS_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + static void Free_SubTable( TTO_SubTable* st, + TTO_Type table_type, + UShort lookup_type ) + { + if ( table_type == GSUB ) + switch ( lookup_type ) + { + case GSUB_LOOKUP_SINGLE: + Free_SingleSubst( &st->st.gsub.single ); + break; + + case GSUB_LOOKUP_MULTIPLE: + Free_MultipleSubst( &st->st.gsub.multiple ); + break; + + case GSUB_LOOKUP_ALTERNATE: + Free_AlternateSubst( &st->st.gsub.alternate ); + break; + + case GSUB_LOOKUP_LIGATURE: + Free_LigatureSubst( &st->st.gsub.ligature ); + break; + + case GSUB_LOOKUP_CONTEXT: + Free_ContextSubst( &st->st.gsub.context ); + break; + + case GSUB_LOOKUP_CHAIN: + Free_ChainContextSubst( &st->st.gsub.chain ); + break; + } + else + switch ( lookup_type ) + { + case GPOS_LOOKUP_SINGLE: + Free_SinglePos( &st->st.gpos.single ); + break; + + case GPOS_LOOKUP_PAIR: + Free_PairPos( &st->st.gpos.pair ); + break; + + case GPOS_LOOKUP_CURSIVE: + Free_CursivePos( &st->st.gpos.cursive ); + break; + + case GPOS_LOOKUP_MARKBASE: + Free_MarkBasePos( &st->st.gpos.markbase ); + break; + + case GPOS_LOOKUP_MARKLIG: + Free_MarkLigPos( &st->st.gpos.marklig ); + break; + + case GPOS_LOOKUP_MARKMARK: + Free_MarkMarkPos( &st->st.gpos.markmark ); + break; + + case GPOS_LOOKUP_CONTEXT: + Free_ContextPos( &st->st.gpos.context ); + break; + + case GPOS_LOOKUP_CHAIN: + Free_ChainContextPos ( &st->st.gpos.chain ); + break; + } + } + + + /* Lookup */ + + static TT_Error Load_Lookup( TTO_Lookup* l, + PFace input, + TTO_Type type ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_SubTable* st; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 6L ) ) + return error; + + l->LookupType = GET_UShort(); + l->LookupFlag = GET_UShort(); + count = l->SubTableCount = GET_UShort(); + + FORGET_Frame(); + + l->SubTable = NULL; + + if ( ALLOC_ARRAY( l->SubTable, count, TTO_SubTable ) ) + return error; + + st = l->SubTable; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_SubTable( &st[n], input, + type, l->LookupType ) ) != TT_Err_Ok ) + goto Fail; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < count; n++ ) + Free_SubTable( &st[n], type, l->LookupType ); + + FREE( l->SubTable ); + return error; + } + + + static void Free_Lookup( TTO_Lookup* l, + TTO_Type type ) + { + UShort n, count; + + TTO_SubTable* st; + + + if ( l->SubTable ) + { + count = l->SubTableCount; + st = l->SubTable; + + for ( n = 0; n < count; n++ ) + Free_SubTable( &st[n], type, l->LookupType ); + + FREE( st ); + } + } + + + /* LookupList */ + + TT_Error Load_LookupList( TTO_LookupList* ll, + PFace input, + TTO_Type type ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + ULong cur_offset, new_offset, base_offset; + + TTO_Lookup* l; + + + base_offset = FILE_Pos(); + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = ll->LookupCount = GET_UShort(); + + FORGET_Frame(); + + ll->Lookup = NULL; + + if ( ALLOC_ARRAY( ll->Lookup, count, TTO_Lookup ) ) + return error; + if ( ALLOC_ARRAY( ll->Properties, count, UShort ) ) + goto Fail2; + + l = ll->Lookup; + + for ( n = 0; n < count; n++ ) + { + if ( ACCESS_Frame( 2L ) ) + goto Fail1; + + new_offset = GET_UShort() + base_offset; + + FORGET_Frame(); + + cur_offset = FILE_Pos(); + if ( FILE_Seek( new_offset ) || + ( error = Load_Lookup( &l[n], input, type ) ) != TT_Err_Ok ) + goto Fail1; + (void)FILE_Seek( cur_offset ); + } + + return TT_Err_Ok; + + Fail1: + FREE( ll->Properties ); + + for ( n = 0; n < count; n++ ) + Free_Lookup( &l[n], type ); + + Fail2: + FREE( ll->Lookup ); + return error; + } + + + void Free_LookupList( TTO_LookupList* ll, + TTO_Type type ) + { + UShort n, count; + + TTO_Lookup* l; + + + FREE( ll->Properties ); + + if ( ll->Lookup ) + { + count = ll->LookupCount; + l = ll->Lookup; + + for ( n = 0; n < count; n++ ) + Free_Lookup( &l[n], type ); + + FREE( l ); + } + } + + + + /***************************** + * Coverage related functions + *****************************/ + + + /* CoverageFormat1 */ + + static TT_Error Load_Coverage1( TTO_CoverageFormat1* cf1, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* ga; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cf1->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + cf1->GlyphArray = NULL; + + if ( ALLOC_ARRAY( cf1->GlyphArray, count, UShort ) ) + return error; + + ga = cf1->GlyphArray; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( cf1->GlyphArray ); + return error; + } + + for ( n = 0; n < count; n++ ) + ga[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + static void Free_Coverage1( TTO_CoverageFormat1* cf1 ) + { + FREE( cf1->GlyphArray ); + } + + + /* CoverageFormat2 */ + + static TT_Error Load_Coverage2( TTO_CoverageFormat2* cf2, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + TTO_RangeRecord* rr; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cf2->RangeCount = GET_UShort(); + + FORGET_Frame(); + + cf2->RangeRecord = NULL; + + if ( ALLOC_ARRAY( cf2->RangeRecord, count, TTO_RangeRecord ) ) + return error; + + rr = cf2->RangeRecord; + + if ( ACCESS_Frame( count * 6L ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + { + rr[n].Start = GET_UShort(); + rr[n].End = GET_UShort(); + rr[n].StartCoverageIndex = GET_UShort(); + + /* sanity check; we are limited to 16bit integers */ + if ( rr[n].Start > rr[n].End || + ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >= + 0x10000L ) + { + error = TTO_Err_Invalid_SubTable; + goto Fail; + } + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail: + FREE( cf2->RangeRecord ); + return error; + } + + + static void Free_Coverage2( TTO_CoverageFormat2* cf2 ) + { + FREE( cf2->RangeRecord ); + } + + + TT_Error Load_Coverage( TTO_Coverage* c, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ACCESS_Frame( 2L ) ) + return error; + + c->CoverageFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( c->CoverageFormat ) + { + case 1: + return Load_Coverage1( &c->cf.cf1, input ); + + case 2: + return Load_Coverage2( &c->cf.cf2, input ); + + default: + return TTO_Err_Invalid_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + void Free_Coverage( TTO_Coverage* c ) + { + switch ( c->CoverageFormat ) + { + case 1: + Free_Coverage1( &c->cf.cf1 ); + break; + + case 2: + Free_Coverage2( &c->cf.cf2 ); + break; + } + } + + + static TT_Error Coverage_Index1( TTO_CoverageFormat1* cf1, + UShort glyphID, + UShort* index ) + { + UShort min, max, new_min, new_max, middle; + + UShort* array = cf1->GlyphArray; + + + /* binary search */ + + new_min = 0; + new_max = cf1->GlyphCount - 1; + + do + { + min = new_min; + max = new_max; + + /* we use (min + max) / 2 = max - (max - min) / 2 to avoid + overflow and rounding errors */ + + middle = max - ( ( max - min ) >> 1 ); + + if ( glyphID == array[middle] ) + { + *index = middle; + return TT_Err_Ok; + } + else if ( glyphID < array[middle] ) + { + if ( middle == min ) + break; + new_max = middle - 1; + } + else + { + if ( middle == max ) + break; + new_min = middle + 1; + } + } while ( min < max ); + + return TTO_Err_Not_Covered; + } + + + static TT_Error Coverage_Index2( TTO_CoverageFormat2* cf2, + UShort glyphID, + UShort* index ) + { + UShort min, max, new_min, new_max, middle; + + TTO_RangeRecord* rr = cf2->RangeRecord; + + + /* binary search */ + + new_min = 0; + new_max = cf2->RangeCount - 1; + + do + { + min = new_min; + max = new_max; + + /* we use (min + max) / 2 = max - (max - min) / 2 to avoid + overflow and rounding errors */ + + middle = max - ( ( max - min ) >> 1 ); + + if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End ) + { + *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start; + return TT_Err_Ok; + } + else if ( glyphID < rr[middle].Start ) + { + if ( middle == min ) + break; + new_max = middle - 1; + } + else + { + if ( middle == max ) + break; + new_min = middle + 1; + } + } while ( min < max ); + + return TTO_Err_Not_Covered; + } + + + TT_Error Coverage_Index( TTO_Coverage* c, + UShort glyphID, + UShort* index ) + { + switch ( c->CoverageFormat ) + { + case 1: + return Coverage_Index1( &c->cf.cf1, glyphID, index ); + + case 2: + return Coverage_Index2( &c->cf.cf2, glyphID, index ); + + default: + return TTO_Err_Invalid_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + + /************************************* + * Class Definition related functions + *************************************/ + + + /* ClassDefFormat1 */ + + static TT_Error Load_ClassDef1( TTO_ClassDefinition* cd, + UShort limit, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* cva; + Bool* d; + + TTO_ClassDefFormat1* cdf1; + + + cdf1 = &cd->cd.cd1; + + if ( ACCESS_Frame( 4L ) ) + return error; + + cdf1->StartGlyph = GET_UShort(); + count = cdf1->GlyphCount = GET_UShort(); + + FORGET_Frame(); + + /* sanity check; we are limited to 16bit integers */ + + if ( cdf1->StartGlyph + (long)count >= 0x10000L ) + return TTO_Err_Invalid_SubTable; + + cdf1->ClassValueArray = NULL; + + if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, UShort ) ) + return error; + + d = cd->Defined; + cva = cdf1->ClassValueArray; + + if ( ACCESS_Frame( count * 2L ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + { + cva[n] = GET_UShort(); + if ( cva[n] >= limit ) + { + error = TTO_Err_Invalid_SubTable; + goto Fail; + } + d[cva[n]] = TRUE; + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail: + FREE( cva ); + + return error; + } + + + static void Free_ClassDef1( TTO_ClassDefFormat1* cdf1 ) + { + FREE( cdf1->ClassValueArray ); + } + + + /* ClassDefFormat2 */ + + static TT_Error Load_ClassDef2 ( TTO_ClassDefinition* cd, + UShort limit, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + TTO_ClassRangeRecord* crr; + Bool* d; + + TTO_ClassDefFormat2* cdf2; + + + cdf2 = &cd->cd.cd2; + + if ( ACCESS_Frame( 2L ) ) + return error; + + count = cdf2->ClassRangeCount = GET_UShort(); + + FORGET_Frame(); + + cdf2->ClassRangeRecord = NULL; + + if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, TTO_ClassRangeRecord ) ) + return error; + + d = cd->Defined; + crr = cdf2->ClassRangeRecord; + + if ( ACCESS_Frame( count * 6L ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + { + crr[n].Start = GET_UShort(); + crr[n].End = GET_UShort(); + crr[n].Class = GET_UShort(); + + /* sanity check */ + + if ( crr[n].Start > crr[n].End || + crr[n].Class >= limit ) + { + error = TTO_Err_Invalid_SubTable; + goto Fail; + } + d[crr[n].Class] = TRUE; + } + + FORGET_Frame(); + + return TT_Err_Ok; + + Fail: + FREE( crr ); + + return error; + } + + + static void Free_ClassDef2( TTO_ClassDefFormat2* cdf2 ) + { + FREE( cdf2->ClassRangeRecord ); + } + + + /* ClassDefinition */ + + TT_Error Load_ClassDefinition( TTO_ClassDefinition* cd, + UShort limit, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + + if ( ALLOC_ARRAY( cd->Defined, limit, Bool ) ) + return error; + + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + cd->ClassFormat = GET_UShort(); + + FORGET_Frame(); + + switch ( cd->ClassFormat ) + { + case 1: + error = Load_ClassDef1( cd, limit, input ); + break; + + case 2: + error = Load_ClassDef2( cd, limit, input ); + break; + + default: + error = TTO_Err_Invalid_SubTable_Format; + break; + } + + if ( error ) + goto Fail; + + cd->loaded = TRUE; + + return TT_Err_Ok; + + Fail: + FREE( cd->Defined ); + return error; + } + + + void Free_ClassDefinition( TTO_ClassDefinition* cd ) + { + if ( !cd->loaded ) + return; + + FREE( cd->Defined ); + + switch ( cd->ClassFormat ) + { + case 1: + Free_ClassDef1( &cd->cd.cd1 ); + break; + + case 2: + Free_ClassDef2( &cd->cd.cd2 ); + break; + } + } + + + static TT_Error Get_Class1( TTO_ClassDefFormat1* cdf1, + UShort glyphID, + UShort* class, + UShort* index ) + { + UShort* cva = cdf1->ClassValueArray; + + + *index = 0; + + if ( glyphID >= cdf1->StartGlyph && + glyphID <= cdf1->StartGlyph + cdf1->GlyphCount ) + { + *class = cva[glyphID - cdf1->StartGlyph]; + return TT_Err_Ok; + } + else + { + *class = 0; + return TTO_Err_Not_Covered; + } + } + + + /* we need the index value of the last searched class range record + in case of failure for constructed GDEF tables */ + + static TT_Error Get_Class2( TTO_ClassDefFormat2* cdf2, + UShort glyphID, + UShort* class, + UShort* index ) + { + TT_Error error = TT_Err_Ok; + UShort min, max, new_min, new_max, middle; + + TTO_ClassRangeRecord* crr = cdf2->ClassRangeRecord; + + + /* binary search */ + + new_min = 0; + new_max = cdf2->ClassRangeCount - 1; + + do + { + min = new_min; + max = new_max; + + /* we use (min + max) / 2 = max - (max - min) / 2 to avoid + overflow and rounding errors */ + + middle = max - ( ( max - min ) >> 1 ); + + if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End ) + { + *class = crr[middle].Class; + error = TT_Err_Ok; + break; + } + else if ( glyphID < crr[middle].Start ) + { + if ( middle == min ) + { + *class = 0; + error = TTO_Err_Not_Covered; + break; + } + new_max = middle - 1; + } + else + { + if ( middle == max ) + { + *class = 0; + error = TTO_Err_Not_Covered; + break; + } + new_min = middle + 1; + } + } while ( min < max ); + + if ( index ) + *index = middle; + + return error; + } + + + TT_Error Get_Class( TTO_ClassDefinition* cd, + UShort glyphID, + UShort* class, + UShort* index ) + { + switch ( cd->ClassFormat ) + { + case 1: + return Get_Class1( &cd->cd.cd1, glyphID, class, index ); + + case 2: + return Get_Class2( &cd->cd.cd2, glyphID, class, index ); + + default: + return TTO_Err_Invalid_SubTable_Format; + } + + return TT_Err_Ok; /* never reached */ + } + + + + /*************************** + * Device related functions + ***************************/ + + + TT_Error Load_Device( TTO_Device* d, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, count; + + UShort* dv; + + + if ( ACCESS_Frame( 6L ) ) + return error; + + d->StartSize = GET_UShort(); + d->EndSize = GET_UShort(); + d->DeltaFormat = GET_UShort(); + + FORGET_Frame(); + + if ( d->StartSize > d->EndSize || + d->DeltaFormat == 0 || d->DeltaFormat > 3 ) + return TTO_Err_Invalid_SubTable; + + d->DeltaValue = NULL; + + count = ( ( d->EndSize - d->StartSize + 1 ) >> + ( 4 - d->DeltaFormat ) ) + 1; + + if ( ALLOC_ARRAY( d->DeltaValue, count, UShort ) ) + return error; + + if ( ACCESS_Frame( count * 2L ) ) + { + FREE( d->DeltaValue ); + return error; + } + + dv = d->DeltaValue; + + for ( n = 0; n < count; n++ ) + dv[n] = GET_UShort(); + + FORGET_Frame(); + + return TT_Err_Ok; + } + + + void Free_Device( TTO_Device* d ) + { + FREE( d->DeltaValue ); + } + + + /* Since we have the delta values stored in compressed form, we must + uncompress it now. To simplify the interface, the function always + returns a meaningful value in `value'; the error is just for + information. + | + format = 1: 0011223344556677|8899101112131415|... + | + byte 1 byte 2 + + 00: (byte >> 14) & mask + 11: (byte >> 12) & mask + ... + + mask = 0x0003 + | + format = 2: 0000111122223333|4444555566667777|... + | + byte 1 byte 2 + + 0000: (byte >> 12) & mask + 1111: (byte >> 8) & mask + ... + + mask = 0x000F + | + format = 3: 0000000011111111|2222222233333333|... + | + byte 1 byte 2 + + 00000000: (byte >> 8) & mask + 11111111: (byte >> 0) & mask + .... + + mask = 0x00FF */ + + TT_Error Get_Device( TTO_Device* d, + UShort size, + Short* value ) + { + UShort byte, bits, mask, f, s; + + + f = d->DeltaFormat; + + if ( size >= d->StartSize && size <= d->EndSize ) + { + s = size - d->StartSize; + byte = d->DeltaValue[s >> ( 4 - f )]; + bits = byte >> ( 16 - ( s % ( 1 << ( 4 - f ) ) + 1 ) * ( 1 << f ) ); + mask = 0xFFFF >> ( 16 - ( 1 << f ) ); + + *value = (Short)( bits & mask ); + + /* conversion to a signed value */ + + if ( *value >= ( ( mask + 1 ) >> 1 ) ) + *value -= mask + 1; + + return TT_Err_Ok; + } + else + { + *value = 0; + return TTO_Err_Not_Covered; + } + } + + +/* END */ diff --git a/lib/extend/ftxopen.h b/lib/extend/ftxopen.h new file mode 100644 index 0000000..861fcdd --- /dev/null +++ b/lib/extend/ftxopen.h @@ -0,0 +1,304 @@ +/******************************************************************* + * + * ftxopen.h + * + * TrueType Open support. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * This file should be included by the application. Nevertheless, + * the table specific APIs (and structures) are located in files like + * ftxgsub.h or ftxgpos.h; these header files are read by ftxopen.h . + * + ******************************************************************/ + +#ifndef FTXOPEN_H +#define FTXOPEN_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TTO_MAX_NESTING_LEVEL 100 + +#define TTO_Err_Invalid_SubTable_Format 0x1000 +#define TTO_Err_Invalid_SubTable 0x1001 +#define TTO_Err_Not_Covered 0x1002 +#define TTO_Err_Too_Many_Nested_Contexts 0x1003 + + + /* Script list related structures */ + + struct TTO_LangSys_ + { + TT_UShort LookupOrderOffset; /* always 0 for TT Open 1.0 */ + TT_UShort ReqFeatureIndex; /* required FeatureIndex */ + TT_UShort FeatureCount; /* number of Feature indices */ + TT_UShort* FeatureIndex; /* array of Feature indices */ + }; + + typedef struct TTO_LangSys_ TTO_LangSys; + + + struct TTO_LangSysRecord_ + { + TT_ULong LangSysTag; /* LangSysTag identifier */ + TTO_LangSys LangSys; /* LangSys table */ + }; + + typedef struct TTO_LangSysRecord_ TTO_LangSysRecord; + + + struct TTO_Script_ + { + TTO_LangSys DefaultLangSys; /* DefaultLangSys table */ + TT_UShort LangSysCount; /* number of LangSysRecords */ + TTO_LangSysRecord* LangSysRecord; /* array of LangSysRecords */ + }; + + typedef struct TTO_Script_ TTO_Script; + + + struct TTO_ScriptRecord_ + { + TT_ULong ScriptTag; /* ScriptTag identifier */ + TTO_Script Script; /* Script table */ + }; + + typedef struct TTO_ScriptRecord_ TTO_ScriptRecord; + + + struct TTO_ScriptList_ + { + TT_UShort ScriptCount; /* number of ScriptRecords */ + TTO_ScriptRecord* ScriptRecord; /* array of ScriptRecords */ + }; + + typedef struct TTO_ScriptList_ TTO_ScriptList; + + + /* Feature list related structures */ + + struct TTO_Feature_ + { + TT_UShort FeatureParams; /* always 0 for TT Open 1.0 */ + TT_UShort LookupListCount; /* number of LookupList indices */ + TT_UShort* LookupListIndex; /* array of LookupList indices */ + }; + + typedef struct TTO_Feature_ TTO_Feature; + + + struct TTO_FeatureRecord_ + { + TT_ULong FeatureTag; /* FeatureTag identifier */ + TTO_Feature Feature; /* Feature table */ + }; + + typedef struct TTO_FeatureRecord_ TTO_FeatureRecord; + + + struct TTO_FeatureList_ + { + TT_UShort FeatureCount; /* number of FeatureRecords */ + TTO_FeatureRecord* FeatureRecord; /* array of FeatureRecords */ + }; + + typedef struct TTO_FeatureList_ TTO_FeatureList; + + + /* Lookup list related structures */ + + struct TTO_SubTable_; /* defined below after inclusion + of ftxgsub.h and ftxgpos.h */ + typedef struct TTO_SubTable_ TTO_SubTable; + + + struct TTO_Lookup_ + { + TT_UShort LookupType; /* Lookup type */ + TT_UShort LookupFlag; /* Lookup qualifiers */ + TT_UShort SubTableCount; /* number of SubTables */ + TTO_SubTable* SubTable; /* array of SubTables */ + }; + + typedef struct TTO_Lookup_ TTO_Lookup; + + + /* The `Properties' field is not defined in the TTO specification but + is needed for processing lookups. If properties[n] is > 0, the + function TT_GSUB_Apply() will process Lookup[n] for glyphs which + have the specific bit not set in the `properties' field of the + input string object. */ + + struct TTO_LookupList_ + { + TT_UShort LookupCount; /* number of Lookups */ + TTO_Lookup* Lookup; /* array of Lookup records */ + TT_UShort* Properties; /* array of flags */ + }; + + typedef struct TTO_LookupList_ TTO_LookupList; + + +/* Possible LookupFlag bit masks. `IGNORE_SPECIAL_MARKS' comes from the + OpenType 1.2 specification. */ + +#define IGNORE_BASE_GLYPHS 0x0002 +#define IGNORE_LIGATURES 0x0004 +#define IGNORE_MARKS 0x0008 +#define IGNORE_SPECIAL_MARKS 0xFF00 + + + struct TTO_CoverageFormat1_ + { + TT_UShort GlyphCount; /* number of glyphs in GlyphArray */ + TT_UShort* GlyphArray; /* array of glyph IDs */ + }; + + typedef struct TTO_CoverageFormat1_ TTO_CoverageFormat1; + + + struct TTO_RangeRecord_ + { + TT_UShort Start; /* first glyph ID in the range */ + TT_UShort End; /* last glyph ID in the range */ + TT_UShort StartCoverageIndex; /* coverage index of first + glyph ID in the range */ + }; + + typedef struct TTO_RangeRecord_ TTO_RangeRecord; + + + struct TTO_CoverageFormat2_ + { + TT_UShort RangeCount; /* number of RangeRecords */ + TTO_RangeRecord* RangeRecord; /* array of RangeRecords */ + }; + + typedef struct TTO_CoverageFormat2_ TTO_CoverageFormat2; + + + struct TTO_Coverage_ + { + TT_UShort CoverageFormat; /* 1 or 2 */ + + union + { + TTO_CoverageFormat1 cf1; + TTO_CoverageFormat2 cf2; + } cf; + }; + + typedef struct TTO_Coverage_ TTO_Coverage; + + + struct TTO_ClassDefFormat1_ + { + TT_UShort StartGlyph; /* first glyph ID of the + ClassValueArray */ + TT_UShort GlyphCount; /* size of the ClassValueArray */ + TT_UShort* ClassValueArray; /* array of class values */ + }; + + typedef struct TTO_ClassDefFormat1_ TTO_ClassDefFormat1; + + + struct TTO_ClassRangeRecord_ + { + TT_UShort Start; /* first glyph ID in the range */ + TT_UShort End; /* last glyph ID in the range */ + TT_UShort Class; /* applied to all glyphs in range */ + }; + + typedef struct TTO_ClassRangeRecord_ TTO_ClassRangeRecord; + + + struct TTO_ClassDefFormat2_ + { + TT_UShort ClassRangeCount; + /* number of ClassRangeRecords */ + TTO_ClassRangeRecord* ClassRangeRecord; + /* array of ClassRangeRecords */ + }; + + typedef struct TTO_ClassDefFormat2_ TTO_ClassDefFormat2; + + + /* The `Defined' field is not defined in the TTO specification but + apparently needed for processing fonts like trado.ttf: This font + refers to a class which contains not a single element. We map such + classes to class 0. */ + + struct TTO_ClassDefinition_ + { + TT_Bool loaded; + + TT_Bool* Defined; /* array of Booleans. + If Defined[n] is FALSE, + class n contains no glyphs. */ + TT_UShort ClassFormat; /* 1 or 2 */ + + union + { + TTO_ClassDefFormat1 cd1; + TTO_ClassDefFormat2 cd2; + } cd; + }; + + typedef struct TTO_ClassDefinition_ TTO_ClassDefinition; + + + struct TTO_Device_ + { + TT_UShort StartSize; /* smallest size to correct */ + TT_UShort EndSize; /* largest size to correct */ + TT_UShort DeltaFormat; /* DeltaValue array data format: + 1, 2, or 3 */ + TT_UShort* DeltaValue; /* array of compressed data */ + }; + + typedef struct TTO_Device_ TTO_Device; + + +#include "ftxgdef.h" +#include "ftxgsub.h" +#include "ftxgpos.h" + + + struct TTO_SubTable_ + { + union + { + TTO_GSUB_SubTable gsub; + TTO_GPOS_SubTable gpos; + } st; + }; + + + enum TTO_Type_ + { + GSUB, + GPOS + }; + + typedef enum TTO_Type_ TTO_Type; + + +#ifdef __cplusplus +} +#endif + +#endif /* FTXOPEN_H */ + + +/* END */ diff --git a/lib/extend/ftxopenf.h b/lib/extend/ftxopenf.h new file mode 100644 index 0000000..ea349af --- /dev/null +++ b/lib/extend/ftxopenf.h @@ -0,0 +1,135 @@ +/******************************************************************* + * + * ftxopenf.h + * + * internal TrueType Open functions + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FTXOPENF_H +#define FTXOPENF_H + +#include "ftxopen.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* functions from ftxopen.c */ + + TT_Error Load_ScriptList( TTO_ScriptList* sl, + PFace input ); + TT_Error Load_FeatureList( TTO_FeatureList* fl, + PFace input ); + TT_Error Load_LookupList( TTO_LookupList* ll, + PFace input, + TTO_Type type ); + + TT_Error Load_Coverage( TTO_Coverage* c, + PFace input ); + TT_Error Load_ClassDefinition( TTO_ClassDefinition* cd, + UShort limit, + PFace input ); + TT_Error Load_Device( TTO_Device* d, + PFace input ); + + void Free_ScriptList( TTO_ScriptList* sl ); + void Free_FeatureList( TTO_FeatureList* fl ); + void Free_LookupList( TTO_LookupList* ll, + TTO_Type type ); + + void Free_Coverage( TTO_Coverage* c ); + void Free_ClassDefinition( TTO_ClassDefinition* cd ); + void Free_Device( TTO_Device* d ); + + + /* functions from ftxgsub.c */ + + TT_Error Load_SingleSubst( TTO_SingleSubst* ss, + PFace input ); + TT_Error Load_MultipleSubst( TTO_MultipleSubst* ms, + PFace input ); + TT_Error Load_AlternateSubst( TTO_AlternateSubst* as, + PFace input ); + TT_Error Load_LigatureSubst( TTO_LigatureSubst* ls, + PFace input ); + TT_Error Load_ContextSubst( TTO_ContextSubst* cs, + PFace input ); + TT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs, + PFace input ); + + void Free_SingleSubst( TTO_SingleSubst* ss ); + void Free_MultipleSubst( TTO_MultipleSubst* ms ); + void Free_AlternateSubst( TTO_AlternateSubst* as ); + void Free_LigatureSubst( TTO_LigatureSubst* ls ); + void Free_ContextSubst( TTO_ContextSubst* cs ); + void Free_ChainContextSubst( TTO_ChainContextSubst* ccs ); + + + /* functions from ftxgpos.c */ + + TT_Error Load_SinglePos( TTO_SinglePos* sp, + PFace input ); + TT_Error Load_PairPos( TTO_PairPos* pp, + PFace input ); + TT_Error Load_CursivePos( TTO_CursivePos* cp, + PFace input ); + TT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp, + PFace input ); + TT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp, + PFace input ); + TT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp, + PFace input ); + TT_Error Load_ContextPos( TTO_ContextPos* cp, + PFace input ); + TT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp, + PFace input ); + + void Free_SinglePos( TTO_SinglePos* sp ); + void Free_PairPos( TTO_PairPos* pp ); + void Free_CursivePos( TTO_CursivePos* cp ); + void Free_MarkBasePos( TTO_MarkBasePos* mbp ); + void Free_MarkLigPos( TTO_MarkLigPos* mlp ); + void Free_MarkMarkPos( TTO_MarkMarkPos* mmp ); + void Free_ContextPos( TTO_ContextPos* cp ); + void Free_ChainContextPos( TTO_ChainContextPos* ccp ); + + + /* query functions */ + + TT_Error Coverage_Index( TTO_Coverage* c, + UShort glyphID, + UShort* index ); + TT_Error Get_Class( TTO_ClassDefinition* cd, + UShort glyphID, + UShort* class, + UShort* index ); + TT_Error Get_Device( TTO_Device* d, + UShort size, + Short* value ); + + + /* functions from ftxgdef.c */ + + TT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef, + UShort glyphID, + UShort property ); + + +#ifdef __cplusplus +} +#endif + +#endif /* FTXOPENF_H */ + + +/* END */ diff --git a/lib/extend/ftxpost.c b/lib/extend/ftxpost.c new file mode 100644 index 0000000..27a92d2 --- /dev/null +++ b/lib/extend/ftxpost.c @@ -0,0 +1,522 @@ +/******************************************************************* + * + * ftxpost.c + * + * post table support API extension body + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The post table is not completely loaded by the core engine. This + * file loads the missing PS glyph names and implements an API to + * access them. + * + ******************************************************************/ + +#include "ftxpost.h" + +#include "tttypes.h" +#include "ttobjs.h" +#include "tttables.h" +#include "ttload.h" /* for the macros */ +#include "ttfile.h" +#include "tttags.h" +#include "ttmemory.h" +#include "ttextend.h" + + +#define POST_ID Build_Extension_ID( 'p', 'o', 's', 't' ) + + + /* the 258 default Mac PS glyph names */ + + String* TT_Post_Default_Names[258] = + { + /* 0 */ + ".notdef", ".null", "CR", "space", "exclam", + "quotedbl", "numbersign", "dollar", "percent", "ampersand", + /* 10 */ + "quotesingle", "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", "zero", + /* 20 */ + "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "colon", + /* 30 */ + "semicolon", "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", + /* 40 */ + "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", + /* 50 */ + "O", "P", "Q", "R", "S", + "T", "U", "V", "W", "X", + /* 60 */ + "Y", "Z", "bracketleft", "backslash", "bracketright", + "asciicircum", "underscore", "grave", "a", "b", + /* 70 */ + "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", + /* 80 */ + "m", "n", "o", "p", "q", + "r", "s", "t", "u", "v", + /* 90 */ + "w", "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", "Aring", + /* 100 */ + "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", + "aacute", "agrave", "acircumflex", "adieresis", "atilde", + /* 110 */ + "aring", "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", "idieresis", + /* 120 */ + "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", + "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", + /* 130 */ + "dagger", "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", "copyright", + /* 140 */ + "trademark", "acute", "dieresis", "notequal", "AE", + "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", + /* 150 */ + "yen", "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", "Omega", + /* 160 */ + "ae", "oslash", "questiondown", "exclamdown", "logicalnot", + "radical", "florin", "approxequal", "Delta", "guillemotleft", + /* 170 */ + "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", "emdash", + /* 180 */ + "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", + "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", + /* 190 */ + "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", + /* 200 */ + "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", + "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", + /* 210 */ + "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", "breve", + /* 220 */ + "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", + "caron", "Lslash", "lslash", "Scaron", "scaron", + /* 230 */ + "Zcaron", "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", "minus", + /* 240 */ + "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", + "onequarter", "threequarters", "franc", "Gbreve", "gbreve", + /* 250 */ + "Idot", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dmacron", + }; + + + + static TT_Error Load_Format_20( TT_Post_20* post20, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort nameindex, n, num; + Byte len; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + num = GET_UShort(); + + FORGET_Frame(); + + /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ + /* than the value in the maxp table (cf. cyberbit.ttf). */ + + /* There already exist fonts which have more than 32768 glyph names */ + /* in this table, so the test for this threshold has been dropped. */ + if ( num > input->numGlyphs ) + return TT_Err_Invalid_Post_Table; + + post20->numGlyphs = num; + + if ( ALLOC_ARRAY( post20->glyphNameIndex, num, TT_UShort ) ) + return error; + + if ( ACCESS_Frame( num * 2L ) ) + goto Fail; + + for ( n = 0; n < num; n++ ) + { + post20->glyphNameIndex[n] = GET_UShort(); + + if ( post20->glyphNameIndex[n] > 258 + num ) + { + FORGET_Frame(); + error = TT_Err_Invalid_Post_Table; + goto Fail; + } + } + + FORGET_Frame(); + + if ( ALLOC_ARRAY( post20->glyphNames, num, Char* ) ) + goto Fail; + + /* We must initialize the glyphNames array for proper */ + /* deallocation. */ + for ( n = 0; n < num; n++ ) + post20->glyphNames[n] = NULL; + + /* Now we can read the glyph names which are stored in */ + /* Pascal string format. */ + for ( n = 0; n < num; n++ ) + { + nameindex = post20->glyphNameIndex[n]; + + if ( nameindex < 258 ) + ; /* default Mac glyph, do nothing */ + else + { + if ( ACCESS_Frame( 1L ) ) + goto Fail1; + + len = GET_Byte(); + + FORGET_Frame(); + + if ( ALLOC_ARRAY( post20->glyphNames[nameindex - 258], + len + 1, Char ) || + FILE_Read( post20->glyphNames[nameindex - 258], len ) ) + goto Fail1; + + /* we make a C string */ + post20->glyphNames[nameindex - 258][len] = '\0'; + } + } + + return TT_Err_Ok; + + + Fail1: + for ( n = 0; n < num; n++ ) + if ( post20->glyphNames[n] ) + FREE( post20->glyphNames[n] ); + + FREE( post20->glyphNames ); + + Fail: + FREE( post20->glyphNameIndex ); + return error; + } + + + static TT_Error Load_Format_25( TT_Post_25* post25, + PFace input ) + { + DEFINE_LOAD_LOCALS( input->stream ); + + UShort n, num; + + + if ( ACCESS_Frame( 2L ) ) + return error; + + /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ + num = GET_UShort(); + + FORGET_Frame(); + + if ( num > input->numGlyphs || num > 258 ) + return TT_Err_Invalid_Post_Table; + + post25->numGlyphs = num; + + if ( ALLOC_ARRAY( post25->offset, num, Char ) ) + return error; + + if ( ACCESS_Frame( num ) ) + goto Fail; + + for ( n = 0; n < num; n++ ) + { + post25->offset[n] = GET_Char(); + + /* We add 128 to the tests to avoid problems with negative */ + /* values for comparison. */ + if ( n + ( post25->offset[n] + 128 ) > num + 128 || + n + ( post25->offset[n] + 128 ) < 128 ) + { + FORGET_Frame(); + error = TT_Err_Invalid_Post_Table; + goto Fail; + } + } + + FORGET_Frame(); + + return TT_Err_Ok; + + + Fail: + FREE( post25->offset ); + return error; + } + + + static TT_Error Post_Create( void* ext, + PFace face ) + { + TT_Post* post = (TT_Post*)ext; + Long table; + + + /* by convention */ + if ( !post ) + return TT_Err_Ok; + + /* we store the start offset and the size of the subtable */ + table = TT_LookUp_Table( face, TTAG_post ); + post->offset = face->dirTables[table].Offset + 32L; + post->length = face->dirTables[table].Length - 32L; + post->loaded = FALSE; + + return TT_Err_Ok; + } + + + static TT_Error Post_Destroy( void* ext, + PFace face ) + { + TT_Post* post = (TT_Post*)ext; + UShort n; + + + /* by convention */ + if ( !post ) + return TT_Err_Ok; + + if ( post->loaded ) + { + switch ( face->postscript.FormatType ) + { + case 0x00010000: /* nothing to do */ + break; + + case 0x00020000: + for ( n = 0; n < post->p.post20.numGlyphs; n++ ) + if ( post->p.post20.glyphNames[n] ) + FREE( post->p.post20.glyphNames[n] ); + FREE( post->p.post20.glyphNames ); + FREE( post->p.post20.glyphNameIndex ); + break; + + case 0x00028000: + FREE( post->p.post25.offset ); + break; + + case 0x00030000: /* nothing to do */ + break; + +#if 0 + case 0x00040000: + break; +#endif + + default: + ; /* invalid format, do nothing */ + } + } + + return TT_Err_Ok; + } + + + EXPORT_FUNC + TT_Error TT_Init_Post_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + error = TT_Register_Extension( _engine, + POST_ID, + sizeof ( TT_Post ), + Post_Create, + Post_Destroy ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Load_PS_Names + * + * Description : Loads the PostScript Glyph Name subtable (if any). + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Load_PS_Names( TT_Face face, + TT_Post* ppost ) + { + PFace faze = HANDLE_Face( face ); + TT_Error error; + TT_Stream stream; + TT_Post* post; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + error = TT_Extension_Get( faze, POST_ID, (void**)&post ); + if ( error ) + return error; + + if ( USE_Stream( faze->stream, stream ) ) + return error; + + + switch ( faze->postscript.FormatType ) + { + case 0x00010000: + error = TT_Err_Ok; /* nothing to do */ + break; + + case 0x00020000: + if ( FILE_Seek( post->offset ) ) + goto Fail; + + error = Load_Format_20( &post->p.post20, faze ); + break; + + case 0x00028000: /* 2.5 in 16.16 format */ + if ( FILE_Seek( post->offset ) ) + goto Fail; + + error = Load_Format_25( &post->p.post25, faze ); + break; + + case 0x00030000: + error = TT_Err_Ok; /* nothing to do */ + break; + +#if 0 + case 0x00040000: + break; +#endif + + default: + error = TT_Err_Invalid_Post_Table_Format; + break; + } + + if ( !error ) + { + post->loaded = TRUE; + *ppost = *post; + } + + + Fail: + DONE_Stream( stream ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Get_PS_Name + * + * Description : Gets the PostScript Glyph Name of a glyph. + * + * Input : index glyph index + * PSname address of a string pointer. + * Will be NULL in case of error; otherwise it + * contains a pointer to the glyph name. + * + * You must not modify the returned string! + * + * Output : error code + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_PS_Name( TT_Face face, + TT_UShort index, + TT_String** PSname ) + { + PFace faze = HANDLE_Face( face ); + TT_Error error; + TT_Post* post; + UShort nameindex; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( index >= faze->numGlyphs ) + return TT_Err_Invalid_Glyph_Index; + + error = TT_Extension_Get( faze, POST_ID, (void**)&post ); + if ( error ) + return error; + + + *PSname = TT_Post_Default_Names[0]; /* default value */ + + switch ( faze->postscript.FormatType ) + { + case 0x00010000: + if ( index < 258 ) /* paranoid checking */ + *PSname = TT_Post_Default_Names[index]; + break; + + case 0x00020000: + if ( index < post->p.post20.numGlyphs ) + nameindex = post->p.post20.glyphNameIndex[index]; + else + break; + + if ( nameindex < 258 ) + *PSname = TT_Post_Default_Names[nameindex]; + else + *PSname = (String*)post->p.post20.glyphNames[nameindex - 258]; + break; + + case 0x00028000: + if ( index < post->p.post25.numGlyphs ) /* paranoid checking */ + *PSname = TT_Post_Default_Names[index + post->p.post25.offset[index]]; + break; + + case 0x00030000: + break; /* nothing to do */ + +#if 0 + case 0x00040000: + break; +#endif + + default: + ; /* should never happen */ + } + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/extend/ftxpost.h b/lib/extend/ftxpost.h new file mode 100644 index 0000000..534b608 --- /dev/null +++ b/lib/extend/ftxpost.h @@ -0,0 +1,107 @@ +/******************************************************************* + * + * ftxpost.h + * + * post table support API extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * The post table is not completely loaded by the core engine. This + * file loads the missing PS glyph names and implements an API to + * access them. + * + ******************************************************************/ + +#ifndef FTXPOST_H +#define FTXPOST_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TT_Err_Invalid_Post_Table_Format 0x0B00 +#define TT_Err_Invalid_Post_Table 0x0B01 + + /* the 258 standard Mac glyph names, used for format 1.0 and 2.5 */ + + extern TT_String* TT_Post_Default_Names[]; + + + /* format 2.0 table */ + + struct TT_Post_20_ + { + TT_UShort numGlyphs; + TT_UShort* glyphNameIndex; + TT_Char** glyphNames; + }; + + typedef struct TT_Post_20_ TT_Post_20; + + struct TT_Post_25_ + { + TT_UShort numGlyphs; + TT_Char* offset; + }; + + typedef struct TT_Post_25_ TT_Post_25; + +#if 0 + /* format 4.0 table -- not implemented yet */ + + struct TT_Post_40_ + { + }; + + typedef struct TT_Post_40_ TT_Post_40; +#endif + + + struct TT_Post_ + { + TT_Long offset; + TT_Long length; + TT_Bool loaded; + + union + { + TT_Post_20 post20; + TT_Post_25 post25; +#if 0 + TT_Post_40 post40; +#endif + } p; + }; + + typedef struct TT_Post_ TT_Post; + + + EXPORT_DEF + TT_Error TT_Init_Post_Extension( TT_Engine engine ); + + EXPORT_DEF + TT_Error TT_Load_PS_Names( TT_Face face, + TT_Post* post ); + EXPORT_DEF + TT_Error TT_Get_PS_Name( TT_Face face, + TT_UShort index, + TT_String** PSname ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXPOST_H */ + + +/* END */ diff --git a/lib/extend/ftxsbit.c b/lib/extend/ftxsbit.c new file mode 100644 index 0000000..02162bd --- /dev/null +++ b/lib/extend/ftxsbit.c @@ -0,0 +1,1391 @@ +/******************************************************************* + * + * ftxsbit.c + * + * Embedded bitmap API extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This extension is used to load the embedded bitmaps present + * in certain TrueType files. + * + ******************************************************************/ + +#include "ftxsbit.h" +#include "ttobjs.h" +#include "ttfile.h" +#include "ttload.h" +#include "ttmemory.h" +#include "tttags.h" +#include "ttextend.h" +#include "ttdebug.h" + + +#define SBIT_ID Build_Extension_ID( 's', 'b', 'i', 't' ) + + +/* Required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_bitmap + +/* In all functions, the stream is taken from the 'face' object */ +#define DEFINE_LOCALS DEFINE_LOAD_LOCALS( face->stream ) +#define DEFINE_LOCALS_WO_FRAME DEFINE_LOAD_LOCALS_WO_FRAME( face->stream ) + + +/*************************** + * + * miscellaneous functions + * + ***************************/ + +/******************************************************************* + * + * Function: Load_BitmapData + * + * Bit-aligned bitmap data -> Byte-aligned bitmap data when pad is 0 + * + ******************************************************************/ + + static + TT_Error Load_BitmapData( TT_SBit_Image* image, + Int image_size, + Byte x_offset, + Byte y_offset, + UShort source_width, + UShort source_height, + Bool byte_padded ) + { + DEFINE_LOCALS; + + Int count; /* number of bits left in rows */ + Int loaded; /* number of bits loaded in the accumulator */ + UShort buff; /* accumulator */ + + PByte line; /* target write cursor */ + PByte limit; + + + if ( ( y_offset + source_height > image->map.rows ) || + ( x_offset + source_width > image->map.width ) ) + return TT_Err_Invalid_Argument; + + if ( ACCESS_Frame( image_size ) ) + return error; + + buff = 0; + loaded = 0; + line = (PByte)image->map.bitmap + + y_offset * image->map.cols; + limit = (PByte)image->map.bitmap + + ( y_offset + source_height ) * image->map.cols; + + for ( ; line < limit; line += image->map.cols ) + { + PByte ptr; + + + ptr = line + x_offset / 8; + count = source_width; + + /* We may assume that `loaded' is less than 8 */ + buff >>= x_offset % 8; + loaded += x_offset % 8; + + /* first of all, read all consecutive bytes */ + while ( count >= 8 ) + { + if ( loaded < 8 ) + { + buff |= ((UShort)GET_Byte()) << (8 - loaded); + loaded += 8; + } + + *ptr++ |= (Byte)(buff >> 8); + buff <<= 8; + loaded -= 8; + count -= 8; + } + + /* now write remaining bits (i.e. end of line with count < 8) */ + if ( count > 0 ) + { + if ( loaded < count ) + { + buff |= ((UShort)GET_Byte()) << (8 - loaded); + loaded += 8; + } + + *ptr |= ((Byte)(buff >> 8)) & ~(0xFF >> count); + buff <<= count; + loaded -= count; + } + + if ( byte_padded ) + { + buff = 0; + loaded = 0; + } + } + + FORGET_Frame(); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function: Crop_Bitmap + * + ******************************************************************/ + + static + void Crop_Bitmap( TT_SBit_Image* image ) + { + /*******************************************************/ + /* In the following situation, some bounding boxes of */ + /* embedded bitmaps are too large. We need to crop it */ + /* to a reasonable size. */ + /* */ + /* --------- */ + /* | | ----- */ + /* | *** | |***| */ + /* | * | -----> | * | */ + /* | * | | * | */ + /* | * | | * | */ + /* | * | | * | */ + /* | *** | |***| */ + /* --------- ----- */ + /* */ + /*******************************************************/ + + Int rows, count; + Long line_len; + PByte line; + + + /********************************************************************/ + /* */ + /* first of all, check the top-most lines of the bitmap and remove */ + /* them if they're empty. */ + /* */ + { + line = (PByte)image->map.bitmap; + rows = image->map.rows; + line_len = image->map.cols; + + for ( count = 0; count < rows; count++ ) + { + PByte cur = line; + PByte limit = line + line_len; + + + for ( ; cur < limit; cur++ ) + if ( cur[0] ) + goto Found_Top; + + /* the current line was empty -- skip to next one */ + line = limit; + } + + Found_Top: + /* check that we have at least one filled line */ + if ( count >= rows ) + goto Empty_Bitmap; + + /* now, crop the empty upper lines */ + if ( count > 0 ) + { + line = (PByte)image->map.bitmap; + + MEM_Move( line, line + count*line_len, (rows-count) * line_len ); + + image->metrics.bbox.yMax -= count; + image->metrics.vertBearingY -= count; + image->metrics.horiBearingY -= count; + image->map.rows -= count; + rows -= count; + } + } + + /*******************************************************************/ + /* */ + /* second, crop the lower lines */ + /* */ + { + line = (PByte)image->map.bitmap + (rows-1) * line_len; + + for ( count = 0; count < rows; count++ ) + { + PByte cur = line; + PByte limit = line + line_len; + + + for ( ; cur < limit; cur++ ) + if ( cur[0] ) + goto Found_Bottom; + + /* the current line was empty -- skip to previous one */ + line -= line_len; + } + + Found_Bottom: + if ( count > 0 ) + { + image->metrics.bbox.yMin += count; + image->map.rows -= count; + rows -= count; + } + } + + /*******************************************************************/ + /* */ + /* third, get rid of the space on the left side of the glyph */ + /* */ + do + { + PByte limit; + + + line = (PByte)image->map.bitmap; + limit = line + rows * line_len; + + for ( ; line < limit; line += line_len ) + if ( line[0] & 0x80 ) + goto Found_Left; + + /* shift the whole glyph one pixel to the left */ + line = (PByte)image->map.bitmap; + limit = line + rows * line_len; + + for ( ; line < limit; line += line_len ) + { + Int n, width = image->map.width; + Byte old; + PByte cur = line; + + + old = cur[0] << 1; + + for ( n = 8; n < width; n += 8 ) + { + Byte val; + + + val = cur[1]; + cur[0] = old | (val >> 7); + old = val << 1; + cur++; + } + cur[0] = old; + } + + image->map.width--; + image->metrics.horiBearingX++; + image->metrics.vertBearingX++; + image->metrics.bbox.xMin++; + + } while ( image->map.width > 0 ); + + Found_Left: + + /*********************************************************************/ + /* */ + /* finally, crop the bitmap width to get rid of the space on the */ + /* right side of the glyph. */ + /* */ + do + { + Int right = image->map.width-1; + PByte limit; + Byte mask; + + + line = (PByte)image->map.bitmap + (right >> 3); + limit = line + rows*line_len; + mask = 0x80 >> (right & 7); + + for ( ; line < limit; line += line_len ) + if ( line[0] & mask ) + goto Found_Right; + + /* crop the whole glyph on the right */ + image->map.width--; + image->metrics.bbox.xMax--; + + } while ( image->map.width > 0 ); + + Found_Right: + /* all right, the bitmap was cropped */ + return; + + Empty_Bitmap: + image->map.width = 0; + image->map.rows = 0; + image->map.cols = 0; + image->map.size = 0; + } + +/************* + * + * Main body + * + *************/ + + + static + TT_Error Load_Range_Codes( TT_SBit_Range* range, + PFace face, + Bool load_offsets ) + { + DEFINE_LOCALS; + + ULong count, n, size; + + + (void)face; + + /* read glyph count */ + if ( ACCESS_Frame( 4L ) ) + goto Exit; + count = GET_ULong(); + FORGET_Frame(); + + range->num_glyphs = count; + + /* Allocate glyph offsets table if needed */ + if ( load_offsets ) + { + if ( ALLOC_ARRAY( range->glyph_offsets, count, ULong ) ) + goto Exit; + + size = count * 4L; + } + else + size = count * 2L; + + /* Allocate glyph codes table and access frame */ + if ( ALLOC_ARRAY ( range->glyph_codes, count, UShort ) || + ACCESS_Frame( size ) ) + goto Exit; + + for ( n = 0; n < count; n++ ) + { + range->glyph_codes[n] = GET_UShort(); + + if ( load_offsets ) + range->glyph_offsets[n] = (ULong)range->image_offset + GET_UShort(); + } + + FORGET_Frame(); + + Exit: + return error; + } + + + static + TT_Error Load_SBit_Range( TT_SBit_Strike* strike, + TT_SBit_Range* range, + PFace face ) + { + DEFINE_LOCALS; + + UShort format; + + + (void)face; + (void)strike; + + format = range->index_format; + PTRACE6(( "Index Format: %d\n", format )); + + switch( format ) + { + case 1: /* variable metrics with 4-byte offsets */ + case 3: /* variable metrics with 2-byte offsets */ + { + UShort num_glyphs, size_elem; + Bool large = (format == 1); + ULong* cur; + + num_glyphs = range->last_glyph - range->first_glyph + 1; + PTRACE5(( " num glyphs: %hu\n", num_glyphs )); + + range->num_glyphs = num_glyphs; + + num_glyphs++; /* BEWARE */ + + size_elem = large ? 4 : 2; + + if ( ALLOC_ARRAY( range->glyph_offsets, num_glyphs, ULong ) || + ACCESS_Frame( num_glyphs * size_elem ) ) + return error; + + cur = range->glyph_offsets; + + while ( num_glyphs > 0 ) + { + cur[0] = (TT_ULong)( range->image_offset + + (large ? GET_ULong() : GET_UShort()) ); + PTRACE7(( " offset: %d\n", cur[0] )); + cur++; + num_glyphs--; + } + + FORGET_Frame(); + } + break; + + case 2: /* all glyphs have identical metrics */ + case 4: + case 5: + { + error = 0; + + if ( format != 4 ) /* read constant metrics, formats 2 and 5 */ + { + TT_SBit_Metrics* metrics; + + + if ( ACCESS_Frame( 12L ) ) + return error; + + range->image_size = GET_ULong(); + metrics = &range->metrics; + + metrics->height = GET_Byte(); + metrics->width = GET_Byte(); + + metrics->horiBearingX = GET_Char(); + metrics->horiBearingY = GET_Char(); + metrics->horiAdvance = GET_Byte(); + + metrics->vertBearingX = GET_Char(); + metrics->vertBearingY = GET_Char(); + metrics->vertAdvance = GET_Byte(); + + FORGET_Frame(); + } + + if ( format != 2 ) /* load range codes, formats 4 and 5 */ + error = Load_Range_Codes( range, face, (format == 4) ); + } + break; + + default: + error = TT_Err_Invalid_File_Format; + } + + PTRACE3(( "Embedded Bitmap Location Tables loaded.\n" )); + + return error; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Eblc + * + * Description : Loads the Eblc table directory into face table. + * + * Input : face face record to look for + * + * Output : Error code. + * + ******************************************************************/ + + static + TT_Error Load_TrueType_Eblc( PFace face, + TT_EBLC* eblc ) + { + DEFINE_LOCALS; + + ULong eblc_offset; + UShort i; + Long table; + + TT_SBit_Strike* strike; + + + PTRACE2(( "Load_EBLC_Table( %08lx )\n", (long)face )); + + eblc->version = 0; + + /* Try to find the `EBLC' or `bloc' table in the font files. */ + /* Both tags describe the same table; `EBLC' is for OpenType */ + /* fonts while `bloc' is for TrueType GX fonts. Many fonts */ + /* contain both tags pointing to the same table. */ + + table = TT_LookUp_Table( face, TTAG_EBLC ); + if ( table < 0 ) + table = TT_LookUp_Table( face, TTAG_bloc ); + + if ( table < 0 ) + /* This table is optional */ + return TT_Err_Ok; + + eblc_offset = face->dirTables[table].Offset; + + if ( FILE_Seek( eblc_offset ) || + ACCESS_Frame( 8L ) ) + return error; + + eblc->version = GET_ULong(); + eblc->num_strikes = GET_ULong(); + + FORGET_Frame(); + + PTRACE2(( "-- Tables count: %12u\n", eblc->num_strikes )); + PTRACE2(( "-- Format version: %08lx\n", eblc->version )); + + if ( eblc->version != 0x00020000 ) + { + PERROR(( "Invalid file format!\n" )); + return TT_Err_Invalid_File_Format; + } + + if ( ALLOC_ARRAY( eblc->strikes, eblc->num_strikes, TT_SBit_Strike ) || + ACCESS_Frame( 48L * eblc->num_strikes ) ) + return error; + + strike = eblc->strikes; + + for ( i = 0; i < eblc->num_strikes; i++, strike++ ) + { /* loop through the tables and get all entries */ + ULong indexTablesSize; + TT_SBit_Line_Metrics* metrics; + Int count; + + + strike->ranges_offset = GET_ULong(); + indexTablesSize = GET_ULong(); /* dont' save */ + + strike->num_ranges = GET_ULong(); + strike->color_ref = GET_ULong(); + + /* load horizontal and vertical metrics */ + metrics = &strike->hori; + for ( count = 2; count > 0; count-- ) + { + metrics->ascender = GET_Char(); + metrics->descender = GET_Char(); + metrics->max_width = GET_Byte(); + + metrics->caret_slope_numerator = GET_Char(); + metrics->caret_slope_denominator = GET_Char(); + metrics->caret_offset = GET_Char(); + + metrics->min_origin_SB = GET_Char(); + metrics->min_advance_SB = GET_Char(); + metrics->max_before_BL = GET_Char(); + metrics->min_after_BL = GET_Char(); + metrics->pads[0] = GET_Char(); + metrics->pads[1] = GET_Char(); + + metrics = &strike->vert; + } + + strike->start_glyph = GET_UShort(); + strike->end_glyph = GET_UShort(); + strike->x_ppem = GET_Byte(); + strike->y_ppem = GET_Byte(); + strike->bit_depth = GET_Byte(); + strike->flags = GET_Char(); + + PTRACE4(( " start - end - ppemX - ppemY\n" )); + PTRACE4(( " %04d - %04d - %3u - %3u\n", + strike->start_glyph, + strike->end_glyph, + strike->x_ppem, + strike->y_ppem )); + } + + FORGET_Frame(); + + /* Load EBLC index ranges */ + strike = eblc->strikes; + + for ( i = 0; i < eblc->num_strikes; i++, strike++ ) + { + TT_SBit_Range* range; + UShort count = strike->num_ranges; + + + /* loop through the tables and get all entries */ + if ( ALLOC_ARRAY( strike->sbit_ranges, + strike->num_ranges, + TT_SBit_Range ) || + FILE_Seek( eblc_offset + strike->ranges_offset ) || + ACCESS_Frame( strike->num_ranges * 8L ) ) + return error; + + for ( range = strike->sbit_ranges; count > 0; count--, range++ ) + { + range->first_glyph = GET_UShort(); + range->last_glyph = GET_UShort(); + range->table_offset = eblc_offset + strike->ranges_offset + + GET_ULong(); + } + FORGET_Frame(); + + /* Now, read each index table */ + range = strike->sbit_ranges; + for ( count = strike->num_ranges; count > 0; count--, range++ ) + { + /* Read the header */ + if ( FILE_Seek( range->table_offset ) || + ACCESS_Frame( 8L ) ) + return error;; + + range->index_format = GET_UShort(); + range->image_format = GET_UShort(); + range->image_offset = GET_ULong(); + + FORGET_Frame(); + + error = Load_SBit_Range( strike, range, face ); + if (error) return error; + } + } + + return TT_Err_Ok; + } + + + static + void Free_TrueType_Eblc( TT_EBLC* eblc ) + { + if ( eblc ) + { + ULong i; + TT_SBit_Strike* strike = eblc->strikes; + + + strike = eblc->strikes; + + for ( i = eblc->num_strikes; i > 0; i--, strike++ ) + { + /* for each strike, release all glyph ranges */ + TT_SBit_Range* range = strike->sbit_ranges; + Int n; + + + for ( n = strike->num_ranges; n > 0; n--, range++ ) + { + /* release a range */ + FREE( range->glyph_offsets ); + FREE( range->glyph_codes ); + } + FREE( strike->sbit_ranges ); + strike->num_ranges = 0; + } + FREE( eblc->strikes ); + eblc->num_strikes = 0; + eblc->version = 0; + } + } + + + static + TT_Error Load_SBit_Metrics( TT_Big_Glyph_Metrics* metrics, + TT_SBit_Range* range, + ULong ebdt_offset ) + { + TT_Error error; + Byte height, width; + + + /* copy bitmap metrics for formats 2 and 5 */ + if ( ( ( range->index_format == 2 ) || ( range->index_format == 5 ) ) && + ( range->image_format == 5 ) ) + /* metrics are taken from current image bitmap */ + /* i.e. from `image.metrics' */ + { + TT_SBit_Metrics* rmetrics = &range->metrics; + + + metrics->bbox.xMin = rmetrics->horiBearingX; + metrics->bbox.xMax = metrics->bbox.xMin + rmetrics->width; + + metrics->bbox.yMax = rmetrics->horiBearingY; + metrics->bbox.yMin = metrics->bbox.yMax - rmetrics->height; + + metrics->horiBearingX = rmetrics->horiBearingX; + metrics->horiBearingY = metrics->bbox.yMax; + metrics->horiAdvance = rmetrics->horiAdvance; + + metrics->vertBearingX = rmetrics->vertBearingX; + metrics->vertBearingY = rmetrics->vertBearingY; + metrics->vertAdvance = rmetrics->vertAdvance; + + return TT_Err_Ok; + } + + switch ( range->image_format ) + { + case 1: + case 2: + case 6: + case 7: + case 8: + case 9: + { + Long length = 5L; + + + if ( range->image_format == 8 ) + length++; + + /* read the small metrics */ + if ( ACCESS_Frame( length ) ) + return error; + + height = GET_Byte(); + width = GET_Byte(); + + metrics->horiBearingX = GET_Char(); + metrics->horiBearingY = GET_Char(); + metrics->horiAdvance = GET_Byte(); + + FORGET_Frame(); + + metrics->bbox.xMin = metrics->horiBearingX; + metrics->bbox.yMax = metrics->horiBearingY; + metrics->bbox.xMax = metrics->bbox.xMin + width; + metrics->bbox.yMin = metrics->bbox.yMax - height; + + /* read the rest of the big metrics for the formats */ + /* that support it. */ + if ( ( range->image_format >= 6 ) && ( range->image_format != 8 ) ) + { + if ( ACCESS_Frame( 3L ) ) + return error; + + metrics->vertBearingX = (Int)GET_Char(); + metrics->vertBearingY = (Int)GET_Char(); + metrics->vertAdvance = (Int)GET_Char(); + + FORGET_Frame(); + } + else + { + /* XXX: How can we fill these when the information isn't */ + /* available? */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + } + } + break; + + case 5: /* metrics are taken from current image bitmap */ + /* i.e. from 'image.metrics' */ + break; + + default: + PERROR(( "Unsupported embedded bitmap format!\n" )); + return TT_Err_Invalid_File_Format; + } + + return TT_Err_Ok; + } + + + static + TT_Error Load_SBit_Image( TT_SBit_Strike strike, + UShort glyph_index, + Byte x_offset, + Byte y_offset, + ULong ebdt_offset, + TT_SBit_Image* image, + UShort component_depth ) + { + TT_Error error; + Byte height, width; + + ULong bitmap_offset; + + TT_SBit_Range* range = 0; + + TT_Big_Glyph_Metrics metrics; + + /********************************************************************/ + /* */ + /* Scan the strike's range for the position/metrics of the source */ + /* glyph. */ + { + UShort count = strike.num_ranges; + TT_SBit_Range* cur = strike.sbit_ranges; + + for ( ; count > 0; count--, cur++ ) + { + /* look for the glyph in the current range */ + switch ( cur->index_format ) + { + case 1: + case 2: + case 3: + if ( glyph_index >= cur->first_glyph && + glyph_index <= cur->last_glyph ) + { + UShort delta = glyph_index - cur->first_glyph; + + + range = cur; + bitmap_offset = cur->index_format == 2 + ? cur->image_offset + cur->image_size * delta + : cur->glyph_offsets[delta]; + goto Found; + } + break; + + case 4: + case 5: + { + UShort n; + + + for ( n = 0; n < cur->num_glyphs; n++ ) + if ( cur->glyph_codes[n] == glyph_index ) + { + range = cur; + bitmap_offset = cur->index_format == 4 + ? cur->glyph_offsets[n] + : cur->image_offset + cur->image_size * n; + goto Found; + } + } + break; + + default: + return TT_Err_Invalid_Glyph_Index; + } + } + /* Not found */ + return TT_Err_Invalid_Glyph_Index; + } + + Found: + if ( FILE_Seek( ebdt_offset + bitmap_offset ) ) + return error; + + /* First of all, load the metrics if needed */ + error = Load_SBit_Metrics( &metrics, range, ebdt_offset ); + if ( error ) + return error; + + width = metrics.bbox.xMax - metrics.bbox.xMin; + height = metrics.bbox.yMax - metrics.bbox.yMin; + + if ( !component_depth ) + { + image->metrics = metrics; + + image->map.width = width; + image->map.rows = height; + + image->map.cols = (width + 7) >> 3; + image->map.size = height * image->map.cols; + + if ( REALLOC( image->map.bitmap, image->map.size ) ) + return error; + + MEM_Set( image->map.bitmap, 0, image->map.size ); + } + + /* Now, load the data as needed */ + switch ( range->image_format ) + { + case 1: + case 6: /* byte-aligned data */ + error = Load_BitmapData( image, + height * (( width + 7 ) >> 3), + x_offset, y_offset, + width, height, + 1 ); + if ( error ) + return error; + break; + + case 2: + case 5: + case 7: + error = Load_BitmapData( image, + (width * height + 7) >> 3, + x_offset, y_offset, + width, height, 0 ); + if ( error ) + return error; + break; + + case 8: + case 9: + { + /* Now, load composite sbit glyphs */ + /* This code is not sophisticated */ + + TT_SBit_Component* component_array; + UShort num_components; + + Int i = 0; + + + if ( ACCESS_Frame( 2L ) ) + return error; + num_components = GET_UShort(); + FORGET_Frame(); + + MEM_Alloc( component_array, + sizeof ( TT_SBit_Component ) * num_components ); + + if ( ACCESS_Frame( 4L * num_components ) ) + return error; + + for ( i = 0; i < num_components; i++ ) + { + component_array[i].glyph_code = GET_UShort(); + component_array[i].x_offset = GET_Char(); + component_array[i].y_offset = GET_Char(); + } + + FORGET_Frame(); + + component_depth++; + + for ( i = 0; i < num_components; i++ ) + { + error = Load_SBit_Image( strike, component_array[i].glyph_code, + component_array[i].x_offset, + component_array[i].y_offset, + ebdt_offset, + image, + component_depth ); + if ( error ) + return error; + } + FREE( component_array ); + break; + + default: + return TT_Err_Invalid_File_Format; + } + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function: Load_TrueType_Ebdt + * + ******************************************************************/ + + static + TT_Error Load_TrueType_Ebdt( PFace face, + TT_SBit_Strike strike, + ULong glyph_index, + TT_SBit_Image* image ) + { + DEFINE_LOCALS; + + ULong ebdt_offset; + ULong version; + Long i; + + + /* Try to find the `EBDT' or `bdat' table in the font files. */ + /* Both tags describe the same table, `EBDT' is for OpenType */ + /* fonts, while `bdat' is for TrueType GX fonts. Many fonts */ + /* contain both tags pointing to the same table */ + + i = TT_LookUp_Table( face, TTAG_EBDT ); + if ( i < 0 ) + i = TT_LookUp_Table( face, TTAG_bdat ); + + if ( i < 0 ) + return TT_Err_Table_Missing; + + ebdt_offset = face->dirTables[i].Offset; + + if ( FILE_Seek( ebdt_offset ) || + ACCESS_Frame( 4L ) ) /* read into frame */ + return error; + + version = GET_ULong(); + FORGET_Frame(); + + PTRACE2(( "-- Format version : %08lx\n", version )); + if ( version != 0x00020000 ) + { + PERROR(( "Invalid file format!\n" )); + return TT_Err_Invalid_File_Format; + } + + /* This doesn't compile, I simply commented it out ?? - David */ + /* PTRACE4(( "-- Format: %d\n", range->image_format )); */ + + error = Load_SBit_Image( strike, + glyph_index, + 0, 0, + ebdt_offset, + image, + 0 ); + if ( error ) + return error; + + return TT_Err_Ok; + } + + + static TT_Error EBLC_Create( void* ext, + PFace face ) + { + TT_EBLC* eblc = (TT_EBLC*)ext; + + + /* by convention */ + if ( !eblc ) + return TT_Err_Ok; + + return Load_TrueType_Eblc( face, eblc ); + } + + + static TT_Error EBLC_Destroy( void* ext, + PFace face ) + { + TT_EBLC* eblc = (TT_EBLC*)ext; + + + (void)face; + + if ( eblc ) + Free_TrueType_Eblc( eblc ); + + return TT_Err_Ok; + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_Init_SBit_Extension */ + /* */ + /* */ + /* Initialize the embedded bitmaps extension for the */ + /* FreeType engine. */ + /* */ + /* */ + /* engine :: handle to current FreeType library instance */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_FUNC + TT_Error TT_Init_SBit_Extension( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + error = TT_Register_Extension( _engine, + SBIT_ID, + sizeof ( TT_EBLC ), + EBLC_Create, + EBLC_Destroy ); + + return error; + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_Get_Face_Bitmaps */ + /* */ + /* */ + /* Loads the `EBLC' table from a font file, if any. */ + /* */ + /* */ + /* face :: handle to the source TrueType font/face */ + /* */ + /* */ + /* eblc_table :: a descriptor for the EBLC table */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* This function returns TT_Err_Table_Missing if the */ + /* font contains no embedded bitmaps. All fields in */ + /* `eblc_table' will then be set to 0. */ + /* */ + EXPORT_FUNC + TT_Error TT_Get_Face_Bitmaps( TT_Face face, + TT_EBLC* eblc_table ) + { + PFace faze = HANDLE_Face( face ); + TT_EBLC* eblc; + TT_Error error; + + + error = TT_Extension_Get( faze, SBIT_ID, (void**)&eblc ); + if ( !error ) + { + if ( eblc->version ) + { + *eblc_table = *eblc; + return TT_Err_Ok; + } + error = TT_Err_Table_Missing; + } + + eblc_table->version = 0; + eblc_table->num_strikes = 0; + eblc_table->strikes = 0; + + return error; + } + + +/******************************************************************* + * + * TT_Get_SBit_Strike + * + * + * Loads suitable strike (bitmap sizetable) for given instance. + * This strike includes sbitLineMetrics. + * + * + * face :: the source face + * instance :: the current size instance + * + * + * strike :: the bitmap strike descriptor + * + * + * TrueType error code. 0 means success. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_SBit_Strike( TT_Face face, + TT_Instance instance, + TT_SBit_Strike* strike ) + { + TT_Error error; + PFace faze = HANDLE_Face( face ); + PInstance ins = HANDLE_Instance( instance ); + + TT_EBLC* eblc; + TT_Int x_ppem, y_ppem; + + + if ( !strike || !ins || ins->owner != faze ) + return TT_Err_Invalid_Argument; + + error = TT_Extension_Get( faze, SBIT_ID, (void**)&eblc ); + if ( error ) + goto Exit; + + /********************************************************************/ + /* */ + /* Look for an sbit strike that matches the current x and y ppms */ + /* */ + { + UShort count = eblc->num_strikes; + TT_SBit_Strike* cur = eblc->strikes; + + + x_ppem = ins->metrics.x_ppem; + y_ppem = ins->metrics.y_ppem; + + MEM_Set( strike, 0, sizeof ( TT_SBit_Strike ) ); + + for ( ; count > 0; count--, cur++ ) + if ( cur->x_ppem == x_ppem && + cur->y_ppem == y_ppem ) + { + *strike = *cur; + break; + } + + /* return immediately if we didn't find an appropriate strike */ + if ( !strike->num_ranges ) + error = TT_Err_Invalid_PPem; + } + + Exit: + return error; + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_Load_Glyph_Bitmap */ + /* */ + /* */ + /* Loads a given glyph embedded bitmap. */ + /* */ + /* */ + /* face :: handle to the source TrueType font/face */ + /* instance :: current size/transform instance */ + /* glyph_index :: index of source glyph */ + /* bitmap :: target embedded bitmap descriptor */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* This function returns an error if there is no */ + /* embedded bitmap for the glyph at the given */ + /* instance. */ + /* */ + EXPORT_FUNC + TT_Error TT_Load_Glyph_Bitmap( TT_Face face, + TT_Instance instance, + TT_UShort glyph_index, + TT_SBit_Image* image ) + { + TT_Stream stream; + TT_Error error; + + PFace faze = HANDLE_Face( face ); + PInstance ins = HANDLE_Instance( instance ); + + TT_SBit_Strike strike; + + + if ( ins->owner != faze ) + { + error = TT_Err_Invalid_Argument; + goto Fail; + } + + /********************************************************************/ + /* */ + /* Look for an sbit strike that matches the current x and y ppms */ + /* */ + error = TT_Get_SBit_Strike( face, instance, &strike ); + if ( error ) + goto Fail; + + /* return immediately if the glyph index isn't in the strike extent */ + if ( glyph_index < strike.start_glyph || + glyph_index > strike.end_glyph ) + { + error = TT_Err_Invalid_Glyph_Index; + goto Fail; + } + + { + image->bit_depth = 1; + + if ( !USE_Stream( faze->stream, stream ) ) + { + error = Load_TrueType_Ebdt( faze, strike, glyph_index, image ); + + DONE_Stream( stream ); + + /* exit successfully if we can */ + if ( !error ) + { + image->map.flow = TT_Flow_Down; + + Crop_Bitmap( image ); + + /* correct sbit metrics */ + { + TT_Big_Glyph_Metrics* metrics = &image->metrics; + + + metrics->bbox.xMin *= 64; + metrics->bbox.xMax *= 64; + + metrics->bbox.yMax *= 64; + metrics->bbox.yMin *= 64; + + metrics->horiBearingX *= 64; + metrics->horiBearingY *= 64; + metrics->horiAdvance *= 64; + + metrics->vertBearingX *= 64; + metrics->vertBearingY *= 64; + metrics->vertAdvance *= 64; + } + + goto Exit; + } + } + } + + Fail: + image->map.width = 0; + image->map.rows = 0; + image->map.cols = 0; + image->map.size = 0; + image->map.bitmap = 0; + image->map.flow = 0; + image->bit_depth = 0; + + Exit: + return error; + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_New_SBit_Image */ + /* */ + /* */ + /* Allocates a new embedded bitmap container. */ + /* */ + /* */ + /* image :: sbit image */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_FUNC + TT_Error TT_New_SBit_Image( TT_SBit_Image** image ) + { + return MEM_Alloc( *image, sizeof ( **image ) ); + } + + + /*************************************************************/ + /* */ + /* */ + /* TT_Done_SBit_Image */ + /* */ + /* */ + /* Releases an embedded bitmap container. */ + /* */ + /* */ + /* image :: sbit image */ + /* */ + EXPORT_FUNC + void TT_Done_SBit_Image( TT_SBit_Image* image ) + { + FREE( image->map.bitmap ); + FREE( image ); + } + + +/* END */ diff --git a/lib/extend/ftxsbit.h b/lib/extend/ftxsbit.h new file mode 100644 index 0000000..05e7b1f --- /dev/null +++ b/lib/extend/ftxsbit.h @@ -0,0 +1,490 @@ +/******************************************************************* + * + * ftxsbit.h + * + * embedded bitmap support API extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This extension is used to load the embedded bitmaps present + * in certain TrueType files. + * + ******************************************************************/ + +#ifndef FTXSBIT_H +#define FTXSBIT_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /*************************************************************/ + /* */ + /* TT_SBit_Metrics */ + /* */ + /* */ + /* A structure used to hold the big metrics of a given */ + /* glyph bitmap in a TrueType or OpenType font. These */ + /* are usually found in the `EBDT' table. */ + /* */ + /* */ + /* height :: glyph height in pixels */ + /* width :: glyph width in pixels */ + /* */ + /* horiBearingX :: horizontal left bearing */ + /* horiBearingY :: horizontal top bearing */ + /* horiAdvance :: horizontal advance */ + /* */ + /* vertBearingX :: vertical left bearing */ + /* vertBearingY :: vertical top bearing */ + /* vertAdvance :: vertical advance */ + /* */ + typedef struct TT_SBit_Metrics_ + { + TT_Byte height; + TT_Byte width; + + TT_Char horiBearingX; + TT_Char horiBearingY; + TT_Byte horiAdvance; + + TT_Char vertBearingX; + TT_Char vertBearingY; + TT_Byte vertAdvance; + + } TT_SBit_Metrics; + + + /*************************************************************/ + /* */ + /* TT_SBit_Small_Metrics */ + /* */ + /* */ + /* A structure used to hold the small metrics of a given */ + /* glyph bitmap in a TrueType or OpenType font. These */ + /* are usually found in the `EBDT' table. */ + /* */ + /* */ + /* height :: glyph height in pixels */ + /* width :: glyph width in pixels */ + /* */ + /* bearingX :: left-side bearing */ + /* bearingY :: top-side bearing */ + /* advance :: advance width or height */ + /* */ + typedef struct TT_SBit_Small_Metrics_ + { + TT_Byte height; + TT_Byte width; + + TT_Char bearingX; + TT_Char bearingY; + TT_Byte advance; + + } TT_SBit_Small_Metrics; + + + /*************************************************************/ + /* */ + /* TT_SBit_Line_Metrics */ + /* */ + /* */ + /* A structure used to describe the text line metrics of */ + /* a given bitmap strike, for either horizontal or */ + /* vertical layout. */ + /* */ + /* */ + /* ascender :: ascender in pixels */ + /* descender :: descender in pixels */ + /* max_width :: maximum glyph width in pixels */ + /* */ + /* caret_slope_enumerator :: Rise of the caret slope, */ + /* typically set to 1 for non-italic fonts. */ + /* caret_slope_denominator :: Rise of the caret slope, */ + /* typically set to 0 for non-italic fonts. */ + /* caret_offset :: Offset in pixels */ + /* to move the caret for proper positioning. */ + /* */ + /* min_origin_SB :: Minimum of horiBearingX */ + /* (resp. vertBearingY) */ + /* min_advance_SB :: Minimum of */ + /* (hori. advance - ( horiBearingX + width )) */ + /* (resp. vert. advance - ( vertBearingY + height )) */ + /* max_before_BL :: Maximum of horiBearingY */ + /* (resp. Maximum of vertBearingY) */ + /* min_after_BL :: Minimum of ( horiBearingY - height ) */ + /* (resp. vertBearingX - width ) */ + /* */ + typedef struct TT_SBit_Line_Metrics_ + { + TT_Char ascender; + TT_Char descender; + TT_Byte max_width; + TT_Char caret_slope_numerator; + TT_Char caret_slope_denominator; + TT_Char caret_offset; + TT_Char min_origin_SB; + TT_Char min_advance_SB; + TT_Char max_before_BL; + TT_Char min_after_BL; + TT_Char pads[2]; + + } TT_SBit_Line_Metrics; + + + /*************************************************************/ + /* */ + /* TT_SBit_Range */ + /* */ + /* */ + /* A TrueType/OpenType subIndexTable as defined in the */ + /* `EBLC' or `bloc' tables. */ + /* */ + /* */ + /* */ + /* first_glyph :: first glyph index in range */ + /* last_glyph :: last glyph index in range */ + /* */ + /* index_format :: format of index table. valid */ + /* values are 1 to 5. */ + /* */ + /* image_format :: format of `EBDT' image data */ + /* image_offset :: offset to image data in `EBDT' */ + /* */ + /* image_size :: for index formats 2 and 5. This is */ + /* the size in bytes of each glyph bitmap */ + /* glyph bitmap */ + /* */ + /* big_metrics :: for index formats 2 and 5. This is */ + /* the big metrics for each glyph bitmap */ + /* */ + /* num_glyphs :: for index formats 4 and 5. This is */ + /* the number of glyphs in the code */ + /* array. */ + /* */ + /* glyph_offsets :: for index formats 1 and 3. */ + /* glyph_codes :: for index formats 4 and 5. */ + /* */ + /* table_offset :: offset of index table in `EBLC' table */ + /* -- only used during strike loading. */ + /* */ + typedef struct TT_SBit_Range + { + TT_UShort first_glyph; + TT_UShort last_glyph; + + TT_UShort index_format; + TT_UShort image_format; + TT_ULong image_offset; + + TT_ULong image_size; + TT_SBit_Metrics metrics; + TT_ULong num_glyphs; + + TT_ULong* glyph_offsets; + TT_UShort* glyph_codes; + + TT_ULong table_offset; + + } TT_SBit_Range; + + + /*************************************************************/ + /* */ + /* TT_SBit_Strike */ + /* */ + /* */ + /* A structure used describe a given bitmap strike in the */ + /* `EBLC' or `bloc' tables. */ + /* */ + /* */ + /* */ + /* num_index_ranges :: number of index ranges */ + /* index_ranges :: array of glyph index ranges */ + /* */ + /* color_ref :: unused. color reference? */ + /* hori :: line metrics for horizontal layouts. */ + /* vert :: line metrics for vertical layouts. */ + /* */ + /* start_glyph :: lowest glyph index for this strike. */ + /* end_glyph :: higher glyph index for this strike. */ + /* */ + /* x_ppem :: horizontal pixels per EM */ + /* y_ppem :: vertical pixels per EM */ + /* bit_depth :: bit depth. valid values are 1, 2, 4 & 8 */ + /* flags :: vertical or horizontal? */ + /* */ + typedef struct TT_SBit_Strike_ + { + TT_Int num_ranges; + TT_SBit_Range* sbit_ranges; + TT_ULong ranges_offset; + + TT_ULong color_ref; + + TT_SBit_Line_Metrics hori; + TT_SBit_Line_Metrics vert; + + TT_UShort start_glyph; + TT_UShort end_glyph; + + TT_Byte x_ppem; + TT_Byte y_ppem; + TT_Byte bit_depth; + TT_Char flags; + + } TT_SBit_Strike; + + + /*************************************************************/ + /* */ + /* TT_SBit_Component */ + /* */ + /* */ + /* A simple structure to describe a compound sbit element */ + /* */ + /* */ + /* glyph_code :: element's glyph index */ + /* x_offset :: element's left bearing */ + /* y_offset :: element's top bearing */ + /* */ + typedef struct TT_SBit_Component_ + { + TT_UShort glyph_code; + TT_Char x_offset; + TT_Char y_offset; + + } TT_SBit_Component; + + + /*************************************************************/ + /* */ + /* TT_SBit_Scale */ + /* */ + /* */ + /* A structure used describe a given bitmap scaling */ + /* table, as defined for the `EBSC' table. */ + /* */ + /* */ + /* hori :: horizontal line metrics */ + /* vert :: vertical line metrics */ + /* */ + /* x_ppem :: horizontal pixels per EM */ + /* y_ppem :: vertical pixels per EM */ + /* */ + /* x_ppem_substitute :: substitution x_ppem */ + /* y_ppem_substitute :: substitution y_ppem */ + /* */ + typedef struct TT_SBit_Scale_ + { + TT_SBit_Line_Metrics hori; + TT_SBit_Line_Metrics vert; + + TT_Byte x_ppem; + TT_Byte y_ppem; + + TT_Byte x_ppem_substitute; + TT_Byte y_ppem_substitute; + + } TT_SBit_Scale; + + + /*************************************************************/ + /* */ + /* TT_SBit_Image */ + /* */ + /* */ + /* A structure used to describe a given embedded bitmap */ + /* image. */ + /* */ + /* */ + /* map :: bitmap descriptor */ + /* bit_depth :: pixel bit depth */ + /* metrics :: glyph metrics for the bitmap */ + /* */ + typedef struct TT_SBit_Image_ + { + TT_Raster_Map map; + int bit_depth; + TT_Big_Glyph_Metrics metrics; + + } TT_SBit_Image; + + + /*************************************************************/ + /* */ + /* TT_EBLC */ + /* */ + /* */ + /* A structure used to describe the `EBLC' table from */ + /* a TrueType font. */ + /* */ + /* */ + /* version :: version number of the EBLC table */ + /* */ + /* num_strikes :: the number of strikes, i.e. bitmap */ + /* sizes, present in this font */ + /* */ + /* strikes :: array of strikes */ + /* */ + typedef struct TT_EBLC_ + { + TT_ULong version; + TT_ULong num_strikes; + TT_SBit_Strike* strikes; + + } TT_EBLC; + + + + + /*************************************************************/ + /* */ + /* */ + /* TT_Init_SBit_Extension */ + /* */ + /* */ + /* Initializes the embedded bitmap extension for the */ + /* FreeType engine. */ + /* */ + /* */ + /* engine :: handle to current FreeType library instance */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_DEF + TT_Error TT_Init_SBit_Extension( TT_Engine engine ); + + + /*************************************************************/ + /* */ + /* */ + /* TT_Get_Face_Bitmaps */ + /* */ + /* */ + /* Loads the `EBLC' table from a font file, if any. */ + /* */ + /* */ + /* face :: handle to the source TrueType font/face */ + /* */ + /* */ + /* eblc_table :: a descriptor for the EBLC table */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* This function returns TT_Err_Table_Missing if the */ + /* font contains no embedded bitmaps. All fields in */ + /* `eblc_table' will then be set to 0. */ + /* */ + EXPORT_DEF + TT_Error TT_Get_Face_Bitmaps( TT_Face face, + TT_EBLC* eblc_table ); + + + /*************************************************************/ + /* */ + /* */ + /* TT_New_SBit_Image */ + /* */ + /* */ + /* Allocates a new embedded bitmap container. */ + /* */ + /* */ + /* image :: sbit image */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_DEF + TT_Error TT_New_SBit_Image( TT_SBit_Image** image ); + + + /*************************************************************/ + /* */ + /* */ + /* TT_Done_SBit_Image */ + /* */ + /* */ + /* Releases an embedded bitmap container. */ + /* */ + /* */ + /* image :: sbit image */ + /* */ + EXPORT_DEF + void TT_Done_SBit_Image( TT_SBit_Image* image ); + + + /*************************************************************/ + /* */ + /* TT_Get_SBit_Strike */ + /* */ + /* */ + /* Loads a suitable strike (bitmap sizetable) for the */ + /* given instance. This strike includes */ + /* sbitLineMetrics. */ + /* */ + /* */ + /* face :: the source face */ + /* instance :: the current size instance */ + /* */ + /* */ + /* strike :: the bitmap strike descriptor */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + EXPORT_DEF + TT_Error TT_Get_SBit_Strike( TT_Face face, + TT_Instance instance, + TT_SBit_Strike* strike ); + + + /*************************************************************/ + /* */ + /* */ + /* TT_Load_Glyph_Bitmap */ + /* */ + /* */ + /* Loads a given glyph embedded bitmap. */ + /* */ + /* */ + /* face :: handle to the source TrueType font/face */ + /* instance :: current size/transform instance */ + /* glyph_index :: index of source glyph */ + /* bitmap :: target embedded bitmap descriptor */ + /* */ + /* */ + /* Error code. 0 means success. */ + /* */ + /* */ + /* This function returns an error if there is no */ + /* embedded bitmap for the glyph at the given */ + /* instance. */ + /* */ + EXPORT_DEF + TT_Error TT_Load_Glyph_Bitmap( TT_Face face, + TT_Instance instance, + TT_UShort glyph_index, + TT_SBit_Image* bitmap ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXSBIT_H */ + + +/* END */ diff --git a/lib/extend/ftxwidth.c b/lib/extend/ftxwidth.c new file mode 100644 index 0000000..5415f5a --- /dev/null +++ b/lib/extend/ftxwidth.c @@ -0,0 +1,185 @@ +/******************************************************************* + * + * ftxwidth.c 1.0 + * + * Glyph Widths (and Heights) fast retrieval extension + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This extension is used to parse the "glyf" table of a TrueType + * file in order to extract the bbox of a given range of glyphs. + * + * The bbox is then used to build font unit widths and height + * that are returned in two parallel arrays. + * + * This extension is needed by the FreeType/2 OS/2 Font Driver. + * + ******************************************************************/ + + +#include "ftxwidth.h" +#include "ttdebug.h" +#include "ttobjs.h" +#include "ttfile.h" +#include "tttags.h" +#include "ttload.h" + +/* Required by the tracing mode */ + +#undef TT_COMPONENT +#define TT_COMPONENT trace_any + + + /******************************************************************/ + /* */ + /* Function: TT_Get_Face_Widths */ + /* */ + /* Description: Returns the widths and/or heights of a given */ + /* range of glyphs for a face. */ + /* */ + /* Input: */ + /* face :: face handle */ + /* */ + /* first_glyph :: first glyph in range */ + /* */ + /* last_glyph :: last glyph in range */ + /* */ + /* widths :: address of table receiving the widths */ + /* expressed in font units (ushorts). Set */ + /* this parameter to NULL if you're not */ + /* interested by these values. */ + /* */ + /* heights :: address of table receiving the heights */ + /* expressed in font units (ushorts). Set */ + /* this parameter to NULL if you're not */ + /* interested by these values. */ + /* */ + /* Returns: */ + /* Error code */ + /* */ + /* */ + /******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Face_Widths( TT_Face face, + TT_UShort first_glyph, + TT_UShort last_glyph, + TT_UShort* widths, + TT_UShort* heights ) + { + DEFINE_ALL_LOCALS; + + PFace faze = HANDLE_Face(face); + UShort n; + Long table; + + ULong glyf_offset; /* offset of glyph table in file */ + UShort zero_width = 0; /* width of glyph 0 */ + UShort zero_height = 0; /* height of glyph 0 */ + + Bool zero_loaded = 0; + +#ifndef TT_HUGE_PTR + PStorage locations; +#else + Storage TT_HUGE_PTR * locations; +#endif + TT_BBox bbox; + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( last_glyph >= faze->numGlyphs || + first_glyph > last_glyph ) + return TT_Err_Invalid_Argument; + + /* find "glyf" table */ + table = TT_LookUp_Table( faze, TTAG_glyf ); + if ( table < 0 ) + { + PERROR(( "ERROR: there is no glyph table in this font file!\n" )); + return TT_Err_Glyf_Table_Missing; + } + glyf_offset = faze->dirTables[table].Offset; + + /* now access stream */ + if ( USE_Stream( faze->stream, stream ) ) + return error; + + locations = faze->glyphLocations + first_glyph; + + /* loop to load each glyph in the range */ + for ( n = first_glyph; n <= last_glyph; n++ ) + { + if ( n + 1 < faze->numGlyphs && + locations[0] == locations[1] ) + { + /* Note : Glyph 0 is always used to indicate a missing glyph */ + /* in a range. We must thus return its width and height */ + /* where appropriate when we find an undefined glyph. */ + if ( zero_loaded == 0 ) + { + if ( FILE_Seek( glyf_offset + faze->glyphLocations[0] ) || + ACCESS_Frame( 10L ) ) + goto Fail; + + (void)GET_Short(); /* skip number of contours */ + + bbox.xMin = GET_Short(); + bbox.yMin = GET_Short(); + bbox.xMax = GET_Short(); + bbox.yMax = GET_Short(); + + FORGET_Frame(); + + zero_width = (UShort)(bbox.xMax - bbox.xMin); + zero_height = (UShort)(bbox.yMax - bbox.yMin); + zero_loaded = 1; + } + + if ( widths ) + *widths++ = zero_width; + + if ( heights ) + *heights++ = zero_height; + } + else + { + /* normal glyph, read header */ + if ( FILE_Seek( glyf_offset + locations[0] ) || + ACCESS_Frame( 10L ) ) + goto Fail; + + (void)GET_Short(); /* skip number of contours */ + + bbox.xMin = GET_Short(); + bbox.yMin = GET_Short(); + bbox.xMax = GET_Short(); + bbox.yMax = GET_Short(); + + FORGET_Frame(); + + if ( widths ) + *widths++ = (UShort)(bbox.xMax - bbox.xMin); + + if ( heights ) + *heights++ = (UShort)(bbox.yMax - bbox.yMin); + } + } + + Fail: + DONE_Stream( stream ); + return error; + } + + +/* END */ diff --git a/lib/extend/ftxwidth.h b/lib/extend/ftxwidth.h new file mode 100644 index 0000000..5ac7251 --- /dev/null +++ b/lib/extend/ftxwidth.h @@ -0,0 +1,80 @@ +/******************************************************************* + * + * ftxwidth.h + * + * Glyph Widths (and Heights) fast retrieval extension. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This extension is used to parse the `glyf' table of a TrueType + * file in order to extract the bounding box of a given range of glyphs. + * + * The bounding box is then used to build font unit widths and heights + * that are returned in two parallel arrays. + * + * This extension is needed by the FreeType/2 OS/2 Font Driver. + * + ******************************************************************/ + +#ifndef FTXWIDTH_H +#define FTXWIDTH_H + +#include "freetype.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /******************************************************************/ + /* */ + /* Function: TT_Get_Face_Widths */ + /* */ + /* Description: Returns the widths and/or heights of a given */ + /* range of glyphs for a face. */ + /* */ + /* Input: */ + /* face :: face handle */ + /* */ + /* first_glyph :: first glyph in range */ + /* */ + /* last_glyph :: last glyph in range */ + /* */ + /* widths :: address of table receiving the widths */ + /* expressed in font units (ushorts). Set */ + /* this parameter to NULL if you're not */ + /* interested by these values. */ + /* */ + /* heights :: address of table receiving the heights */ + /* expressed in font units (ushorts). Set */ + /* this parameter to NULL if you're not */ + /* interested by these values */ + /* */ + /* Returns: */ + /* Error code */ + /* */ + /* */ + /******************************************************************/ + + EXPORT_DEF + TT_Error TT_Get_Face_Widths( TT_Face face, + TT_UShort first_glyph, + TT_UShort last_glyph, + TT_UShort* widths, + TT_UShort* heights ); + +#ifdef __cplusplus +} +#endif + +#endif /* FTXWIDTH_H */ + + +/* END */ diff --git a/lib/extend/readme.1st b/lib/extend/readme.1st new file mode 100644 index 0000000..cce94cd --- /dev/null +++ b/lib/extend/readme.1st @@ -0,0 +1,61 @@ +This directory contains several extensions to the core engine. + +An extension is a separately compilable unit which can be linked by +a client application to add new functionalities to the engine. + +There are two kinds of extensions: an `API extension' provides +clients with new APIs to access internal engine structures or data, +while an `engine extension' implements new TrueType data or table +management. + +This directory contains the following: + + ftxcmap: An API extension to iterate over cmaps. + + ftxgasp: A simple API extension which returns the TrueType `gasp' + table to client applications, when found in a font file. + Though this table is always loaded by the engine, there + is no function in the core API to access it. The reason + is simple: to demonstrate a simple API extension with + `ftxgasp'! + + ftxkern: This engine extension is used to access kerning data, + when available in a font file. Note that it implements + on-the-fly loading and retrieving of kerning tables. + However, it doesn't interpret or process the data, and + client applications should use it according to the + TrueType specification. + + ftxpost: An engine extension to load the PostScript glyph names + of the `post' table. See the `ftzoom' program for an + example how to use it. + + ftxwidth: A simple extension used to load the widths and heights + of a given range of glyphs in a face. Results are + expressed in unscaled font units. This is required by + the latest version of the FreeType/2 DLL to speed up + font loading in the GRE (the OS/2 GRaphics Engine). It + can be used by other applications though... + + ftxerr18: This extension simply converts a TrueType engine error + code into a corresponding string describing the error. + It is useful if you intend to write a package for end + users and want to give them not `Error code 135' but + `OS/2 table missing'. See docs/errstr.txt for a + description how to use it (really simple!). ftxerr18 + supports localization of error strings (that is: error + strings are automatically translated into supported + languages) using gettext(). See docs/i18n.txt about + using gettext. + + ftxsbit: Embedded bitmap support. This is an engine extension. + See e.g. the `ftstrtto' program for its usage. + + ftxopen, + ftxgsub, + ftxgpos, + ftxgdef: This is experimental stuff for TrueType Open support! + Please ignore it or help debugging :-) + + +--- END --- diff --git a/lib/freetype.h b/lib/freetype.h new file mode 100644 index 0000000..0b0237c --- /dev/null +++ b/lib/freetype.h @@ -0,0 +1,1147 @@ +/******************************************************************* + * + * freetype.h + * + * High-level interface specification. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Note: + * + * This is the only file that should be included by client + * application sources. All other types and functions defined + * in the `tt*.h' files are library internals and should not be + * included. + * + ******************************************************************/ + +#ifndef FREETYPE_H +#define FREETYPE_H + + +#define TT_FREETYPE_MAJOR 1 +#define TT_FREETYPE_MINOR 3 + + +#include "fterrid.h" +#include "ftnameid.h" + +/* To make freetype.h independent from configuration files we check */ +/* whether EXPORT_DEF has been defined already. */ + +#ifndef EXPORT_DEF +#define EXPORT_DEF extern +#endif + +/* The same for TT_Text. If you define the HAVE_TT_TEXT macro, you */ +/* have to provide a typedef declaration for TT_Text before */ +/* including this file. */ + +#ifndef HAVE_TT_TEXT +#define HAVE_TT_TEXT + typedef char TT_Text; /* The data type to represent */ + /* file name string elements. */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + + /*******************************************************************/ + /* */ + /* FreeType types definitions. */ + /* */ + /* All these begin with a 'TT_' prefix. */ + /* */ + /*******************************************************************/ + + typedef int TT_Bool; + + typedef signed long TT_Fixed; /* signed fixed 16.16 float */ + + typedef signed short TT_FWord; /* distance in FUnits */ + typedef unsigned short TT_UFWord; /* unsigned distance */ + + typedef char TT_String; + typedef signed char TT_Char; + typedef unsigned char TT_Byte; + typedef signed short TT_Short; + typedef unsigned short TT_UShort; + typedef int TT_Int; + typedef unsigned int TT_UInt; + typedef signed long TT_Long; + typedef unsigned long TT_ULong; + + typedef signed short TT_F2Dot14; /* Signed fixed float 2.14 used for */ + /* unit vectors, with layout */ + /* */ + /* s : 1 -- sign bit */ + /* m : 1 -- integer bit */ + /* f : 14 -- unsigned fractional */ + /* */ + /* `s:m' is the 2-bit signed int */ + /* value to which the positive */ + /* fractional part should be added. */ + + typedef signed long TT_F26Dot6; /* 26.6 fixed float, used for */ + /* glyph points pixel coordinates. */ + + typedef signed long TT_Pos; /* Point position, expressed either */ + /* in fractional pixels or notional */ + /* units, depending on context. */ + /* For example, glyph coordinates */ + /* returned by TT_Load_Glyph() are */ + /* expressed in font units if */ + /* scaling wasn't requested, and */ + /* in 26.6 fractional pixels if it */ + /* was. */ + + + struct TT_UnitVector_ /* guess what... */ + { + TT_F2Dot14 x; + TT_F2Dot14 y; + }; + + typedef struct TT_UnitVector_ TT_UnitVector; + + + struct TT_Vector_ /* simple vector type */ + { + TT_F26Dot6 x; + TT_F26Dot6 y; + }; + + typedef struct TT_Vector_ TT_Vector; + + + /* A simple 2x2 matrix used for transformations. */ + /* You should use 16.16 fixed floats. */ + /* */ + /* x' = xx*x + xy*y */ + /* y' = yx*x + yy*y */ + /* */ + + struct TT_Matrix_ + { + TT_Fixed xx, xy; + TT_Fixed yx, yy; + }; + + typedef struct TT_Matrix_ TT_Matrix; + + + /* A structure used to describe the source glyph to the renderer. */ + + struct TT_Outline_ + { + TT_Short n_contours; /* number of contours in glyph */ + TT_UShort n_points; /* number of points in the glyph */ + + TT_Vector* points; /* the outline's points */ + TT_Byte* flags; /* the points flags */ + TT_UShort* contours; /* the contour end points */ + + /* The following flag indicates that the outline owns the arrays it */ + /* refers to. Typically, this is true of outlines created from the */ + /* TT_New_Outline() API, while it isn't for those returned by */ + /* TT_Get_Glyph_Outline(). */ + + TT_Bool owner; /* The outline owns the coordinates, */ + /* flags and contours array it uses. */ + + /* The following flags are set automatically by */ + /* TT_Get_Glyph_Outline(). Their meaning is the following: */ + /* */ + /* high_precision If true, the scan-line converter will use a */ + /* higher precision to render bitmaps (i.e., a */ + /* 1/1024 pixel precision). This is important for */ + /* small ppem sizes. */ + /* */ + /* second_pass If true, the scan-line converter performs a */ + /* second sweep phase dedicated to find vertical */ + /* drop-outs. If false, only horizontal drop-outs */ + /* will be checked during the first vertical */ + /* sweep (yes, this is a bit confusing but it is */ + /* really the way it should work). This is */ + /* important for small ppems too. */ + /* */ + /* dropout_mode Specifies the TrueType drop-out mode to use for */ + /* continuity checking. Valid values are 0 (no */ + /* check), 1, 2, 4, and 5. */ + /* */ + /* Most of the engine's users will safely ignore these fields... */ + + TT_Bool high_precision; /* high precision rendering */ + TT_Bool second_pass; /* two sweeps rendering */ + TT_Char dropout_mode; /* dropout mode */ + }; + + typedef struct TT_Outline_ TT_Outline; + + + /* A structure used to describe a simple bounding box. */ + + struct TT_BBox_ + { + TT_Pos xMin; + TT_Pos yMin; + TT_Pos xMax; + TT_Pos yMax; + }; + + typedef struct TT_BBox_ TT_BBox; + + + /* A structure used to return glyph metrics. */ + /* */ + /* The `bearingX' isn't called `left-side bearing' anymore because */ + /* it has different meanings depending on the glyph's orientation. */ + /* */ + /* The same is true for `bearingY', which is the top-side bearing */ + /* defined by the TT_Spec, i.e., the distance from the baseline to */ + /* the top of the glyph's bbox. According to our current convention, */ + /* this is always the same as `bbox.yMax' but we make it appear for */ + /* consistency in its proper field. */ + /* */ + /* The `advance' field is the advance width for horizontal layout, */ + /* and advance height for vertical layouts. */ + + struct TT_Glyph_Metrics_ + { + TT_BBox bbox; /* glyph bounding box */ + + TT_Pos bearingX; /* left-side bearing */ + TT_Pos bearingY; /* top-side bearing, per se the TT spec */ + + TT_Pos advance; /* advance width (or height) */ + }; + + typedef struct TT_Glyph_Metrics_ TT_Glyph_Metrics; + + + /* A structure used to return horizontal _and_ vertical glyph */ + /* metrics. */ + /* */ + /* A glyph can be used either in a horizontal or vertical layout. */ + /* Its glyph metrics vary with orientation. The TT_Big_Glyph_Metrics */ + /* structure is used to return _all_ metrics in one call. */ + + struct TT_Big_Glyph_Metrics_ + { + TT_BBox bbox; /* glyph bounding box */ + + TT_Pos horiBearingX; /* left side bearing in horizontal layouts */ + TT_Pos horiBearingY; /* top side bearing in horizontal layouts */ + + TT_Pos vertBearingX; /* left side bearing in vertical layouts */ + TT_Pos vertBearingY; /* top side bearing in vertical layouts */ + + TT_Pos horiAdvance; /* advance width for horizontal layout */ + TT_Pos vertAdvance; /* advance height for vertical layout */ + + /* The following fields represent unhinted scaled metrics values. */ + /* They can be useful for applications needing to do some device */ + /* independent placement of glyphs. */ + /* */ + /* Applying these metrics to hinted glyphs will most surely ruin */ + /* the grid fitting performed by the bytecode interpreter. These */ + /* values are better used to compute accumulated positioning */ + /* distances. */ + + TT_Pos linearHoriBearingX; /* linearly scaled horizontal lsb */ + TT_Pos linearHoriAdvance; /* linearly scaled horizontal advance */ + + TT_Pos linearVertBearingY; /* linearly scaled vertical tsb */ + TT_Pos linearVertAdvance; /* linearly scaled vertical advance */ + }; + + typedef struct TT_Big_Glyph_Metrics_ TT_Big_Glyph_Metrics; + + + /* A structure used to return instance metrics. */ + + struct TT_Instance_Metrics_ + { + TT_F26Dot6 pointSize; /* char. size in points (1pt = 1/72 inch) */ + + TT_UShort x_ppem; /* horizontal pixels per EM square */ + TT_UShort y_ppem; /* vertical pixels per EM square */ + + TT_Fixed x_scale; /* 16.16 to convert from EM units to 26.6 pix */ + TT_Fixed y_scale; /* 16.16 to convert from EM units to 26.6 pix */ + + TT_UShort x_resolution; /* device horizontal resolution in dpi */ + TT_UShort y_resolution; /* device vertical resolution in dpi */ + }; + + typedef struct TT_Instance_Metrics_ TT_Instance_Metrics; + + + /* Flow constants: */ + /* */ + /* The flow of a bitmap refers to the way lines are oriented */ + /* within the bitmap data, i.e., the orientation of the Y */ + /* coordinate axis. */ + /* */ + /* For example, if the first bytes of the bitmap pertain to */ + /* its top-most line, then the flow is `down'. If these bytes */ + /* pertain to its lowest line, the the flow is `up'. */ + +#define TT_Flow_Down -1 /* bitmap is oriented from top to bottom */ +#define TT_Flow_Up 1 /* bitmap is oriented from bottom to top */ +#define TT_Flow_Error 0 /* an error occurred during rendering */ + + + /* A structure used to describe the target bitmap or pixmap to the */ + /* renderer. Note that there is nothing in this structure that */ + /* gives the nature of the buffer. */ + /* */ + /* IMPORTANT NOTE: */ + /* */ + /* In the case of a pixmap, the `width' and `cols' fields must */ + /* have the _same_ values, and _must_ be padded to 32-bits, i.e., */ + /* be a multiple of 4. Clipping problems will arise otherwise, */ + /* if not even page faults! */ + /* */ + /* The typical settings are: */ + /* */ + /* - for a WxH bitmap: */ + /* */ + /* rows = H */ + /* cols = (W+7) / 8 */ + /* width = W */ + /* flow = your_choice */ + /* */ + /* - for a WxH pixmap: */ + /* */ + /* rows = H */ + /* cols = (W+3) & ~3 */ + /* width = cols */ + /* flow = your_choice */ + + struct TT_Raster_Map_ + { + int rows; /* number of rows */ + int cols; /* number of columns (bytes) per row */ + int width; /* number of pixels per line */ + int flow; /* bitmap orientation */ + + void* bitmap; /* bit/pixmap buffer */ + long size; /* bit/pixmap size in bytes */ + }; + + typedef struct TT_Raster_Map_ TT_Raster_Map; + + + /* ------ The font header TrueType table structure ------ */ + + struct TT_Header_ + { + TT_Fixed Table_Version; + TT_Fixed Font_Revision; + + TT_Long CheckSum_Adjust; + TT_Long Magic_Number; + + TT_UShort Flags; + TT_UShort Units_Per_EM; + + TT_Long Created [2]; + TT_Long Modified[2]; + + TT_FWord xMin; + TT_FWord yMin; + TT_FWord xMax; + TT_FWord yMax; + + TT_UShort Mac_Style; + TT_UShort Lowest_Rec_PPEM; + + TT_Short Font_Direction; + TT_Short Index_To_Loc_Format; + TT_Short Glyph_Data_Format; + }; + + typedef struct TT_Header_ TT_Header; + + + /* ------ The horizontal header TrueType table structure ------ */ + + /*******************************************************/ + /* This structure is the one defined by the TrueType */ + /* specification, plus two fields used to link the */ + /* font-units metrics to the header. */ + + struct TT_Horizontal_Header_ + { + TT_Fixed Version; + TT_FWord Ascender; + TT_FWord Descender; + TT_FWord Line_Gap; + + TT_UFWord advance_Width_Max; /* advance width maximum */ + + TT_FWord min_Left_Side_Bearing; /* minimum left-sb */ + TT_FWord min_Right_Side_Bearing; /* minimum right-sb */ + TT_FWord xMax_Extent; /* xmax extents */ + TT_FWord caret_Slope_Rise; + TT_FWord caret_Slope_Run; + + TT_Short Reserved0, + Reserved1, + Reserved2, + Reserved3, + Reserved4; + + TT_Short metric_Data_Format; + TT_UShort number_Of_HMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + }; + + typedef struct TT_Horizontal_Header_ TT_Horizontal_Header; + + + /*******************************************************/ + /* This structure is the one defined by the TrueType */ + /* specification. Note that it has exactly the same */ + /* layout as the horizontal header (both are loaded */ + /* by the same function). */ + + struct TT_Vertical_Header_ + { + TT_Fixed Version; + TT_FWord Ascender; + TT_FWord Descender; + TT_FWord Line_Gap; + + TT_UFWord advance_Height_Max; /* advance height maximum */ + + TT_FWord min_Top_Side_Bearing; /* minimum left-sb or top-sb */ + TT_FWord min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ + TT_FWord yMax_Extent; /* xmax or ymax extents */ + TT_FWord caret_Slope_Rise; + TT_FWord caret_Slope_Run; + TT_FWord caret_Offset; + + TT_Short Reserved1, + Reserved2, + Reserved3, + Reserved4; + + TT_Short metric_Data_Format; + TT_UShort number_Of_VMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + }; + + typedef struct TT_Vertical_Header_ TT_Vertical_Header; + + + /* ------ The OS/2 table ------ */ + + /************************************************************************/ + /* Note that since FreeType 1.3, we support Mac fonts which do not have */ + /* an OS/2 table. In this case the `version' field will be set to */ + /* 0xFFFF by the table loader; all other fields should be 0. */ + + struct TT_OS2_ + { + TT_UShort version; /* 0x0001 */ + TT_FWord xAvgCharWidth; + TT_UShort usWeightClass; + TT_UShort usWidthClass; + TT_Short fsType; + TT_FWord ySubscriptXSize; + TT_FWord ySubscriptYSize; + TT_FWord ySubscriptXOffset; + TT_FWord ySubscriptYOffset; + TT_FWord ySuperscriptXSize; + TT_FWord ySuperscriptYSize; + TT_FWord ySuperscriptXOffset; + TT_FWord ySuperscriptYOffset; + TT_FWord yStrikeoutSize; + TT_FWord yStrikeoutPosition; + TT_Short sFamilyClass; + + TT_Byte panose[10]; + + TT_ULong ulUnicodeRange1; /* Bits 0-31 */ + TT_ULong ulUnicodeRange2; /* Bits 32-63 */ + TT_ULong ulUnicodeRange3; /* Bits 64-95 */ + TT_ULong ulUnicodeRange4; /* Bits 96-127 */ + + TT_Char achVendID[4]; + + TT_UShort fsSelection; + TT_UShort usFirstCharIndex; + TT_UShort usLastCharIndex; + TT_Short sTypoAscender; + TT_Short sTypoDescender; + TT_Short sTypoLineGap; + TT_UShort usWinAscent; + TT_UShort usWinDescent; + + /* only version 1 tables: */ + + TT_ULong ulCodePageRange1; /* Bits 0-31 */ + TT_ULong ulCodePageRange2; /* Bits 32-63 */ + }; + + typedef struct TT_OS2_ TT_OS2; + + + /* ------ The PostScript table ------ */ + + struct TT_Postscript_ + { + TT_Fixed FormatType; + TT_Fixed italicAngle; + TT_FWord underlinePosition; + TT_FWord underlineThickness; + TT_ULong isFixedPitch; + TT_ULong minMemType42; + TT_ULong maxMemType42; + TT_ULong minMemType1; + TT_ULong maxMemType1; + + /* Glyph names follow in the file, but we don't */ + /* load them by default. See the ftxpost.c extension. */ + }; + + typedef struct TT_Postscript_ TT_Postscript; + + + /* ------ The horizontal device metrics table (`hdmx') ------ */ + + struct TT_Hdmx_Record_ + { + TT_Byte ppem; + TT_Byte max_width; + TT_Byte* widths; + }; + + typedef struct TT_Hdmx_Record_ TT_Hdmx_Record; + + + struct TT_Hdmx_ + { + TT_UShort version; + TT_Short num_records; + TT_Hdmx_Record* records; + }; + + typedef struct TT_Hdmx_ TT_Hdmx; + + + /* A structure used to describe face properties. */ + + struct TT_Face_Properties_ + { + TT_UShort num_Glyphs; /* number of glyphs in face */ + TT_UShort max_Points; /* maximum number of points in a glyph */ + TT_UShort max_Contours; /* maximum number of contours in a glyph */ + + TT_UShort num_CharMaps; /* number of charmaps in the face */ + TT_UShort num_Names; /* number of name records in the face */ + + TT_ULong num_Faces; /* 1 for normal TrueType files, and the */ + /* number of embedded faces for TrueType */ + /* collections */ + + TT_Header* header; /* TrueType header table */ + TT_Horizontal_Header* horizontal; /* TrueType horizontal header */ + TT_OS2* os2; /* TrueType OS/2 table */ + TT_Postscript* postscript; /* TrueType Postscript table */ + TT_Hdmx* hdmx; /* TrueType hor. dev. metr. table */ + TT_Vertical_Header* vertical; /* TT Vertical header, if present */ + }; + + typedef struct TT_Face_Properties_ TT_Face_Properties; + + + /* Here are the definitions of the handle types used for FreeType's */ + /* most common objects accessed by the client application. We use */ + /* a simple trick: */ + /* */ + /* Each handle type is a structure that only contains one */ + /* pointer. The advantage of structures is that they are */ + /* mutually exclusive types. We could have defined the */ + /* following types: */ + /* */ + /* typedef void* TT_Stream; */ + /* typedef void* TT_Face; */ + /* typedef void* TT_Instance; */ + /* typedef void* TT_Glyph; */ + /* typedef void* TT_CharMap; */ + /* */ + /* but these would have allowed lines like: */ + /* */ + /* stream = instance; */ + /* */ + /* in the client code this would be a severe bug, unnoticed */ + /* by the compiler! */ + /* */ + /* Thus, we enforce type checking with a simple language */ + /* trick... */ + /* */ + /* NOTE: Some macros are defined in tttypes.h to perform */ + /* automatic type conversions for library hackers... */ + + struct TT_Engine_ { void* z; }; + struct TT_Stream_ { void* z; }; + struct TT_Face_ { void* z; }; + struct TT_Instance_ { void* z; }; + struct TT_Glyph_ { void* z; }; + struct TT_CharMap_ { void* z; }; + + typedef struct TT_Engine_ TT_Engine; /* engine instance */ + typedef struct TT_Stream_ TT_Stream; /* stream handle type */ + typedef struct TT_Face_ TT_Face; /* face handle type */ + typedef struct TT_Instance_ TT_Instance; /* instance handle type */ + typedef struct TT_Glyph_ TT_Glyph; /* glyph handle type */ + typedef struct TT_CharMap_ TT_CharMap; /* character map handle type */ + + + /* Almost all functions return an error code of this type. */ + + typedef long TT_Error; + + + /*******************************************************************/ + /* */ + /* FreeType API */ + /* */ + /* All these begin with a `TT_' prefix. */ + /* */ + /* Most of them are implemented in the `ttapi.c' source file. */ + /* */ + /*******************************************************************/ + + /* Get version information. */ + + EXPORT_DEF + TT_Error TT_FreeType_Version( int *major, + int *minor ); + + + /* Initialize the engine. */ + + EXPORT_DEF + TT_Error TT_Init_FreeType( TT_Engine* engine ); + + + /* Finalize the engine, and release all allocated objects. */ + + EXPORT_DEF + TT_Error TT_Done_FreeType( TT_Engine engine ); + + + /* Set the gray level palette. This is an array of 5 bytes used */ + /* to produce the font smoothed pixmaps. By convention: */ + /* */ + /* palette[0] = background (white) */ + /* palette[1] = light */ + /* palette[2] = medium */ + /* palette[3] = dark */ + /* palette[4] = foreground (black) */ + /* */ + + EXPORT_DEF + TT_Error TT_Set_Raster_Gray_Palette( TT_Engine engine, + TT_Byte* palette ); + + + /* ----------------------- face management ----------------------- */ + + /* Open a new TrueType font file, and returns a handle for */ + /* it in variable '*face'. */ + /* */ + /* Note: The file can be either a TrueType file (*.ttf) or */ + /* a TrueType collection (*.ttc, in this case, only */ + /* the first face is opened). The number of faces in */ + /* the same collection can be obtained in the face's */ + /* properties, using TT_Get_Face_Properties() and the */ + /* `max_Faces' field. */ + + EXPORT_DEF + TT_Error TT_Open_Face( TT_Engine engine, + const TT_Text* fontPathName, + TT_Face* face ); + + + /* Open a TrueType font file located inside a collection. */ + /* The font is assigned by its index in `fontIndex'. */ + + EXPORT_DEF + TT_Error TT_Open_Collection( TT_Engine engine, + const TT_Text* collectionPathName, + TT_ULong fontIndex, + TT_Face* face ); + + + /* Return face properties in the `properties' structure. */ + /* */ + /* Note that since version 1.3, we support font files with no */ + /* OS/2 table (mainly old Mac fonts). In this case, the OS/2 */ + /* `version' field will be set to 0xFFFF, and all other fields */ + /* will be zeroed. */ + + EXPORT_DEF + TT_Error TT_Get_Face_Properties( TT_Face face, + TT_Face_Properties* properties ); + + + /* Set a face object's generic pointer */ + + EXPORT_DEF + TT_Error TT_Set_Face_Pointer( TT_Face face, + void* data ); + + + /* Get a face object's generic pointer */ + + EXPORT_DEF + void* TT_Get_Face_Pointer( TT_Face face ); + + + /* Close a face's file handle to save system resources. The file */ + /* will be re-opened automatically on the next disk access. */ + + EXPORT_DEF + TT_Error TT_Flush_Face( TT_Face face ); + + /* Get a face's glyph metrics expressed in font units. Returns any */ + /* number of arrays. Set the fields to NULL if you are not interested */ + /* by a given array. */ + + EXPORT_DEF + TT_Error TT_Get_Face_Metrics( TT_Face face, + TT_UShort firstGlyph, + TT_UShort lastGlyph, + TT_Short* leftBearings, + TT_UShort* widths, + TT_Short* topBearings, + TT_UShort* heights ); + + + /* Close a given font object, destroying all associated */ + /* instances. */ + + EXPORT_DEF + TT_Error TT_Close_Face( TT_Face face ); + + + /* Get font or table data. */ + + EXPORT_DEF + TT_Error TT_Get_Font_Data( TT_Face face, + TT_ULong tag, + TT_Long offset, + void* buffer, + TT_Long* length ); + + +/* A simple macro to build table tags from ASCII chars */ + +#define MAKE_TT_TAG( _x1, _x2, _x3, _x4 ) \ + (((TT_ULong)_x1 << 24) | \ + ((TT_ULong)_x2 << 16) | \ + ((TT_ULong)_x3 << 8) | \ + (TT_ULong)_x4) + + + + /* ----------------------- instance management -------------------- */ + + /* Open a new font instance and returns an instance handle */ + /* for it in `*instance'. */ + + EXPORT_DEF + TT_Error TT_New_Instance( TT_Face face, + TT_Instance* instance ); + + + /* Set device resolution for a given instance. The values are */ + /* given in dpi (Dots Per Inch). Default is 96 in both directions. */ + + EXPORT_DEF + TT_Error TT_Set_Instance_Resolutions( TT_Instance instance, + TT_UShort xResolution, + TT_UShort yResolution ); + + + /* Set the pointsize for a given instance. Default is 10pt. */ + + EXPORT_DEF + TT_Error TT_Set_Instance_CharSize( TT_Instance instance, + TT_F26Dot6 charSize ); + + EXPORT_DEF + TT_Error TT_Set_Instance_CharSizes( TT_Instance instance, + TT_F26Dot6 charWidth, + TT_F26Dot6 charHeight ); + +#define TT_Set_Instance_PointSize( ins, ptsize ) \ + TT_Set_Instance_CharSize( ins, ptsize*64L ) + + EXPORT_DEF + TT_Error TT_Set_Instance_PixelSizes( TT_Instance instance, + TT_UShort pixelWidth, + TT_UShort pixelHeight, + TT_F26Dot6 pointSize ); + + + /* This function has been deprecated! Do not use it, as it */ + /* doesn't work reliably. You can perfectly control hinting */ + /* yourself when loading glyphs, then apply transforms as usual. */ + + EXPORT_DEF + TT_Error TT_Set_Instance_Transform_Flags( TT_Instance instance, + TT_Bool rotated, + TT_Bool stretched ); + + + /* Return instance metrics in `metrics'. */ + + EXPORT_DEF + TT_Error TT_Get_Instance_Metrics( TT_Instance instance, + TT_Instance_Metrics* metrics ); + + + /* Set an instance's generic pointer. */ + + EXPORT_DEF + TT_Error TT_Set_Instance_Pointer( TT_Instance instance, + void* data ); + + + /* Get an instance's generic pointer. */ + + EXPORT_DEF + void* TT_Get_Instance_Pointer( TT_Instance instance ); + + + /* Close a given instance object, destroying all associated data. */ + + EXPORT_DEF + TT_Error TT_Done_Instance( TT_Instance instance ); + + + + /* ----------------------- glyph management ----------------------- */ + + /* Create a new glyph object related to the given `face'. */ + + EXPORT_DEF + TT_Error TT_New_Glyph( TT_Face face, + TT_Glyph* glyph ); + + + /* Discard (and destroy) a given glyph object. */ + + EXPORT_DEF + TT_Error TT_Done_Glyph( TT_Glyph glyph ); + + +#define TTLOAD_SCALE_GLYPH 1 +#define TTLOAD_HINT_GLYPH 2 +#define TTLOAD_PEDANTIC 128 +#define TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 256 + +#define TTLOAD_DEFAULT (TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH) + + + /* Load and process (scale/transform and hint) a glyph from the */ + /* given `instance'. The glyph and instance handles must be */ + /* related to the same face object. The glyph index can be */ + /* computed with a call to TT_Char_Index(). */ + /* */ + /* The 'load_flags' argument is a combination of the macros */ + /* TTLOAD_SCALE_GLYPH and TTLOAD_HINT_GLYPH. Hinting will be */ + /* applied only if the scaling is selected. */ + /* */ + /* If scaling is off (i.e., load_flags = 0), the returned */ + /* outlines are in EM square coordinates (also called FUnits), */ + /* extracted directly from the font with no hinting. Other */ + /* glyph metrics are also in FUnits. */ + /* */ + /* If scaling is on, the returned outlines are in fractional */ + /* pixel units (i.e. TT_F26Dot6 = 26.6 fixed floats). */ + /* */ + /* NOTE: The glyph index must be in the range 0..num_glyphs-1, */ + /* where `num_glyphs' is the total number of glyphs in */ + /* the font file (given in the face properties). */ + + EXPORT_DEF + TT_Error TT_Load_Glyph( TT_Instance instance, + TT_Glyph glyph, + TT_UShort glyphIndex, + TT_UShort loadFlags ); + + + /* Return glyph outline pointers in `outline'. Note that the returned */ + /* pointers are owned by the glyph object, and will be destroyed with */ + /* it. The client application should _not_ change the pointers. */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Outline( TT_Glyph glyph, + TT_Outline* outline ); + + + /* Copy the glyph metrics into `metrics'. */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Metrics( TT_Glyph glyph, + TT_Glyph_Metrics* metrics ); + + + /* Copy the glyph's big metrics into `metrics'. */ + /* Necessary to obtain vertical metrics. */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Big_Metrics( TT_Glyph glyph, + TT_Big_Glyph_Metrics* metrics ); + + + /* Render the glyph into a bitmap, with given position offsets. */ + /* */ + /* Note: Only use integer pixel offsets to preserve the fine */ + /* hinting of the glyph and the `correct' anti-aliasing */ + /* (where vertical and horizontal stems aren't grayed). This */ + /* means that `xOffset' and `yOffset' must be multiples */ + /* of 64! */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Bitmap( TT_Glyph glyph, + TT_Raster_Map* map, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + + /* Render the glyph into a pixmap, with given position offsets. */ + /* */ + /* Note: Only use integer pixel offsets to preserve the fine */ + /* hinting of the glyph and the `correct' anti-aliasing */ + /* (where vertical and horizontal stems aren't grayed). This */ + /* means that `xOffset' and `yOffset' must be multiples */ + /* of 64! */ + + EXPORT_DEF + TT_Error TT_Get_Glyph_Pixmap( TT_Glyph glyph, + TT_Raster_Map* map, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + + + /* ----------------------- outline support ------------------------ */ + + /* Allocate a new outline. Reserve space for `numPoints' and */ + /* `numContours'. */ + + EXPORT_DEF + TT_Error TT_New_Outline( TT_UShort numPoints, + TT_Short numContours, + TT_Outline* outline ); + + + /* Release an outline. */ + + EXPORT_DEF + TT_Error TT_Done_Outline( TT_Outline* outline ); + + + /* Copy an outline into another one. */ + + EXPORT_DEF + TT_Error TT_Copy_Outline( TT_Outline* source, + TT_Outline* target ); + + + /* Render an outline into a bitmap. */ + + EXPORT_DEF + TT_Error TT_Get_Outline_Bitmap( TT_Engine engine, + TT_Outline* outline, + TT_Raster_Map* map ); + + + /* Render an outline into a pixmap. */ + + EXPORT_DEF + TT_Error TT_Get_Outline_Pixmap( TT_Engine engine, + TT_Outline* outline, + TT_Raster_Map* map ); + + + /* Return an outline's bounding box -- this function is slow as it */ + /* performs a complete scan-line process, without drawing, to get */ + /* the most accurate values. */ + + EXPORT_DEF + TT_Error TT_Get_Outline_BBox( TT_Outline* outline, + TT_BBox* bbox ); + + + /* Apply a transformation to a glyph outline. */ + + EXPORT_DEF + void TT_Transform_Outline( TT_Outline* outline, + TT_Matrix* matrix ); + + + /* Apply a translation to a glyph outline. */ + + EXPORT_DEF + void TT_Translate_Outline( TT_Outline* outline, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ); + + + /* Apply a transformation to a vector. */ + + EXPORT_DEF + void TT_Transform_Vector( TT_F26Dot6* x, + TT_F26Dot6* y, + TT_Matrix* matrix ); + + + /* Compute A*B/C with 64 bits intermediate precision. */ + + EXPORT_DEF + TT_Long TT_MulDiv( TT_Long A, + TT_Long B, + TT_Long C ); + + + /* Compute A*B/0x10000 with 64 bits intermediate precision. */ + /* Useful to multiply by a 16.16 fixed float value. */ + + EXPORT_DEF + TT_Long TT_MulFix( TT_Long A, + TT_Long B ); + + + /* ----------------- character mapping support --------------- */ + + /* Return the number of character mappings found in this file. */ + /* Returns -1 in case of failure (invalid face handle). */ + /* */ + /* DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED! */ + /* */ + /* It is retained for backwards compatibility only and will */ + /* fail on 16bit systems. */ + /* */ + /* You can now get the charmap count in the `num_CharMaps' */ + /* field of a face's properties. */ + /* */ + + EXPORT_DEF + int TT_Get_CharMap_Count( TT_Face face ); + + + /* Return the ID of charmap number `charmapIndex' of a given face */ + /* used to enumerate the charmaps present in a TrueType file. */ + + EXPORT_DEF + TT_Error TT_Get_CharMap_ID( TT_Face face, + TT_UShort charmapIndex, + TT_UShort* platformID, + TT_UShort* encodingID ); + + + /* Look up the character maps found in `face' and return a handle */ + /* for the one matching `platformID' and `platformEncodingID' */ + /* (see the TrueType specs relating to the `cmap' table for */ + /* information on these ID numbers). Returns an error code. */ + /* In case of failure, the handle is set to NULL and is invalid. */ + + EXPORT_DEF + TT_Error TT_Get_CharMap( TT_Face face, + TT_UShort charmapIndex, + TT_CharMap* charMap ); + + + /* Translate a character code through a given character map */ + /* and return the corresponding glyph index to be used in */ + /* a TT_Load_Glyph() call. This function returns 0 in case */ + /* of failure. */ + + EXPORT_DEF + TT_UShort TT_Char_Index( TT_CharMap charMap, + TT_UShort charCode ); + + + + /* --------------------- names table support ------------------- */ + + /* Return the number of name strings found in the name table. */ + /* Returns -1 in case of failure (invalid face handle). */ + /* */ + /* DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED! */ + /* */ + /* It is retained for backwards compatibility only and will */ + /* fail on 16bit systems. */ + /* */ + /* You can now get the number of name strings in a face with */ + /* the `num_Names' field of its properties. */ + + EXPORT_DEF + int TT_Get_Name_Count( TT_Face face ); + + + /* Return the ID of the name number `nameIndex' of a given face */ + /* used to enumerate the charmaps present in a TrueType file. */ + + EXPORT_DEF + TT_Error TT_Get_Name_ID( TT_Face face, + TT_UShort nameIndex, + TT_UShort* platformID, + TT_UShort* encodingID, + TT_UShort* languageID, + TT_UShort* nameID ); + + + /* Return the address and length of the name number `nameIndex' */ + /* of a given face in the variables `stringPtr' resp. `length'. */ + /* The string is part of the face object and shouldn't be */ + /* written to or released. */ + /* */ + /* Note that for an invalid platform ID a null pointer will be */ + /* returned. */ + + EXPORT_DEF + TT_Error TT_Get_Name_String( TT_Face face, + TT_UShort nameIndex, + TT_String** stringPtr, + TT_UShort* length ); + + +#ifdef __cplusplus + } +#endif + +#endif /* FREETYPE_H */ + + +/* END */ diff --git a/lib/fterrid.h b/lib/fterrid.h new file mode 100644 index 0000000..0444e6f --- /dev/null +++ b/lib/fterrid.h @@ -0,0 +1,161 @@ +/******************************************************************* + * + * fterrid.h + * + * TrueType Error ID definitions + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FREETYPE_H +#error "Don't include this file! Use freetype.h instead." +#endif + +#ifndef FTERRID_H +#define FTERRID_H + + /************************ error codes declaration **************/ + + /* The error codes are grouped in 'classes' used to indicate the */ + /* 'level' at which the error happened. */ + /* The class is given by an error code's high byte. */ + + + /* ------------- Success is always 0 -------- */ + +#define TT_Err_Ok 0 + + + /* -------- High-level API error codes ------ */ + +#define TT_Err_Invalid_Face_Handle 0x001 +#define TT_Err_Invalid_Instance_Handle 0x002 +#define TT_Err_Invalid_Glyph_Handle 0x003 +#define TT_Err_Invalid_CharMap_Handle 0x004 +#define TT_Err_Invalid_Result_Address 0x005 +#define TT_Err_Invalid_Glyph_Index 0x006 +#define TT_Err_Invalid_Argument 0x007 +#define TT_Err_Could_Not_Open_File 0x008 +#define TT_Err_File_Is_Not_Collection 0x009 + +#define TT_Err_Table_Missing 0x00A +#define TT_Err_Invalid_Horiz_Metrics 0x00B +#define TT_Err_Invalid_CharMap_Format 0x00C +#define TT_Err_Invalid_PPem 0x00D +#define TT_Err_Invalid_Vert_Metrics 0x00E + +#define TT_Err_Invalid_File_Format 0x010 + +#define TT_Err_Invalid_Engine 0x020 +#define TT_Err_Too_Many_Extensions 0x021 +#define TT_Err_Extensions_Unsupported 0x022 +#define TT_Err_Invalid_Extension_Id 0x023 + +#define TT_Err_No_Vertical_Data 0x030 + +#define TT_Err_Max_Profile_Missing 0x080 +#define TT_Err_Header_Table_Missing 0x081 +#define TT_Err_Horiz_Header_Missing 0x082 +#define TT_Err_Locations_Missing 0x083 +#define TT_Err_Name_Table_Missing 0x084 +#define TT_Err_CMap_Table_Missing 0x085 +#define TT_Err_Hmtx_Table_Missing 0x086 +#define TT_Err_OS2_Table_Missing 0x087 +#define TT_Err_Post_Table_Missing 0x088 +#define TT_Err_Glyf_Table_Missing 0x089 + + + /* -------- Memory component error codes ---- */ + + /* this error indicates that an operation cannot */ + /* be performed due to memory exhaustion. */ + +#define TT_Err_Out_Of_Memory 0x100 + + + /* -------- File component error codes ------ */ + + /* these error codes indicate that the file could */ + /* not be accessed properly. Usually, this means */ + /* a broken font file! */ + +#define TT_Err_Invalid_File_Offset 0x200 +#define TT_Err_Invalid_File_Read 0x201 +#define TT_Err_Invalid_Frame_Access 0x202 + + + /* -------- Glyph loader error codes -------- */ + + /* Produced only by the glyph loader, these error */ + /* codes indicate a broken glyph in a font file. */ + +#define TT_Err_Too_Many_Points 0x300 +#define TT_Err_Too_Many_Contours 0x301 +#define TT_Err_Invalid_Composite 0x302 +#define TT_Err_Too_Many_Ins 0x303 + + + /* --- bytecode interpreter error codes ----- */ + + /* These error codes are produced by the TrueType */ + /* bytecode interpreter. They usually indicate a */ + /* broken font file, a broken glyph within a font */ + /* file, or a bug in the interpreter! */ + +#define TT_Err_Invalid_Opcode 0x400 +#define TT_Err_Too_Few_Arguments 0x401 +#define TT_Err_Stack_Overflow 0x402 +#define TT_Err_Code_Overflow 0x403 +#define TT_Err_Bad_Argument 0x404 +#define TT_Err_Divide_By_Zero 0x405 +#define TT_Err_Storage_Overflow 0x406 +#define TT_Err_Cvt_Overflow 0x407 +#define TT_Err_Invalid_Reference 0x408 +#define TT_Err_Invalid_Distance 0x409 +#define TT_Err_Interpolate_Twilight 0x40A +#define TT_Err_Debug_OpCode 0x40B +#define TT_Err_ENDF_In_Exec_Stream 0x40C +#define TT_Err_Out_Of_CodeRanges 0x40D +#define TT_Err_Nested_DEFS 0x40E +#define TT_Err_Invalid_CodeRange 0x40F +#define TT_Err_Invalid_Displacement 0x410 +#define TT_Err_Execution_Too_Long 0x411 + + + /* ------ internal failure error codes ----- */ + + /* These error codes are produced when an incoherent */ + /* library state has been detected. These reflect a */ + /* severe bug in the engine! (Or a major overwrite */ + /* of your application into the library's data.) */ + +#define TT_Err_Nested_Frame_Access 0x500 +#define TT_Err_Invalid_Cache_List 0x501 +#define TT_Err_Could_Not_Find_Context 0x502 +#define TT_Err_Unlisted_Object 0x503 + + + /* ---- scan-line converter error codes ----- */ + + /* These error codes are produced by the raster component. */ + /* They indicate that an outline structure was incoherently */ + /* setup, or that you're trying to render an horribly */ + /* complex glyph! */ + +#define TT_Err_Raster_Pool_Overflow 0x600 +#define TT_Err_Raster_Negative_Height 0x601 +#define TT_Err_Raster_Invalid_Value 0x602 +#define TT_Err_Raster_Not_Initialized 0x603 + +#endif /* FTERRID_H */ + + +/* END */ diff --git a/lib/ftnameid.h b/lib/ftnameid.h new file mode 100644 index 0000000..5d51234 --- /dev/null +++ b/lib/ftnameid.h @@ -0,0 +1,628 @@ +/******************************************************************* + * + * ftnameid.h + * + * TrueType Name ID definitions + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef FREETYPE_H +#error "Don't include this file! Use freetype.h instead." +#endif + +#ifndef FTNAMEID_H +#define FTNAMEID_H + +/* + * possible values for the 'Platform' identifier code in the name + * records of the TTF "name" table + */ + +#define TT_PLATFORM_APPLE_UNICODE 0 +#define TT_PLATFORM_MACINTOSH 1 +#define TT_PLATFORM_ISO 2 +#define TT_PLATFORM_MICROSOFT 3 + + +/* + * possible values of the platform specific encoding identifier field in + * the name records of the TTF "name" table when the 'Platform' identifier + * code is TT_PLATFORM_APPLE_UNICODE + */ + +#define TT_APPLE_ID_DEFAULT 0 +#define TT_APPLE_ID_UNICODE_1_1 1 +#define TT_APPLE_ID_ISO_10646 2 +#define TT_APPLE_ID_UNICODE_2_0 3 + + +/* + * possible values of the platform specific encoding identifier field in + * the name records of the TTF "name" table when the 'Platform' identifier + * code is TT_PLATFORM_MACINTOSH + */ + +#define TT_MAC_ID_ROMAN 0 +#define TT_MAC_ID_JAPANESE 1 +#define TT_MAC_ID_TRADITIONAL_CHINESE 2 +#define TT_MAC_ID_KOREAN 3 +#define TT_MAC_ID_ARABIC 4 +#define TT_MAC_ID_HEBREW 5 +#define TT_MAC_ID_GREEK 6 +#define TT_MAC_ID_RUSSIAN 7 +#define TT_MAC_ID_RSYMBOL 8 +#define TT_MAC_ID_DEVANAGARI 9 +#define TT_MAC_ID_GURMUKHI 10 +#define TT_MAC_ID_GUJARATI 11 +#define TT_MAC_ID_ORIYA 12 +#define TT_MAC_ID_BENGALI 13 +#define TT_MAC_ID_TAMIL 14 +#define TT_MAC_ID_TELUGU 15 +#define TT_MAC_ID_KANNADA 16 +#define TT_MAC_ID_MALAYALAM 17 +#define TT_MAC_ID_SINHALESE 18 +#define TT_MAC_ID_BURMESE 19 +#define TT_MAC_ID_KHMER 20 +#define TT_MAC_ID_THAI 21 +#define TT_MAC_ID_LAOTIAN 22 +#define TT_MAC_ID_GEORGIAN 23 +#define TT_MAC_ID_ARMENIAN 24 +#define TT_MAC_ID_MALDIVIAN 25 +#define TT_MAC_ID_SIMPLIFIED_CHINESE 25 +#define TT_MAC_ID_TIBETAN 26 +#define TT_MAC_ID_MONGOLIAN 27 +#define TT_MAC_ID_GEEZ 28 +#define TT_MAC_ID_SLAVIC 29 +#define TT_MAC_ID_VIETNAMESE 30 +#define TT_MAC_ID_SINDHI 31 +#define TT_MAC_ID_UNINTERP 32 + + +/* + * possible values of the platform specific encoding identifier field in + * the name records of the TTF "name" table when the 'Platform' identifier + * code is TT_PLATFORM_ISO + */ + +#define TT_ISO_ID_7BIT_ASCII 0 +#define TT_ISO_ID_10646 1 +#define TT_ISO_ID_8859_1 2 + + +/* + * possible values of the platform specific encoding identifier field in + * the name records of the TTF "name" table when the 'Platform' identifier + * code is TT_PLATFORM_MICROSOFT + */ + +#define TT_MS_ID_SYMBOL_CS 0 +#define TT_MS_ID_UNICODE_CS 1 +#define TT_MS_ID_SJIS 2 +#define TT_MS_ID_GB2312 3 +#define TT_MS_ID_BIG_5 4 +#define TT_MS_ID_WANSUNG 5 +#define TT_MS_ID_JOHAB 6 + + + +/* + * possible values of the language identifier field in the name records of + * the TTF "name" table when the 'Platform' identifier code is + * TT_PLATFORM_MACINTOSH + * + * the canonical source for the Apple assigned Language ID's is at + * http://fonts.apple.com/TTRefMan/RM06/Chap6name.html + */ + +#define TT_MAC_LANGID_ENGLISH 0 +#define TT_MAC_LANGID_FRENCH 1 +#define TT_MAC_LANGID_GERMAN 2 +#define TT_MAC_LANGID_ITALIAN 3 +#define TT_MAC_LANGID_DUTCH 4 +#define TT_MAC_LANGID_SWEDISH 5 +#define TT_MAC_LANGID_SPANISH 6 +#define TT_MAC_LANGID_DANISH 7 +#define TT_MAC_LANGID_PORTUGUESE 8 +#define TT_MAC_LANGID_NORWEGIAN 9 +#define TT_MAC_LANGID_HEBREW 10 +#define TT_MAC_LANGID_JAPANESE 11 +#define TT_MAC_LANGID_ARABIC 12 +#define TT_MAC_LANGID_FINNISH 13 +#define TT_MAC_LANGID_GREEK 14 +#define TT_MAC_LANGID_ICELANDIC 15 +#define TT_MAC_LANGID_MALTESE 16 +#define TT_MAC_LANGID_TURKISH 17 +#define TT_MAC_LANGID_CROATIAN 18 +#define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 +#define TT_MAC_LANGID_URDU 20 +#define TT_MAC_LANGID_HINDI 21 +#define TT_MAC_LANGID_THAI 22 +#define TT_MAC_LANGID_KOREAN 23 +#define TT_MAC_LANGID_LITHUANIAN 24 +#define TT_MAC_LANGID_POLISH 25 +#define TT_MAC_LANGID_HUNGARIAN 26 +#define TT_MAC_LANGID_ESTONIAN 27 +#define TT_MAC_LANGID_LETTISH 28 +#define TT_MAC_LANGID_SAAMISK 29 +#define TT_MAC_LANGID_FAEROESE 30 +#define TT_MAC_LANGID_FARSI 31 +#define TT_MAC_LANGID_RUSSIAN 32 +#define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 +#define TT_MAC_LANGID_FLEMISH 34 +#define TT_MAC_LANGID_IRISH 35 +#define TT_MAC_LANGID_ALBANIAN 36 +#define TT_MAC_LANGID_ROMANIAN 37 +#define TT_MAC_LANGID_CZECH 38 +#define TT_MAC_LANGID_SLOVAK 39 +#define TT_MAC_LANGID_SLOVENIAN 40 +#define TT_MAC_LANGID_YIDDISH 41 +#define TT_MAC_LANGID_SERBIAN 42 +#define TT_MAC_LANGID_MACEDONIAN 43 +#define TT_MAC_LANGID_BULGARIAN 44 +#define TT_MAC_LANGID_UKRAINIAN 45 +#define TT_MAC_LANGID_BYELORUSSIAN 46 +#define TT_MAC_LANGID_UZBEK 47 +#define TT_MAC_LANGID_KAZAKH 48 +#define TT_MAC_LANGID_AZERBAIJANI 49 +#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 +#define TT_MAC_LANGID_ARMENIAN 51 +#define TT_MAC_LANGID_GEORGIAN 52 +#define TT_MAC_LANGID_MOLDAVIAN 53 +#define TT_MAC_LANGID_KIRGHIZ 54 +#define TT_MAC_LANGID_TAJIKI 55 +#define TT_MAC_LANGID_TURKMEN 56 +#define TT_MAC_LANGID_MONGOLIAN 57 +#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 +#define TT_MAC_LANGID_PASHTO 59 +#define TT_MAC_LANGID_KURDISH 60 +#define TT_MAC_LANGID_KASHMIRI 61 +#define TT_MAC_LANGID_SINDHI 62 +#define TT_MAC_LANGID_TIBETAN 63 +#define TT_MAC_LANGID_NEPALI 64 +#define TT_MAC_LANGID_SANSKRIT 65 +#define TT_MAC_LANGID_MARATHI 66 +#define TT_MAC_LANGID_BENGALI 67 +#define TT_MAC_LANGID_ASSAMESE 68 +#define TT_MAC_LANGID_GUJARATI 69 +#define TT_MAC_LANGID_PUNJABI 70 +#define TT_MAC_LANGID_ORIYA 71 +#define TT_MAC_LANGID_MALAYALAM 72 +#define TT_MAC_LANGID_KANNADA 73 +#define TT_MAC_LANGID_TAMIL 74 +#define TT_MAC_LANGID_TELUGU 75 +#define TT_MAC_LANGID_SINHALESE 76 +#define TT_MAC_LANGID_BURMESE 77 +#define TT_MAC_LANGID_KHMER 78 +#define TT_MAC_LANGID_LAO 79 +#define TT_MAC_LANGID_VIETNAMESE 80 +#define TT_MAC_LANGID_INDONESIAN 81 +#define TT_MAC_LANGID_TAGALOG 82 +#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 +#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 +#define TT_MAC_LANGID_AMHARIC 85 +#define TT_MAC_LANGID_TIGRINYA 86 +#define TT_MAC_LANGID_GALLA 87 +#define TT_MAC_LANGID_SOMALI 88 +#define TT_MAC_LANGID_SWAHILI 89 +#define TT_MAC_LANGID_RUANDA 90 +#define TT_MAC_LANGID_RUNDI 91 +#define TT_MAC_LANGID_CHEWA 92 +#define TT_MAC_LANGID_MALAGASY 93 +#define TT_MAC_LANGID_ESPERANTO 94 +#define TT_MAC_LANGID_WELSH 128 +#define TT_MAC_LANGID_BASQUE 129 +#define TT_MAC_LANGID_CATALAN 130 +#define TT_MAC_LANGID_LATIN 131 +#define TT_MAC_LANGID_QUECHUA 132 +#define TT_MAC_LANGID_GUARANI 133 +#define TT_MAC_LANGID_AYMARA 134 +#define TT_MAC_LANGID_TATAR 135 +#define TT_MAC_LANGID_UIGHUR 136 +#define TT_MAC_LANGID_DZONGKHA 137 +#define TT_MAC_LANGID_JAVANESE 138 +#define TT_MAC_LANGID_SUNDANESE 139 +#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 +#define TT_MAC_LANGID_IRISH_GAELIC 141 +#define TT_MAC_LANGID_BRETON 142 +#define TT_MAC_LANGID_INUKTITUT 143 + + +/* + * possible values of the language identifier field in the name records of + * the TTF "name" table when the 'Platform' identifier code is + * TT_PLATFORM_MICROSOFT + * + * the canonical source for the MS assigned LCID's is at + * http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt + */ + +#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 +#define TT_MS_LANGID_ARABIC_IRAQ 0x0801 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0c01 +#define TT_MS_LANGID_ARABIC_LIBYA 0x1001 +#define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 +#define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1c01 +#define TT_MS_LANGID_ARABIC_OMAN 0x2001 +#define TT_MS_LANGID_ARABIC_YEMEN 0x2401 +#define TT_MS_LANGID_ARABIC_SYRIA 0x2801 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2c01 +#define TT_MS_LANGID_ARABIC_LEBANON 0x3001 +#define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 +#define TT_MS_LANGID_ARABIC_UAE 0x3801 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3c01 +#define TT_MS_LANGID_ARABIC_QATAR 0x4001 +#define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 +#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 +#define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 +#define TT_MS_LANGID_CHINESE_PRC 0x0804 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0c04 +#define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 +#define TT_MS_LANGID_CHINESE_MACAU 0x1404 +#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 +#define TT_MS_LANGID_DANISH_DENMARK 0x0406 +#define TT_MS_LANGID_GERMAN_GERMANY 0x0407 +#define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0c07 +#define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 +#define TT_MS_LANGID_GREEK_GREECE 0x0408 +#define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 +#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0c09 +#define TT_MS_LANGID_ENGLISH_CANADA 0x1009 +#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 +#define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1c09 +#define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 +#define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 +#define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2c09 +#define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 +#define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040a +#define TT_MS_LANGID_SPANISH_MEXICO 0x080a +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0c0a +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100a +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140a +#define TT_MS_LANGID_SPANISH_PANAMA 0x180a +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1c0a +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200a +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240a +#define TT_MS_LANGID_SPANISH_PERU 0x280a +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2c0a +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300a +#define TT_MS_LANGID_SPANISH_CHILE 0x340a +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380a +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3c0a +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400a +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440a +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480a +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4c0a +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500a +#define TT_MS_LANGID_FINNISH_FINLAND 0x040b +#define TT_MS_LANGID_FRENCH_FRANCE 0x040c +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080c +#define TT_MS_LANGID_FRENCH_CANADA 0x0c0c +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100c +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140c +#define TT_MS_LANGID_FRENCH_MONACO 0x180c +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040d +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040e +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040f +#define TT_MS_LANGID_ITALIAN_ITALY 0x0410 +#define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 +#define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 +#define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 +#define TT_MS_LANGID_POLISH_POLAND 0x0415 +#define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 +#define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 +#define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 +#define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041a +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081a +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0c1a +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041b +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041c +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041d +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081d +#define TT_MS_LANGID_THAI_THAILAND 0x041e +#define TT_MS_LANGID_TURKISH_TURKEY 0x041f +#define TT_MS_LANGID_URDU_PAKISTAN 0x0420 +#define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 +#define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 +#define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 +#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 +#define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 +#define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 +#define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0428 +#define TT_MS_LANGID_FARSI_IRAN 0x0429 +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042a +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042b +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042c +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082c +#define TT_MS_LANGID_BASQUE_SPAIN 0x042d +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042e +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042f +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 +#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 +#define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 +#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 +#define TT_MS_LANGID_HINDI_INDIA 0x0439 +#define TT_MS_LANGID_MALTESE_MALTA 0x043a +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043b +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043e +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083e +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043f +#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 +#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 +#define TT_MS_LANGID_BENGALI_INDIA 0x0445 +#define TT_MS_LANGID_PUNJABI_INDIA 0x0446 +#define TT_MS_LANGID_GUJARATI_INDIA 0x0447 +#define TT_MS_LANGID_ORIYA_INDIA 0x0448 +#define TT_MS_LANGID_TAMIL_INDIA 0x0449 +#define TT_MS_LANGID_TELUGU_INDIA 0x044a +#define TT_MS_LANGID_KANNADA_INDIA 0x044b +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044c +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044d +#define TT_MS_LANGID_MARATHI_INDIA 0x044e +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044f +#define TT_MS_LANGID_KONKANI_INDIA 0x0457 + + +/* + * possible values of the 'Name' identifier field in the name records of + * the TTF "name" table. These values are platform independent. + */ + +#define TT_NAME_ID_COPYRIGHT 0 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 +#define TT_NAME_ID_FULL_NAME 4 +#define TT_NAME_ID_VERSION_STRING 5 +#define TT_NAME_ID_PS_NAME 6 +#define TT_NAME_ID_TRADEMARK 7 +/* the following values are from the OpenType spec */ +#define TT_NAME_ID_MANUFACTURER 8 +#define TT_NAME_ID_DESIGNER 9 +#define TT_NAME_ID_DESCRIPTION 10 +#define TT_NAME_ID_VENDOR_URL 11 +#define TT_NAME_ID_DESIGNER_URL 12 +#define TT_NAME_ID_LICENSE 13 +#define TT_NAME_ID_LICENSE_URL 14 +/* number 15 is reserved */ +#define TT_NAME_ID_PREFERRED_FAMILY 16 +#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 +#define TT_NAME_ID_MAC_FULL_NAME 18 + + +/* + * Bit Mask values for the Unicode Ranges from the TTF "OS2 " table. + */ + +/* General Scripts Area */ + +/* Bit 0 C0 Controls and Basic Latin */ +#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0000-U+007F */ +/* Bit 1 C1 Controls and Latin-1 Supplement */ +#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ +/* Bit 2 Latin Extended-A */ +#define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ +/* Bit 3 Latin Extended-B */ +#define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ +/* Bit 4 IPA Extensions */ +#define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ +/* Bit 5 Spacing Modifier Letters */ +#define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ +/* Bit 6 Combining Diacritical Marks */ +#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ +/* Bit 7 Greek */ +#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ +/* Bit 8 is reserved (was: Greek Symbols and Coptic) */ +/* Bit 9 Cyrillic */ +#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ +/* Bit 10 Armenian */ +#define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ +/* Bit 11 Hebrew */ +#define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ +/* Bit 12 is reserved (was: Hebrew Extended) */ +/* Bit 13 Arabic */ +#define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ +/* Bit 14 is reserved (was: Arabic Extended) */ +/* Bit 15 Devanagari */ +#define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ +/* Bit 16 Bengali */ +#define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ +/* Bit 17 Gurmukhi */ +#define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ +/* Bit 18 Gujarati */ +#define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ +/* Bit 19 Oriya */ +#define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ +/* Bit 20 Tamil */ +#define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ +/* Bit 21 Telugu */ +#define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ +/* Bit 22 Kannada */ +#define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ +/* Bit 23 Malayalam */ +#define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ +/* Bit 24 Thai */ +#define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ +/* Bit 25 Lao */ +#define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ +/* Bit 26 Georgian */ +#define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ +/* Bit 27 is reserved (was Georgian Extended) */ +/* Bit 28 Hangul Jamo */ +#define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ +/* Bit 29 Latin Extended Additional */ +#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ +/* Bit 30 Greek Extended */ +#define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ + +/* Symbols Area */ + +/* Bit 31 General Punctuation */ +#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ +/* Bit 32 Superscripts And Subscripts */ +#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ +/* Bit 33 Currency Symbols */ +#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ +/* Bit 34 Combining Diacritical Marks For Symbols */ +#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ +/* Bit 35 Letterlike Symbols */ +#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ +/* Bit 36 Number Forms */ +#define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ +/* Bit 37 Arrows */ +#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ +/* Bit 38 Mathematical Operators */ +#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ +/* Bit 39 Miscellaneous Technical */ +#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ +/* Bit 40 Control Pictures */ +#define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ +/* Bit 41 Optical Character Recognition */ +#define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ +/* Bit 42 Enclosed Alphanumerics */ +#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ +/* Bit 43 Box Drawing */ +#define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ +/* Bit 44 Block Elements */ +#define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ +/* Bit 45 Geometric Shapes */ +#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ +/* Bit 46 Miscellaneous Symbols */ +#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ +/* Bit 47 Dingbats */ +#define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ + +/* CJK Phonetics and Symbols Area */ + +/* Bit 48 CJK Symbols And Punctuation */ +#define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ +/* Bit 49 Hiragana */ +#define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ +/* Bit 50 Katakana */ +#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ +/* Bit 51 Bopomofo */ +#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ +/* Bit 52 Hangul Compatibility Jamo */ +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ +/* Bit 53 CJK Miscellaneous */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+3190-U+319F */ +/* Bit 54 Enclosed CJK Letters And Months */ +#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ +/* Bit 55 CJK Compatibility */ +#define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ + +/* Hangul Syllables Area */ + +/* Bit 56 Hangul */ +#define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ + +/* Surrogates Area */ + +/* Bit 57 Surrogates */ +#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DFFF */ +/* Bit 58 is reserved for Unicode SubRanges */ + +/* CJK Ideographs Area */ + +/* Bit 59 CJK Unified Ideographs */ +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ + +/* Private Use Area */ + +/* Bit 60 Private Use */ +#define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ + +/* Compatibility Area and Specials */ + +/* Bit 61 CJK Compatibility Ideographs */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+F900-U+FAFF */ +/* Bit 62 Alphabetic Presentation Forms */ +#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ +/* Bit 63 Arabic Presentation Forms-A */ +#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FSFF */ +/* Bit 64 Combining Half Marks */ +#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ +/* Bit 65 CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE30-U+FE4F */ +/* Bit 66 Small Form Variants */ +#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ +/* Bit 67 Arabic Presentation Forms-B */ +#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFF */ +/* Bit 68 Halfwidth And Fullwidth Forms */ +#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ +/* Bit 69 Specials */ +#define TT_UCR_SPECIALS (1L << 5) /* U+FEFF, + U+FFF0-U+FFFF */ +/* Bit 70 Tibetan */ +#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FBF */ + + +/* Some compilers have a very limited length of identifiers. */ +#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) +#define HAVE_LIMIT_ON_IDENTS +#endif + +#ifndef HAVE_LIMIT_ON_IDENTS + +/* + * Here some alias #defines in order to be clearer. + * + * These are not always #defined to stay within the 31 character limit + * which some compilers have. + * + * Credits go to Dave Hoo for pointing out that modern + * Borland compilers (read: from BC++ 3.1 on) can increase this limit. + * If you get a warning with such a compiler, use the -i40 switch. + */ + +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ + TT_UCR_ARABIC_PRESENTATIONS_A +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ + TT_UCR_ARABIC_PRESENTATIONS_B + +#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ + TT_UCR_COMBINING_DIACRITICS +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ + TT_UCR_COMBINING_DIACRITICS_SYMB + +#endif /* ndef HAVE_LIMIT_ON_IDENTS */ + +#endif /* FTNAMEID_H */ + + +/* END */ diff --git a/lib/header.h b/lib/header.h new file mode 100644 index 0000000..ebd5574 --- /dev/null +++ b/lib/header.h @@ -0,0 +1,49 @@ +/******************************************************************* + * + * Function : + * + * Description : + * + * Input : + * + * Output : + * + * Notes : + * + ******************************************************************/ + +/******************************************************************* + * + * Function : + * + * Description : + * + * Input : None + * + * Output : Error code. + * + ******************************************************************/ + +/******************************************************************* + * + * Function : + * + * Description : + * + ******************************************************************/ + +/******************************************************************* + * + * Component Name (e.g. TTRaster.C) + eventually a version number. + * + * Component Short Description (e.g. Rasterizer). + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ diff --git a/lib/ttapi.c b/lib/ttapi.c new file mode 100644 index 0000000..3ee90b4 --- /dev/null +++ b/lib/ttapi.c @@ -0,0 +1,2219 @@ +/******************************************************************* + * + * ttapi.c + * + * High-level interface implementation + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Notes: + * + * This file is used to implement most of the functions that are + * defined in the file "freetype.h". However, two functions are + * implemented elsewhere : + * + * TT_MulDiv and TT_MulFix are in ttcalc.h/ttcalc.c + * + ******************************************************************/ + +#include "ttconfig.h" + +#include "freetype.h" +#include "ttengine.h" +#include "ttcalc.h" +#include "ttmemory.h" +#include "ttcache.h" +#include "ttfile.h" +#include "ttobjs.h" +#include "ttload.h" +#include "ttgload.h" +#include "ttraster.h" +#include "ttextend.h" + + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_api + + +#ifdef TT_STATIC_RASTER +#define RAS_OPS /* void */ +#define RAS_OP /* void */ +#else +#define RAS_OPS ((TRaster_Instance*)_engine->raster_component), +#define RAS_OP ((TRaster_Instance*)_engine->raster_component) +#endif /* TT_STATIC_RASTER */ + + +#define RENDER_Glyph( glyph, target ) \ + Render_Glyph( RAS_OPS glyph, target ) + +#define RENDER_Gray_Glyph( glyph, target, palette ) \ + Render_Gray_Glyph( RAS_OPS glyph, target, palette ) + + + +/******************************************************************* + * + * Function : TT_FreeType_Version + * + * Description : Returns the major and minor version of the library. + * + * Input : major, minor addresses + * + * Output : Error code. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_FreeType_Version( int *major, int *minor ) + { + if ( !major || !minor ) + return TT_Err_Invalid_Argument; + + *major = TT_FREETYPE_MAJOR; + *minor = TT_FREETYPE_MINOR; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Init_FreeType + * + * Description : The library's engine initializer. This function + * must be called prior to any call. + * + * Input : engine pointer to a FreeType engine instance + * + * Output : Error code. + * + * MT-Note : This function should be called each time you want + * to create a TT_Engine. It is not necessarily thread + * safe depending on the implementations of ttmemory, + * ttfile and ttmutex, so take care. Their default + * implementations are safe, however. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Init_FreeType( TT_Engine* engine ) + { + PEngine_Instance _engine; + + TT_Error error; + int n; + + + /* first of all, initialize memory sub-system */ + error = TTMemory_Init(); + if ( error ) + return error; + + /* Allocate engine instance */ + if ( ALLOC( _engine, sizeof ( TEngine_Instance ) ) ) + return error; + +#undef TT_FAIL +#define TT_FAIL( x ) ( error = x (_engine) ) != TT_Err_Ok + + /* Initalize components */ + if ( TT_FAIL( TTFile_Init ) || + TT_FAIL( TTCache_Init ) || +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + TT_FAIL( TTExtend_Init ) || +#endif + TT_FAIL( TTObjs_Init ) || + TT_FAIL( TTRaster_Init ) ) + goto Fail; + +#undef TT_FAIL + + /* set the gray palette defaults: 0 to 4 */ + for ( n = 0; n < 5; n++ ) + _engine->raster_palette[n] = (Byte)n; /* Conversion ok, some warn */ + + /* create the engine lock */ + MUTEX_Create( _engine->lock ); + + HANDLE_Set( *engine, _engine ); + return TT_Err_Ok; + + Fail: + TT_Done_FreeType( *engine ); + HANDLE_Set( *engine, NULL ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_FreeType + * + * Description : The library's engine finalizer. This function + * will discard all active face and glyph objects + * from the heap. + * + * Input : engine FreeType engine instance + * + * Output : Error code. + * + * MT-Note : Destroys an engine. Not necessarily thread-safe + * depending on the implementations of ttmemory, + * ttfile and ttmutex. The default implementations + * are safe, however. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_FreeType( TT_Engine engine ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + + if ( !_engine ) + return TT_Err_Ok; + + MUTEX_Destroy( _engine->lock ); + + TTRaster_Done( _engine ); + TTObjs_Done ( _engine ); +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + TTExtend_Done( _engine ); +#endif + TTCache_Done ( _engine ); + TTFile_Done ( _engine ); + FREE( _engine ); + + TTMemory_Done(); + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/******************************************************************* + * + * Function : TT_Set_Raster_Gray_Palette + * + * Description : Sets the gray-levels palette used for font + * smoothing. + * + * Input : engine FreeType engine instance + * palette address of palette (a 5 byte array) + * + * Output : Invalid argument if 'palette' is NULL. + * + * MT-Note: NO! Unprotected modification of an engine's palette. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Raster_Gray_Palette( TT_Engine engine, + Byte* palette ) + { + int i; + + + if ( !palette ) + return TT_Err_Invalid_Argument; + + for ( i = 0; i < 5; i++ ) + HANDLE_Engine( engine )->raster_palette[i] = (Byte)palette[i]; + + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + +/******************************************************************* + * + * Function : TT_Open_Face + * + * Description : Creates a new face object from a given font file. + * + * Input : engine FreeType engine instance + * fontPathName the font file's pathname + * face adress of returned face handle + * + * Output : Error code. + * + * Note : The face handle is set to NULL in case of failure. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Open_Face( TT_Engine engine, + const TT_Text* fontPathName, + TT_Face* face ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TFont_Input input; + TT_Error error; + TT_Stream stream; + PFace _face; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + /* open the file */ + error = TT_Open_Stream( fontPathName, &stream ); + if ( error ) + return error; + + input.stream = stream; + input.fontIndex = 0; + input.engine = _engine; + + /* Create and load the new face object - this is thread-safe */ + error = CACHE_New( _engine->objs_face_cache, + _face, + &input ); + + /* Set the handle */ + HANDLE_Set( *face, _face ); + + if ( error ) + goto Fail; + + return TT_Err_Ok; + + Fail: + TT_Close_Stream( &stream ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Open_Collection + * + * Description : Creates a new face object from a given font file. + * + * Input : engine FreeType engine instance + * collectionPathName the font file's pathname + * fontIndex index of font in TrueType collection + * face adress of returned face handle + * + * Output : Error code. + * + * Note : The face handle is set to NULL in case of failure. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Open_Collection( TT_Engine engine, + const TT_Text* collectionPathName, + TT_ULong fontIndex, + TT_Face* face ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + + TFont_Input input; + TT_Error error; + TT_Stream stream; + PFace _face; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + /* open the file */ + error = TT_Open_Stream( collectionPathName, &stream ); + if ( error ) + return error; + + input.stream = stream; + input.fontIndex = fontIndex; + input.engine = _engine; + + /* Create and load the new face object - this is thread-safe */ + error = CACHE_New( _engine->objs_face_cache, + _face, + &input ); + + /* Set the handle */ + HANDLE_Set( *face, _face ); + + if ( error ) + goto Fail; + + return TT_Err_Ok; + + Fail: + TT_Close_Stream( &stream ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Get_Face_Properties + * + * Description : Returns face properties. + * + * Input : face the face handle + * properties address of target properties record + * + * Output : Error code. + * + * Note : Currently, max_Faces is always set to 0. + * + * MT-Note : YES! Reads only permanent data. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Face_Properties( TT_Face face, + TT_Face_Properties* properties ) + { + PFace _face = HANDLE_Face( face ); + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + properties->num_Glyphs = _face->numGlyphs; + properties->max_Points = _face->maxPoints; + properties->max_Contours = _face->maxContours; + properties->num_CharMaps = _face->numCMaps; + properties->num_Names = _face->nameTable.numNameRecords; + + if ( _face->ttcHeader.DirCount == 0 ) + properties->num_Faces = 1; + else + properties->num_Faces = _face->ttcHeader.DirCount; + + properties->header = &_face->fontHeader; + properties->horizontal = &_face->horizontalHeader; + + if ( _face->verticalInfo ) + properties->vertical = &_face->verticalHeader; + else + properties->vertical = NULL; + + properties->os2 = &_face->os2; + properties->postscript = &_face->postscript; + properties->hdmx = &_face->hdmx; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Set_Face_Pointer + * + * Description : Each face object has one pointer, which use is + * reserved to client applications. The TrueType + * engine never accesses or uses this field. + * + * This function is used to set the pointer. + * + * Input : face the given face handle + * data the generic pointer value + * + * Output : Error code. + * + * MT-Note : NO! But this function is reserved to "enlightened" + * developers, so it shouldn't be a problem. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Face_Pointer( TT_Face face, + void* data ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + else + faze->generic = data; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Face_Pointer + * + * Description : Each face object has one pointer, which use is + * reserved to client applications. The TrueType + * engine never access or use this field. + * + * This function is used to read the pointer. + * + * Input : face the given face handle + * data the generic pointer value + * + * Output : Error code. + * + * MT-Note : NO! But this function is reserved to "enlightened" + * developers, so it shouldn't be a problem. + * + ******************************************************************/ + + EXPORT_FUNC + void* TT_Get_Face_Pointer( TT_Face face ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return NULL; + else + return faze->generic; + } + + +/******************************************************************* + * + * Function : TT_Get_Face_Metrics + * + * Description : This function returns the original horizontal AND + * vertical metrics as found in the "hmtx" and "vmtx" + * tables. These are the glyphs' left-side-bearings + * and advance widths (horizontal), as well as top + * side bearings and advance heights (vertical). + * + * All are expressed in FONT UNITS, a.k.a. EM + * units. + * + * Input : face The given face handle. + * first Index of first glyph in table. + * last Index of last glyph in table. + * + * leftBearings A pointer to an array of TT_Shorts where the + * left side bearings for the glyphs 'first' + * to 'last' will be returned. If these metrics + * don't interest you, simply set it to NULL. + * + * widths A pointer to an array of TT_UShorts + * where the advance widths for the glyphs + * 'first' to 'last' will be returned. If these + * metrics don't interest you, simply set it + * to NULL. + * + * topBearings A pointer to an array of TT_Shorts where the + * top side bearings for the glyphs 'first' + * to 'last' will be returned. If these metrics + * don't interest you, simply set it to NULL. + * + * heights A pointer to an array of TT_UShorts + * where the advance heights for the glyphs + * 'first' to 'last' will be returned. If these + * metrics don't interest you, simply set it + * to NULL. + * + * Output : Error code. + * + * IMPORTANT NOTE : + * + * As vertical metrics are optional in a TrueType font, this + * function will return an error ( TT_Err_No_Vertical_Data ) + * whenever this function is called on such a face with non-NULL + * 'topBearings' or 'heights' arguments. + * + * When a font has no vertical data, the 'vertical' field in its + * properties structure is set to NULL. + * + * MT-Note : YES! Reads only permanent data. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Face_Metrics( TT_Face face, + TT_UShort firstGlyph, + TT_UShort lastGlyph, + TT_Short* leftBearings, + TT_UShort* widths, + TT_Short* topBearings, + TT_UShort* heights ) + { + PFace _face = HANDLE_Face( face ); + UShort num; + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + /* Check the glyph range */ + if ( lastGlyph >= _face->numGlyphs || firstGlyph > lastGlyph ) + return TT_Err_Invalid_Argument; + + num = lastGlyph - firstGlyph; /* number of elements-1 in each array */ + + /* store the left side bearings and advance widths first */ + { + UShort n; + Short left_bearing; + UShort advance_width; + + + for ( n = 0; n <= num; n++ ) + { + TT_Get_Metrics( &_face->horizontalHeader, + firstGlyph + n, &left_bearing, &advance_width ); + + if ( leftBearings ) leftBearings[n] = left_bearing; + if ( widths ) widths[n] = advance_width; + } + } + + /* check for vertical data if topBearings or heights is non-NULL */ + if ( !topBearings && !heights ) + return TT_Err_Ok; + + if ( !_face->verticalInfo ) + return TT_Err_No_Vertical_Data; + + /* store the top side bearings */ + { + UShort n; + Short top_bearing; + UShort advance_height; + + for ( n = 0; n <= num; n++ ) + { + TT_Get_Metrics( (TT_Horizontal_Header*)&_face->verticalHeader, + firstGlyph + n, &top_bearing, &advance_height ); + + if ( topBearings ) topBearings[n] = top_bearing; + if ( heights ) heights[n] = advance_height; + } + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Face + * + * Description : This function is used to close an active face's + * file handle or descriptor. This is useful to save + * system resources, if your application uses tons + * of fonts. + * + * Input : face the given face handle + * + * Output : Error code. + * + * MT-Note : YES! (If ttfile is.) + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Face( TT_Face face ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + else + return TT_Flush_Stream( &faze->stream ); + } + + +/******************************************************************* + * + * Function : TT_Close_Face + * + * Description : Closes an opened face object. This function + * will destroy all objects associated to the + * face, except the glyphs. + * + * Input : face the given face handle + * + * Output : Error code. + * + * NOTE : The handle is set to NULL on exit. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Close_Face( TT_Face face ) + { + PFace _face = HANDLE_Face( face ); + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + TT_Close_Stream( &_face->stream ); + + /* delete the face object -- this is thread-safe */ + return CACHE_Done( _face->engine->objs_face_cache, _face ); + } + + +/******************************************************************* + * + * Function : TT_New_Instance + * + * Description : Creates a new instance from a given face. + * + * Input : face parent face handle + * instance address of instance handle + * + * Output : Error code. + * + * Note : The handle is set to NULL in case of failure. + * + * MT-Note : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_New_Instance( TT_Face face, + TT_Instance* instance ) + { + TT_Error error; + PFace _face = HANDLE_Face( face ); + PInstance _ins; + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + /* get a new instance from the face's cache -- this is thread-safe */ + error = CACHE_New( &_face->instances, _ins, _face ); + + HANDLE_Set( *instance, _ins ); + + if ( !error ) + { + error = Instance_Init( _ins ); + if ( error ) + { + HANDLE_Set( *instance, NULL ); + CACHE_Done( &_face->instances, _ins ); + } + } + + return error; + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_Resolutions + * + * Description : Resets an instance to a new device resolution. + * + * Input : instance the instance handle + * xResolution new horizontal device resolution in dpi + * yResolution new vertical device resolution in dpi + * + * Output : Error code. + * + * Note : There is no check for overflow; with other words, + * the product of glyph dimensions times the device + * resolutions must have reasonable values. + * + * MT-Note : You should set the charsize or pixel size immediately + * after this call in multi-threaded programs. This will + * force the instance data to be resetted. Otherwise, you + * may encounter corruption when loading two glyphs from + * the same instance concurrently! + * + * Happily, 99.99% will do just that :-) + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_Resolutions( TT_Instance instance, + TT_UShort xResolution, + TT_UShort yResolution ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + ins->metrics.x_resolution = xResolution; + ins->metrics.y_resolution = yResolution; + ins->valid = FALSE; + + /* In the case of a thread-safe implementation, we immediately */ + /* call Instance_Reset in order to change the instance's variable */ + + /* In the case of a non-threaded build, we simply set the 'valid' */ + /* flag to FALSE, which will force the instance's resetting at */ + /* the next glyph loading */ + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_CharSizes + * + * Description : Resets an instance to new point size. + * + * Input : instance the instance handle + * charWidth the new width in 26.6 char points + * charHeight the new height in 26.6 char points + * + * Output : Error code. + * + * Note : There is no check for overflow; with other words, + * the product of glyph dimensions times the device + * resolution must have reasonable values. + * + * MT-Note : NO! This should be called only when setting/resetting + * instances, so there is no need to protect. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_CharSizes( TT_Instance instance, + TT_F26Dot6 charWidth, + TT_F26Dot6 charHeight ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + if ( charWidth < 1 * 64 ) + charWidth = 1 * 64; + + if ( charHeight < 1 * 64 ) + charHeight = 1 * 64; + + ins->metrics.x_scale1 = ( charWidth * ins->metrics.x_resolution ) / 72; + ins->metrics.x_scale2 = ins->owner->fontHeader.Units_Per_EM; + + ins->metrics.y_scale1 = ( charHeight * ins->metrics.y_resolution ) / 72; + ins->metrics.y_scale2 = ins->owner->fontHeader.Units_Per_EM; + + if ( ins->owner->fontHeader.Flags & 8 ) + { + ins->metrics.x_scale1 = (ins->metrics.x_scale1+32) & -64; + ins->metrics.y_scale1 = (ins->metrics.y_scale1+32) & -64; + } + + ins->metrics.x_ppem = ins->metrics.x_scale1 / 64; + ins->metrics.y_ppem = ins->metrics.y_scale1 / 64; + + if ( charWidth > charHeight ) + ins->metrics.pointSize = charWidth; + else + ins->metrics.pointSize = charHeight; + + ins->valid = FALSE; + + return Instance_Reset( ins ); + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_CharSize + * + * Description : Resets an instance to new point size. + * + * Input : instance the instance handle + * charSize the new character size in 26.6 char points + * + * Output : Error code. + * + * Note : There is no check for overflow; with other words, + * the product of glyph dimensions times the device + * resolution must have reasonable values. + * + * MT-Note : NO! This should be called only when setting/resetting + * instances, so there is no need to protect. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_CharSize( TT_Instance instance, + TT_F26Dot6 charSize ) + { + return TT_Set_Instance_CharSizes( instance, charSize, charSize ); + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_PixelSizes + * + * Description : Resets an instance to new pixel sizes + * + * Input : instance the instance handle + * pixelWidth the new width in pixels + * pixelHeight the new height in pixels + * + * Output : Error code. + * + * Note : There is no check for overflow; with other words, + * the product of glyph dimensions times the device + * resolution must have reasonable values. + * + * MT-Note : NO! This should be called only when setting/resetting + * instances, so there is no need to protect. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_PixelSizes( TT_Instance instance, + TT_UShort pixelWidth, + TT_UShort pixelHeight, + TT_F26Dot6 pointSize ) + { + PInstance ins = HANDLE_Instance( instance ); + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + if ( pixelWidth < 1 ) pixelWidth = 1; + if ( pixelHeight < 1 ) pixelHeight = 1; + + ins->metrics.x_ppem = pixelWidth; + ins->metrics.y_ppem = pixelHeight; + ins->metrics.pointSize = pointSize; + + ins->metrics.x_scale1 = ins->metrics.x_ppem * 64L; + ins->metrics.x_scale2 = ins->owner->fontHeader.Units_Per_EM; + ins->metrics.y_scale1 = ins->metrics.y_ppem * 64L; + ins->metrics.y_scale2 = ins->owner->fontHeader.Units_Per_EM; + + ins->valid = FALSE; + + return Instance_Reset( ins ); + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_Transform_Flags + * + * Description : Informs the interpreter about the transformations + * that will be applied to the rendered glyphs. + * + * Input : instance the instance handle + * rotated set to TRUE if the glyph are rotated + * stretched set to TRUE if the glyph are stretched + * + * Output : Error code. + * + * Note : This function is deprecated! It's much better to + * control hinting manually when calling TT_Load_Glyph + * than relying on the font programs... + * + * Never use it, unless calling for trouble ;-) + * + * MT-Note : NO! This should be called only when setting/resetting + * instances, so there is no need to protect. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_Transform_Flags( TT_Instance instance, + TT_Bool rotated, + TT_Bool stretched ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + ins->metrics.rotated = rotated; + ins->metrics.stretched = stretched; + ins->valid = FALSE; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Instance_Metrics + * + * Description : Returns instance metrics. + * + * Input : instance the instance handle + * metrics address of target instance metrics record + * + * Output : Error code. + * + * MT-Note : YES! Reads only semi-permanent data. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Instance_Metrics( TT_Instance instance, + TT_Instance_Metrics* metrics ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + if ( !ins->valid ) + Instance_Reset( ins ); + + metrics->pointSize = ins->metrics.pointSize; + + metrics->x_scale = TT_MulDiv( 0x10000, + ins->metrics.x_scale1, + ins->metrics.x_scale2 ); + + metrics->y_scale = TT_MulDiv( 0x10000, + ins->metrics.y_scale1, + ins->metrics.y_scale2 ); + + metrics->x_resolution = ins->metrics.x_resolution; + metrics->y_resolution = ins->metrics.y_resolution; + metrics->x_ppem = ins->metrics.x_ppem; + metrics->y_ppem = ins->metrics.y_ppem; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Set_Instance_Pointer + * + * Description : Each instance has one pointer, which use is + * reserved to client applications. The TrueType + * engine never accesses or uses this field. + * + * This function is used to set the pointer. + * + * Input : face the given face handle + * data the generic pointer value + * + * Output : Error code. + * + * MT-Note : NO! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Set_Instance_Pointer( TT_Instance instance, + void* data ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + else + ins->generic = data; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Instance_Pointer + * + * Description : Each instance has one pointer, which use is + * reserved to client applications. The TrueType + * engine never accesses or uses this field. + * + * This function is used to read the pointer. + * + * Input : face the given face handle + * data the generic pointer value + * + * Output : Error code. + * + * MT-Safe : NO! + * + ******************************************************************/ + + EXPORT_FUNC + void* TT_Get_Instance_Pointer( TT_Instance instance ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return NULL; + else + return ins->generic; + } + + +/******************************************************************* + * + * Function : TT_Done_Instance + * + * Description : Closes a given instance. + * + * Input : instance address of instance handle + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Instance( TT_Instance instance ) + { + PInstance ins = HANDLE_Instance( instance ); + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + /* delete the instance -- this is thread-safe */ + return CACHE_Done( &ins->owner->instances, ins ); + } + + +/******************************************************************* + * + * Function : TT_New_Glyph + * + * Description : Creates a new glyph object related to a given + * face. + * + * Input : face the face handle + * glyph address of target glyph handle + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_New_Glyph( TT_Face face, + TT_Glyph* glyph ) + { + TT_Error error; + PFace _face = HANDLE_Face( face ); + PGlyph _glyph; + + + if ( !_face ) + return TT_Err_Invalid_Face_Handle; + + /* get a new glyph from the face's cache -- this is thread-safe */ + error = CACHE_New( &_face->glyphs, _glyph, _face ); + + HANDLE_Set( *glyph, _glyph ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_Glyph + * + * Description : Destroys a given glyph object. + * + * Input : glyph the glyph handle + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Glyph( TT_Glyph glyph ) + { + PGlyph _glyph = HANDLE_Glyph( glyph ); + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + /* delete the engine -- this is thread-safe */ + return CACHE_Done( &_glyph->face->glyphs, _glyph ); + } + + +/******************************************************************* + * + * Function : TT_Load_Glyph + * + * Description : Loads a glyph. + * + * Input : instance the instance handle + * glyph the glyph handle + * glyphIndex the glyph index + * loadFlags flags controlling how to load the glyph + * (none, scaled, hinted, both) + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Load_Glyph( TT_Instance instance, + TT_Glyph glyph, + TT_UShort glyphIndex, + TT_UShort loadFlags ) + { + PInstance _ins; + PGlyph _glyph; + TT_Error error; + + + _ins = HANDLE_Instance( instance ); + + if ( !_ins ) + loadFlags &= ~(TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH); + + if ( (loadFlags & TTLOAD_SCALE_GLYPH) == 0 ) + _ins = 0; + + _glyph = HANDLE_Glyph( glyph ); + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + if ( _ins ) + { + if ( _ins->owner != _glyph->face ) + return TT_Err_Invalid_Face_Handle; + + if ( !_ins->valid ) + { + /* This code can only be called in non thread-safe builds */ + error = Instance_Reset( _ins ); + if ( error ) + return error; + } + } + + return Load_TrueType_Glyph( _ins, _glyph, glyphIndex, loadFlags ); + } + + +/******************************************************************* + * + * Function : TT_Get_Glyph_Outline + * + * Description : Returns the glyph's outline data. + * + * Input : glyph the glyph handle + * outline address where the glyph outline will be returned + * + * Output : Error code. + * + * MT-Safe : YES! Reads only semi-permanent data. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Outline( TT_Glyph glyph, + TT_Outline* outline ) + { + PGlyph _glyph = HANDLE_Glyph( glyph ); + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + *outline = _glyph->outline; + outline->owner = FALSE; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Glyph_Metrics + * + * Description : Extracts the glyph's horizontal metrics information. + * + * Input : glyph glyph object handle + * metrics address where metrics will be returned + * + * Output : Error code. + * + * MT-Safe : NO! Glyph containers can't be shared. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Metrics( TT_Glyph glyph, + TT_Glyph_Metrics* metrics ) + { + PGlyph _glyph = HANDLE_Glyph( glyph ); + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + metrics->bbox = _glyph->metrics.bbox; + metrics->bearingX = _glyph->metrics.horiBearingX; + metrics->bearingY = _glyph->metrics.horiBearingY; + metrics->advance = _glyph->metrics.horiAdvance; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Glyph_Big_Metrics + * + * Description : Extracts the glyph's big metrics information. + * + * Input : glyph glyph object handle + * metrics address where big metrics will be returned + * + * Output : Error code. + * + * MT-Safe : NO! Glyph containers can't be shared. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Big_Metrics( TT_Glyph glyph, + TT_Big_Glyph_Metrics* metrics ) + { + PGlyph _glyph = HANDLE_Glyph( glyph ); + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + *metrics = _glyph->metrics; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Glyph_Bitmap + * + * Description : Produces a bitmap from a glyph outline. + * + * Input : glyph the glyph container's handle + * map target pixmap description block + * xOffset x offset in fractional pixels (26.6 format) + * yOffset y offset in fractional pixels (26.6 format) + * + * Output : Error code. + * + * Note : Only use integer pixel offsets if you want to preserve + * the fine hints applied to the outline. This means that + * xOffset and yOffset must be multiples of 64! + * + * MT-Safe : NO! Glyph containers can't be shared. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Bitmap( TT_Glyph glyph, + TT_Raster_Map* map, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ) + { + PEngine_Instance _engine; + TT_Engine engine; + TT_Error error; + PGlyph _glyph = HANDLE_Glyph( glyph ); + + TT_Outline outline; + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + _engine = _glyph->face->engine; + HANDLE_Set( engine, _engine ); + + outline = _glyph->outline; + /* XXX : For now, use only dropout mode 2 */ + /* outline.dropout_mode = _glyph->scan_type; */ + outline.dropout_mode = 2; + + TT_Translate_Outline( &outline, xOffset, yOffset ); + error = TT_Get_Outline_Bitmap( engine, &outline, map ); + TT_Translate_Outline( &outline, -xOffset, -yOffset ); + + return error; + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/******************************************************************* + * + * Function : TT_Get_Glyph_Pixmap + * + * Description : Produces a grayscaled pixmap from a glyph + * outline. + * + * Input : glyph the glyph container's handle + * map target pixmap description block + * xOffset x offset in fractional pixels (26.6 format) + * yOffset y offset in fractional pixels (26.6 format) + * + * Output : Error code. + * + * Note : Only use integer pixel offsets to preserve the fine + * hinting of the glyph and the 'correct' anti-aliasing + * (where vertical and horizontal stems aren't grayed). + * This means that xOffset and yOffset must be multiples + * of 64! + * + * You can experiment with offsets of +32 to get 'blurred' + * versions of the glyphs (a nice effect at large sizes that + * some graphic designers may appreciate :) + * + * MT-Safe : NO! Glyph containers can't be shared. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Glyph_Pixmap( TT_Glyph glyph, + TT_Raster_Map* map, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ) + { + PEngine_Instance _engine; + TT_Engine engine; + TT_Error error; + PGlyph _glyph = HANDLE_Glyph( glyph ); + + TT_Outline outline; + + + if ( !_glyph ) + return TT_Err_Invalid_Glyph_Handle; + + _engine = _glyph->face->engine; + HANDLE_Set(engine,_engine); + + outline = _glyph->outline; + /* XXX : For now, use only dropout mode 2 */ + /* outline.dropout_mode = _glyph->scan_type; */ + outline.dropout_mode = 2; + + TT_Translate_Outline( &outline, xOffset, yOffset ); + error = TT_Get_Outline_Pixmap( engine, &outline, map ); + TT_Translate_Outline( &outline, -xOffset, -yOffset ); + + return error; + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + + static const TT_Outline null_outline + = { 0, 0, NULL, NULL, NULL, 0, 0, 0, 0 }; + + +/******************************************************************* + * + * Function : TT_New_Outline + * + * Description : Creates a new TrueType outline, reserving + * array space for a given number of points and + * contours. + * + * Input : numPoints number of points + * numContours number of contours + * outline address of target outline structure + * + * Output : Error code + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_New_Outline( TT_UShort numPoints, + TT_Short numContours, + TT_Outline* outline ) + { + TT_Error error; + + + if ( !outline ) + return TT_Err_Invalid_Argument; + + *outline = null_outline; + + if ( ALLOC( outline->points, numPoints*2*sizeof ( TT_F26Dot6 ) ) || + ALLOC( outline->flags, numPoints *sizeof ( Byte ) ) || + ALLOC( outline->contours, numContours*sizeof ( UShort ) ) ) + goto Fail; + + outline->n_points = numPoints; + outline->n_contours = numContours; + outline->owner = TRUE; + return TT_Err_Ok; + + Fail: + outline->owner = TRUE; + TT_Done_Outline( outline ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Done_Outline + * + * Description : Deletes an outline created through TT_New_Outline(). + * Calling this function for outlines returned + * by TT_Get_Glyph_Outline() yields an error. + * + * Input : outline address of outline + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Outline( TT_Outline* outline ) + { + if ( outline ) + { + if ( outline->owner ) + { + FREE( outline->points ); + FREE( outline->flags ); + FREE( outline->contours ); + } + *outline = null_outline; + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + +/******************************************************************* + * + * Function : TT_Get_Outline_Bitmap + * + * Description : Render a TrueType outline into a bitmap. + * Note that the bitmap must be created by the caller. + * + * Input : outline the outline to render + * map the target bitmap + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Outline_Bitmap( TT_Engine engine, + TT_Outline* outline, + TT_Raster_Map* map ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + if ( !outline || !map ) + return TT_Err_Invalid_Argument; + + MUTEX_Lock( _engine->raster_lock ); + error = RENDER_Glyph( outline, map ); + MUTEX_Release( _engine->raster_lock ); + + return error; + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/******************************************************************* + * + * Function : TT_Get_Outline_Pixmap + * + * Description : Render a TrueType outline into a pixmap. + * Note that the pixmap must be created by the caller. + * + * Input : outline the outline to render + * map the target bitmap + * + * Output : Error code + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Outline_Pixmap( TT_Engine engine, + TT_Outline* outline, + TT_Raster_Map* map ) + { + PEngine_Instance _engine = HANDLE_Engine( engine ); + TT_Error error; + + + if ( !_engine ) + return TT_Err_Invalid_Engine; + + if ( !outline || !map ) + return TT_Err_Invalid_Argument; + + MUTEX_Lock( _engine->raster_lock ); + error = RENDER_Gray_Glyph( outline, map, _engine->raster_palette ); + MUTEX_Release( _engine->raster_lock ); + return error; + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + +/******************************************************************* + * + * Function : TT_Copy_Outline + * + * Description : Copy an outline into another. The source and + * target outlines must have the same points and + * contours numbers. + * + * Input : source address of source outline + * target address of target outline + * + * Output : Error code + * + * Note : This function doesn't touch the target outline's 'owner' + * field. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Copy_Outline( TT_Outline* source, + TT_Outline* target ) + { + if ( !source || !target || + source->n_points != target->n_points || + source->n_contours != target->n_contours ) + return TT_Err_Invalid_Argument; + + MEM_Copy( target->points, source->points, + source->n_points * 2 * sizeof ( TT_F26Dot6 ) ); + + MEM_Copy( target->flags, source->flags, + source->n_points * sizeof ( Byte ) ); + + MEM_Copy( target->contours, source->contours, + source->n_contours * sizeof ( Short ) ); + + target->high_precision = source->high_precision; + target->second_pass = target->second_pass; + target->dropout_mode = source->dropout_mode; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Transform_Outline + * + * Description : Applies a simple transformation to an outline. + * + * Input : outline the glyph's outline. Can be extracted + * from a glyph container through + * TT_Get_Glyph_Outline(). + * + * matrix simple matrix with 16.16 fixed floats + * + * Output : Error code (always TT_Err_Ok). + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + void TT_Transform_Outline( TT_Outline* outline, + TT_Matrix* matrix ) + { + UShort n; + TT_F26Dot6 x, y; + TT_Vector* vec; + + + vec = outline->points; + for ( n = 0; n < outline->n_points; n++ ) + { + x = TT_MulFix( vec->x, matrix->xx ) + + TT_MulFix( vec->y, matrix->xy ); + + y = TT_MulFix( vec->x, matrix->yx ) + + TT_MulFix( vec->y, matrix->yy ); + + vec->x = x; + vec->y = y; + vec++; + } + } + + +/******************************************************************* + * + * Function : TT_Transform_Vector + * + * Description : Apply a simple transform to a vector + * + * Input : x, y the vector. + * + * matrix simple matrix with 16.16 fixed floats + * + * Output : None. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + void TT_Transform_Vector( TT_F26Dot6* x, + TT_F26Dot6* y, + TT_Matrix* matrix ) + { + TT_F26Dot6 xz, yz; + + + xz = TT_MulFix( *x, matrix->xx ) + + TT_MulFix( *y, matrix->xy ); + + yz = TT_MulFix( *x, matrix->yx ) + + TT_MulFix( *y, matrix->yy ); + + *x = xz; + *y = yz; + } + + +/******************************************************************* + * + * Function : TT_Translate_Outline + * + * Description : Applies a simple translation. + * + * Input : outline no comment :) + * xOffset + * yOffset + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + void TT_Translate_Outline( TT_Outline* outline, + TT_F26Dot6 xOffset, + TT_F26Dot6 yOffset ) + { + UShort n; + TT_Vector* vec = outline->points; + + + for ( n = 0; n < outline->n_points; n++ ) + { + vec->x += xOffset; + vec->y += yOffset; + vec++; + } + } + + +/******************************************************************* + * + * Function : TT_Get_Outline_BBox + * + * Description : Returns an outline's bounding box. + * + * Input : outline no comment :) + * bbox address where the bounding box is returned + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Outline_BBox( TT_Outline* outline, + TT_BBox* bbox ) + { + TT_F26Dot6 x, y; + UShort k; + + + if ( outline && bbox ) + { + if ( outline->n_points == 0 ) + { + bbox->xMin = 0; + bbox->yMin = 0; + bbox->xMax = 0; + bbox->yMax = 0; + } + else + { + TT_Vector* vec = outline->points; + + bbox->xMin = bbox->xMax = vec->x; + bbox->yMin = bbox->yMax = vec->y; + vec++; + + for ( k = 1; k < outline->n_points; k++ ) + { + x = vec->x; + if ( x < bbox->xMin ) bbox->xMin = x; + if ( x > bbox->xMax ) bbox->xMax = x; + y = vec->y; + if ( y < bbox->yMin ) bbox->yMin = y; + if ( y > bbox->yMax ) bbox->yMax = y; + vec++; + } + } + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + + + /* ----------------- character mappings support ------------- */ + +/******************************************************************* + * + * Function : TT_Get_CharMap_Count + * + * Description : Returns the number of charmaps in a given face. + * + * Input : face face object handle + * + * Output : Number of tables. -1 in case of error (bad handle). + * + * Note : DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED! + * + * It is retained for backwards compatibility only and will + * fail on 16bit systems. + * + * MT-Safe : YES ! + * + ******************************************************************/ + + EXPORT_FUNC + int TT_Get_CharMap_Count( TT_Face face ) + { + PFace faze = HANDLE_Face( face ); + + return ( faze ? faze->numCMaps : -1 ); + } + + +/******************************************************************* + * + * Function : TT_Get_CharMap_ID + * + * Description : Returns the ID of a given charmap. + * + * Input : face face object handle + * charmapIndex index of charmap in directory + * platformID address of returned platform ID + * encodingID address of returned encoding ID + * + * Output : error code + * + * MT-Safe : YES ! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_CharMap_ID( TT_Face face, + TT_UShort charmapIndex, + TT_UShort* platformID, + TT_UShort* encodingID ) + { + PCMapTable cmap; + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( charmapIndex >= faze->numCMaps ) + return TT_Err_Invalid_Argument; + + cmap = faze->cMaps + charmapIndex; + + *platformID = cmap->platformID; + *encodingID = cmap->platformEncodingID; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_CharMap + * + * Description : Looks up a charmap. + * + * Input : face face object handle + * charmapIndex index of charmap in directory + * charMap address of returned charmap handle + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_CharMap( TT_Face face, + TT_UShort charmapIndex, + TT_CharMap* charMap ) + { + TT_Error error; + TT_Stream stream; + PCMapTable cmap; + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( charmapIndex >= faze->numCMaps ) + return TT_Err_Invalid_Argument; + + cmap = faze->cMaps + charmapIndex; + + /* Load table if needed */ + error = TT_Err_Ok; + + /* MT-NOTE: We're modifying the face object, so protect it. */ + MUTEX_Lock( faze->lock ); + + if ( !cmap->loaded ) + { + (void)USE_Stream( faze->stream, stream ); + if ( !error ) + { + error = CharMap_Load( cmap, stream ); + DONE_Stream( stream ); + } + + if ( error ) + cmap = NULL; + else + cmap->loaded = TRUE; + } + MUTEX_Release( faze->lock ); + + HANDLE_Set( *charMap, cmap ); + + return error; + } + + +/******************************************************************* + * + * Function : TT_Char_Index + * + * Description : Returns the glyph index corresponding to + * a given character code defined for the 'charmap'. + * + * Input : charMap charmap handle + * charcode character code + * + * Output : glyph index. + * + * Notes : Character code 0 is the unknown glyph, which should never + * be displayed. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_UShort TT_Char_Index( TT_CharMap charMap, + TT_UShort charCode ) + { + PCMapTable cmap = HANDLE_CharMap( charMap ); + + + if ( !cmap ) + return 0; /* we return 0 in case of invalid char map */ + + return CharMap_Index( cmap, charCode ); + } + + +/******************************************************************* + * + * Function : TT_Get_Name_Count + * + * Description : Returns the number of strings found in the + * name table. + * + * Input : face face handle + * + * Output : number of strings. + * + * Notes : Returns -1 on error (invalid handle). + * + * DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED! + * + * It is retained for backwards compatibility only and will + * fail on 16bit systems. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + int TT_Get_Name_Count( TT_Face face ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return -1; + + return faze->nameTable.numNameRecords; + } + + +/******************************************************************* + * + * Function : TT_Get_Name_ID + * + * Description : Returns the IDs of the string number 'nameIndex' + * in the name table of a given face. + * + * Input : face face handle + * nameIndex index of string. First is 0 + * platformID addresses of returned IDs + * encodingID + * languageID + * nameID + * + * Output : Error code. + * + * Notes : Some files have a corrupt or unusual name table, with some + * entries having a platformID > 3. These can usually + * be ignored by a client application. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Name_ID( TT_Face face, + TT_UShort nameIndex, + TT_UShort* platformID, + TT_UShort* encodingID, + TT_UShort* languageID, + TT_UShort* nameID ) + { + TNameRec* namerec; + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( nameIndex >= faze->nameTable.numNameRecords ) + return TT_Err_Invalid_Argument; + + namerec = faze->nameTable.names + nameIndex; + + *platformID = namerec->platformID; + *encodingID = namerec->encodingID; + *languageID = namerec->languageID; + *nameID = namerec->nameID; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Name_String + * + * Description : Returns the address and length of a given + * string found in the name table. + * + * Input : face face handle + * nameIndex string index + * stringPtr address of returned pointer to string + * length address of returned string length + * + * Output : Error code. + * + * Notes : If the string's platformID is invalid, + * stringPtr is NULL, and length is 0. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Name_String( TT_Face face, + TT_UShort nameIndex, + TT_String** stringPtr, + TT_UShort* length ) + { + TNameRec* namerec; + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + if ( nameIndex >= faze->nameTable.numNameRecords ) + return TT_Err_Invalid_Argument; + + namerec = faze->nameTable.names + nameIndex; + + *stringPtr = (String*)namerec->string; + *length = namerec->stringLength; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Get_Font_Data + * + * Description : Loads any font table into client memory. + * + * Input : face Face object to look for. + * + * tag Tag of table to load. Use the value 0 if you + * want to access the whole font file, else set + * this parameter to a valid TrueType table tag + * that you can forge with the MAKE_TT_TAG + * macro. + * + * offset Starting offset in the table (or the file + * if tag == 0). + * + * buffer Address of target buffer + * + * length Address of decision variable: + * + * if length == NULL: + * Load the whole table. Returns an + * error if 'offset' != 0. + * + * if *length == 0 : + * Exit immediately, returning the + * length of the given table, or of + * the font file, depending on the + * value of 'tag'. + * + * if *length != 0 : + * Load the next 'length' bytes of + * table or font, starting at offset + * 'offset' (in table or font too). + * + * Output : Error code. + * + * MT-Safe : YES! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Get_Font_Data( TT_Face face, + TT_ULong tag, + TT_Long offset, + void* buffer, + TT_Long* length ) + { + PFace faze = HANDLE_Face( face ); + + + if ( !faze ) + return TT_Err_Invalid_Face_Handle; + + return Load_TrueType_Any( faze, tag, offset, buffer, length ); + } + + + /************************ callback definition ******************/ + + /* Register a new callback to the TrueType engine -- this should */ + /* only be used by higher-level libraries, not typical clients */ + /* */ + /* This is not part of the current FreeType release, thus */ + /* undefined... */ + +#if 0 + EXPORT_FUNC + TT_Error TT_Register_Callback( TT_Engine engine, + int callback_id, + void* callback_ptr ) + { + PEngine_Instance eng = HANDLE_Engine( engine ); + + + if ( !eng ) + return TT_Err_Invalid_Argument; + + /* currently, we only support one callback */ + if (callback_id != TT_Callback_Glyph_Outline_Load) + return TT_Err_Invalid_Argument; + + eng->glCallback = (TT_Glyph_Loader_Callback)callback_ptr; + return TT_Err_Ok; + } +#endif /* 0 */ + + +/* END */ diff --git a/lib/ttcache.c b/lib/ttcache.c new file mode 100644 index 0000000..5162419 --- /dev/null +++ b/lib/ttcache.c @@ -0,0 +1,463 @@ +/******************************************************************* + * + * ttcache.c 1.1 + * + * Generic object cache + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 1.1 and 1.0: + * + * - introduced the refresher and finalizer in the cache class + * definition/implementation. + * + ******************************************************************/ + +#include "ttengine.h" +#include "ttmemory.h" +#include "ttcache.h" +#include "ttobjs.h" +#include "ttdebug.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_cache + +#define ZERO_List( list ) list = NULL + +/* The macro FREE_Elements aliases the current engine instance's */ +/* free list_elements recycle list. */ +#define FREE_Elements ( engine->list_free_elements ) + +/* Redefinition of LOCK and UNLOCK macros for New_Element and Done_Element */ +/* Note: The macros are redefined below for the cache functions */ + +#undef LOCK +#define LOCK() MUTEX_Lock ( engine->lock ) + +#undef UNLOCK +#define UNLOCK() MUTEX_Release( engine->lock ) + +/******************************************************************* + * + * Function : Element_New + * + * Description : Gets a new (either fresh or recycled) list + * element. The element is unlisted. + * + * Input : None + * + * Output : List element address. NULL if out of memory. + * + ******************************************************************/ + + static + PList_Element Element_New( PEngine_Instance engine ) + { + PList_Element element; + + + LOCK(); + if ( FREE_Elements ) + { + element = (PList_Element)FREE_Elements; + FREE_Elements = element->next; + } + else + { + if ( !MEM_Alloc( element, sizeof ( TList_Element ) ) ) + { + element->next = NULL; + element->data = NULL; + } + } + + /* Note: in case of failure, Alloc sets the pointer to NULL */ + UNLOCK(); + + return element; + } + + +/******************************************************************* + * + * Function : Element_Done + * + * Description : Recycles an unlinked list element. + * + * Input : The list element to recycle. It _must_ be unlisted. + * + * Output : none. + * + * Note : This function doesn't check the element. + * + ******************************************************************/ + + static + void Element_Done( PEngine_Instance engine, + PList_Element element ) + { + LOCK(); + /* Simply add the list element to the recycle list */ + element->next = (PList_Element)FREE_Elements; + FREE_Elements = element; + UNLOCK(); + } + + +/* Redefinition of LOCK and UNLOCK macros for the cache functions */ +/* Note: The macros are defined above for the list element functions */ + +#undef LOCK +#define LOCK() MUTEX_Lock( *cache->lock ) + +#undef UNLOCK +#define UNLOCK() MUTEX_Release( *cache->lock ) + + +/******************************************************************* + * + * Function : Cache_Create + * + * Description : Creates a new cache that will be used to list + * and recycle several objects of the same class. + * + * Input : clazz a pointer to the cache's class. This is + * a simple structure that describes the + * the cache's object types and recycling + * limits. + * + * cache address of cache to create + * + * lock address of the mutex to use for this + * cache. The mutex will be used to protect + * the cache's lists. Use NULL for unprotected + * cache. + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Cache_Create( PEngine_Instance engine, + PCache_Class clazz, + TCache* cache, + TMutex* lock ) + { + cache->engine = engine; + cache->clazz = clazz; + cache->lock = lock; + cache->idle_count = 0; + + ZERO_List( cache->active ); + ZERO_List( cache->idle ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Cache_Destroy + * + * Description : Destroys a cache and all its idle and active + * objects. This will call each object's destructor + * before freeing it. + * + * Input : cache address of cache to destroy + * + * Output : error code. + * + * Note: This function is not MT-Safe, as we assume that a client + * isn't stupid enough to use an object while destroying it. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Cache_Destroy( TCache* cache ) + { + PDestructor destroy; + PList_Element current; + PList_Element next; + + + /* now destroy all active and idle listed objects */ + + /* get the destructor function */ + destroy = cache->clazz->done; + + /* destroy all elements in active list */ + current = cache->active; + while ( current ) + { + next = current->next; + destroy( current->data ); + FREE( current->data ); + + Element_Done( cache->engine, current ); + current = next; + } + ZERO_List(cache->active); + + /* destroy all elements in idle list */ + current = cache->idle; + while ( current ) + { + next = current->next; + destroy( current->data ); + FREE( current->data ); + + Element_Done( cache->engine, current ); + current = next; + } + ZERO_List(cache->idle); + + cache->clazz = NULL; + cache->idle_count = 0; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Cache_New + * + * Description : Extracts a new object from a cache. This will + * try to recycle an idle object, if any is found. + * Otherwise, a new object will be allocated and + * built (by calling its constructor). + * + * Input : cache address of cache to use + * new_object address of target pointer to the 'new' + * object + * parent_object this pointer is passed to a new object + * constructor (unused if object is + * recycled) + * + * Output : Error code. + * + * Notes: This function is thread-safe, each cache list is protected + * through the cache's mutex, if there is one... + * + * *new_object will be set to NULL in case of failure. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Cache_New( TCache* cache, + void** new_object, + void* parent_object ) + { + TT_Error error; + PList_Element current; + PConstructor build; + PRefresher reset; + void* object; + + + LOCK(); + current = cache->idle; + if ( current ) + { + cache->idle = current->next; + cache->idle_count--; + } + UNLOCK(); + + if ( current ) + { + object = current->data; + reset = cache->clazz->reset; + if ( reset ) + { + error = reset( object, parent_object ); + if ( error ) + { + LOCK(); + current->next = cache->idle; + cache->idle = current; + cache->idle_count++; + UNLOCK(); + goto Exit; + } + } + } + else + { + /* if no object was found in the cache, create a new one */ + build = cache->clazz->init; + + if ( MEM_Alloc( object, cache->clazz->object_size ) ) + goto Memory_Fail; + + current = Element_New( cache->engine ); + if ( !current ) + goto Memory_Fail; + + current->data = object; + + error = build( object, parent_object ); + if ( error ) + { + Element_Done( cache->engine, current ); + goto Fail; + } + } + + LOCK(); + current->next = cache->active; + cache->active = current; + UNLOCK(); + + *new_object = current->data; + return TT_Err_Ok; + + Exit: + *new_object = NULL; + return error; + + Memory_Fail: + error = TT_Err_Out_Of_Memory; + + Fail: + FREE( object ); + goto Exit; + } + + +/******************************************************************* + * + * Function : Cache_Done + * + * Description : Releases an object to the cache. This will either + * recycle or destroy the object, based on the cache's + * class and state. + * + * Input : cache the cache to use + * data the object to recycle/discard + * + * Output : error code. + * + * Notes : The object's destructor is called only when + * the objectwill be effectively destroyed by this + * function. This will not happen during recycling. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Cache_Done( TCache* cache, void* data ) + { + TT_Error error; + PList_Element element; + PList_Element prev; + PFinalizer finalize; + Long limit; + Bool destroy; + + + /* Look for object in active list */ + LOCK(); + + element = cache->active; + prev = NULL; + while ( element ) + { + if ( element->data == data ) + { + if ( prev ) + prev->next = element->next; + else + cache->active = element->next; + goto Suite; + } + prev = element; + element = element->next; + } + + UNLOCK(); + return TT_Err_Unlisted_Object; + + Suite: + + limit = cache->clazz->idle_limit; + destroy = (cache->idle_count >= limit); + UNLOCK(); + + if ( destroy ) + { + /* destroy the object when the cache is full */ + cache->clazz->done( element->data ); + FREE( element->data ); + Element_Done( cache->engine, element ); + } + else + { + /* Finalize the object before adding it to the */ + /* idle list. Return the error if any is found. */ + + finalize = cache->clazz->finalize; + if ( finalize ) + { + error = finalize( element->data ); + if ( error ) + goto Exit; + + /* Note: a failure at finalize time is a severe bug in */ + /* the engine, which is why we allow ourselves to */ + /* lose the object in this case. A finalizer should */ + /* have its own error codes to spot this kind of */ + /* problems easily. */ + } + + LOCK(); + element->next = cache->idle; + cache->idle = element; + cache->idle_count++; + UNLOCK(); + } + + error = TT_Err_Ok; + + Exit: + return error; + } + + + LOCAL_FUNC + TT_Error TTCache_Init( PEngine_Instance engine ) + { + /* Create list elements mutex */ + FREE_Elements = NULL; + return TT_Err_Ok; + } + + + LOCAL_FUNC + TT_Error TTCache_Done( PEngine_Instance engine ) + { + /* We don't protect this function, as this is the end of the engine's */ + /* execution.. */ + PList_Element element, next; + + + /* frees the recycled list elements */ + element = FREE_Elements; + while ( element ) + { + next = element->next; + FREE( element ); + element = next; + } + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/ttcache.h b/lib/ttcache.h new file mode 100644 index 0000000..e6f17c3 --- /dev/null +++ b/lib/ttcache.h @@ -0,0 +1,216 @@ +/******************************************************************* + * + * ttcache.h 1.1 + * + * Generic object cache + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This component defines and implements object caches. + * + * An object class is a structure layout that encapsulate one + * given type of data used by the FreeType engine. Each object + * class is completely described by: + * + * - a 'root' or 'leading' structure containing the first + * important fields of the class. The root structure is + * always of fixed size. + * + * It is implemented as a simple C structure, and may + * contain several pointers to sub-tables that can be + * sized and allocated dynamically. + * + * Examples: TFace, TInstance, TGlyph & TExecution_Context + * (defined in 'ttobjs.h') + * + * - we make a difference between 'child' pointers and 'peer' + * pointers. A 'child' pointer points to a sub-table that is + * owned by the object, while a 'peer' pointer points to any + * other kind of data the object isn't responsible for. + * + * An object class is thus usually a 'tree' of 'child' tables. + * + * - each object class needs a constructor and a destructor. + * + * A constructor is a function which receives the address of + * freshly allocated and zeroed object root structure and + * 'builds' all the valid child data that must be associated + * to the object before it becomes 'valid'. + * + * A destructor does the inverse job: given the address of + * a valid object, it must discard all its child data and + * zero its main fields (essentially the pointers and array + * sizes found in the root fields). + * + * + * Important notes: + * + * When the constructor fails to allocate an object, it must + * return immediately with an error code, and not try to release + * what it has previously allocated before the error. The cache + * manager detects the error and calls the destructor on the + * partial object, before returning the error to the caller (along + * with a NULL pointer for the "new" object). + * + * The destructor must thus be able to deal with "partial objects", + * i.e., objects where only part of the child tables are allocated, + * and only release these ones. As the TT_Free() function accepts + * a NULL parameter (and returns successfuly in this case), no check + * is really necessary when using the macro 'FREE()'. + * + * Currently, there is no check in the cache manager to see if a + * destructor fails (double error state!). + * + * This scheme is more compact and more maintanable than the one + * where de-allocation code is duplicated in the constructor + * _and_ the destructor. + * + * + * + * Changes between 1.1 and 1.0: + * + * - introduced the refreshed and finalizer class definition/implementation + * - inserted an engine instance pointer in the cache structure + * + ******************************************************************/ + +#ifndef TTCACHE_H +#define TTCACHE_H + +#include "tttypes.h" +#include "ttconfig.h" +#include "ttmutex.h" + +#ifdef __cplusplus + extern "C" { +#endif + + typedef TT_Error TConstructor( void* object, + void* parent ); + + typedef TT_Error TDestructor ( void* object ); + + typedef TConstructor TRefresher; + typedef TDestructor TFinalizer; + + typedef TConstructor* PConstructor; + typedef TDestructor* PDestructor; + typedef TRefresher* PRefresher; + typedef TFinalizer* PFinalizer; + + + /* A Cache class record holds the data necessary to define */ + /* a cache kind. */ + struct TCache_Class_ + { + ULong object_size; + Long idle_limit; + PConstructor init; + PDestructor done; + PRefresher reset; + PFinalizer finalize; + }; + + typedef struct TCache_Class_ TCache_Class; + typedef TCache_Class* PCache_Class; + + + + /* Simple list node record. A list element is said to be 'unlinked' */ + /* when it doesn't belong to any list. */ + struct TList_Element_; + + typedef struct TList_Element_ TList_Element; + typedef TList_Element* PList_Element; + + struct TList_Element_ + { + PList_Element next; + void* data; + }; + + + /* Simple singly-linked list record - LIFO style, no tail field */ + typedef PList_Element TSingle_List; + + struct TCache_ + { + PEngine_Instance engine; + PCache_Class clazz; /* 'class' is a reserved word in C++ */ + TMutex* lock; + TSingle_List active; + TSingle_List idle; + Long idle_count; + }; + + typedef struct TCache_ TCache; + typedef TCache* PCache; + + /* Returns a new list element, either fresh or recycled. */ + /* Note: the returned element is unlinked. */ + + /* An object cache holds two lists tracking the active and */ + /* idle objects that are currently created and used by the */ + /* engine. It can also be 'protected' by a mutex. */ + + /* Initializes a new cache, of class 'clazz', pointed by 'cache', */ + /* protected by the 'lock' mutex. Set 'lock' to NULL if the cache */ + /* doesn't need protection */ + + LOCAL_DEF + TT_Error Cache_Create( PEngine_Instance engine, + PCache_Class clazz, + TCache* cache, + TMutex* lock ); + + /* Destroys a cache and all its listed objects */ + + LOCAL_DEF + TT_Error Cache_Destroy( TCache* cache ); + + + /* Extracts a new object from the cache */ + + LOCAL_DEF + TT_Error Cache_New( TCache* cache, + void** new_object, + void* parent_object ); + + + /* Returns an object to the cache, or discards it depending */ + /* on the cache class' 'idle_limit' field */ + + LOCAL_DEF + TT_Error Cache_Done( TCache* cache, void* data ); + +#define CACHE_New( _cache, _newobj, _parent ) \ + Cache_New( (TCache*)_cache, (void**)&_newobj, (void*)_parent ) + +#define CACHE_Done( _cache, _obj ) \ + Cache_Done( (TCache*)_cache, (void*)_obj ) + + + + LOCAL_DEF + TT_Error TTCache_Init( PEngine_Instance engine ); + + LOCAL_DEF + TT_Error TTCache_Done( PEngine_Instance engine ); + + +#ifdef __cplusplus + } +#endif + +#endif /* TTCACHE_H */ + + +/* END */ diff --git a/lib/ttcalc.c b/lib/ttcalc.c new file mode 100644 index 0000000..0733624 --- /dev/null +++ b/lib/ttcalc.c @@ -0,0 +1,403 @@ +/******************************************************************* + * + * ttcalc.c + * + * Arithmetic Computations (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "ttcalc.h" +#include "ttdebug.h" +#include "tttables.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_calc + + +/* Support for 1-complement arithmetic has been totally dropped in this */ +/* release. You can still write your own code if you need it... */ + + static const Long Roots[63] = + { + 1, 1, 2, 3, 4, 5, 8, 11, + 16, 22, 32, 45, 64, 90, 128, 181, + 256, 362, 512, 724, 1024, 1448, 2048, 2896, + 4096, 5892, 8192, 11585, 16384, 23170, 32768, 46340, + + 65536, 92681, 131072, 185363, 262144, 370727, + 524288, 741455, 1048576, 1482910, 2097152, 2965820, + 4194304, 5931641, 8388608, 11863283, 16777216, 23726566, + + 33554432, 47453132, 67108864, 94906265, + 134217728, 189812531, 268435456, 379625062, + 536870912, 759250125, 1073741824, 1518500250, + 2147483647 + }; + + +#ifdef LONG64 + + EXPORT_FUNC + TT_Long TT_MulDiv( TT_Long a, TT_Long b, TT_Long c ) + { + Long s; + + + s = a; a = ABS( a ); + s ^= b; b = ABS( b ); + s ^= c; c = ABS( c ); + + a = ((TT_Int64)a * b + c/2) / c; + return ( s < 0 ) ? -a : a; + } + + + EXPORT_FUNC + TT_Long TT_MulFix( TT_Long a, TT_Long b ) + { + Long s; + + + s = a; a = ABS( a ); + s ^= b; b = ABS( b ); + + a = ((TT_Int64)a * b + 0x8000) / 0x10000; + return ( s < 0 ) ? -a : a; + } + + + LOCAL_FUNC + Int Order64( TT_Int64 z ) + { + Int j = 0; + + + while ( z ) + { + z = (unsigned INT64)z >> 1; + j++; + } + return j - 1; + } + + + LOCAL_FUNC + TT_Int32 Sqrt64( TT_Int64 l ) + { + TT_Int64 r, s; + + + if ( l <= 0 ) return 0; + if ( l == 1 ) return 1; + + r = Roots[Order64( l )]; + + do + { + s = r; + r = ( r + l/r ) >> 1; + } + while ( r > s || r*r > l ); + + return r; + } + +#else /* LONG64 */ + + + /* The TT_MulDiv function has been optimized thanks to ideas from */ + /* Graham Asher. The trick is to optimize computation when everything */ + /* fits within 32-bits (a rather common case). */ + /* */ + /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ + /* */ + /* 46340 is FLOOR(SQRT(2^31-1)). */ + /* */ + /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ + /* */ + /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ + /* */ + /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ + /* */ + /* and 2*0x157F0 = 176096 */ + /* */ + + EXPORT_FUNC + TT_Long TT_MulDiv( TT_Long a, TT_Long b, TT_Long c ) + { + long s; + + + if ( a == 0 || b == c ) + return a; + + s = a; a = ABS( a ); + s ^= b; b = ABS( b ); + s ^= c; c = ABS( c ); + + if ( a <= 46340 && b <= 46340 && c <= 176095 ) + { + a = ( a*b + c/2 )/c; + } + else + { + TT_Int64 temp, temp2; + + MulTo64( a, b, &temp ); + temp2.hi = (TT_Int32)(c >> 31); + temp2.lo = (TT_Word32)(c / 2); + Add64( &temp, &temp2, &temp ); + a = Div64by32( &temp, c ); + } + + return ( s < 0 ) ? -a : a; + } + + /* The optimization for TT_MulFix is different. We could simply be */ + /* happy by applying the same principles than with TT_MulDiv, because */ + /* */ + /* c = 0x10000 < 176096 */ + /* */ + /* however, in most cases, we have a 'b' with a value around 0x10000 */ + /* which is greater than 46340. */ + /* */ + /* According to Graham's testing, most cases have 'a' < 100, so a good */ + /* idea is to use bounds like 1024 and 2097151 (= floor(2^31-1)/1024 ) */ + /* for 'a' and 'b' respectively.. */ + /* */ + + EXPORT_FUNC + TT_Long TT_MulFix( TT_Long a, TT_Long b ) + { + long s; + + if ( a == 0 || b == 0x10000 ) + return a; + + s = a; a = ABS( a ); + s ^= b; b = ABS( b ); + + if ( a <= 1024 && b <= 2097151 ) + { + a = ( a*b + 0x8000 ) >> 16; + } + else + { + TT_Int64 temp, temp2; + + MulTo64( a, b, &temp ); + temp2.hi = 0; + temp2.lo = 0x8000; + Add64( &temp, &temp2, &temp ); + a = Div64by32( &temp, 0x10000 ); + } + + return ( s < 0 ) ? -a : a; + } + + + LOCAL_FUNC + void Neg64( TT_Int64* x ) + { + /* Remember that -(0x80000000) == 0x80000000 with 2-complement! */ + /* We take care of that here. */ + + x->hi ^= 0xFFFFFFFFUL; + x->lo ^= 0xFFFFFFFFUL; + x->lo++; + + if ( !x->lo ) + { + x->hi++; + if ( x->hi == 0x80000000UL ) /* Check -MaxInt32 - 1 */ + { + x->lo--; + x->hi--; /* We return 0x7FFFFFFF! */ + } + } + } + + + LOCAL_FUNC + void Add64( TT_Int64* x, TT_Int64* y, TT_Int64* z ) + { + register TT_Word32 lo, hi; + + + lo = x->lo + y->lo; + hi = x->hi + y->hi + ( lo < x->lo ); + + z->lo = lo; + z->hi = hi; + } + + + LOCAL_FUNC + void Sub64( TT_Int64* x, TT_Int64* y, TT_Int64* z ) + { + register TT_Word32 lo, hi; + + + lo = x->lo - y->lo; + hi = x->hi - y->hi - ( (TT_Int32)lo < 0 ); + + z->lo = lo; + z->hi = hi; + } + + + LOCAL_FUNC + void MulTo64( TT_Int32 x, TT_Int32 y, TT_Int64* z ) + { + TT_Int32 s; + TT_Word32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + s = x; x = ABS( x ); + s ^= y; y = ABS( y ); + + lo1 = x & 0x0000FFFF; hi1 = x >> 16; + lo2 = y & 0x0000FFFF; hi2 = y >> 16; + + lo = lo1*lo2; + i1 = lo1*hi2; + i2 = lo2*hi1; + hi = hi1*hi2; + + /* Check carry overflow of i1 + i2 */ + + if ( i2 ) + { + if ( i1 >= (TT_Word32)-(TT_Int32)i2 ) hi += 1L << 16; + i1 += i2; + } + + i2 = i1 >> 16; + i1 = i1 << 16; + + /* Check carry overflow of i1 + lo */ + if ( i1 ) + { + if ( lo >= (TT_Word32)-(TT_Int32)i1 ) hi++; + lo += i1; + } + + hi += i2; + + z->lo = lo; + z->hi = hi; + + if ( s < 0 ) Neg64( z ); + } + + + LOCAL_FUNC + TT_Int32 Div64by32( TT_Int64* x, TT_Int32 y ) + { + TT_Int32 s; + TT_Word32 q, r, i, lo; + + + s = x->hi; if ( s < 0 ) Neg64( x ); + s ^= y; y = ABS( y ); + + /* Shortcut */ + if ( x->hi == 0 ) + { + q = x->lo / y; + return ( s < 0 ) ? -(TT_Int32)q : (TT_Int32)q; + } + + r = x->hi; + lo = x->lo; + + if ( r >= (TT_Word32)y ) /* we know y is to be treated as unsigned here */ + return ( s < 0 ) ? 0x80000001UL : 0x7FFFFFFFUL; + /* Return Max/Min Int32 if divide overflow */ + /* This includes division by zero! */ + q = 0; + for ( i = 0; i < 32; i++ ) + { + r <<= 1; + q <<= 1; + r |= lo >> 31; + + if ( r >= (TT_Word32)y ) + { + r -= y; + q |= 1; + } + lo <<= 1; + } + + return ( s < 0 ) ? -(TT_Int32)q : (TT_Int32)q; + } + + + LOCAL_FUNC + Int Order64( TT_Int64* z ) + { + TT_Word32 i; + Int j; + + + if ( z->hi ) + { + i = z->hi; + j = 32; + } + else + { + i = z->lo; + j = 0; + } + + while ( i > 0 ) + { + i >>= 1; + j++; + } + return j-1; + } + + + LOCAL_FUNC + TT_Int32 Sqrt64( TT_Int64* l ) + { + TT_Int64 l2; + TT_Int32 r, s; + + + if ( (TT_Int32)l->hi < 0 || + (l->hi == 0 && l->lo == 0) ) return 0; + + s = Order64( l ); + if ( s == 0 ) return 1; + + r = Roots[s]; + do + { + s = r; + r = ( r + Div64by32(l,r) ) >> 1; + MulTo64( r, r, &l2 ); + Sub64 ( l, &l2, &l2 ); + } + while ( r > s || (TT_Int32)l2.hi < 0 ); + + return r; + } + +#endif /* LONG64 */ + + +/* END */ diff --git a/lib/ttcalc.h b/lib/ttcalc.h new file mode 100644 index 0000000..9b4c306 --- /dev/null +++ b/lib/ttcalc.h @@ -0,0 +1,97 @@ +/******************************************************************* + * + * ttcalc.h + * + * Arithmetic Computations (specification). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTCALC_H +#define TTCALC_H + +#include "ttconfig.h" +#include "freetype.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef LONG64 + + typedef INT64 TT_Int64; + +#define ADD_64( x, y, z ) z = x + y +#define SUB_64( x, y, z ) z = x - y +#define MUL_64( x, y, z ) z = (TT_Int64)(x) * (y) + +#define DIV_64( x, y ) ( (x) / (y) ) + +#define SQRT_64( x ) Sqrt64( x ) +#define SQRT_32( x ) Sqrt32( x ) + + LOCAL_DEF TT_Int32 Sqrt64( TT_Int64 l ); + +#else /* LONG64 */ + + struct TT_Int64_ + { + TT_Word32 lo; + TT_Word32 hi; + }; + + typedef struct TT_Int64_ TT_Int64; + +#define ADD_64( x, y, z ) Add64( &x, &y, &z ) +#define SUB_64( x, y, z ) Sub64( &x, &y, &z ) +#define MUL_64( x, y, z ) MulTo64( x, y, &z ) + +#define DIV_64( x, y ) Div64by32( &x, y ) + +#define SQRT_64( x ) Sqrt64( &x ) +#define SQRT_32( x ) Sqrt32( x ) + + LOCAL_DEF void Add64( TT_Int64* x, TT_Int64* y, TT_Int64* z ); + LOCAL_DEF void Sub64( TT_Int64* x, TT_Int64* y, TT_Int64* z ); + + LOCAL_DEF void MulTo64( TT_Int32 x, TT_Int32 y, TT_Int64* z ); + + LOCAL_DEF TT_Int32 Div64by32( TT_Int64* x, TT_Int32 y ); + + LOCAL_DEF int Order64( TT_Int64* z ); + + LOCAL_DEF TT_Int32 Sqrt64( TT_Int64* l ); + +#endif /* LONG64 */ + + /* The two following functions are now part of the API! */ + + /* TT_Long TT_MulDiv( TT_Long a, TT_Long b, TT_Long c ); */ + /* TT_Long TT_MulFix( TT_Long a, TT_Long b ); */ + + +#define INT_TO_F26DOT6( x ) ( (Long)(x) << 6 ) +#define INT_TO_F2DOT14( x ) ( (Long)(x) << 14 ) +#define INT_TO_FIXED( x ) ( (Long)(x) << 16 ) +#define F2DOT14_TO_FIXED( x ) ( (Long)(x) << 2 ) +#define FLOAT_TO_FIXED( x ) ( (Long)(x * 65536.0) ) + +#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ((x) + 32) & -64) \ + : ( -((32 - (x)) & -64) ) ) + +#ifdef __cplusplus + } +#endif + +#endif /* TTCALC_H */ + +/* END */ diff --git a/lib/ttcmap.c b/lib/ttcmap.c new file mode 100644 index 0000000..6b8596f --- /dev/null +++ b/lib/ttcmap.c @@ -0,0 +1,503 @@ +/******************************************************************* + * + * ttcmap.c 1.0 + * + * TrueType Character Mappings + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "ttobjs.h" +#include "ttdebug.h" +#include "ttfile.h" +#include "ttmemory.h" +#include "ttload.h" +#include "ttcmap.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_cmap + + +/******************************************************************* + * + * Function : CharMap_Load + * + * Description : Loads a given charmap into memory. + * + * Input : cmap pointer to cmap table + * + * Output : Error code. + * + * Notes : - Assumes the the stream is already used (opened). + * + * - In case of error, releases all partially allocated + * tables. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error CharMap_Load( PCMapTable cmap, + TT_Stream input ) + { + DEFINE_LOAD_LOCALS( input ); + + UShort num_SH, num_Seg, i; + + UShort u, l; + + PCMap0 cmap0; + PCMap2 cmap2; + PCMap4 cmap4; + PCMap6 cmap6; + + PCMap2SubHeader cmap2sub; + PCMap4Segment segments; + + + if ( cmap->loaded ) + return TT_Err_Ok; + + if ( FILE_Seek( cmap->offset ) ) + return error; + + switch ( cmap->format ) + { + case 0: + cmap0 = &cmap->c.cmap0; + + if ( ALLOC( cmap0->glyphIdArray, 256L ) || + FILE_Read( (void*)cmap0->glyphIdArray, 256L ) ) + goto Fail; + + break; + + case 2: + num_SH = 0; + cmap2 = &cmap->c.cmap2; + + /* allocate subheader keys */ + + if ( ALLOC_ARRAY( cmap2->subHeaderKeys, 256, UShort ) || + ACCESS_Frame( 512L ) ) + goto Fail; + + for ( i = 0; i < 256; i++ ) + { + u = GET_UShort() / 8; + cmap2->subHeaderKeys[i] = u; + + if ( num_SH < u ) + num_SH = u; + } + + FORGET_Frame(); + + /* load subheaders */ + + cmap2->numGlyphId = l = + ( ( cmap->length - 2L * (256 + 3) - num_SH * 8L ) & 0xffff) / 2; + + if ( ALLOC_ARRAY( cmap2->subHeaders, + num_SH + 1, + TCMap2SubHeader ) || + ACCESS_Frame( ( num_SH + 1 ) * 8L ) ) + goto Fail; + + cmap2sub = cmap2->subHeaders; + + for ( i = 0; i <= num_SH; i++ ) + { + cmap2sub->firstCode = GET_UShort(); + cmap2sub->entryCount = GET_UShort(); + cmap2sub->idDelta = GET_Short(); + /* we apply the location offset immediately */ + cmap2sub->idRangeOffset = GET_UShort() - ( num_SH - i ) * 8 - 2; + + cmap2sub++; + } + + FORGET_Frame(); + + /* load glyph ids */ + + if ( ALLOC_ARRAY( cmap2->glyphIdArray, l, UShort ) || + ACCESS_Frame( l * 2L ) ) + goto Fail; + + for ( i = 0; i < l; i++ ) + cmap2->glyphIdArray[i] = GET_UShort(); + + FORGET_Frame(); + break; + + case 4: + cmap4 = &cmap->c.cmap4; + + /* load header */ + + if ( ACCESS_Frame( 8L ) ) + goto Fail; + + cmap4->segCountX2 = GET_UShort(); + cmap4->searchRange = GET_UShort(); + cmap4->entrySelector = GET_UShort(); + cmap4->rangeShift = GET_UShort(); + + num_Seg = cmap4->segCountX2 / 2; + + FORGET_Frame(); + + /* load segments */ + + if ( ALLOC_ARRAY( cmap4->segments, + num_Seg, + TCMap4Segment ) || + ACCESS_Frame( (num_Seg * 4 + 1) * 2L ) ) + goto Fail; + + segments = cmap4->segments; + + for ( i = 0; i < num_Seg; i++ ) + segments[i].endCount = GET_UShort(); + + (void)GET_UShort(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].startCount = GET_UShort(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].idDelta = GET_Short(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].idRangeOffset = GET_UShort(); + + FORGET_Frame(); + + cmap4->numGlyphId = l = + ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xffff ) / 2; + + /* load ids */ + + if ( ALLOC_ARRAY( cmap4->glyphIdArray, l , UShort ) || + ACCESS_Frame( l * 2L ) ) + goto Fail; + + for ( i = 0; i < l; i++ ) + cmap4->glyphIdArray[i] = GET_UShort(); + + FORGET_Frame(); + break; + + case 6: + cmap6 = &cmap->c.cmap6; + + if ( ACCESS_Frame( 4L ) ) + goto Fail; + + cmap6->firstCode = GET_UShort(); + cmap6->entryCount = GET_UShort(); + + FORGET_Frame(); + + l = cmap6->entryCount; + + if ( ALLOC_ARRAY( cmap6->glyphIdArray, + cmap6->entryCount, + Short ) || + ACCESS_Frame( l * 2L ) ) + goto Fail; + + for ( i = 0; i < l; i++ ) + cmap6->glyphIdArray[i] = GET_UShort(); + + FORGET_Frame(); + break; + + default: /* corrupt character mapping table */ + return TT_Err_Invalid_CharMap_Format; + + } + return TT_Err_Ok; + + Fail: + CharMap_Free( cmap ); + return error; + } + + +/******************************************************************* + * + * Function : CharMap_Free + * + * Description : Releases a given charmap table. + * + * Input : cmap pointer to cmap table + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error CharMap_Free( PCMapTable cmap ) + { + if ( !cmap ) + return TT_Err_Ok; + + switch ( cmap->format ) + { + case 0: + FREE( cmap->c.cmap0.glyphIdArray ); + break; + + case 2: + FREE( cmap->c.cmap2.subHeaderKeys ); + FREE( cmap->c.cmap2.subHeaders ); + FREE( cmap->c.cmap2.glyphIdArray ); + break; + + case 4: + FREE( cmap->c.cmap4.segments ); + FREE( cmap->c.cmap4.glyphIdArray ); + cmap->c.cmap4.segCountX2 = 0; + break; + + case 6: + FREE( cmap->c.cmap6.glyphIdArray ); + cmap->c.cmap6.entryCount = 0; + break; + + default: + /* invalid table format, do nothing */ + ; + } + + cmap->loaded = FALSE; + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : CharMap_Index + * + * Description : Performs charcode->glyph index translation. + * + * Input : cmap pointer to cmap table + * + * Output : Glyph index, 0 in case of failure. + * + ******************************************************************/ + + static UShort code_to_index0( UShort charCode, PCMap0 cmap0 ); + static UShort code_to_index2( UShort charCode, PCMap2 cmap2 ); + static UShort code_to_index4( UShort charCode, PCMap4 cmap4 ); + static UShort code_to_index6( UShort charCode, PCMap6 cmap6 ); + + + LOCAL_FUNC + UShort CharMap_Index( PCMapTable cmap, + UShort charcode ) + { + switch ( cmap->format ) + { + case 0: + return code_to_index0( charcode, &cmap->c.cmap0 ); + case 2: + return code_to_index2( charcode, &cmap->c.cmap2 ); + case 4: + return code_to_index4( charcode, &cmap->c.cmap4 ); + case 6: + return code_to_index6( charcode, &cmap->c.cmap6 ); + default: + return 0; + } + } + + +/******************************************************************* + * + * Function : code_to_index0 + * + * Description : Converts the character code into a glyph index. + * Uses format 0. + * charCode will be masked to get a value in the range + * 0x00-0xFF. + * + * Input : charCode the wanted character code + * cmap0 a pointer to a cmap table in format 0 + * + * Output : Glyph index into the glyphs array. + * 0 if the glyph does not exist. + * + ******************************************************************/ + + static UShort code_to_index0( UShort charCode, + PCMap0 cmap0 ) + { + if ( charCode <= 0xFF ) + return cmap0->glyphIdArray[charCode]; + else + return 0; + } + + +/******************************************************************* + * + * Function : code_to_index2 + * + * Description : Converts the character code into a glyph index. + * Uses format 2. + * + * Input : charCode the wanted character code + * cmap2 a pointer to a cmap table in format 2 + * + * Output : Glyph index into the glyphs array. + * 0 if the glyph does not exist. + * + ******************************************************************/ + + static UShort code_to_index2( UShort charCode, + PCMap2 cmap2 ) + { + UShort index1, idx, offset; + TCMap2SubHeader sh2; + + + index1 = cmap2->subHeaderKeys[charCode <= 0xFF ? + charCode : (charCode >> 8)]; + + if ( index1 == 0 ) + { + if ( charCode <= 0xFF ) + return cmap2->glyphIdArray[charCode]; /* 8bit character code */ + else + return 0; + } + else /* 16bit character code */ + { + if ( charCode <= 0xFF ) + return 0; + + sh2 = cmap2->subHeaders[index1]; + + if ( (charCode & 0xFF) < sh2.firstCode ) + return 0; + + if ( (charCode & 0xFF) >= (sh2.firstCode + sh2.entryCount) ) + return 0; + + offset = sh2.idRangeOffset / 2 + (charCode & 0xFF) - sh2.firstCode; + if ( offset < cmap2->numGlyphId ) + idx = cmap2->glyphIdArray[offset]; + else + return 0; + + if ( idx ) + return (idx + sh2.idDelta) & 0xFFFF; + else + return 0; + } + } + + +/******************************************************************* + * + * Function : code_to_index4 + * + * Description : Converts the character code into a glyph index. + * Uses format 4. + * + * Input : charCode the wanted character code + * cmap4 a pointer to a cmap table in format 4 + * + * Output : Glyph index into the glyphs array. + * 0 if the glyph does not exist. + * + ******************************************************************/ + + static UShort code_to_index4( UShort charCode, + PCMap4 cmap4 ) + { + UShort index1, segCount; + UShort i; + TCMap4Segment seg4; + + + segCount = cmap4->segCountX2 / 2; + + for ( i = 0; i < segCount; i++ ) + if ( charCode <= cmap4->segments[i].endCount ) + break; + + /* Safety check - even though the last endCount should be 0xFFFF */ + if ( i >= segCount ) + return 0; + + seg4 = cmap4->segments[i]; + + if ( charCode < seg4.startCount ) + return 0; + + if ( seg4.idRangeOffset == 0 ) + return ( charCode + seg4.idDelta ) & 0xFFFF; + else + { + index1 = seg4.idRangeOffset / 2 + (charCode - seg4.startCount) - + (segCount - i); + + if ( index1 < cmap4->numGlyphId ) + { + if ( cmap4->glyphIdArray[index1] == 0 ) + return 0; + else + return ( cmap4->glyphIdArray[index1] + seg4.idDelta ) & 0xFFFF; + } + else + return 0; + } + } + + +/******************************************************************* + * + * Function : code_to_index6 + * + * Description : Converts the character code into a glyph index. + * Uses format 6. + * + * Input : charCode the wanted character code + * cmap6 a pointer to a cmap table in format 6 + * + * Output : Glyph index into the glyphs array. + * 0 if the glyph does not exist (`missing character glyph'). + * + ******************************************************************/ + + static UShort code_to_index6( UShort charCode, + PCMap6 cmap6 ) + { + UShort firstCode; + + + firstCode = cmap6->firstCode; + + if ( charCode < firstCode ) + return 0; + + if ( charCode >= (firstCode + cmap6->entryCount) ) + return 0; + + return cmap6->glyphIdArray[charCode - firstCode]; + } + + +/* END */ diff --git a/lib/ttcmap.h b/lib/ttcmap.h new file mode 100644 index 0000000..8a1f834 --- /dev/null +++ b/lib/ttcmap.h @@ -0,0 +1,169 @@ +/******************************************************************* + * + * ttcmap.h 1.0 + * + * TrueType Character Mappings + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + ******************************************************************/ + +#ifndef TTCMAP_H +#define TTCMAP_H + +#include "ttconfig.h" +#include "tttypes.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + /* format 0 */ + + struct TCMap0_ + { + PByte glyphIdArray; + }; + + typedef struct TCMap0_ TCMap0; + typedef TCMap0* PCMap0; + + + /* format 2 */ + + struct TCMap2SubHeader_ + { + UShort firstCode; /* first valid low byte */ + UShort entryCount; /* number of valid low bytes */ + Short idDelta; /* delta value to glyphIndex */ + UShort idRangeOffset; /* offset from here to 1st code */ + }; + + typedef struct TCMap2SubHeader_ TCMap2SubHeader; + typedef TCMap2SubHeader* PCMap2SubHeader; + + struct TCMap2_ + { + PUShort subHeaderKeys; + /* high byte mapping table */ + /* value = subHeader index * 8 */ + + PCMap2SubHeader subHeaders; + PUShort glyphIdArray; + UShort numGlyphId; /* control value */ + }; + + typedef struct TCMap2_ TCMap2; + typedef TCMap2* PCMap2; + + + /* format 4 */ + + struct TCMap4Segment_ + { + UShort endCount; + UShort startCount; + Short idDelta; /* in the specs defined as UShort but the + example there gives negative values... */ + UShort idRangeOffset; + }; + + typedef struct TCMap4Segment_ TCMap4Segment; + typedef TCMap4Segment* PCMap4Segment; + + struct TCMap4_ + { + UShort segCountX2; /* number of segments * 2 */ + UShort searchRange; /* these parameters can be used */ + UShort entrySelector; /* for a binary search */ + UShort rangeShift; + + PCMap4Segment segments; + PUShort glyphIdArray; + UShort numGlyphId; /* control value */ + }; + + typedef struct TCMap4_ TCMap4; + typedef TCMap4* PCMap4; + + + /* format 6 */ + + struct TCMap6_ + { + UShort firstCode; /* first character code of subrange */ + UShort entryCount; /* number of character codes in subrange */ + + PUShort glyphIdArray; + }; + + typedef struct TCMap6_ TCMap6; + typedef TCMap6* PCMap6; + + + /* charmap table */ + + struct TCMapTable_ + { + UShort platformID; + UShort platformEncodingID; + UShort format; + UShort length; + UShort version; + + Bool loaded; + ULong offset; + + union + { + TCMap0 cmap0; + TCMap2 cmap2; + TCMap4 cmap4; + TCMap6 cmap6; + } c; + }; + + typedef struct TCMapTable_ TCMapTable; + typedef TCMapTable* PCMapTable; + + + + /* Load character mappings directory when face is loaded. */ + /* The mappings themselves are only loaded on demand. */ + + LOCAL_DEF + TT_Error CharMap_Load( PCMapTable table, + TT_Stream input ); + + + /* Destroy one character mapping table */ + + LOCAL_DEF + TT_Error CharMap_Free( PCMapTable table ); + + + /* Use character mapping table to perform mapping */ + + LOCAL_DEF + UShort CharMap_Index( PCMapTable cmap, + UShort charCode ); + + /* NOTE: The PFace type isn't defined at this point */ + +#ifdef __cplusplus + } +#endif + +#endif /* TTCMAP_H */ + + +/* END */ diff --git a/lib/ttconfig.h b/lib/ttconfig.h new file mode 100644 index 0000000..c56e1ac --- /dev/null +++ b/lib/ttconfig.h @@ -0,0 +1,279 @@ +/******************************************************************* + * + * ttconfig.h 1.0 + * + * Configuration settings header file (spec only). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Notes: + * + * All the configuration #define statements have been gathered in + * this file to allow easy check and modification. + * + ******************************************************************/ + +#ifndef TTCONFIG_H +#define TTCONFIG_H + + + +/* ------------ auto configuration ------------------------------------- */ + + +/*************************************************************************/ +/* Here we include the file ft_conf.h for system dependent stuff. */ +/* The specific makefile is responsible for providing the right path to */ +/* this file. */ + +#include "ft_conf.h" + + +/**************************************************************************/ +/* Define TT_CONFIG_THREAD_SAFE if you want to build a thread-safe */ +/* version of the library. */ + +/* #define TT_CONFIG_OPTION_THREAD_SAFE */ + + + +/* ------------ general debugging -------------------------------------- */ + + +/************************************************************************* + * + * There are now three debugging modes: + * + * - trace mode: + * + * Error and trace messages are sent to the log file + * (which can be the standard error output). Define + * DEBUG_LEVEL_TRACE to enable this mode. + * + * - error mode: + * + * Only error messages are generated. Define + * DEBUG_LEVEL_ERROR to enable this mode. + * + * - release mode: + * + * Error messages are neither sent nor generated. The code is + * free from any debugging parts. + * + * + * Note that you should link the engine with the 'ttdebug' component. + * in case either DEBUG_LEVEL_TRACE or DEBUG_LEVEL_ERROR is defined. + * + * Please consult ttdebug.h for more details. */ + +/* #define DEBUG_LEVEL_TRACE */ +/* #define DEBUG_LEVEL_ERROR */ + + + +/* ------------ special debugging -------------------------------------- */ + + +/*************************************************************************/ +/* Define this if you want to generate a special debug version of the */ +/* rasterizer. This will progressively draw the glyphs while the */ +/* computations are done directly on the graphics screen... (with */ +/* inverted glyphs). */ +/* */ +/* Use it at your own risk! It is not maintained currently. */ +/* */ +/* IMPORTANT: This is reserved to developers willing to debug the */ +/* rasterizer, which seems working very well in its */ +/* current state... */ + +/* #define DEBUG_RASTER */ + + +/*************************************************************************/ +/* Define this to have a simple debugger version of RunIns(). */ +/* */ +/* Use it at your own risk! It is not maintained currently. */ + +/* #define DEBUG_INTERPRETER */ + + +/*************************************************************************/ +/* Define this to have some housekeeping of allocation and deallocation. */ +/* */ +/* Please note that probably not all OS-specific versions of ttmemory.c */ +/* provide this functionality. */ + +/* #define DEBUG_MEMORY */ + + +/*************************************************************************/ +/* Define this to have bounds checking for file buffer frames. */ +/* */ +/* Please note that probably not all OS-specific versions of ttfile.c */ +/* provide this functionality. */ + +/* #define DEBUG_FILE */ + + + +/* ------------ arithmetic and processor support ----------------------- */ + + +/*************************************************************************/ +/* Define TT_USE_LONG_LONG if you want to enable the use of the */ +/* 'long long' 64-bit type provided by gcc and other compilers. Note */ +/* that : */ +/* */ +/* 1. The type isn't ANSI, and thus will produce many warnings */ +/* during library compilation. */ +/* */ +/* 2. Though the generated object files are slightly smaller, the */ +/* resulting executables are bigger of about 4Kb! gcc must be */ +/* linking some extra code in there! */ +/* */ +/* 3. There is really no speed gain in doing so (but it may help */ +/* debug the ttcalc component). */ +/* */ +/* IMPORTANT NOTE: You don't need to define it on 64-bits machines! */ +/* */ +/* NOTE 2 : This flag used to be _GNUC_LONG64_ */ + +/* #define TT_USE_LONG_LONG */ + + +/*************************************************************************/ +/* define ALIGNMENT to your processor/environment preferred alignment */ +/* size. A value of 8 should work on all current processors, even */ +/* 64-bits ones. */ + +#define ALIGNMENT 8 + + + +/* --------------- miscellaneous ----------------------------------- */ + + +/*********************************************************************/ +/* The number of extensions available. Don't change this value */ +/* except if you add new extensions to the engine. */ + +#define TT_MAX_EXTENSIONS 8 + + + +/* --------------- automatic setup -- don't touch ------------------ */ + + +/*********************************************************************/ +/* If HAVE_TT_TEXT is defined we don't provide a default typedef for */ +/* defining TT_Text. */ + +#ifndef HAVE_TT_TEXT +#define HAVE_TT_TEXT + typedef char TT_Text; +#endif + + +/*********************************************************************/ +/* We define NULL in case it's not defined yet. The default */ +/* location is stdlib.h. */ + +#ifdef HAVE_STDLIB_H +#include +#endif + + +/*********************************************************************/ +/* Some systems can't use vfprintf for error messages on stderr; if */ +/* HAVE_PRINT_FUNCTION is defined, the Print macro must be supplied */ +/* externally (having the same parameters). */ +/* */ +/* This is only used by the "ttdebug" component, which should be */ +/* linked to the engine only in debug mode. */ + +#if defined( DEBUG_LEVEL_TRACE ) || defined( DEBUG_LEVEL_ERROR ) +#ifndef HAVE_PRINT_FUNCTION +#define Print( format, ap ) vfprintf( stderr, (format), (ap) ) +#endif +#endif + + +/********************************************************************/ +/* */ +/* I have added the ability to compile the library into a single */ +/* object file. This gets rids of all the external symbols defined */ +/* in each component interface, and de-pollutes the name-space. */ +/* */ +/* I use two macros, namely LOCAL_FUNC and LOCAL_DEF, which only */ +/* apply to functions that are internal to the engine, and */ +/* should never be seen or linked by a client application. */ +/* */ +/* LOCAL_DEF used in header (.h) files, to define a function */ +/* that will be seen by other components. This */ +/* translates to "extern" in normal mode, and to */ +/* "static" in single-object mode. */ +/* */ +/* LOCAL_FUNC used in implementation (.c) files, just before */ +/* the function body. This translates to nothing */ +/* in normal mode, and to "static" in single-object */ +/* mode. */ +/* */ +/* Getting rid of un-necessary symbols makes the "ttcommon" */ +/* renaming macros hack unnecessary. Moreover, the stripped */ +/* single object file (freetype.o) is 52 Kb, instead of the */ +/* previous 57 Kb (size of all combined .o files), and gives */ +/* a better idea of the engine's real code size. */ +/* */ +/* It is called a "MAKE_OPTION" because the macro must be */ +/* defined in the Makefile, rather than this one. It allows */ +/* any developer to quickly switch from one mode to the other */ +/* without messing with "ttconfig.h" each time. */ +/* */ +#ifndef TT_MAKE_OPTION_SINGLE_OBJECT +#define LOCAL_FUNC /* void */ +#define LOCAL_DEF extern +#else +#define LOCAL_FUNC static +#define LOCAL_DEF static +#endif + + +/*************************************************************************/ +/* Define EXPORT_DEF and EXPORT_FUNC as needed to build e.g. a DLL. All */ +/* variables and functions visible from outside have these prefixes. */ + +#ifndef EXPORT_DEF +#define EXPORT_DEF extern +#endif + +#ifndef EXPORT_FUNC +#define EXPORT_FUNC /* void */ +#endif + + + +/* -------------- internal (developer) configuration toggles ------------ */ + + +#undef TT_STATIC_INTERPRETER +/* Do not undefine this configuration macro. It is now a default that */ +/* must be kept in all release builds. */ + + +#undef TT_STATIC_RASTER +/* Define this if you want to generate a static raster. This makes */ +/* a non re-entrant version of the scan-line converter, which is */ +/* about 10% faster and 50% bigger than an indirect one! */ + + +#endif /* TTCONFIG_H */ + + +/* END */ diff --git a/lib/ttdebug.c b/lib/ttdebug.c new file mode 100644 index 0000000..4afe2dc --- /dev/null +++ b/lib/ttdebug.c @@ -0,0 +1,404 @@ +/* Simple debugging component. Temporary */ + +#include "ttdebug.h" +#include "tttables.h" +#include "ttobjs.h" + + +#ifdef DEBUG_LEVEL_TRACE + char tt_trace_levels[trace_max]; +#endif + +#if defined( DEBUG_LEVEL_ERROR ) || defined( DEBUG_LEVEL_TRACE ) + +#include +#include +#include + + + static String tempStr[128]; + + static const String* OpStr[256] = + { + "SVTCA y", /* Set vectors to coordinate axis y */ + "SVTCA x", /* Set vectors to coordinate axis x */ + "SPvTCA y", /* Set Proj. vec. to coord. axis y */ + "SPvTCA x", /* Set Proj. vec. to coord. axis x */ + "SFvTCA y", /* Set Free. vec. to coord. axis y */ + "SFvTCA x", /* Set Free. vec. to coord. axis x */ + "SPvTL //", /* Set Proj. vec. parallel to segment */ + "SPvTL +", /* Set Proj. vec. normal to segment */ + "SFvTL //", /* Set Free. vec. parallel to segment */ + "SFvTL +", /* Set Free. vec. normal to segment */ + "SPvFS", /* Set Proj. vec. from stack */ + "SFvFS", /* Set Free. vec. from stack */ + "GPV", /* Get projection vector */ + "GFV", /* Get freedom vector */ + "SFvTPv", /* Set free. vec. to proj. vec. */ + "ISECT", /* compute intersection */ + + "SRP0", /* Set reference point 0 */ + "SRP1", /* Set reference point 1 */ + "SRP2", /* Set reference point 2 */ + "SZP0", /* Set Zone Pointer 0 */ + "SZP1", /* Set Zone Pointer 1 */ + "SZP2", /* Set Zone Pointer 2 */ + "SZPS", /* Set all zone pointers */ + "SLOOP", /* Set loop counter */ + "RTG", /* Round to Grid */ + "RTHG", /* Round to Half-Grid */ + "SMD", /* Set Minimum Distance */ + "ELSE", /* Else */ + "JMPR", /* Jump Relative */ + "SCvTCi", /* Set CVT */ + "SSwCi", /* */ + "SSW", /* */ + + "DUP", + "POP", + "CLEAR", + "SWAP", + "DEPTH", + "CINDEX", + "MINDEX", + "AlignPTS", + "INS_$28", + "UTP", + "LOOPCALL", + "CALL", + "FDEF", + "ENDF", + "MDAP[-]", + "MDAP[r]", + + "IUP[y]", + "IUP[x]", + "SHP[0]", + "SHP[1]", + "SHC[0]", + "SHC[1]", + "SHZ[0]", + "SHZ[1]", + "SHPIX", + "IP", + "MSIRP[0]", + "MSIRP[1]", + "AlignRP", + "RTDG", + "MIAP[-]", + "MIAP[r]", + + "NPushB", + "NPushW", + "WS", + "RS", + "WCvtP", + "RCvt", + "GC[0]", + "GC[1]", + "SCFS", + "MD[0]", + "MD[1]", + "MPPEM", + "MPS", + "FlipON", + "FlipOFF", + "DEBUG", + + "LT", + "LTEQ", + "GT", + "GTEQ", + "EQ", + "NEQ", + "ODD", + "EVEN", + "IF", + "EIF", + "AND", + "OR", + "NOT", + "DeltaP1", + "SDB", + "SDS", + + "ADD", + "SUB", + "DIV", + "MUL", + "ABS", + "NEG", + "FLOOR", + "CEILING", + "ROUND[G]", + "ROUND[B]", + "ROUND[W]", + "ROUND[?]", + "NROUND[G]", + "NROUND[B]", + "NROUND[W]", + "NROUND[?]", + + "WCvtF", + "DeltaP2", + "DeltaP3", + "DeltaC1", + "DeltaC2", + "DeltaC3", + "SROUND", + "S45Round", + "JROT", + "JROF", + "ROFF", + "INS_$7B", + "RUTG", + "RDTG", + "SANGW", + "AA", + + "FlipPT", + "FlipRgON", + "FlipRgOFF", + "INS_$83", + "INS_$84", + "ScanCTRL", + "SDPVTL[0]", + "SDPVTL[1]", + "GetINFO", + "IDEF", + "ROLL", + "MAX", + "MIN", + "ScanTYPE", + "IntCTRL", + "INS_$8F", + + "INS_$90", + "INS_$91", + "INS_$92", + "INS_$93", + "INS_$94", + "INS_$95", + "INS_$96", + "INS_$97", + "INS_$98", + "INS_$99", + "INS_$9A", + "INS_$9B", + "INS_$9C", + "INS_$9D", + "INS_$9E", + "INS_$9F", + + "INS_$A0", + "INS_$A1", + "INS_$A2", + "INS_$A3", + "INS_$A4", + "INS_$A5", + "INS_$A6", + "INS_$A7", + "INS_$A8", + "INS_$A9", + "INS_$AA", + "INS_$AB", + "INS_$AC", + "INS_$AD", + "INS_$AE", + "INS_$AF", + + "PushB[0]", + "PushB[1]", + "PushB[2]", + "PushB[3]", + "PushB[4]", + "PushB[5]", + "PushB[6]", + "PushB[7]", + "PushW[0]", + "PushW[1]", + "PushW[2]", + "PushW[3]", + "PushW[4]", + "PushW[5]", + "PushW[6]", + "PushW[7]", + + "MDRP[G]", + "MDRP[B]", + "MDRP[W]", + "MDRP[?]", + "MDRP[rG]", + "MDRP[rB]", + "MDRP[rW]", + "MDRP[r?]", + "MDRP[mG]", + "MDRP[mB]", + "MDRP[mW]", + "MDRP[m?]", + "MDRP[mrG]", + "MDRP[mrB]", + "MDRP[mrW]", + "MDRP[mr?]", + "MDRP[pG]", + "MDRP[pB]", + + "MDRP[pW]", + "MDRP[p?]", + "MDRP[prG]", + "MDRP[prB]", + "MDRP[prW]", + "MDRP[pr?]", + "MDRP[pmG]", + "MDRP[pmB]", + "MDRP[pmW]", + "MDRP[pm?]", + "MDRP[pmrG]", + "MDRP[pmrB]", + "MDRP[pmrW]", + "MDRP[pmr?]", + + "MIRP[G]", + "MIRP[B]", + "MIRP[W]", + "MIRP[?]", + "MIRP[rG]", + "MIRP[rB]", + "MIRP[rW]", + "MIRP[r?]", + "MIRP[mG]", + "MIRP[mB]", + "MIRP[mW]", + "MIRP[m?]", + "MIRP[mrG]", + "MIRP[mrB]", + "MIRP[mrW]", + "MIRP[mr?]", + "MIRP[pG]", + "MIRP[pB]", + + "MIRP[pW]", + "MIRP[p?]", + "MIRP[prG]", + "MIRP[prB]", + "MIRP[prW]", + "MIRP[pr?]", + "MIRP[pmG]", + "MIRP[pmB]", + "MIRP[pmW]", + "MIRP[pm?]", + "MIRP[pmrG]", + "MIRP[pmrB]", + "MIRP[pmrW]", + "MIRP[pmr?]" + }; + + + const String* Cur_U_Line( void* _exec ) + { + String s[32]; + + Int op, i, n; + + PExecution_Context exec; + + + exec = _exec; + + op = exec->code[exec->IP]; + + sprintf( tempStr, "%s", OpStr[op] ); + + if ( op == 0x40 ) + { + n = exec->code[exec->IP + 1]; + sprintf( s, "(%d)", n ); + strncat( tempStr, s, 8 ); + + if ( n > 20 ) n = 20; /* limit output */ + + for ( i = 0; i < n; i++ ) + { + sprintf( s, " $%02hx", exec->code[exec->IP + i + 2] ); + strncat( tempStr, s, 8 ); + } + } + else if ( op == 0x41 ) + { + n = exec->code[exec->IP + 1]; + sprintf( s, "(%d)", n ); + strncat( tempStr, s, 8 ); + + if ( n > 20 ) n = 20; /* limit output */ + + for ( i = 0; i < n; i++ ) + { + sprintf( s, " $%02hx%02hx", exec->code[exec->IP + i*2 + 2], + exec->code[exec->IP + i*2 + 3] ); + strncat( tempStr, s, 8 ); + } + } + else if ( (op & 0xF8) == 0xB0 ) + { + n = op - 0xB0; + + for ( i = 0; i <= n; i++ ) + { + sprintf( s, " $%02hx", exec->code[exec->IP + i + 1] ); + strncat( tempStr, s, 8 ); + } + } + else if ( (op & 0xF8) == 0xB8 ) + { + n = op-0xB8; + + for ( i = 0; i <= n; i++ ) + { + sprintf( s, " $%02hx%02hx", exec->code[exec->IP + i*2 + 1], + exec->code[exec->IP + i*2 + 2] ); + strncat( tempStr, s, 8 ); + } + } + + return (String*)tempStr; + } + + + /* the Print() function is defined in ttconfig.h; */ + /* it defaults to vprintf on systems which have it */ + + void TT_Message( const String* fmt, ... ) + { + va_list ap; + + va_start( ap, fmt ); + Print( fmt, ap ); + va_end( ap ); + } + + + void TT_Panic( const String* fmt, ... ) + { + va_list ap; + + va_start( ap, fmt ); + Print( fmt, ap ); + va_end( ap ); + + exit( EXIT_FAILURE ); + } + +#endif /* defined( DEBUG_LEVEL_ERROR ) || defined( DEBUG_LEVEL_TRACE ) */ + +#if defined( DEBUG_LEVEL_TRACE ) + + /* use this function to set the values of tt_trace_levels */ + + void set_tt_trace_levels( int index, char value ) + { + tt_trace_levels[index] = value; + } + +#endif + +/* END */ diff --git a/lib/ttdebug.h b/lib/ttdebug.h new file mode 100644 index 0000000..8e889dc --- /dev/null +++ b/lib/ttdebug.h @@ -0,0 +1,170 @@ +/******************************************************************* + * + * ttdebug.h + * + * Debugging and Logging component (specification) + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This component contains various macros and functions used to + * ease the debugging of the FreeType engine. Its main purpose + * is in assertion checking, tracing, and error detection. + * + * There are now three debugging modes: + * + * - trace mode: + * + * Error and trace messages are sent to the log file + * (which can be the standard error output). Define + * DEBUG_LEVEL_TRACE to enable this mode. + * + * - error mode: + * + * Only error messages are generated. Define + * DEBUG_LEVEL_ERROR to enable this mode. + * + * - release mode: + * + * Error messages are neither sent nor generated. The code is + * free from any debugging parts. + * + ******************************************************************/ + +#ifndef TTDEBUG_H +#define TTDEBUG_H + +#include "ttconfig.h" +#include "tttypes.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + +#if defined( DEBUG_LEVEL_TRACE ) + + typedef enum Trace_Component_ + { + trace_any = 0, + trace_api, + trace_interp, + trace_load, + trace_gload, + trace_memory, + trace_file, + trace_mutex, + trace_cache, + trace_calc, + trace_cmap, + trace_extend, + trace_objs, + trace_raster, + + trace_bitmap, + trace_max + + } Trace_Component; + + + /* Here we define an array to hold the trace levels per component. */ + /* Since it is globally defined, all array members are set to 0. */ + /* You should set the values in this array either in your program */ + /* or with your debugger. */ + /* */ + /* Currently, up to eight levels (PTRACE0-PTRACE7, see below) are */ + /* used in some parts of the engine. */ + /* */ + /* For example, to have all tracing messages in the raster */ + /* component, say */ + /* */ + /* #define DEBUG_LEVEL_TRACE */ + /* #include "ttdebug.h" */ + /* */ + /* ... */ + /* set_tt_trace_levels( trace_raster, 7 ) */ + /* */ + /* in your code before initializing the FreeType engine. */ + /* */ + /* Maybe it is better to define DEBUG_LEVEL_TRACE in ttconfig.h... */ + + extern char tt_trace_levels[trace_max]; + + /* IMPORTANT: */ + /* */ + /* Each component must define the macro TT_COMPONENT */ + /* to a valid Trace_Component value before using any */ + /* PTRACEx macro. */ + /* */ + +#define PTRACE( level, varformat ) \ + if ( tt_trace_levels[TT_COMPONENT] >= level ) TT_Message##varformat + +#elif defined( DEBUG_LEVEL_ERROR ) + +#define PTRACE( level, varformat ) /* nothing */ + +#else /* RELEASE MODE */ + +#define TT_Assert( condition, action ) /* nothing */ + +#define PTRACE( level, varformat ) /* nothing */ +#define PERROR( varformat ) /* nothing */ +#define PANIC( varformat ) /* nothing */ + +#endif + + +/************************************************************************/ +/* */ +/* Define macros and fuctions that are common to the debug and trace */ +/* modes. */ +/* */ + +#if defined( DEBUG_LEVEL_TRACE ) || defined( DEBUG_LEVEL_ERROR ) + + +#define TT_Assert( condition, action ) if ( !(condition) ) ( action ) + + void TT_Message( const String* fmt, ... ); + void TT_Panic ( const String* fmt, ... ); + /* print a message and exit */ + + const String* Cur_U_Line( void* exec ); + +#define PERROR( varformat ) TT_Message##varformat +#define PANIC( varformat ) TT_Panic##varformat + +#endif + +#if defined( DEBUG_LEVEL_TRACE ) + + void set_tt_trace_levels( int index, char value ); + +#endif + + +#define PTRACE0( varformat ) PTRACE( 0, varformat ) +#define PTRACE1( varformat ) PTRACE( 1, varformat ) +#define PTRACE2( varformat ) PTRACE( 2, varformat ) +#define PTRACE3( varformat ) PTRACE( 3, varformat ) +#define PTRACE4( varformat ) PTRACE( 4, varformat ) +#define PTRACE5( varformat ) PTRACE( 5, varformat ) +#define PTRACE6( varformat ) PTRACE( 6, varformat ) +#define PTRACE7( varformat ) PTRACE( 7, varformat ) + + +#ifdef __cplusplus + } +#endif + + +#endif /* TTDEBUG_H */ diff --git a/lib/ttengine.h b/lib/ttengine.h new file mode 100644 index 0000000..e946d06 --- /dev/null +++ b/lib/ttengine.h @@ -0,0 +1,115 @@ +/******************************************************************* + * + * ttengine.h 1.1 + * + * Engine instance structure definition. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * New in 1.1 : + * + * - added the 'raster_lock' mutex field to synchronize + * scan-line conversion in thread-safe and re-entrant builds. + * + ******************************************************************/ + +#ifndef TTENGINE_H +#define TTENGINE_H + +#include "tttypes.h" +#include "ttconfig.h" +#include "freetype.h" +#include "ttmutex.h" + +#ifdef __cplusplus + extern "C" { +#endif + + /********************************************************************/ + /* */ + /* The freetype engine instance structure. */ + /* */ + /* This structure holds all the data that is necessary to run */ + /* one instance of the freetype engine. It is needed to get a */ + /* completely re-entrant version of the library. */ + /* */ + /* The goal is to move _all_ component-specific variables, either */ + /* static or global in the structure; the component initializers */ + /* and finalizers will all be called with the address of a valid */ + /* TEngine_Instance. */ + /* */ + /********************************************************************/ + + struct TEngine_Instance_ + { + TMutex lock; /* engine lock */ + + void* list_free_elements; + + void* objs_face_class; /* the face cache class */ + void* objs_instance_class; /* the instance cache class */ + void* objs_execution_class; /* the context cache class */ + void* objs_glyph_class; /* the glyph cache class */ + + void* objs_face_cache; /* these caches are used to track */ + void* objs_exec_cache; /* the current face and execution */ + /* context objects */ + + void* file_component; /* ttfile implementation dependent */ + + TMutex raster_lock; /* mutex for this engine's render pool */ + void* raster_component; /* ttraster implementation depedent */ + Byte raster_palette[5]; /* gray-levels palette for anti-aliasing */ + + void* extension_component; /* extensions dependent */ + +#if 0 + TT_Glyph_Loader_Callback glCallback; /* glyph loader callback, if any */ +#endif + }; + + /* NOTE : The raster's lock is only acquired by the Render_Glyph and */ + /* Render_Gray_Glyph functions, which always release it on exit */ + /* They do not lock the engine mutex. This means you shouldn't */ + /* be concerned about deadlocks between the two mutexes, as these */ + /* should never appear.. */ + + typedef struct TEngine_Instance_ TEngine_Instance; + typedef TEngine_Instance* PEngine_Instance; + + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE /* for re-entrant builds */ + +#define ENGINE_ARG TEngine_Instance* _engine +#define ENGINE_ARGS TEngine_Instance* _engine, + +#define ENGINE_VAR _engine +#define ENGINE_VARS _engine, + +#define ENGINE _engine + +#else /* for thread-safe builds */ + +#define ENGINE_ARG /* void */ +#define ENGINE_ARGS + +#define ENGINE_VAR +#define ENGINE_VARS + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + +#ifdef __cplusplus + } +#endif + +#endif /* TTENGINE_H */ + + +/* END */ diff --git a/lib/ttextend.c b/lib/ttextend.c new file mode 100644 index 0000000..cb77e7f --- /dev/null +++ b/lib/ttextend.c @@ -0,0 +1,212 @@ +/******************************************************************* + * + * ttextend.h 2.0 + * + * Extensions Interface + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * This is an updated version of the extension component, now + * located in the main library's source directory. It allows + * the dynamic registration/use of various face object extensions + * through a simple API. + * + ******************************************************************/ + +#include "ttextend.h" +#include "ttengine.h" +#include "ttmemory.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_extend + + + struct TExtension_Registry_ + { + Int num_extensions; + Long cur_offset; + TExtension_Class classes[TT_MAX_EXTENSIONS]; + }; + + typedef struct TExtension_Registry_ TExtension_Registry; + typedef TExtension_Registry* PExtension_Registry; + + + + /* Initialize the extension component */ + + LOCAL_FUNC + TT_Error TTExtend_Init( PEngine_Instance engine ) + { + TT_Error error; + PExtension_Registry exts; + + + if ( ALLOC( exts, sizeof ( TExtension_Registry ) ) ) + return error; + + exts->num_extensions = 0; + exts->cur_offset = 0; + engine->extension_component = (void*)exts; + + return TT_Err_Ok; + } + + + /* Finalize the extension component */ + + LOCAL_FUNC + TT_Error TTExtend_Done( PEngine_Instance engine ) + { + FREE( engine->extension_component ); + return TT_Err_Ok; + } + + + /* Register a new extension */ + + EXPORT_FUNC + TT_Error TT_Register_Extension( PEngine_Instance engine, + Long id, + Long size, + PExt_Constructor create, + PExt_Destructor destroy ) + { + PExtension_Registry exts; + PExtension_Class clazz; + Int p; + + + exts = (PExtension_Registry)engine->extension_component; + if ( !exts ) + return TT_Err_Ok; + + p = exts->num_extensions; + + if ( p >= TT_MAX_EXTENSIONS ) + return TT_Err_Too_Many_Extensions; + + clazz = exts->classes + p; + clazz->id = id; + clazz->size = size; + clazz->build = create; + clazz->destroy = destroy; + + clazz->offset = exts->cur_offset; + + exts->num_extensions++; + exts->cur_offset += ( size + ALIGNMENT-1 ) & -ALIGNMENT; + + return TT_Err_Ok; + } + + + /* Query an extension block by extension_ID */ + + EXPORT_FUNC + TT_Error TT_Extension_Get( PFace face, + Long extension_id, + void** extension_block ) + { + PExtension_Registry registry; + PExtension_Class clazz; + Int n; + + + if ( !face->extension ) + return TT_Err_Extensions_Unsupported; + + registry = (PExtension_Registry)face->engine->extension_component; + + for ( n = 0; n < face->n_extensions; n++ ) + { + clazz = registry->classes + n; + if ( clazz->id == extension_id ) + { + *extension_block = (PByte)face->extension + clazz->offset; + return TT_Err_Ok; + } + } + + return TT_Err_Invalid_Extension_Id; + } + + + /* Destroy all extensions within a face object. Called by the */ + /* face object destructor. */ + + LOCAL_FUNC + TT_Error Extension_Destroy( PFace face ) + { + PEngine_Instance engine = face->engine; + PExtension_Registry registry; + PExtension_Class clazz; + Int n; + PByte ext; + + + registry = (PExtension_Registry)engine->extension_component; + + for ( n = 0; n < face->n_extensions; n++ ) + { + clazz = registry->classes + n; + ext = (PByte)face->extension + clazz->offset; + + /* the destructor is optional */ + if ( clazz->destroy ) + clazz->destroy( (void*)ext, face ); + } + + /* destroy the face's extension block too */ + FREE( face->extension ); + face->n_extensions = 0; + + return TT_Err_Ok; + } + + + /* Create an extension within a face object. Called by the */ + /* face object constructor. */ + + LOCAL_FUNC + TT_Error Extension_Create( PFace face ) + { + PEngine_Instance engine = face->engine; + PExtension_Registry registry; + PExtension_Class clazz; + TT_Error error; + Int n; + PByte ext; + + + registry = (PExtension_Registry)engine->extension_component; + + face->n_extensions = registry->num_extensions; + if ( ALLOC( face->extension, registry->cur_offset ) ) + return error; + + for ( n = 0; n < face->n_extensions; n++ ) + { + clazz = registry->classes + n; + ext = (PByte)face->extension + clazz->offset; + error = clazz->build( (void*)ext, face ); + if ( error ) + goto Fail; + } + return TT_Err_Ok; + + Fail: + Extension_Destroy( face ); + return error; + } + + +/* END */ diff --git a/lib/ttextend.h b/lib/ttextend.h new file mode 100644 index 0000000..d5d8622 --- /dev/null +++ b/lib/ttextend.h @@ -0,0 +1,168 @@ +/******************************************************************* + * + * ttextend.h 2.0 + * + * Extensions Interface. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * This is an updated version of the extension component, now + * located in the main library's source directory. It allows + * the dynamic registration/use of various face object extensions + * through a simple API. + * + ******************************************************************/ + +#ifndef TTEXTEND_H +#define TTEXTEND_H + +#include "ttconfig.h" +#include "tttypes.h" +#include "ttobjs.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + /* The extensions don't need to be integrated at compile time into */ + /* the engine, only at link time. */ + + + /* When a new face object is created, the face constructor calls */ + /* the extension constructor with the following arguments: */ + /* */ + /* ext : typeless pointer to the face's extension block. */ + /* Its size is the one given at registration time */ + /* in the extension class's 'size' field. */ + /* */ + /* face : the parent face object. Note that the extension */ + /* constructor is called when the face object is */ + /* built. */ + + typedef TT_Error TExt_Constructor( void* ext, PFace face ); + + + /* When a face object is destroyed, the face destructor calls */ + /* the extension destructor with the following arguments. */ + /* */ + /* ext : typeless pointer to the face's extension block. */ + /* Its size is the one given at registration time */ + /* in the extension class's 'size' field. */ + /* */ + /* face : the parent face object. Note that the extension */ + /* destructor is called before the actual face object */ + /* is destroyed. */ + + typedef TT_Error TExt_Destructor ( void* ext, PFace face ); + + typedef TExt_Constructor* PExt_Constructor; + typedef TExt_Destructor* PExt_Destructor; + + + struct TExtension_Class_ + { + Long id; /* extension id */ + Long size; /* size in bytes of extension record */ + PExt_Constructor build; /* the extension's class constructor */ + PExt_Destructor destroy; /* the extension's class destructor */ + + Long offset; /* offset of ext. record in face obj */ + /* (set by the engine) */ + }; + + typedef struct TExtension_Class_ TExtension_Class; + typedef TExtension_Class* PExtension_Class; + + +#define Build_Extension_ID( a, b, c, d ) \ + ( ((ULong)(a) << 24) | \ + ((ULong)(b) << 16) | \ + ((ULong)(c) << 8 ) | \ + (ULong)(d) ) + + /* A note regarding extensions and the single-object compilation */ + /* mode : */ + /* */ + /* When the engine is compiled as a single object file, extensions */ + /* must remain linkable *after* compile time. In order to do this, */ + /* we need to export the functions that an extension may need. */ + /* Fortunately, we can limit ourselves to : */ + /* */ + /* o TT_Register_Extension (previously called Extension_Register) */ + /* which is to be called by each extension on within */ + /* it TT_Init_XXXX_Extension initializer. */ + /* */ + /* o File and frame access functions. Fortunately, these already */ + /* have their names prefixed by "TT_", so no change was needed */ + /* except replacing the LOCAL_DEF keyword with EXPORT_DEF */ + /* */ + /* o Memory access functions, i.e. TT_Alloc and TT_Free. Again, */ + /* the change is minimal */ + /* */ + /* o the table-lookup function : TT_LookUp_Table, formerly known */ + /* as Load_TrueType_Table in ttload.c. */ + /* */ + /* */ + /* Other than that, an extension should be able to #include all */ + /* relevant header files to get access to internal types, but */ + /* should not call engine internal functions.. */ + /* */ + /* If there is a need for a specific internal function call, let */ + /* me known to see if we need to export it by default.. */ + /* - DavidT */ + /* */ + + /* Register a new extension. Called by extension */ + /* service initializers. */ + EXPORT_DEF + TT_Error TT_Register_Extension( PEngine_Instance engine, + Long id, + Long size, + PExt_Constructor create, + PExt_Destructor destroy ); + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + /* Initialize the extension component */ + LOCAL_DEF + TT_Error TTExtend_Init( PEngine_Instance engine ); + + /* Finalize the extension component */ + LOCAL_DEF + TT_Error TTExtend_Done( PEngine_Instance engine ); + + /* Create an extension within a face object. Called by the */ + /* face object constructor. */ + LOCAL_DEF + TT_Error Extension_Create( PFace face ); + + /* Destroy all extensions within a face object. Called by the */ + /* face object destructor. */ + LOCAL_DEF + TT_Error Extension_Destroy( PFace face ); +#endif + + /* Query an extension block by extension_ID. Called by extension */ + /* service routines. */ + EXPORT_DEF + TT_Error TT_Extension_Get( PFace face, + Long extension_id, + void** extension_block ); + +#ifdef __cplusplus + } +#endif + + +#endif /* TTEXTEND_H */ + + +/* END */ diff --git a/lib/ttfile.c b/lib/ttfile.c new file mode 100644 index 0000000..07d9698 --- /dev/null +++ b/lib/ttfile.c @@ -0,0 +1,1175 @@ +/******************************************************************* + * + * ttfile.c (extended version) 2.1 + * + * File I/O Component (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES: + * + * This implementation relies on the ANSI libc. You may wish to + * modify it to get rid of libc and go straight to the your + * platform's stream routines. + * + * The same source code can be used for thread-safe and re-entrant + * builds of the library. + * + * Changes between 2.0 and 2.1 : + * + * - it is now possible to close a stream's file handle explicitely + * through the new API "TT_Flush_Stream". This will simply close + * a stream's file handle (useful to save system resources when + * dealing with lots of opened fonts). Of course, the function + * "TT_Use_Stream" will automatically re-open a stream's handle if + * necessary. + * + * - added "TT_Stream_Size" to replace "TT_File_Size" which wasn't + * used anyway. This one returns the size of any stream, even + * flushed one (when the previous TT_File_Size could only return + * the size of the current working stream). This is used by the + * new "Load_TrueType_Any" function in the tables loader. + * + ******************************************************************/ + +#include "ttconfig.h" + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttmemory.h" +#include "ttfile.h" /* our prototypes */ + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_file + + +/* For now, we don't define additional error messages in the core library */ +/* to report open-on demand errors. Define these error as standard ones */ + +#define TT_Err_Could_Not_ReOpen_File TT_Err_Could_Not_Open_File +#define TT_Err_Could_Not_ReSeek_File TT_Err_Could_Not_Open_File + + /* This definition is mandatory for each file component! */ + EXPORT_FUNC + const TFileFrame TT_Null_FileFrame = { NULL, 0, 0 }; + +/* It has proven useful to do some bounds checks during development phase. */ +/* They should probably be undefined for speed reasons in a later release. */ + +#if DEBUG_FILE +#define CHECK_FRAME( frame, n ) \ + do { \ + if ( frame.cursor + n > frame.address + frame.size ) \ + Panic( "Frame boundary error!\n" ); \ + } while ( 0 ) +#else +#define CHECK_FRAME( frame, n ) /* nothing */ +#endif + + /* Because a stream can be flushed, i.e. its file handle can be */ + /* closed to save system resources, we must keep the stream's file */ + /* pathname to be able to re-open it on demand when it is flushed */ + + struct TStream_Rec_; + typedef struct TStream_Rec_ TStream_Rec; + typedef TStream_Rec* PStream_Rec; + + struct TStream_Rec_ + { + Bool opened; /* is the stream handle opened ? */ + TT_Text* name; /* the file's pathname */ + Long position; /* current position within the file */ + + FILE* file; /* file handle */ + Long base; /* stream base in file */ + Long size; /* stream size in file */ + }; + + /* We support embedded TrueType files by allowing them to be */ + /* inside any file, at any location, hence the 'base' argument. */ + /* Note however that the current implementation does not allow you */ + /* to specify a 'base' index when opening a file. */ + /* (will come later) */ + /* I still don't know if this will turn out useful ?? - DavidT */ + +#define STREAM2REC( x ) ( (TStream_Rec*)HANDLE_Val( x ) ) + + static TT_Error Stream_Activate ( PStream_Rec stream ); + static TT_Error Stream_Deactivate( PStream_Rec stream ); + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /**** ****/ + /**** N O N R E E N T R A N T I M P L E M E N T A T I O N ****/ + /**** ****/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* in non-rentrant builds, we allocate a single block where we'll */ + /* place all the frames smaller than FRAME_CACHE_SIZE, rather than */ + /* allocating a new block on each access. Bigger frames will be */ + /* malloced normally in the heap. */ + /* */ + /* See TT_Access_Frame() and TT_Forget_Frame() for details. */ + +#define FRAME_CACHE_SIZE 2048 + + /* The TFile_Component structure holds all the data that was */ + /* previously declared static or global in this component. */ + /* */ + /* It is accessible through the 'engine.file_component' */ + /* variable in re-entrant builds, or directly through the */ + /* static 'files' variable in other builds. */ + + struct TFile_Component_ + { + TMutex lock; /* used by the thread-safe build only */ + Byte* frame_cache; /* frame cache */ + PStream_Rec stream; /* current stream */ + TFileFrame frame; /* current frame */ + }; + + typedef struct TFile_Component_ TFile_Component; + + static TFile_Component files; + +#define CUR_Stream files.stream +#define CUR_Frame files.frame + +#define STREAM_VARS /* void */ +#define STREAM_VAR /* void */ + +/* The macro CUR_Stream denotes the current input stream. */ +/* Note that for the re-entrant version, the 'stream' name has been */ +/* chosen according to the macro STREAM_ARGS. */ + +/* The macro CUR_Frame denotes the current file frame. */ +/* Note that for the re-entrant version, the 'frame' name has been */ +/* chosen according to the macro FRAME_ARGS. */ + +/* The macro STREAM_VAR is used when calling public functions */ +/* that need an 'optional' stream argument. */ + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + TT_Error error; + + + MUTEX_Create( files.lock ); + files.stream = NULL; + ZERO_Frame( files.frame ); + + if ( ALLOC( files.frame_cache, FRAME_CACHE_SIZE ) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + FREE( files.frame_cache ); + MUTEX_Destroy( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Copies or duplicates a given stream. + * + * Input : org_stream original stream + * stream target stream (copy or duplicate) + * + * Output : Error code. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ) + { + MUTEX_Lock( files.lock ); /* lock file mutex */ + + *stream = org_stream; /* copy the stream */ + files.stream = STREAM2REC(org_stream); /* set current stream */ + + Stream_Activate( files.stream ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : Error code. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + HANDLE_Set( *stream, NULL ); + MUTEX_Release( files.lock ); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( size <= FRAME_CACHE_SIZE ) + { + /* use the cache */ + CUR_Frame.address = files.frame_cache; + CUR_Frame.size = FRAME_CACHE_SIZE; + } + else + { + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + } + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if (error) + { + if ( size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + CUR_Frame.address = NULL; + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * `size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function truncates `size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes, requested; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( size <= FRAME_CACHE_SIZE ) + { + /* use the cache */ + CUR_Frame.address = files.frame_cache; + CUR_Frame.size = FRAME_CACHE_SIZE; + } + else + { + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + } + + requested = size; + readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR ); + if ( size > readBytes ) + size = readBytes; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if (error) + { + if ( requested > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + CUR_Frame.address = NULL; + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + if ( CUR_Frame.size > FRAME_CACHE_SIZE ) + FREE( CUR_Frame.address ); + + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + + +#else /* TT_CONFIG_OPTION_THREAD_SAFE */ + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /******** ********/ + /******** R E E N T R A N T I M P L E M E N T A T I O N ********/ + /******** ********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/* a simple macro to access the file component's data */ +#define files ( *((TFile_Component*)engine.file_component) ) + +#define CUR_Stream STREAM2REC( stream ) /* re-entrant macros */ +#define CUR_Frame (*frame) + +#define STREAM_VARS stream, +#define STREAM_VAR stream + + +/******************************************************************* + * + * Function : TTFile_Init + * + * Description : Initializes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Init( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalizes the File component. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTFile_Done( PEngine_Instance engine ) + { + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Duplicates a stream for a new usage. + * + * Input : input_stream source stream to duplicate + * copy address of target duplicate stream + * + * Output : error code. + * The target stream is set to NULL in case of failure. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Use_Stream( TT_Stream input_stream, + TT_Stream* copy ) + { + PStream_Rec rec = STREAM2REC( input_stream ); + + return TT_Open_Stream( rec->name, copy ); + } + + +/******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Releases a given stream. + * + * Input : stream target stream + * + * Output : + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Done_Stream( TT_Stream* stream ) + { + return TT_Close_Stream( stream ); + } + + +/******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * 'size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function fails if the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big in both cases). + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * `size' bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : size number of bytes to access. + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes: The function truncates `size' if the byte range is not + * within the file. + * + * It will fail if there is not enough memory to cache + * the bytes properly (which usually means that `size' is + * too big). + * + * It will fail if you make two consecutive calls + * to TT_Access_Frame(), without a TT_Forget_Frame() between + * them. + * + * The only difference with TT_Access_Frame() is that we + * check that the frame is within the current file. We + * otherwise truncate it. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ) + { + TT_Error error; + Long readBytes; + + + if ( CUR_Frame.address != NULL ) + return TT_Err_Nested_Frame_Access; + + if ( ALLOC( CUR_Frame.address, size ) ) + return error; + CUR_Frame.size = size; + + readBytes = CUR_Stream->size - TT_File_Pos( STREAM_VAR ); + if ( size > readBytes ) + size = readBytes; + + error = TT_Read_File( STREAM_VARS (void*)CUR_Frame.address, size ); + if ( error ) + { + FREE( CUR_Frame.address ); + CUR_Frame.size = 0; + } + + CUR_Frame.cursor = CUR_Frame.address; + return error; + } + + +/******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading. + * + * Input : None + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Forget_Frame( FRAME_ARG ) + { + if ( CUR_Frame.address == NULL ) + return TT_Err_Nested_Frame_Access; + + FREE( CUR_Frame.address ); + ZERO_Frame( CUR_Frame ); + + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + /*********** ***********/ + /*********** C O M M O N I M P L E M E N T A T I O N ***********/ + /*********** ***********/ + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + +/******************************************************************* + * + * Function : Stream_Activate + * + * Description : activates a stream, this will either: + * - open a new file handle if the stream is closed + * - move the stream to the head of the linked list + * + * Input : stream the stream to activate + * + * Output : error condition. + * + * Note : This function is also called with fresh new streams + * created by TT_Open_Stream(). They have their 'size' + * field set to -1. + * + ******************************************************************/ + + static TT_Error Stream_Activate( PStream_Rec stream ) + { + if ( !stream->opened ) + { + if ( (stream->file = fopen( (TT_Text*)stream->name, "rb" )) == 0 ) + return TT_Err_Could_Not_ReOpen_File; + + stream->opened = TRUE; + + /* A newly created stream has a size field of -1 */ + if ( stream->size < 0 ) + { + fseek( stream->file, 0, SEEK_END ); + stream->size = ftell( stream->file ); + fseek( stream->file, 0, SEEK_SET ); + } + + /* Reset cursor in file */ + if ( stream->position ) + { + if ( fseek( stream->file, stream->position, SEEK_SET ) != 0 ) + { + /* error during seek */ + fclose( stream->file ); + stream->opened = FALSE; + return TT_Err_Could_Not_ReSeek_File; + } + } + } + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Stream_DeActivate + * + * Description : deactivates a stream, this will : + * - close its file handle if it was opened + * - remove it from the opened list if necessary + * + * Input : stream the stream to deactivate + * + * Output : Error condition + * + * Note : the function is called whenever a stream is deleted + * (_not_ when a stream handle's is closed due to an + * activation). However, the stream record isn't + * destroyed by it.. + * + ******************************************************************/ + + static TT_Error Stream_Deactivate( PStream_Rec stream ) + { + if ( stream->opened ) + { + /* Save its current position within the file */ + stream->position = ftell( stream->file ); + fclose( stream->file ); + stream->file = 0; + stream->opened = FALSE; + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Stream_Size + * + * Description : Returns the length of a given stream, even if it + * is flushed. + * + * Input : stream the stream + * + * Output : Length of stream in bytes. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Stream_Size( TT_Stream stream ) + { + PStream_Rec rec = STREAM2REC( stream ); + + + if ( rec ) + return rec->size; + else + return 0; /* invalid stream - return 0 */ + } + + +/******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : Opens the font file and saves the total file size. + * + * Input : error address of stream's error variable + * (re-entrant build only) + * filepathname pathname of the file to open + * stream address of target TT_Stream structure + * + * Output : SUCCESS on sucess, FAILURE on error. + * The target stream is set to -1 in case of failure. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Open_Stream( const TT_Text* filepathname, + TT_Stream* stream ) + { + Int len; + TT_Error error; + PStream_Rec stream_rec; + + if ( ALLOC( *stream, sizeof ( TStream_Rec ) ) ) + return error; + + stream_rec = STREAM2REC( *stream ); + + stream_rec->file = NULL; + stream_rec->size = -1L; + stream_rec->base = 0; + stream_rec->opened = FALSE; + stream_rec->position = 0; + + len = strlen( filepathname ) + 1; + if ( ALLOC( stream_rec->name, len ) ) + goto Fail; + + strncpy( stream_rec->name, filepathname, len ); + + error = Stream_Activate( stream_rec ); + if ( error ) + goto Fail_Activate; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + CUR_Stream = stream_rec; +#endif + + return TT_Err_Ok; + + Fail_Activate: + FREE( stream_rec->name ); + Fail: + FREE( stream_rec ); + return error; + } + + +/******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes a stream. + * + * Input : stream address of target TT_Stream structure + * + * Output : SUCCESS (always). + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TT_Close_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + Stream_Deactivate( rec ); + FREE( rec->name ); + FREE( rec ); + + HANDLE_Set( *stream, NULL ); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : Flushes a stream, i.e., closes its file handle. + * + * Input : stream address of target TT_Stream structure + * + * Output : Error code + * + * NOTE : Never flush the current opened stream. This means that + * you should _never_ call this function between a + * TT_Use_Stream() and a TT_Done_Stream()! + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Flush_Stream( TT_Stream* stream ) + { + PStream_Rec rec = STREAM2REC( *stream ); + + + if ( rec ) + { + Stream_Deactivate( rec ); + return TT_Err_Ok; + } + else + return TT_Err_Invalid_Argument; + } + + +/******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seeks the file cursor to a different position. + * + * Input : position new position in file + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Seek_File( STREAM_ARGS Long position ) + { + position += CUR_Stream->base; + + if ( fseek( CUR_Stream->file, position, SEEK_SET ) ) + return TT_Err_Invalid_File_Offset; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skips forward the file cursor. + * + * Input : distance number of bytes to skip + * + * Output : see TT_Seek_File() + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Skip_File( STREAM_ARGS Long distance ) + { + return TT_Seek_File( STREAM_VARS ftell( CUR_Stream->file ) - + CUR_Stream->base + distance ); + } + + +/******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copies it to memory. + * + * Input : buffer target buffer + * count length in bytes to read + * + * Output : SUCCESS on success. FAILURE if out of range. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_File( STREAM_ARGS void* buffer, Long count ) + { + if ( fread( buffer, 1, count, CUR_Stream->file ) != (ULong)count ) + return TT_Err_Invalid_File_Read; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Reads file at a specified position. + * + * Input : position position to seek to before read + * buffer target buffer + * count number of bytes to read + * + * Output : SUCCESS on success. FAILURE if error. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ) + { + TT_Error error; + + + if ( (error = TT_Seek_File( STREAM_VARS position )) != TT_Err_Ok || + (error = TT_Read_File( STREAM_VARS buffer, count )) != TT_Err_Ok ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TT_File_Pos + * + * Description : Returns current file seek pointer. + * + * Input : none + * + * Output : Current file position. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_File_Pos( STREAM_ARG ) + { + return ftell( CUR_Stream->file ) - CUR_Stream->base; + } + + +/******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted Byte. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + Byte TT_Get_Byte( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Byte)(*CUR_Frame.cursor++); + } +#endif + + +/******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted char. + * + ******************************************************************/ + EXPORT_FUNC + Char TT_Get_Char( FRAME_ARG ) + { + CHECK_FRAME( CUR_Frame, 1 ); + + return (Char)(*CUR_Frame.cursor++); + } + + +/******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame. + * + * Input : None or current frame + * + * Output : Extracted short. + * + ******************************************************************/ + + EXPORT_FUNC + Short TT_Get_Short( FRAME_ARG ) + { + Short getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = (Short)((CUR_Frame.cursor[0] << 8) | + CUR_Frame.cursor[1]); + + CUR_Frame.cursor += 2; + + return getshort; + } + + +/******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame. + * + * Input : None or current frame + * + * Output : Extracted ushort. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + UShort TT_Get_UShort( FRAME_ARG ) + { + UShort getshort; + + + CHECK_FRAME( CUR_Frame, 2 ); + + getshort = (UShort)((CUR_Frame.cursor[0] << 8) | + CUR_Frame.cursor[1]); + + CUR_Frame.cursor += 2; + + return getshort; + } +#endif + + +/******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame. + * + * Input : None or current frame + * + * Output : Extracted long. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_Get_Long( FRAME_ARG ) + { + Long getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ((Long)CUR_Frame.cursor[0] << 24) | + ((Long)CUR_Frame.cursor[1] << 16) | + ((Long)CUR_Frame.cursor[2] << 8 ) | + (Long)CUR_Frame.cursor[3]; + + CUR_Frame.cursor += 4; + + return getlong; + } + + +/******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame. + * + * Input : None or current frame + * + * Output : Extracted ulong. + * + ******************************************************************/ +#if 0 + EXPORT_FUNC + ULong TT_Get_ULong( FRAME_ARG ) + { + ULong getlong; + + + CHECK_FRAME( CUR_Frame, 4 ); + + getlong = ( ((ULong)CUR_Frame.cursor[0] << 24) | + ((ULong)CUR_Frame.cursor[1] << 16) | + ((ULong)CUR_Frame.cursor[2] << 8 ) | + (ULong)CUR_Frame.cursor[3] ); + + CUR_Frame.cursor += 4; + + return getlong; + } +#endif + + +/* END */ diff --git a/lib/ttfile.h b/lib/ttfile.h new file mode 100644 index 0000000..eebd1c1 --- /dev/null +++ b/lib/ttfile.h @@ -0,0 +1,271 @@ +/******************************************************************* + * + * ttfile.h 1.3 + * + * File I/O Component (specification). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 1.3 and 1.2: + * + * - all functions report error values now + * + * - the stream semantics have also changed + * + * Changes between 1.2 and 1.1: + * + * - added macros to support re-entrant builds + * + * - added the TT_Duplicate_File function to duplicate streams + * (re-entrant builds only) + * + ******************************************************************/ + +#ifndef TTFILE_H +#define TTFILE_H + +#include "ttconfig.h" +#include "freetype.h" +#include "ttengine.h" +#include "ttdebug.h" + +#ifdef __cplusplus + extern "C" { +#endif + + /* Initialize file component */ + LOCAL_DEF + TT_Error TTFile_Init( PEngine_Instance engine ); + + /* Done with file component */ + LOCAL_DEF + TT_Error TTFile_Done( PEngine_Instance engine ); + + + /**********************************************************************/ + /* */ + /* Stream functions. */ + /* */ + /**********************************************************************/ + + /* Open a file and return a stream handle for it. */ + /* Should only be used for a new face object's main stream. */ + + LOCAL_DEF + TT_Error TT_Open_Stream( const TT_Text* name, + TT_Stream* stream ); + + + /* Closes, then discards, a stream when it's no longer needed. */ + /* Should only be used for a stream opend with TT_Open_Stream(). */ + + LOCAL_DEF + TT_Error TT_Close_Stream( TT_Stream* stream ); + + + /* Informs the component that we're going to use the file */ + /* opened in 'org_stream', and report errors to the 'error' */ + /* variable. */ + + /* in non re-entrant builds, 'org_stream' is simply copied */ + /* to 'stream'. Otherwise, the latter is a duplicate handle */ + /* for the file opened with 'org_stream' */ + + EXPORT_DEF + TT_Error TT_Use_Stream( TT_Stream org_stream, + TT_Stream* stream ); + + /* Informs the component that we don't need to perform file */ + /* operations on the stream 'stream' anymore. This must be */ + /* used with streams "opened" with TT_Use_Stream() only! */ + + /* in re-entrant builds, this will really discard the stream */ + + EXPORT_DEF + TT_Error TT_Done_Stream( TT_Stream* stream ); + + /* Closes the stream's file handle to release system resources */ + /* The function TT_Use_Stream automatically re-activates a */ + /* flushed stream when it uses one */ + + EXPORT_DEF + TT_Error TT_Flush_Stream( TT_Stream* stream ); + +/* The macros STREAM_ARGS and STREAM_ARG let us build a thread-safe */ +/* or re-entrant implementation depending on a single configuration */ +/*define. */ + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE + +#define STREAM_ARGS TT_Stream stream, +#define STREAM_ARG TT_Stream stream + +#else + +#define STREAM_ARGS /* void */ +#define STREAM_ARG void + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /****************************************************************/ + /* */ + /* File Functions. */ + /* */ + /* The following functions perform file operations on the */ + /* currently 'used' stream. In thread-safe builds, only one */ + /* stream can be used at a time. Synchronisation is performed */ + /* through the Use_Stream()/Done_Stream() functions. */ + /* */ + /****************************************************************/ + + /* Read 'count' bytes from file into 'buffer' */ + + EXPORT_DEF + TT_Error TT_Read_File( STREAM_ARGS void* buffer, + Long count ); + + + /* Seek file cursor to a given position */ + + EXPORT_DEF + TT_Error TT_Seek_File( STREAM_ARGS Long position ); + + + /* Skip the next 'distance' bytes in file */ + + EXPORT_DEF + TT_Error TT_Skip_File( STREAM_ARGS Long distance ); + + + /* Read the 'count' bytes at 'position' into 'buffer' */ + + EXPORT_DEF + TT_Error TT_Read_At_File( STREAM_ARGS Long position, + void* buffer, + Long count ); + + /* Return current file position */ + + EXPORT_DEF + Long TT_File_Pos( STREAM_ARG ); + + /* Return length of a given stream, even if it is flushed */ + + EXPORT_DEF + Long TT_Stream_Size( TT_Stream stream ); + + + /********************************************************************/ + /* */ + /* Frame operations. */ + /* */ + /* For a comprehensive explanation of frames, please refer to the */ + /* documentation files. */ + /* */ + /********************************************************************/ + + /* Frame type declaration.*/ + + struct TFileFrame_ + { + Byte* address; /* frame buffer */ + Byte* cursor; /* current cursor position in frame */ + Long size; /* frame size */ + }; + + typedef struct TFileFrame_ TFileFrame; + + EXPORT_DEF + const TFileFrame TT_Null_FileFrame; + + +/* The macro ZERO_Frame is used to define and init a frame. */ +/* It is important to have a default frame of { NULL, NULL, 0 } */ +/* before a call to TT_Access_Frame(). Otherwise, the call will */ +/* fail with a TT_Err_Nested_Frame_Accesses error. */ + +#define ZERO_Frame( frame ) \ + { \ + (frame).address = NULL; \ + (frame).cursor = NULL; \ + (frame).size = 0; \ + } + + +/* The macros FRAME_ARGS and FRAME_ARG let us build a thread-safe */ +/* or re-entrant implementation depending on a single configuration */ +/* define */ + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE + +#define FRAME_ARGS TFileFrame* frame, +#define FRAME_ARG TFileFrame* frame + +#else + +#define FRAME_ARGS /* void */ +#define FRAME_ARG void + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + + /* Access the next 'size' bytes from current position. */ + /* Fails if all bytes cannot be read/accessed. */ + + EXPORT_DEF + TT_Error TT_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ); + + + /* Access the bytes located in the next 'size' bytes of the file. */ + /* Doesn't fail if less than 'size' bytes are accessible (like */ + /* at the end of the file). */ + + EXPORT_DEF + TT_Error TT_Check_And_Access_Frame( STREAM_ARGS FRAME_ARGS Long size ); + + /* Forget frame */ + + EXPORT_DEF + TT_Error TT_Forget_Frame( FRAME_ARG ); + + + /* primitive routines for data accessing */ + + EXPORT_DEF + Char TT_Get_Char ( FRAME_ARG ); + EXPORT_DEF + Short TT_Get_Short( FRAME_ARG ); + EXPORT_DEF + Long TT_Get_Long ( FRAME_ARG ); + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE + +#define TT_Get_Byte( frame ) ( (Byte )TT_Get_Char ( frame ) ) +#define TT_Get_UShort( frame ) ( (UShort)TT_Get_Short( frame ) ) +#define TT_Get_ULong( frame ) ( (ULong )TT_Get_Long ( frame ) ) + +#else + +#define TT_Get_Byte() ( (Byte )TT_Get_Char () ) +#define TT_Get_UShort() ( (UShort)TT_Get_Short() ) +#define TT_Get_ULong() ( (ULong )TT_Get_Long () ) + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + +#ifdef __cplusplus + } +#endif + +#endif /* TTFILE_H */ + + +/* END */ diff --git a/lib/ttgload.c b/lib/ttgload.c new file mode 100644 index 0000000..a7ca317 --- /dev/null +++ b/lib/ttgload.c @@ -0,0 +1,1351 @@ +/******************************************************************* + * + * ttgload.c 1.0 + * + * TrueType Glyph Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "tttypes.h" +#include "ttdebug.h" +#include "ttcalc.h" +#include "ttfile.h" + +#include "tttables.h" +#include "ttobjs.h" +#include "ttgload.h" + +#include "ttmemory.h" +#include "tttags.h" +#include "ttload.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_gload + + +/* composite font flags */ + +#define ARGS_ARE_WORDS 0x001 +#define ARGS_ARE_XY_VALUES 0x002 +#define ROUND_XY_TO_GRID 0x004 +#define WE_HAVE_A_SCALE 0x008 +/* reserved 0x010 */ +#define MORE_COMPONENTS 0x020 +#define WE_HAVE_AN_XY_SCALE 0x040 +#define WE_HAVE_A_2X2 0x080 +#define WE_HAVE_INSTR 0x100 +#define USE_MY_METRICS 0x200 + + +/********************************************************/ +/* Return horizontal or vertical metrics in font units */ +/* for a given glyph. The metrics are the left side */ +/* bearing (resp. top side bearing) and advance width */ +/* (resp. advance height). */ +/* */ +/* This function will much probably move to another */ +/* component in the short future, but I haven't decided */ +/* which yet... */ + + LOCAL_FUNC + void TT_Get_Metrics( TT_Horizontal_Header* header, + UShort index, + Short* bearing, + UShort* advance ) + { + PLongMetrics longs_m; + + UShort k = header->number_Of_HMetrics; + + + if ( index < k ) + { + longs_m = (PLongMetrics)header->long_metrics + index; + *bearing = longs_m->bearing; + *advance = longs_m->advance; + } + else + { + *bearing = ((PShortMetrics)header->short_metrics)[index - k]; + *advance = ((PLongMetrics)header->long_metrics)[k - 1].advance; + } + } + + +/********************************************************/ +/* Return horizontal metrics in font units for a given */ +/* glyph. If `check' is true, take care of mono-spaced */ +/* fonts by returning the advance width max. */ + + static void Get_HMetrics( PFace face, + UShort index, + Bool check, + Short* lsb, + UShort* aw ) + { + TT_Get_Metrics( &face->horizontalHeader, index, lsb, aw ); + + if ( check && face->postscript.isFixedPitch ) + *aw = face->horizontalHeader.advance_Width_Max; + } + + +/********************************************************/ +/* Return advance width table for a given pixel size */ +/* if it is found in the font's `hdmx' table (if any). */ + + static PByte Get_Advance_Widths( PFace face, + UShort ppem ) + { + UShort n; + + + for ( n = 0; n < face->hdmx.num_records; n++ ) + if ( face->hdmx.records[n].ppem == ppem ) + return face->hdmx.records[n].widths; + + return NULL; + } + + +/********************************************************/ +/* Copy current glyph into original one. */ + +#define cur_to_org( n, zone ) \ + MEM_Copy( (zone)->org, (zone)->cur, (n) * sizeof ( TT_Vector ) ) + +/********************************************************/ +/* copy original glyph into current one */ + +#define org_to_cur( n, zone ) \ + MEM_Copy( (zone)->cur, (zone)->org, (n) * sizeof ( TT_Vector ) ) + +/********************************************************/ +/* translate an array of coordinates */ + + static void translate_array( UShort n, + TT_Vector* coords, + TT_Pos delta_x, + TT_Pos delta_y ) + { + UShort k; + + + if ( delta_x ) + for ( k = 0; k < n; k++ ) + coords[k].x += delta_x; + + if ( delta_y ) + for ( k = 0; k < n; k++ ) + coords[k].y += delta_y; + } + + +/********************************************************/ +/* mount one zone on top of another */ + + static void mount_zone( PGlyph_Zone source, + PGlyph_Zone target ) + { + UShort np; + Short nc; + + np = source->n_points; + nc = source->n_contours; + + target->org = source->org + np; + target->cur = source->cur + np; + target->touch = source->touch + np; + + target->contours = source->contours + nc; + + target->n_points = 0; + target->n_contours = 0; + } + + +/******************************************************************* + * + * Function: Load_Simple_Glyph + * + ******************************************************************/ + + static TT_Error Load_Simple_Glyph( PExecution_Context exec, + TT_Stream input, + Short n_contours, + Short left_contours, + UShort left_points, + UShort load_flags, + PSubglyph_Record subg ) + { + DEFINE_LOAD_LOCALS( input ); + + PGlyph_Zone pts; + Short k; + UShort j; + UShort n_points, n_ins; + PFace face; + Byte* flag; + TT_Vector* vec; + TT_F26Dot6 x, y; + + + face = exec->face; + + /* simple check */ + if ( n_contours > left_contours ) + { + PTRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n", + subg->index, n_contours, left_contours )); + return TT_Err_Too_Many_Contours; + } + + + /* preparing the execution context */ + mount_zone( &subg->zone, &exec->pts ); + + /* reading the contours endpoints */ + if ( ACCESS_Frame( (n_contours + 1) * 2L ) ) + return error; + + PTRACE4(( " Contour endpoints:" )); + + for ( k = 0; k < n_contours; k++ ) + { + exec->pts.contours[k] = GET_UShort(); + PTRACE4(( " %d", exec->pts.contours[k] )); + } + PTRACE4(( "\n" )); + + if ( n_contours > 0 ) + n_points = exec->pts.contours[n_contours - 1] + 1; + else + n_points = 0; + + n_ins = GET_UShort(); + + FORGET_Frame(); + + if ( n_points > left_points ) + { + PTRACE0(( "ERROR: Too many points in glyph %ld\n", subg->index )); + return TT_Err_Too_Many_Points; + } + + /* loading instructions */ + + PTRACE4(( " Instructions size: %d\n", n_ins )); + + if ( n_ins > face->maxProfile.maxSizeOfInstructions ) + { + PTRACE0(( "ERROR: Too many instructions!\n" )); + return TT_Err_Too_Many_Ins; + } + + if ( FILE_Read( exec->glyphIns, n_ins ) ) + return error; + + if ( (error = Set_CodeRange( exec, + TT_CodeRange_Glyph, + exec->glyphIns, + n_ins )) != TT_Err_Ok ) + return error; + + + /* read the flags */ + + if ( CHECK_ACCESS_Frame( n_points * 5L ) ) + return error; + + j = 0; + flag = exec->pts.touch; + + while ( j < n_points ) + { + Byte c, cnt; + + flag[j] = c = GET_Byte(); + j++; + + if ( c & 8 ) + { + cnt = GET_Byte(); + while( cnt > 0 ) + { + flag[j++] = c; + cnt--; + } + } + } + + /* read the X */ + + x = 0; + vec = exec->pts.org; + + for ( j = 0; j < n_points; j++ ) + { + if ( flag[j] & 2 ) + { + if ( flag[j] & 16 ) + x += GET_Byte(); + else + x -= GET_Byte(); + } + else + { + if ( (flag[j] & 16) == 0 ) + x += GET_Short(); + } + + vec[j].x = x; + } + + + /* read the Y */ + + y = 0; + + for ( j = 0; j < n_points; j++ ) + { + if ( flag[j] & 4 ) + { + if ( flag[j] & 32 ) + y += GET_Byte(); + else + y -= GET_Byte(); + } + else + { + if ( (flag[j] & 32) == 0 ) + y += GET_Short(); + } + + vec[j].y = y; + } + + FORGET_Frame(); + + /* Now add the two shadow points at n and n + 1. */ + /* We need the left side bearing and advance width. */ + + /* pp1 = xMin - lsb */ + vec[n_points].x = subg->metrics.bbox.xMin - subg->metrics.horiBearingX; + vec[n_points].y = 0; + + /* pp2 = pp1 + aw */ + vec[n_points+1].x = vec[n_points].x + subg->metrics.horiAdvance; + vec[n_points+1].y = 0; + + /* clear the touch flags */ + + for ( j = 0; j < n_points; j++ ) + exec->pts.touch[j] &= TT_Flag_On_Curve; + + exec->pts.touch[n_points ] = 0; + exec->pts.touch[n_points + 1] = 0; + + /* Note that we return two more points that are not */ + /* part of the glyph outline. */ + + n_points += 2; + + /* now eventually scale and hint the glyph */ + + pts = &exec->pts; + pts->n_points = n_points; + pts->n_contours = n_contours; + + if ( (load_flags & TTLOAD_SCALE_GLYPH) == 0 ) + { + /* no scaling, just copy the orig arrays into the cur ones */ + org_to_cur( n_points, pts ); + } + else + { + /* first scale the glyph points */ + + for ( j = 0; j < n_points; j++ ) + { + pts->org[j].x = Scale_X( &exec->metrics, pts->org[j].x ); + pts->org[j].y = Scale_Y( &exec->metrics, pts->org[j].y ); + } + + /* if hinting, round pp1, and shift the glyph accordingly */ + if ( subg->is_hinted ) + { + x = pts->org[n_points - 2].x; + x = ((x+32) & -64) - x; + translate_array( n_points, pts->org, x, 0 ); + + org_to_cur( n_points, pts ); + + pts->cur[n_points - 1].x = (pts->cur[n_points - 1].x + 32) & -64; + + /* now consider hinting */ + if ( n_ins > 0 ) + { + exec->is_composite = FALSE; + exec->pedantic_hinting = load_flags & TTLOAD_PEDANTIC; + + error = Context_Run( exec, FALSE ); + if (error && exec->pedantic_hinting) + return error; + } + } + else + org_to_cur( n_points, pts ); + } + + /* save glyph phantom points */ + if (!subg->preserve_pps) + { + subg->pp1 = pts->cur[n_points - 2]; + subg->pp2 = pts->cur[n_points - 1]; + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_Composite_End + * + ******************************************************************/ + + static + TT_Error Load_Composite_End( UShort n_points, + Short n_contours, + PExecution_Context exec, + PSubglyph_Record subg, + UShort load_flags, + TT_Stream input ) + { + DEFINE_LOAD_LOCALS( input ); + + UShort k, n_ins; + PGlyph_Zone pts; + + + if ( subg->is_hinted && + subg->element_flag & WE_HAVE_INSTR ) + { + if ( ACCESS_Frame( 2L ) ) + return error; + + n_ins = GET_UShort(); /* read size of instructions */ + FORGET_Frame(); + + PTRACE4(( " Instructions size: %d\n", n_ins )); + + if ( n_ins > exec->face->maxProfile.maxSizeOfInstructions ) + { + PTRACE0(( "ERROR: Too many instructions in composite glyph %ld\n", + subg->index )); + return TT_Err_Too_Many_Ins; + } + + if ( FILE_Read( exec->glyphIns, n_ins ) ) + return error; + + error = Set_CodeRange( exec, + TT_CodeRange_Glyph, + exec->glyphIns, + n_ins ); + + if ( error ) + return error; + } + else + n_ins = 0; + + + /* prepare the execution context */ + n_points += 2; + exec->pts = subg->zone; + pts = &exec->pts; + + pts->n_points = n_points; + pts->n_contours = n_contours; + + /* add phantom points */ + pts->cur[n_points - 2] = subg->pp1; + pts->cur[n_points - 1] = subg->pp2; + + pts->touch[n_points - 1] = 0; + pts->touch[n_points - 2] = 0; + + /* if hinting, round the phantom points */ + if ( subg->is_hinted ) + { + pts->cur[n_points - 2].x = (subg->pp1.x + 32) & -64; + pts->cur[n_points - 1].x = (subg->pp2.x + 32) & -64; + } + + for ( k = 0; k < n_points; k++ ) + pts->touch[k] &= TT_Flag_On_Curve; + + cur_to_org( n_points, pts ); + + /* now consider hinting */ + if ( subg->is_hinted && n_ins > 0 ) + { + exec->is_composite = TRUE; + exec->pedantic_hinting = load_flags & TTLOAD_PEDANTIC; + + error = Context_Run( exec, FALSE ); + if (error && exec->pedantic_hinting) + return error; + } + + /* save glyph origin and advance points */ + subg->pp1 = pts->cur[n_points - 2]; + subg->pp2 = pts->cur[n_points - 1]; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Init_Glyph_Component + * + ******************************************************************/ + + static + void Init_Glyph_Component( PSubglyph_Record element, + PSubglyph_Record original, + PExecution_Context exec ) + { + element->index = -1; + element->is_scaled = FALSE; + element->is_hinted = FALSE; + + if ( original ) + mount_zone( &original->zone, &element->zone ); + else + element->zone = exec->pts; + + element->zone.n_contours = 0; + element->zone.n_points = 0; + + element->arg1 = 0; + element->arg2 = 0; + + element->element_flag = 0; + element->preserve_pps = FALSE; + + element->transform.xx = 1L << 16; + element->transform.xy = 0; + element->transform.yx = 0; + element->transform.yy = 1L << 16; + + element->transform.ox = 0; + element->transform.oy = 0; + + element->metrics.horiBearingX = 0; + element->metrics.horiAdvance = 0; + } + + + + LOCAL_FUNC + TT_Error Load_TrueType_Glyph( PInstance instance, + PGlyph glyph, + UShort glyph_index, + UShort load_flags ) + { + enum TPhases_ + { + Load_Exit, + Load_Glyph, + Load_Header, + Load_Simple, + Load_Composite, + Load_End + }; + + typedef enum TPhases_ TPhases; + + DEFINE_ALL_LOCALS; + + PFace face; + + UShort num_points; + Short num_contours; + UShort left_points; + Short left_contours; + UShort num_elem_points; + + Long table; + UShort load_top; + Long k, l; + UShort new_flags; + Long index; + UShort u, v; + + Long glyph_offset, offset; + + TT_F26Dot6 x, y, nx, ny; + + Fixed xx, xy, yx, yy; + + PExecution_Context exec; + + PSubglyph_Record subglyph, subglyph2; + + TGlyph_Zone base_pts; + + TPhases phase; + PByte widths; + +/* TT_Glyph_Loader_Callback cacheCb; */ +/* TT_Outline cached_outline; */ + + + /* first of all, check arguments */ + if ( !glyph ) + return TT_Err_Invalid_Glyph_Handle; + + face = glyph->face; + if ( !face ) + return TT_Err_Invalid_Glyph_Handle; + + if ( glyph_index >= face->numGlyphs ) + return TT_Err_Invalid_Glyph_Index; + + if ( instance && (load_flags & TTLOAD_SCALE_GLYPH) == 0 ) + { + instance = 0; + load_flags &= ~( TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH ); + } + + table = TT_LookUp_Table( face, TTAG_glyf ); + if ( table < 0 ) + { + PTRACE0(( "ERROR: There is no glyph table in this font file!\n" )); + return TT_Err_Glyf_Table_Missing; + } + + glyph_offset = face->dirTables[table].Offset; + + /* query new execution context */ + + if ( instance && instance->debug ) + exec = instance->context; + else + exec = New_Context( face ); + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + Context_Load( exec, face, instance ); + + if ( instance ) + { + if ( instance->GS.instruct_control & 2 ) + exec->GS = Default_GraphicsState; + else + exec->GS = instance->GS; + /* load default graphics state */ + + glyph->outline.high_precision = ( instance->metrics.y_ppem < 24 ); + } + + /* save its critical pointers, as they'll be modified during load */ + base_pts = exec->pts; + + /* init variables */ + left_points = face->maxPoints; + left_contours = face->maxContours; + + num_points = 0; + num_contours = 0; + + load_top = 0; + subglyph = exec->loadStack; + + Init_Glyph_Component( subglyph, NULL, exec ); + + subglyph->index = glyph_index; + subglyph->is_hinted = load_flags & TTLOAD_HINT_GLYPH; + + /* when the cvt program has disabled hinting, the argument */ + /* is ignored. */ + if ( instance && instance->GS.instruct_control & 1 ) + subglyph->is_hinted = FALSE; + + + /* now access stream */ + + if ( USE_Stream( face->stream, stream ) ) + goto Fin; + + /* Main loading loop */ + + phase = Load_Glyph; + index = 0; + + while ( phase != Load_Exit ) + { + subglyph = exec->loadStack + load_top; + + switch ( phase ) + { + /************************************************************/ + /* */ + /* Load_Glyph state */ + /* */ + /* reading a glyph's generic header to determine */ + /* whether it's simple or composite */ + /* */ + /* exit states: Load_Header and Load_End */ + + case Load_Glyph: + /* check glyph index and table */ + + index = subglyph->index; + if ( index < 0 || index >= face->numGlyphs ) + { + error = TT_Err_Invalid_Glyph_Index; + goto Fail; + } + + /* get horizontal metrics */ + + { + Short left_bearing; + UShort advance_width; + + + Get_HMetrics( face, (UShort)index, + !(load_flags & TTLOAD_IGNORE_GLOBAL_ADVANCE_WIDTH), + &left_bearing, + &advance_width ); + + subglyph->metrics.horiBearingX = left_bearing; + subglyph->metrics.horiAdvance = advance_width; + } + + phase = Load_Header; + + + /* The cache callback isn't part of the FreeType release yet */ + /* It is discarded for the moment.. */ + /* */ +#if 0 + if ( instance ) + { + /* is the glyph in an outline cache ? */ + cacheCb = instance->owner->engine->glCallback; + if ( cacheCb && 0 ) /* disabled */ + { + /* we have a callback */ + error = cacheCb( instance->generic, + index, &cached_outline, &x, &y ); + if ( !error ) + { + /* no error, then append the outline to the current subglyph */ + /* error = Append_Outline( subglyph, + &left_points, + &left_contours, + &cached_outline ); */ + phase = Load_End; + } + } + } +#endif + break; + + + /************************************************************/ + /* */ + /* Load_Header state */ + /* */ + /* reading a glyph's generic header to determine */ + /* wether it's simple or composite */ + /* */ + /* exit states: Load_Simple and Load_Composite */ + /* */ + + case Load_Header: /* load glyph */ + + if ( index + 1 < face->numLocations && + face->glyphLocations[index] == face->glyphLocations[index + 1] ) + { + /* as described by Frederic Loyer, these are spaces, and */ + /* not the unknown glyph. */ + + num_contours = 0; + num_points = 0; + + subglyph->metrics.bbox.xMin = 0; + subglyph->metrics.bbox.xMax = 0; + subglyph->metrics.bbox.yMin = 0; + subglyph->metrics.bbox.yMax = 0; + + subglyph->pp1.x = 0; + subglyph->pp2.x = subglyph->metrics.horiAdvance; + if (load_flags & TTLOAD_SCALE_GLYPH) + subglyph->pp2.x = Scale_X( &exec->metrics, subglyph->pp2.x ); + + exec->glyphSize = 0; + phase = Load_End; + break; + } + + offset = glyph_offset + face->glyphLocations[index]; + + /* read first glyph header */ + if ( FILE_Seek( offset ) || + ACCESS_Frame( 10L ) ) + goto Fail_File; + + num_contours = GET_Short(); + + subglyph->metrics.bbox.xMin = GET_Short(); + subglyph->metrics.bbox.yMin = GET_Short(); + subglyph->metrics.bbox.xMax = GET_Short(); + subglyph->metrics.bbox.yMax = GET_Short(); + + FORGET_Frame(); + + PTRACE6(( "Glyph %ld:\n", index )); + PTRACE6(( " # of contours: %d\n", num_contours )); + PTRACE6(( " xMin: %4d xMax: %4d\n", + subglyph->metrics.bbox.xMin, + subglyph->metrics.bbox.xMax )); + PTRACE6(( " yMin: %4d yMax: %4d\n", + subglyph->metrics.bbox.yMin, + subglyph->metrics.bbox.yMax )); + + if ( num_contours > left_contours ) + { + PTRACE0(( "ERROR: Too many contours for glyph %ld\n", index )); + error = TT_Err_Too_Many_Contours; + goto Fail; + } + + subglyph->pp1.x = subglyph->metrics.bbox.xMin - + subglyph->metrics.horiBearingX; + subglyph->pp1.y = 0; + subglyph->pp2.x = subglyph->pp1.x + subglyph->metrics.horiAdvance; + if (load_flags & TTLOAD_SCALE_GLYPH) + { + subglyph->pp1.x = Scale_X( &exec->metrics, subglyph->pp1.x ); + subglyph->pp2.x = Scale_X( &exec->metrics, subglyph->pp2.x ); + } + + /* is it a simple glyph ? */ + if ( num_contours > 0 ) + phase = Load_Simple; + else + phase = Load_Composite; + + break; + + + /************************************************************/ + /* */ + /* Load_Simple state */ + /* */ + /* reading a simple glyph (num_contours must be set to */ + /* the glyph's number of contours.) */ + /* */ + /* exit states : Load_End */ + /* */ + + case Load_Simple: + new_flags = load_flags; + + /* disable hinting when scaling */ + if ( !subglyph->is_hinted ) + new_flags &= ~TTLOAD_HINT_GLYPH; + + error = Load_Simple_Glyph( exec, + stream, + num_contours, + left_contours, + left_points, + new_flags, + subglyph ); + if ( error ) + goto Fail; + + /* Note: We could have put the simple loader source there */ + /* but the code is fat enough already :-) */ + + num_points = exec->pts.n_points - 2; + + phase = Load_End; + + break; + + + /************************************************************/ + /* */ + /* Load_Composite state */ + /* */ + /* reading a composite glyph header a pushing a new */ + /* load element on the stack. */ + /* */ + /* exit states: Load_Glyph */ + /* */ + + case Load_Composite: + + /* create a new element on the stack */ + load_top++; + + if ( load_top > face->maxComponents ) + { + error = TT_Err_Invalid_Composite; + goto Fail; + } + + subglyph2 = exec->loadStack + load_top; + + Init_Glyph_Component( subglyph2, subglyph, NULL ); + subglyph2->is_hinted = subglyph->is_hinted; + + /* now read composite header */ + + if ( ACCESS_Frame( 4L ) ) + goto Fail_File; + + subglyph->element_flag = new_flags = GET_UShort(); + + subglyph2->index = GET_UShort(); + + FORGET_Frame(); + + k = 1 + 1; + + if ( new_flags & ARGS_ARE_WORDS ) + k *= 2; + + if ( new_flags & WE_HAVE_A_SCALE ) + k += 2; + + else if ( new_flags & WE_HAVE_AN_XY_SCALE ) + k += 4; + + else if ( new_flags & WE_HAVE_A_2X2 ) + k += 8; + + if ( ACCESS_Frame( k ) ) + goto Fail_File; + + if ( new_flags & ARGS_ARE_WORDS ) + { + k = GET_Short(); + l = GET_Short(); + } + else + { + k = GET_Char(); + l = GET_Char(); + } + + subglyph->arg1 = k; + subglyph->arg2 = l; + + if ( new_flags & ARGS_ARE_XY_VALUES ) + { + subglyph->transform.ox = k; + subglyph->transform.oy = l; + } + + xx = 1L << 16; + xy = 0; + yx = 0; + yy = 1L << 16; + + if ( new_flags & WE_HAVE_A_SCALE ) + { + xx = (Fixed)GET_Short() << 2; + yy = xx; + subglyph2->is_scaled = TRUE; + } + else if ( new_flags & WE_HAVE_AN_XY_SCALE ) + { + xx = (Fixed)GET_Short() << 2; + yy = (Fixed)GET_Short() << 2; + subglyph2->is_scaled = TRUE; + } + else if ( new_flags & WE_HAVE_A_2X2 ) + { + xx = (Fixed)GET_Short() << 2; + xy = (Fixed)GET_Short() << 2; + yx = (Fixed)GET_Short() << 2; + yy = (Fixed)GET_Short() << 2; + subglyph2->is_scaled = TRUE; + } + + FORGET_Frame(); + + subglyph->transform.xx = xx; + subglyph->transform.xy = xy; + subglyph->transform.yx = yx; + subglyph->transform.yy = yy; + + k = TT_MulFix( xx, yy ) - TT_MulFix( xy, yx ); + + /* disable hinting in case of scaling/slanting */ + if ( ABS( k ) != (1L << 16) ) + subglyph2->is_hinted = FALSE; + + subglyph->file_offset = FILE_Pos(); + + phase = Load_Glyph; + + break; + + + /************************************************************/ + /* */ + /* Load_End state */ + /* */ + /* after loading a glyph, apply transformation and offset */ + /* where necessary, pops element and continue or */ + /* stop process. */ + /* */ + /* exit states : Load_Composite and Load_Exit */ + /* */ + + case Load_End: + if ( load_top > 0 ) + { + subglyph2 = subglyph; + + load_top--; + subglyph = exec->loadStack + load_top; + + /* check advance width and left side bearing */ + + if ( !subglyph->preserve_pps && + subglyph->element_flag & USE_MY_METRICS ) + { + subglyph->metrics.horiBearingX = subglyph2->metrics.horiBearingX; + subglyph->metrics.horiAdvance = subglyph2->metrics.horiAdvance; + + subglyph->pp1 = subglyph2->pp1; + subglyph->pp2 = subglyph2->pp2; + + subglyph->preserve_pps = TRUE; + } + + /* apply scale */ + + if ( subglyph2->is_scaled ) + { + TT_Vector* cur = subglyph2->zone.cur; + TT_Vector* org = subglyph2->zone.org; + + for ( u = 0; u < num_points; u++ ) + { + nx = TT_MulFix( cur->x, subglyph->transform.xx ) + + TT_MulFix( cur->y, subglyph->transform.yx ); + + ny = TT_MulFix( cur->x, subglyph->transform.xy ) + + TT_MulFix( cur->y, subglyph->transform.yy ); + + cur->x = nx; + cur->y = ny; + + nx = TT_MulFix( org->x, subglyph->transform.xx ) + + TT_MulFix( org->y, subglyph->transform.yx ); + + ny = TT_MulFix( org->x, subglyph->transform.xy ) + + TT_MulFix( org->y, subglyph->transform.yy ); + + org->x = nx; + org->y = ny; + + cur++; + org++; + } + } + + /* adjust counts */ + + num_elem_points = subglyph->zone.n_points; + + for ( k = 0; k < num_contours; k++ ) + subglyph2->zone.contours[k] += num_elem_points; + + subglyph->zone.n_points += num_points; + subglyph->zone.n_contours += num_contours; + + left_points -= num_points; + left_contours -= num_contours; + + if ( !(subglyph->element_flag & ARGS_ARE_XY_VALUES) ) + { + /* move second glyph according to control points */ + /* the attach points are relative to the specific component */ + + u = (UShort)subglyph->arg1; + v = (UShort)subglyph->arg2; + + if ( u >= num_elem_points || + v >= num_points ) + { + error = TT_Err_Invalid_Composite; + goto Fail; + } + + /* adjust count */ + v += num_elem_points; + + x = subglyph->zone.cur[u].x - subglyph->zone.cur[v].x; + y = subglyph->zone.cur[u].y - subglyph->zone.cur[v].y; + } + else + { + /* apply offset */ + + x = subglyph->transform.ox; + y = subglyph->transform.oy; + + if ( load_flags & TTLOAD_SCALE_GLYPH ) + { + x = Scale_X( &exec->metrics, x ); + y = Scale_Y( &exec->metrics, y ); + + if ( subglyph->element_flag & ROUND_XY_TO_GRID ) + { + x = (x+32) & -64; + y = (y+32) & -64; + } + } + } + + translate_array( num_points, subglyph2->zone.cur, x, y ); + + cur_to_org( num_points, &subglyph2->zone ); + + num_points = subglyph->zone.n_points; + num_contours = subglyph->zone.n_contours; + + /* check for last component */ + + if ( FILE_Seek( subglyph->file_offset ) ) + goto Fail_File; + + if ( subglyph->element_flag & MORE_COMPONENTS ) + phase = Load_Composite; + else + { + error = Load_Composite_End( num_points, + num_contours, + exec, + subglyph, + load_flags, + stream ); + if ( error ) + goto Fail; + + phase = Load_End; + } + } + else + phase = Load_Exit; + + break; + + + case Load_Exit: + break; + } + } + + /* finally, copy the points arrays to the glyph object */ + + exec->pts = base_pts; + + for ( u = 0; u < num_points + 2; u++ ) + { + glyph->outline.points[u] = exec->pts.cur[u]; + glyph->outline.flags [u] = exec->pts.touch[u]; + } + + for ( k = 0; k < num_contours; k++ ) + glyph->outline.contours[k] = exec->pts.contours[k]; + + glyph->outline.n_points = num_points; + glyph->outline.n_contours = num_contours; + glyph->outline.second_pass = TRUE; + + /* translate array so that (0,0) is the glyph's origin */ + translate_array( num_points + 2, + glyph->outline.points, + -subglyph->pp1.x, + 0 ); + + TT_Get_Outline_BBox( &glyph->outline, &glyph->metrics.bbox ); + + if ( subglyph->is_hinted ) + { + /* grid-fit the bounding box */ + glyph->metrics.bbox.xMin &= -64; + glyph->metrics.bbox.yMin &= -64; + glyph->metrics.bbox.xMax = (glyph->metrics.bbox.xMax+63) & -64; + glyph->metrics.bbox.yMax = (glyph->metrics.bbox.yMax+63) & -64; + } + + /* get the device-independent scaled horizontal metrics */ + /* take care of fixed-pitch fonts... */ + { + TT_Pos left_bearing; + TT_Pos advance; + + + left_bearing = subglyph->metrics.horiBearingX; + advance = subglyph->metrics.horiAdvance; + + if ( face->postscript.isFixedPitch ) + advance = face->horizontalHeader.advance_Width_Max; + + if ( load_flags & TTLOAD_SCALE_GLYPH ) + { + left_bearing = Scale_X( &exec->metrics, left_bearing ); + advance = Scale_X( &exec->metrics, advance ); + } + + glyph->metrics.linearHoriBearingX = left_bearing; + glyph->metrics.linearHoriAdvance = advance; + } + + glyph->metrics.horiBearingX = glyph->metrics.bbox.xMin; + glyph->metrics.horiBearingY = glyph->metrics.bbox.yMax; + glyph->metrics.horiAdvance = subglyph->pp2.x - subglyph->pp1.x; + + /* Now take care of vertical metrics. In the case where there is */ + /* no vertical information within the font (relatively common), make */ + /* up some metrics `by hand' ... */ + + { + Short top_bearing; /* vertical top side bearing (EM units) */ + UShort advance_height; /* vertical advance height (EM units) */ + + TT_Pos left; /* scaled vertical left side bearing */ + TT_Pos Top; /* scaled original vertical top side bearing */ + TT_Pos top; /* scaled vertical top side bearing */ + TT_Pos advance; /* scaled vertical advance height */ + + + /* Get the unscaled `tsb' and `ah' values */ + if ( face->verticalInfo && + face->verticalHeader.number_Of_VMetrics > 0 ) + { + /* Don't assume that both the vertical header and vertical */ + /* metrics are present in the same font :-) */ + + TT_Get_Metrics( (TT_Horizontal_Header*)&face->verticalHeader, + glyph_index, + &top_bearing, + &advance_height ); + } + else + { + /* Make up the distances from the horizontal header.. */ + + /* NOTE: The OS/2 values are the only `portable' ones, */ + /* which is why we use them... */ + /* */ + /* NOTE2: The sTypoDescender is negative, which is why */ + /* we compute the baseline-to-baseline distance */ + /* here with : */ + /* ascender - descender + linegap */ + /* */ + top_bearing = (Short) (face->os2.sTypoLineGap / 2); + advance_height = (UShort)(face->os2.sTypoAscender - + face->os2.sTypoDescender + + face->os2.sTypoLineGap); + } + + /* We must adjust the top_bearing value from the bounding box given + in the glyph header to te bounding box calculated with + TT_Get_Outline_BBox() */ + + /* scale the metrics */ + if ( load_flags & TTLOAD_SCALE_GLYPH ) + { + Top = Scale_Y( &exec->metrics, top_bearing ); + top = Scale_Y( &exec->metrics, + top_bearing + subglyph->metrics.bbox.yMax ) - + glyph->metrics.bbox.yMax; + advance = Scale_Y( &exec->metrics, advance_height ); + } + else + { + Top = top_bearing; + top = top_bearing + subglyph->metrics.bbox.yMax - + glyph->metrics.bbox.yMax; + advance = advance_height; + } + + glyph->metrics.linearVertBearingY = Top; + glyph->metrics.linearVertAdvance = advance; + + /* XXX : for now, we have no better algo for the lsb, but it should */ + /* work ok.. */ + /* */ + left = ( glyph->metrics.bbox.xMin - glyph->metrics.bbox.xMax ) / 2; + + /* grid-fit them if necessary */ + if ( subglyph->is_hinted ) + { + left &= -64; + top = (top + 63) & -64; + advance = (advance + 32) & -64; + } + + glyph->metrics.vertBearingX = left; + glyph->metrics.vertBearingY = top; + glyph->metrics.vertAdvance = advance; + } + + /* Adjust advance width to the value contained in the hdmx table. */ + if ( !exec->face->postscript.isFixedPitch && instance && + subglyph->is_hinted ) + { + widths = Get_Advance_Widths( exec->face, + exec->instance->metrics.x_ppem ); + if ( widths ) + glyph->metrics.horiAdvance = widths[glyph_index] << 6; + } + + glyph->outline.dropout_mode = (Char)exec->GS.scan_type; + + error = TT_Err_Ok; + + Fail_File: + Fail: + DONE_Stream( stream ); + + Fin: + + /* reset the execution context */ + exec->pts = base_pts; + + if ( !instance || !instance->debug ) + Done_Context( exec ); + + return error; + } + + +/* END */ diff --git a/lib/ttgload.h b/lib/ttgload.h new file mode 100644 index 0000000..cfdfb2c --- /dev/null +++ b/lib/ttgload.h @@ -0,0 +1,51 @@ +/******************************************************************* + * + * ttgload.h 1.0 + * + * TrueType Glyph Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTGLOAD_H +#define TTGLOAD_H + +#include "ttconfig.h" +#include "tttypes.h" +#include "ttobjs.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + LOCAL_DEF + void TT_Get_Metrics( TT_Horizontal_Header* header, + UShort index, + Short* bearing, + UShort* advance ); + + + LOCAL_DEF + TT_Error Load_TrueType_Glyph( PInstance instance, + PGlyph glyph, + UShort glyph_index, + UShort load_flags ); + +#ifdef __cplusplus + } +#endif + + +#endif /* TTGLOAD_H */ + + +/* END */ diff --git a/lib/ttinterp.c b/lib/ttinterp.c new file mode 100644 index 0000000..9158fec --- /dev/null +++ b/lib/ttinterp.c @@ -0,0 +1,6654 @@ +/******************************************************************* + * + * ttinterp.c 3.1 + * + * TrueType bytecode intepreter. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 3.1 and 3.0: + * + * - A more relaxed version of the interpreter. It is now able to + * ignore errors like out-of-bound array access and writes in order + * to silently support broken glyphs (even if the results are not + * always pretty). + * + * Note that one can use the flag TTLOAD_PEDANTIC to force + * TrueType-compliant interpretation. + * + * - A big #if used to completely disable the interpreter, which + * is due to the Apple patents issues which emerged recently. + * + ******************************************************************/ + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttcalc.h" +#include "ttmemory.h" +#include "ttinterp.h" + + +#ifdef TT_CONFIG_OPTION_NO_INTERPRETER + + LOCAL_FUNC + TT_Error RunIns( PExecution_Context exc ) + { + /* do nothing - always successful */ + (void)exc; + return TT_Err_Ok; + } + +#else + + +#ifdef DEBUG_INTERPRETER +#include +#include "ttdebug.h" + +/* Define the `getch()' function. On Unix systems, it is an alias */ +/* for `getchar()', and the debugger front end must ensure that the */ +/* `stdin' file descriptor is not in line-by-line input mode. */ +#ifdef OS2 +#include +#else +#define getch getchar +#endif + +#endif /* DEBUG_INTEPRETER */ + + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_interp + + +/* In order to detect infinite loops in the code, we set-up */ +/* a counter within the run loop. a singly stroke of interpretation */ +/* is now limited to a maximum number of opcodes defined below.. */ +/* */ +#define MAX_RUNNABLE_OPCODES 1000000 + + +/* There are two kinds of implementations there: */ +/* */ +/* a. static implementation: */ +/* */ +/* The current execution context is a static variable, */ +/* which fields are accessed directly by the interpreter */ +/* during execution. The context is named 'cur'. */ +/* */ +/* This version is non-reentrant, of course. */ +/* */ +/* */ +/* b. indirect implementation: */ +/* */ +/* The current execution context is passed to _each_ */ +/* function as its first argument, and each field is */ +/* thus accessed indirectly. */ +/* */ +/* This version is, however, fully re-entrant. */ +/* */ +/* */ +/* The idea is that an indirect implementation may be */ +/* slower to execute on the low-end processors that are */ +/* used in some systems (like 386s or even 486s). */ +/* */ +/* When the interpreter started, we had no idea of the */ +/* time that glyph hinting (i.e. executing instructions) */ +/* could take in the whole process of rendering a glyph, */ +/* and a 10 to 30% performance penalty on low-end systems */ +/* didn't seem much of a good idea. This question led us */ +/* to provide two distinct builds of the C version from */ +/* a single source, with the use of macros (again). */ +/* */ +/* Now that the engine is working (and working really */ +/* well!), it seems that the greatest time-consuming */ +/* factors are: file i/o, glyph loading, rasterizing and */ +/* _then_ glyph hinting! */ +/* */ +/* Tests performed with two versions of the 'fttimer' */ +/* program seem to indicate that hinting takes less than 5% */ +/* of the rendering process, which is dominated by glyph */ +/* loading and scan-line conversion by an high order of */ +/* magnitude. */ +/* */ +/* As a consequence, the indirect implementation is now the */ +/* default, as its performance costs can be considered */ +/* negligible in our context. Note, however, that we */ +/* kept the same source with macros because: */ +/* */ +/* - the code is kept very close in design to the */ +/* Pascal one used for development. */ +/* */ +/* - it's much more readable that way! */ +/* */ +/* - it's still open to later experimentation and tuning */ + + + +#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ + +#define CUR (*exc) /* see ttobjs.h */ + +#else /* static implementation */ + +#define CUR cur + + static TExecution_Context cur; /* static exec. context variable */ + + /* apparently, we have a _lot_ of direct indexing when accessing */ + /* the static 'cur', which makes the code bigger (due to all the */ + /* four bytes addresses). */ + +#endif /* !TT_CONFIG_OPTION_STATIC_INTERPRETER */ + + +#define INS_ARG EXEC_OPS PStorage args /* see ttobjs.h */ + +#define SKIP_Code() SkipCode( EXEC_ARG ) + +#define GET_ShortIns() GetShortIns( EXEC_ARG ) + +#define COMPUTE_Funcs() Compute_Funcs( EXEC_ARG ) + +#define NORMalize( x, y, v ) Normalize( EXEC_ARGS x, y, v ) + +#define SET_SuperRound( scale, flags ) \ + SetSuperRound( EXEC_ARGS scale, flags ) + +#define INS_Goto_CodeRange( range, ip ) \ + Ins_Goto_CodeRange( EXEC_ARGS range, ip ) + +#define CUR_Func_project( x, y ) CUR.func_project( EXEC_ARGS x, y ) +#define CUR_Func_move( z, p, d ) CUR.func_move( EXEC_ARGS z, p, d ) +#define CUR_Func_dualproj( x, y ) CUR.func_dualproj( EXEC_ARGS x, y ) +#define CUR_Func_freeProj( x, y ) CUR.func_freeProj( EXEC_ARGS x, y ) +#define CUR_Func_round( d, c ) CUR.func_round( EXEC_ARGS d, c ) + +#define CUR_Func_read_cvt( index ) \ + CUR.func_read_cvt( EXEC_ARGS index ) + +#define CUR_Func_write_cvt( index, val ) \ + CUR.func_write_cvt( EXEC_ARGS index, val ) + +#define CUR_Func_move_cvt( index, val ) \ + CUR.func_move_cvt( EXEC_ARGS index, val ) + +#define CURRENT_Ratio() Current_Ratio( EXEC_ARG ) +#define CURRENT_Ppem() Current_Ppem( EXEC_ARG ) + +#define CALC_Length() Calc_Length( EXEC_ARG ) + +#define INS_SxVTL( a, b, c, d ) Ins_SxVTL( EXEC_ARGS a, b, c, d ) + +#define COMPUTE_Point_Displacement( a, b, c, d ) \ + Compute_Point_Displacement( EXEC_ARGS a, b, c, d ) + +#define MOVE_Zp2_Point( a, b, c, t ) Move_Zp2_Point( EXEC_ARGS a, b, c, t ) + +#define CUR_Ppem() Cur_PPEM( EXEC_ARG ) + + /* Instruction dispatch function, as used by the interpreter */ + typedef void (*TInstruction_Function)( INS_ARG ); + +#define BOUNDS( x, n ) ( (x) >= (n) ) + + + +/*********************************************************************/ +/* */ +/* Before an opcode is executed, the interpreter verifies that */ +/* there are enough arguments on the stack, with the help of */ +/* the Pop_Push_Count table. */ +/* */ +/* For each opcode, the first column gives the number of arguments */ +/* that are popped from the stack; the second one gives the number */ +/* of those that are pushed in result. */ +/* */ +/* Note that for opcodes with a varying number of parameters, */ +/* either 0 or 1 arg is verified before execution, depending */ +/* on the nature of the instruction: */ +/* */ +/* - if the number of arguments is given by the bytecode */ +/* stream or the loop variable, 0 is chosen. */ +/* */ +/* - if the first argument is a count n that is followed */ +/* by arguments a1..an, then 1 is chosen. */ +/* */ +/*********************************************************************/ + +#undef PACK +#define PACK( x, y ) ((x << 4) | y) + + static const Byte Pop_Push_Count[256] = + { + /* opcodes are gathered in groups of 16 */ + /* please keep the spaces as they are */ + + /* SVTCA y */ PACK( 0, 0 ), + /* SVTCA x */ PACK( 0, 0 ), + /* SPvTCA y */ PACK( 0, 0 ), + /* SPvTCA x */ PACK( 0, 0 ), + /* SFvTCA y */ PACK( 0, 0 ), + /* SFvTCA x */ PACK( 0, 0 ), + /* SPvTL // */ PACK( 2, 0 ), + /* SPvTL + */ PACK( 2, 0 ), + /* SFvTL // */ PACK( 2, 0 ), + /* SFvTL + */ PACK( 2, 0 ), + /* SPvFS */ PACK( 2, 0 ), + /* SFvFS */ PACK( 2, 0 ), + /* GPV */ PACK( 0, 2 ), + /* GFV */ PACK( 0, 2 ), + /* SFvTPv */ PACK( 0, 0 ), + /* ISECT */ PACK( 5, 0 ), + + /* SRP0 */ PACK( 1, 0 ), + /* SRP1 */ PACK( 1, 0 ), + /* SRP2 */ PACK( 1, 0 ), + /* SZP0 */ PACK( 1, 0 ), + /* SZP1 */ PACK( 1, 0 ), + /* SZP2 */ PACK( 1, 0 ), + /* SZPS */ PACK( 1, 0 ), + /* SLOOP */ PACK( 1, 0 ), + /* RTG */ PACK( 0, 0 ), + /* RTHG */ PACK( 0, 0 ), + /* SMD */ PACK( 1, 0 ), + /* ELSE */ PACK( 0, 0 ), + /* JMPR */ PACK( 1, 0 ), + /* SCvTCi */ PACK( 1, 0 ), + /* SSwCi */ PACK( 1, 0 ), + /* SSW */ PACK( 1, 0 ), + + /* DUP */ PACK( 1, 2 ), + /* POP */ PACK( 1, 0 ), + /* CLEAR */ PACK( 0, 0 ), + /* SWAP */ PACK( 2, 2 ), + /* DEPTH */ PACK( 0, 1 ), + /* CINDEX */ PACK( 1, 1 ), + /* MINDEX */ PACK( 1, 0 ), + /* AlignPTS */ PACK( 2, 0 ), + /* INS_$28 */ PACK( 0, 0 ), + /* UTP */ PACK( 1, 0 ), + /* LOOPCALL */ PACK( 2, 0 ), + /* CALL */ PACK( 1, 0 ), + /* FDEF */ PACK( 1, 0 ), + /* ENDF */ PACK( 0, 0 ), + /* MDAP[0] */ PACK( 1, 0 ), + /* MDAP[1] */ PACK( 1, 0 ), + + /* IUP[0] */ PACK( 0, 0 ), + /* IUP[1] */ PACK( 0, 0 ), + /* SHP[0] */ PACK( 0, 0 ), + /* SHP[1] */ PACK( 0, 0 ), + /* SHC[0] */ PACK( 1, 0 ), + /* SHC[1] */ PACK( 1, 0 ), + /* SHZ[0] */ PACK( 1, 0 ), + /* SHZ[1] */ PACK( 1, 0 ), + /* SHPIX */ PACK( 1, 0 ), + /* IP */ PACK( 0, 0 ), + /* MSIRP[0] */ PACK( 2, 0 ), + /* MSIRP[1] */ PACK( 2, 0 ), + /* AlignRP */ PACK( 0, 0 ), + /* RTDG */ PACK( 0, 0 ), + /* MIAP[0] */ PACK( 2, 0 ), + /* MIAP[1] */ PACK( 2, 0 ), + + /* NPushB */ PACK( 0, 0 ), + /* NPushW */ PACK( 0, 0 ), + /* WS */ PACK( 2, 0 ), + /* RS */ PACK( 1, 1 ), + /* WCvtP */ PACK( 2, 0 ), + /* RCvt */ PACK( 1, 1 ), + /* GC[0] */ PACK( 1, 1 ), + /* GC[1] */ PACK( 1, 1 ), + /* SCFS */ PACK( 2, 0 ), + /* MD[0] */ PACK( 2, 1 ), + /* MD[1] */ PACK( 2, 1 ), + /* MPPEM */ PACK( 0, 1 ), + /* MPS */ PACK( 0, 1 ), + /* FlipON */ PACK( 0, 0 ), + /* FlipOFF */ PACK( 0, 0 ), + /* DEBUG */ PACK( 1, 0 ), + + /* LT */ PACK( 2, 1 ), + /* LTEQ */ PACK( 2, 1 ), + /* GT */ PACK( 2, 1 ), + /* GTEQ */ PACK( 2, 1 ), + /* EQ */ PACK( 2, 1 ), + /* NEQ */ PACK( 2, 1 ), + /* ODD */ PACK( 1, 1 ), + /* EVEN */ PACK( 1, 1 ), + /* IF */ PACK( 1, 0 ), + /* EIF */ PACK( 0, 0 ), + /* AND */ PACK( 2, 1 ), + /* OR */ PACK( 2, 1 ), + /* NOT */ PACK( 1, 1 ), + /* DeltaP1 */ PACK( 1, 0 ), + /* SDB */ PACK( 1, 0 ), + /* SDS */ PACK( 1, 0 ), + + /* ADD */ PACK( 2, 1 ), + /* SUB */ PACK( 2, 1 ), + /* DIV */ PACK( 2, 1 ), + /* MUL */ PACK( 2, 1 ), + /* ABS */ PACK( 1, 1 ), + /* NEG */ PACK( 1, 1 ), + /* FLOOR */ PACK( 1, 1 ), + /* CEILING */ PACK( 1, 1 ), + /* ROUND[0] */ PACK( 1, 1 ), + /* ROUND[1] */ PACK( 1, 1 ), + /* ROUND[2] */ PACK( 1, 1 ), + /* ROUND[3] */ PACK( 1, 1 ), + /* NROUND[0] */ PACK( 1, 1 ), + /* NROUND[1] */ PACK( 1, 1 ), + /* NROUND[2] */ PACK( 1, 1 ), + /* NROUND[3] */ PACK( 1, 1 ), + + /* WCvtF */ PACK( 2, 0 ), + /* DeltaP2 */ PACK( 1, 0 ), + /* DeltaP3 */ PACK( 1, 0 ), + /* DeltaCn[0] */ PACK( 1, 0 ), + /* DeltaCn[1] */ PACK( 1, 0 ), + /* DeltaCn[2] */ PACK( 1, 0 ), + /* SROUND */ PACK( 1, 0 ), + /* S45Round */ PACK( 1, 0 ), + /* JROT */ PACK( 2, 0 ), + /* JROF */ PACK( 2, 0 ), + /* ROFF */ PACK( 0, 0 ), + /* INS_$7B */ PACK( 0, 0 ), + /* RUTG */ PACK( 0, 0 ), + /* RDTG */ PACK( 0, 0 ), + /* SANGW */ PACK( 1, 0 ), + /* AA */ PACK( 1, 0 ), + + /* FlipPT */ PACK( 0, 0 ), + /* FlipRgON */ PACK( 2, 0 ), + /* FlipRgOFF */ PACK( 2, 0 ), + /* INS_$83 */ PACK( 0, 0 ), + /* INS_$84 */ PACK( 0, 0 ), + /* ScanCTRL */ PACK( 1, 0 ), + /* SDVPTL[0] */ PACK( 2, 0 ), + /* SDVPTL[1] */ PACK( 2, 0 ), + /* GetINFO */ PACK( 1, 1 ), + /* IDEF */ PACK( 1, 0 ), + /* ROLL */ PACK( 3, 3 ), + /* MAX */ PACK( 2, 1 ), + /* MIN */ PACK( 2, 1 ), + /* ScanTYPE */ PACK( 1, 0 ), + /* InstCTRL */ PACK( 2, 0 ), + /* INS_$8F */ PACK( 0, 0 ), + + /* INS_$90 */ PACK( 0, 0 ), + /* INS_$91 */ PACK( 0, 0 ), + /* INS_$92 */ PACK( 0, 0 ), + /* INS_$93 */ PACK( 0, 0 ), + /* INS_$94 */ PACK( 0, 0 ), + /* INS_$95 */ PACK( 0, 0 ), + /* INS_$96 */ PACK( 0, 0 ), + /* INS_$97 */ PACK( 0, 0 ), + /* INS_$98 */ PACK( 0, 0 ), + /* INS_$99 */ PACK( 0, 0 ), + /* INS_$9A */ PACK( 0, 0 ), + /* INS_$9B */ PACK( 0, 0 ), + /* INS_$9C */ PACK( 0, 0 ), + /* INS_$9D */ PACK( 0, 0 ), + /* INS_$9E */ PACK( 0, 0 ), + /* INS_$9F */ PACK( 0, 0 ), + + /* INS_$A0 */ PACK( 0, 0 ), + /* INS_$A1 */ PACK( 0, 0 ), + /* INS_$A2 */ PACK( 0, 0 ), + /* INS_$A3 */ PACK( 0, 0 ), + /* INS_$A4 */ PACK( 0, 0 ), + /* INS_$A5 */ PACK( 0, 0 ), + /* INS_$A6 */ PACK( 0, 0 ), + /* INS_$A7 */ PACK( 0, 0 ), + /* INS_$A8 */ PACK( 0, 0 ), + /* INS_$A9 */ PACK( 0, 0 ), + /* INS_$AA */ PACK( 0, 0 ), + /* INS_$AB */ PACK( 0, 0 ), + /* INS_$AC */ PACK( 0, 0 ), + /* INS_$AD */ PACK( 0, 0 ), + /* INS_$AE */ PACK( 0, 0 ), + /* INS_$AF */ PACK( 0, 0 ), + + /* PushB[0] */ PACK( 0, 1 ), + /* PushB[1] */ PACK( 0, 2 ), + /* PushB[2] */ PACK( 0, 3 ), + /* PushB[3] */ PACK( 0, 4 ), + /* PushB[4] */ PACK( 0, 5 ), + /* PushB[5] */ PACK( 0, 6 ), + /* PushB[6] */ PACK( 0, 7 ), + /* PushB[7] */ PACK( 0, 8 ), + /* PushW[0] */ PACK( 0, 1 ), + /* PushW[1] */ PACK( 0, 2 ), + /* PushW[2] */ PACK( 0, 3 ), + /* PushW[3] */ PACK( 0, 4 ), + /* PushW[4] */ PACK( 0, 5 ), + /* PushW[5] */ PACK( 0, 6 ), + /* PushW[6] */ PACK( 0, 7 ), + /* PushW[7] */ PACK( 0, 8 ), + + /* MDRP[00] */ PACK( 1, 0 ), + /* MDRP[01] */ PACK( 1, 0 ), + /* MDRP[02] */ PACK( 1, 0 ), + /* MDRP[03] */ PACK( 1, 0 ), + /* MDRP[04] */ PACK( 1, 0 ), + /* MDRP[05] */ PACK( 1, 0 ), + /* MDRP[06] */ PACK( 1, 0 ), + /* MDRP[07] */ PACK( 1, 0 ), + /* MDRP[08] */ PACK( 1, 0 ), + /* MDRP[09] */ PACK( 1, 0 ), + /* MDRP[10] */ PACK( 1, 0 ), + /* MDRP[11] */ PACK( 1, 0 ), + /* MDRP[12] */ PACK( 1, 0 ), + /* MDRP[13] */ PACK( 1, 0 ), + /* MDRP[14] */ PACK( 1, 0 ), + /* MDRP[15] */ PACK( 1, 0 ), + + /* MDRP[16] */ PACK( 1, 0 ), + /* MDRP[17] */ PACK( 1, 0 ), + /* MDRP[18] */ PACK( 1, 0 ), + /* MDRP[19] */ PACK( 1, 0 ), + /* MDRP[20] */ PACK( 1, 0 ), + /* MDRP[21] */ PACK( 1, 0 ), + /* MDRP[22] */ PACK( 1, 0 ), + /* MDRP[23] */ PACK( 1, 0 ), + /* MDRP[24] */ PACK( 1, 0 ), + /* MDRP[25] */ PACK( 1, 0 ), + /* MDRP[26] */ PACK( 1, 0 ), + /* MDRP[27] */ PACK( 1, 0 ), + /* MDRP[28] */ PACK( 1, 0 ), + /* MDRP[29] */ PACK( 1, 0 ), + /* MDRP[30] */ PACK( 1, 0 ), + /* MDRP[31] */ PACK( 1, 0 ), + + /* MIRP[00] */ PACK( 2, 0 ), + /* MIRP[01] */ PACK( 2, 0 ), + /* MIRP[02] */ PACK( 2, 0 ), + /* MIRP[03] */ PACK( 2, 0 ), + /* MIRP[04] */ PACK( 2, 0 ), + /* MIRP[05] */ PACK( 2, 0 ), + /* MIRP[06] */ PACK( 2, 0 ), + /* MIRP[07] */ PACK( 2, 0 ), + /* MIRP[08] */ PACK( 2, 0 ), + /* MIRP[09] */ PACK( 2, 0 ), + /* MIRP[10] */ PACK( 2, 0 ), + /* MIRP[11] */ PACK( 2, 0 ), + /* MIRP[12] */ PACK( 2, 0 ), + /* MIRP[13] */ PACK( 2, 0 ), + /* MIRP[14] */ PACK( 2, 0 ), + /* MIRP[15] */ PACK( 2, 0 ), + + /* MIRP[16] */ PACK( 2, 0 ), + /* MIRP[17] */ PACK( 2, 0 ), + /* MIRP[18] */ PACK( 2, 0 ), + /* MIRP[19] */ PACK( 2, 0 ), + /* MIRP[20] */ PACK( 2, 0 ), + /* MIRP[21] */ PACK( 2, 0 ), + /* MIRP[22] */ PACK( 2, 0 ), + /* MIRP[23] */ PACK( 2, 0 ), + /* MIRP[24] */ PACK( 2, 0 ), + /* MIRP[25] */ PACK( 2, 0 ), + /* MIRP[26] */ PACK( 2, 0 ), + /* MIRP[27] */ PACK( 2, 0 ), + /* MIRP[28] */ PACK( 2, 0 ), + /* MIRP[29] */ PACK( 2, 0 ), + /* MIRP[30] */ PACK( 2, 0 ), + /* MIRP[31] */ PACK( 2, 0 ) + }; + + static const TT_Vector Null_Vector = {0,0}; + +#undef NULL_Vector +#define NULL_Vector (TT_Vector*)&Null_Vector + +/******************************************************************* + * + * Function : Norm + * + * Description : Returns the norm (length) of a vector. + * + * Input : X, Y vector + * + * Output : Returns length in F26dot6. + * + *****************************************************************/ + + static TT_F26Dot6 Norm( TT_F26Dot6 X, TT_F26Dot6 Y ) + { + TT_Int64 T1, T2; + + + MUL_64( X, X, T1 ); + MUL_64( Y, Y, T2 ); + + ADD_64( T1, T2, T1 ); + + return (TT_F26Dot6)SQRT_64( T1 ); + } + + +/******************************************************************* + * + * Function : FUnits_To_Pixels + * + * Description : Scale a distance in FUnits to pixel coordinates. + * + * Input : Distance in FUnits + * + * Output : Distance in 26.6 format. + * + *****************************************************************/ + + static TT_F26Dot6 FUnits_To_Pixels( EXEC_OPS Short distance ) + { + return TT_MulDiv( distance, + CUR.metrics.scale1, + CUR.metrics.scale2 ); + } + + +/******************************************************************* + * + * Function : Current_Ratio + * + * Description : Return the current aspect ratio scaling factor + * depending on the projection vector's state and + * device resolutions. + * + * Input : None + * + * Output : Aspect ratio in 16.16 format, always <= 1.0 . + * + *****************************************************************/ + + static Long Current_Ratio( EXEC_OP ) + { + if ( CUR.metrics.ratio ) + return CUR.metrics.ratio; + + if ( CUR.GS.projVector.y == 0 ) + CUR.metrics.ratio = CUR.metrics.x_ratio; + + else if ( CUR.GS.projVector.x == 0 ) + CUR.metrics.ratio = CUR.metrics.y_ratio; + + else + { + Long x, y; + + + x = TT_MulDiv( CUR.GS.projVector.x, CUR.metrics.x_ratio, 0x4000 ); + y = TT_MulDiv( CUR.GS.projVector.y, CUR.metrics.y_ratio, 0x4000 ); + CUR.metrics.ratio = Norm( x, y ); + } + + return CUR.metrics.ratio; + } + + + static Long Current_Ppem( EXEC_OP ) + { + return TT_MulFix( CUR.metrics.ppem, CURRENT_Ratio() ); + } + + + static TT_F26Dot6 Read_CVT( EXEC_OPS ULong index ) + { + return CUR.cvt[index]; + } + + + static TT_F26Dot6 Read_CVT_Stretched( EXEC_OPS ULong index ) + { + return TT_MulFix( CUR.cvt[index], CURRENT_Ratio() ); + } + + + static void Write_CVT( EXEC_OPS ULong index, TT_F26Dot6 value ) + { + CUR.cvt[index] = value; + } + + static void Write_CVT_Stretched( EXEC_OPS ULong index, TT_F26Dot6 value ) + { + CUR.cvt[index] = TT_MulDiv( value, 0x10000, CURRENT_Ratio() ); + } + + + static void Move_CVT( EXEC_OPS ULong index, TT_F26Dot6 value ) + { + CUR.cvt[index] += value; + } + + static void Move_CVT_Stretched( EXEC_OPS ULong index, TT_F26Dot6 value ) + { + CUR.cvt[index] += TT_MulDiv( value, 0x10000, CURRENT_Ratio() ); + } + + +/****************************************************************** + * + * Function : Calc_Length + * + * Description : Computes the length in bytes of current opcode. + * + *****************************************************************/ + + static Bool Calc_Length( EXEC_OP ) + { + CUR.opcode = CUR.code[CUR.IP]; + + switch ( CUR.opcode ) + { + case 0x40: + if ( CUR.IP + 1 >= CUR.codeSize ) + return FAILURE; + + CUR.length = CUR.code[CUR.IP + 1] + 2; + break; + + case 0x41: + if ( CUR.IP + 1 >= CUR.codeSize ) + return FAILURE; + + CUR.length = CUR.code[CUR.IP + 1] * 2 + 2; + break; + + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + CUR.length = CUR.opcode - 0xB0 + 2; + break; + + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + CUR.length = (CUR.opcode - 0xB8) * 2 + 3; + break; + + default: + CUR.length = 1; + break; + } + + /* make sure result is in range */ + + if ( CUR.IP + CUR.length > CUR.codeSize ) + return FAILURE; + + return SUCCESS; + } + + +/******************************************************************* + * + * Function : GetShortIns + * + * Description : Returns a short integer taken from the instruction + * stream at address IP. + * + * Input : None + * + * Output : Short read at Code^[IP..IP+1] + * + * Notes : This one could become a Macro in the C version. + * + *****************************************************************/ + + static Short GetShortIns( EXEC_OP ) + { + /* Reading a byte stream so there is no endianess (DaveP) */ + CUR.IP += 2; + return (Short)((CUR.code[CUR.IP - 2] << 8) + CUR.code[CUR.IP - 1]); + } + + +/******************************************************************* + * + * Function : Ins_Goto_CodeRange + * + * Description : Goes to a certain code range in the instruction + * stream. + * + * + * Input : aRange + * aIP + * + * Output : SUCCESS or FAILURE. + * + *****************************************************************/ + + static Bool Ins_Goto_CodeRange( EXEC_OPS Int aRange, ULong aIP ) + { + TCodeRange* WITH; + + + if ( aRange < 1 || aRange > 3 ) + { + CUR.error = TT_Err_Bad_Argument; + return FAILURE; + } + + WITH = &CUR.codeRangeTable[aRange - 1]; + + if ( WITH->Base == NULL ) /* invalid coderange */ + { + CUR.error = TT_Err_Invalid_CodeRange; + return FAILURE; + } + + /* NOTE: Because the last instruction of a program may be a CALL */ + /* which will return to the first byte *after* the code */ + /* range, we test for aIP <= Size, instead of aIP < Size. */ + + if ( aIP > WITH->Size ) + { + CUR.error = TT_Err_Code_Overflow; + return FAILURE; + } + + CUR.code = WITH->Base; + CUR.codeSize = WITH->Size; + CUR.IP = aIP; + CUR.curRange = aRange; + + return SUCCESS; + } + + +/******************************************************************* + * + * Function : Direct_Move + * + * Description : Moves a point by a given distance along the + * freedom vector. The point will be touched. + * + * Input : point index of point to move + * distance distance to apply + * zone affected glyph zone + * + * Output : None + * + *****************************************************************/ + + static void Direct_Move( EXEC_OPS PGlyph_Zone zone, + UShort point, + TT_F26Dot6 distance ) + { + TT_F26Dot6 v; + + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + { + zone->cur[point].x += TT_MulDiv( distance, + v * 0x10000L, + CUR.F_dot_P ); + + zone->touch[point] |= TT_Flag_Touched_X; + } + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + { + zone->cur[point].y += TT_MulDiv( distance, + v * 0x10000L, + CUR.F_dot_P ); + + zone->touch[point] |= TT_Flag_Touched_Y; + } + } + + +/******************************************************************/ +/* */ +/* The following versions are used whenever both vectors are both */ +/* along one of the coordinate unit vectors, i.e. in 90% cases. */ +/* */ +/******************************************************************/ + +/******************************************************************* + * Direct_Move_X + * + *******************************************************************/ + + static void Direct_Move_X( EXEC_OPS PGlyph_Zone zone, + UShort point, + TT_F26Dot6 distance ) + { + zone->cur[point].x += distance; + zone->touch[point] |= TT_Flag_Touched_X; + } + + +/******************************************************************* + * Direct_Move_Y + * + *******************************************************************/ + + static void Direct_Move_Y( EXEC_OPS PGlyph_Zone zone, + UShort point, + TT_F26Dot6 distance ) + { + zone->cur[point].y += distance; + zone->touch[point] |= TT_Flag_Touched_Y; + } + + +/******************************************************************* + * + * Function : Round_None + * + * Description : Does not round, but adds engine compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance. + * + * NOTE : The spec says very few about the relationship between + * rounding and engine compensation. However, it seems + * from the description of super round that we should + * should add the compensation before rounding. + * + ******************************************************************/ + + static TT_F26Dot6 Round_None( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( val < 0 ) + val = 0; + } + else { + val = distance - compensation; + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_To_Grid + * + * Description : Rounds value to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_To_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation + 32; + if ( val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -( (compensation - distance + 32) & (-64) ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_To_Half_Grid + * + * Description : Rounds value to half grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_To_Half_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = ((distance + compensation) & (-64)) + 32; + if ( val < 0 ) + val = 0; + } + else + { + val = -( ((compensation - distance) & (-64)) + 32 ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_Down_To_Grid + * + * Description : Rounds value down to grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_Down_To_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -( (compensation - distance) & (-64) ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_Up_To_Grid + * + * Description : Rounds value up to grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_Up_To_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation + 63; + if ( val > 0 ) + val &= ~63; + else + val = 0; + } + else + { + val = -( (compensation - distance + 63) & (-64) ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_To_Double_Grid + * + * Description : Rounds value to double grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + *****************************************************************/ + + static TT_F26Dot6 Round_To_Double_Grid( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = distance + compensation + 16; + if ( val > 0 ) + val &= ~31; + else + val = 0; + } + else + { + val = -( (compensation - distance + 16) & (-32) ); + if ( val > 0 ) + val = 0; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_Super + * + * Description : Super-rounds value to grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + * NOTE : The spec says very few about the relationship between + * rounding and engine compensation. However, it seems + * from the description of super round that we should + * should add the compensation before rounding. + * + *****************************************************************/ + + static TT_F26Dot6 Round_Super( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = (distance - CUR.phase + CUR.threshold + compensation) & + (-CUR.period); + if ( val < 0 ) + val = 0; + val += CUR.phase; + } + else + { + val = -( (CUR.threshold - CUR.phase - distance + compensation) & + (-CUR.period) ); + if ( val > 0 ) + val = 0; + val -= CUR.phase; + } + + return val; + } + + +/******************************************************************* + * + * Function : Round_Super_45 + * + * Description : Super-rounds value to grid after adding engine + * compensation. + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : Rounded distance. + * + * NOTE : There is a separate function for Round_Super_45 as we + * may need a greater precision. + * + *****************************************************************/ + + static TT_F26Dot6 Round_Super_45( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ) + { + TT_F26Dot6 val; + + + if ( distance >= 0 ) + { + val = ( (distance - CUR.phase + CUR.threshold + compensation) / + CUR.period ) * CUR.period; + if ( val < 0 ) + val = 0; + val += CUR.phase; + } + else + { + val = -( ( (CUR.threshold - CUR.phase - distance + compensation) / + CUR.period ) * CUR.period ); + if ( val > 0 ) + val = 0; + val -= CUR.phase; + } + + return val; + } + + +/******************************************************************* + * Compute_Round + * + *****************************************************************/ + + static void Compute_Round( EXEC_OPS Byte round_mode ) + { + switch ( round_mode ) + { + case TT_Round_Off: + CUR.func_round = (TRound_Function)Round_None; + break; + + case TT_Round_To_Grid: + CUR.func_round = (TRound_Function)Round_To_Grid; + break; + + case TT_Round_Up_To_Grid: + CUR.func_round = (TRound_Function)Round_Up_To_Grid; + break; + + case TT_Round_Down_To_Grid: + CUR.func_round = (TRound_Function)Round_Down_To_Grid; + break; + + case TT_Round_To_Half_Grid: + CUR.func_round = (TRound_Function)Round_To_Half_Grid; + break; + + case TT_Round_To_Double_Grid: + CUR.func_round = (TRound_Function)Round_To_Double_Grid; + break; + + case TT_Round_Super: + CUR.func_round = (TRound_Function)Round_Super; + break; + + case TT_Round_Super_45: + CUR.func_round = (TRound_Function)Round_Super_45; + break; + } + } + + +/******************************************************************* + * + * Function : SetSuperRound + * + * Description : Sets Super Round parameters. + * + * Input : GridPeriod Grid period + * selector SROUND opcode + * + * Output : None. + * + *****************************************************************/ + + static void SetSuperRound( EXEC_OPS TT_F26Dot6 GridPeriod, + Long selector ) + { + switch ( (Int)(selector & 0xC0) ) + { + case 0: + CUR.period = GridPeriod / 2; + break; + + case 0x40: + CUR.period = GridPeriod; + break; + + case 0x80: + CUR.period = GridPeriod * 2; + break; + + /* This opcode is reserved, but... */ + + case 0xC0: + CUR.period = GridPeriod; + break; + } + + switch ( (Int)(selector & 0x30) ) + { + case 0: + CUR.phase = 0; + break; + + case 0x10: + CUR.phase = CUR.period / 4; + break; + + case 0x20: + CUR.phase = CUR.period / 2; + break; + + case 0x30: + CUR.phase = GridPeriod * 3 / 4; + break; + } + + if ( (selector & 0x0F) == 0 ) + CUR.threshold = CUR.period - 1; + else + CUR.threshold = ( (Int)(selector & 0x0F) - 4 ) * CUR.period / 8; + + CUR.period /= 256; + CUR.phase /= 256; + CUR.threshold /= 256; + } + + +/******************************************************************* + * + * Function : Project + * + * Description : Computes the projection of vector given by (v2-v1) + * along the current projection vector. + * + * Input : v1, v2 input vector + * + * Output : Returns distance in F26dot6 format. + * + *****************************************************************/ + + static TT_F26Dot6 Project( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + TT_Int64 T1, T2; + + + MUL_64( v1->x - v2->x, CUR.GS.projVector.x, T1 ); + MUL_64( v1->y - v2->y, CUR.GS.projVector.y, T2 ); + + ADD_64( T1, T2, T1 ); + + return (TT_F26Dot6)DIV_64( T1, 0x4000L ); + } + + +/******************************************************************* + * + * Function : Dual_Project + * + * Description : Computes the projection of the vector given by + * (v2-v1) along the current dual vector. + * + * Input : v1, v2 input vector + * + * Output : Returns distance in F26dot6 format. + * + *****************************************************************/ + + static TT_F26Dot6 Dual_Project( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + TT_Int64 T1, T2; + + + MUL_64( v1->x - v2->x, CUR.GS.dualVector.x, T1 ); + MUL_64( v1->y - v2->y, CUR.GS.dualVector.y, T2 ); + + ADD_64( T1, T2, T1 ); + + return (TT_F26Dot6)DIV_64( T1, 0x4000L ); + } + + +/******************************************************************* + * + * Function : Free_Project + * + * Description : Computes the projection of the vector given by + * (v2-v1) along the current freedom vector. + * + * Input : v1, v2 input vector + * + * Output : Returns distance in F26dot6 format. + * + *****************************************************************/ + + static TT_F26Dot6 Free_Project( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + TT_Int64 T1, T2; + + + MUL_64( v1->x - v2->x, CUR.GS.freeVector.x, T1 ); + MUL_64( v1->y - v2->y, CUR.GS.freeVector.y, T2 ); + + ADD_64( T1, T2, T1 ); + + return (TT_F26Dot6)DIV_64( T1, 0x4000L ); + } + + +/******************************************************************* + * + * Function : Project_x + * + * Input : Vx, Vy input vector + * + * Output : Returns Vx. + * + * Note : Used as a dummy function. + * + *****************************************************************/ + + static TT_F26Dot6 Project_x( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + return (v1->x - v2->x); + } + + +/******************************************************************* + * + * Function : Project_y + * + * Input : Vx, Vy input vector + * + * Output : Returns Vy. + * + * Note : Used as a dummy function. + * + *****************************************************************/ + + static TT_F26Dot6 Project_y( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ) + { + return (v1->y - v2->y); + } + + +/******************************************************************* + * + * Function : Compute_Funcs + * + * Description : Computes the projections and movement function + * pointers according to the current graphics state. + * + * Input : None + * + *****************************************************************/ + + static void Compute_Funcs( EXEC_OP ) + { + if ( CUR.GS.freeVector.x == 0x4000 ) + { + CUR.func_freeProj = (TProject_Function)Project_x; + CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; + } + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + { + CUR.func_freeProj = (TProject_Function)Project_y; + CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; + } + else + { + CUR.func_freeProj = (TProject_Function)Free_Project; + CUR.F_dot_P = (Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + + (Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; + } + } + + CUR.cached_metrics = FALSE; + + if ( CUR.GS.projVector.x == 0x4000 ) + CUR.func_project = (TProject_Function)Project_x; + else + { + if ( CUR.GS.projVector.y == 0x4000 ) + CUR.func_project = (TProject_Function)Project_y; + else + CUR.func_project = (TProject_Function)Project; + } + + if ( CUR.GS.dualVector.x == 0x4000 ) + CUR.func_dualproj = (TProject_Function)Project_x; + else + { + if ( CUR.GS.dualVector.y == 0x4000 ) + CUR.func_dualproj = (TProject_Function)Project_y; + else + CUR.func_dualproj = (TProject_Function)Dual_Project; + } + + CUR.func_move = (TMove_Function)Direct_Move; + + if ( CUR.F_dot_P == 0x40000000L ) + { + if ( CUR.GS.freeVector.x == 0x4000 ) + CUR.func_move = (TMove_Function)Direct_Move_X; + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + CUR.func_move = (TMove_Function)Direct_Move_Y; + } + } + + /* at small sizes, F_dot_P can become too small, resulting */ + /* in overflows and 'spikes' in a number of glyphs like 'w'. */ + + if ( ABS( CUR.F_dot_P ) < 0x4000000L ) + CUR.F_dot_P = 0x40000000L; + + /* Disable cached aspect ratio */ + CUR.metrics.ratio = 0; + } + + +/******************************************************************* + * + * Function : Normalize + * + * Description : Norms a vector + * + * Input : Vx, Vy input vector + * R normed unit vector + * + * Output : Returns FAILURE if a vector parameter is zero. + * + *****************************************************************/ + + static Bool Normalize( EXEC_OPS TT_F26Dot6 Vx, + TT_F26Dot6 Vy, + TT_UnitVector* R ) + { + TT_F26Dot6 W; + Bool S1, S2; + + + if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) + { + Vx *= 0x100; + Vy *= 0x100; + + W = Norm( Vx, Vy ); + + if ( W == 0 ) + { + /* XXX : UNDOCUMENTED! It seems that it's possible to try */ + /* to normalize the vector (0,0). Return immediately */ + return SUCCESS; + } + + R->x = (TT_F2Dot14)TT_MulDiv( Vx, 0x4000L, W ); + R->y = (TT_F2Dot14)TT_MulDiv( Vy, 0x4000L, W ); + + return SUCCESS; + } + + W = Norm( Vx, Vy ); + + Vx = TT_MulDiv( Vx, 0x4000L, W ); + Vy = TT_MulDiv( Vy, 0x4000L, W ); + + W = Vx * Vx + Vy * Vy; + + /* Now, we want that Sqrt( W ) = 0x4000 */ + /* Or 0x1000000 <= W < 0x1004000 */ + + if ( Vx < 0 ) + { + Vx = -Vx; + S1 = TRUE; + } + else + S1 = FALSE; + + if ( Vy < 0 ) + { + Vy = -Vy; + S2 = TRUE; + } + else + S2 = FALSE; + + while ( W < 0x1000000L ) + { + /* We need to increase W, by a minimal amount */ + if ( Vx < Vy ) + Vx++; + else + Vy++; + + W = Vx * Vx + Vy * Vy; + } + + while ( W >= 0x1004000L ) + { + /* We need to decrease W, by a minimal amount */ + if ( Vx < Vy ) + Vx--; + else + Vy--; + + W = Vx * Vx + Vy * Vy; + } + + /* Note that in various cases, we can only */ + /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */ + + if ( S1 ) + Vx = -Vx; + + if ( S2 ) + Vy = -Vy; + + R->x = (TT_F2Dot14)Vx; /* Type conversion */ + R->y = (TT_F2Dot14)Vy; /* Type conversion */ + + return SUCCESS; + } + + +/**************************************************************** + * + * Opcodes + * + ****************************************************************/ + + + static Bool Ins_SxVTL( EXEC_OPS UShort aIdx1, + UShort aIdx2, + Int aOpc, + TT_UnitVector* Vec ) + { + Long A, B, C; + TT_Vector* p1; + TT_Vector* p2; + + + if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || + BOUNDS( aIdx2, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return FAILURE; + } + + p1 = CUR.zp1.cur + aIdx2; + p2 = CUR.zp2.cur + aIdx1; + + A = p1->x - p2->x; + B = p1->y - p2->y; + + if ( (aOpc & 1) != 0 ) + { + C = B; /* CounterClockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, Vec ); + return SUCCESS; + } + + +/* When not using the big switch statements, the interpreter uses a */ +/* call table defined later below in this source. Each opcode must */ +/* thus have a corresponding function, even trivial ones. */ +/* */ +/* They're all defined there. */ + +#define DO_SVTCA \ + { \ + Short A, B; \ + \ + \ + A = (Short)(CUR.opcode & 1) << 14; \ + B = A ^ (Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.projVector.x = A; \ + CUR.GS.dualVector.x = A; \ + \ + CUR.GS.freeVector.y = B; \ + CUR.GS.projVector.y = B; \ + CUR.GS.dualVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTCA \ + { \ + Short A, B; \ + \ + \ + A = (Short)(CUR.opcode & 1) << 14; \ + B = A ^ (Short)0x4000; \ + \ + CUR.GS.projVector.x = A; \ + CUR.GS.dualVector.x = A; \ + \ + CUR.GS.projVector.y = B; \ + CUR.GS.dualVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTCA \ + { \ + Short A, B; \ + \ + \ + A = (Short)(CUR.opcode & 1) << 14; \ + B = A ^ (Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.freeVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTL \ + if ( INS_SxVTL( (UShort)args[1], \ + (UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.projVector) == SUCCESS ) \ + { \ + CUR.GS.dualVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTL \ + if ( INS_SxVTL( (UShort)args[1], \ + (UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.freeVector) == SUCCESS ) \ + COMPUTE_Funcs(); + + +#define DO_SFVTPV \ + CUR.GS.freeVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); + + +#define DO_SPVFS \ + { \ + Short S; \ + Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (Short)args[1]; \ + Y = (Long)S; \ + S = (Short)args[0]; \ + X = (Long)S; \ + \ + NORMalize( X, Y, &CUR.GS.projVector ); \ + \ + CUR.GS.dualVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVFS \ + { \ + Short S; \ + Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (Short)args[1]; \ + Y = (Long)S; \ + S = (Short)args[0]; \ + X = S; \ + \ + NORMalize( X, Y, &CUR.GS.freeVector ); \ + COMPUTE_Funcs(); \ + } + + +#define DO_GPV \ + args[0] = CUR.GS.projVector.x; \ + args[1] = CUR.GS.projVector.y; + + +#define DO_GFV \ + args[0] = CUR.GS.freeVector.x; \ + args[1] = CUR.GS.freeVector.y; + + +#define DO_SRP0 \ + CUR.GS.rp0 = (UShort)args[0]; + + +#define DO_SRP1 \ + CUR.GS.rp1 = (UShort)args[0]; + + +#define DO_SRP2 \ + CUR.GS.rp2 = (UShort)args[0]; + + +#define DO_RTHG \ + CUR.GS.round_state = TT_Round_To_Half_Grid; \ + CUR.func_round = (TRound_Function)Round_To_Half_Grid; + + +#define DO_RTG \ + CUR.GS.round_state = TT_Round_To_Grid; \ + CUR.func_round = (TRound_Function)Round_To_Grid; + + +#define DO_RTDG \ + CUR.GS.round_state = TT_Round_To_Double_Grid; \ + CUR.func_round = (TRound_Function)Round_To_Double_Grid; + + +#define DO_RUTG \ + CUR.GS.round_state = TT_Round_Up_To_Grid; \ + CUR.func_round = (TRound_Function)Round_Up_To_Grid; + + +#define DO_RDTG \ + CUR.GS.round_state = TT_Round_Down_To_Grid; \ + CUR.func_round = (TRound_Function)Round_Down_To_Grid; + + +#define DO_ROFF \ + CUR.GS.round_state = TT_Round_Off; \ + CUR.func_round = (TRound_Function)Round_None; + + +#define DO_SROUND \ + SET_SuperRound( 0x4000L, args[0] ); \ + CUR.GS.round_state = TT_Round_Super; \ + CUR.func_round = (TRound_Function)Round_Super; + + +#define DO_S45ROUND \ + SET_SuperRound( 0x2D41L, args[0] ); \ + CUR.GS.round_state = TT_Round_Super_45; \ + CUR.func_round = (TRound_Function)Round_Super_45; + + +#define DO_SLOOP \ + if ( args[0] < 0 ) \ + CUR.error = TT_Err_Bad_Argument; \ + else \ + CUR.GS.loop = args[0]; + + +#define DO_SMD \ + CUR.GS.minimum_distance = (TT_F26Dot6)args[0]; + + +#define DO_SCVTCI \ + CUR.GS.control_value_cutin = (TT_F26Dot6)args[0]; + + +#define DO_SSWCI \ + CUR.GS.single_width_cutin = (TT_F26Dot6)args[0]; + + + /* XXX : UNDOCUMENTED! or bug in the Windows engine? */ + /* */ + /* It seems that the value that is read here is */ + /* expressed in 16.16 format, rather than in */ + /* font units.. */ + /* */ +#define DO_SSW \ + CUR.GS.single_width_value = (TT_F26Dot6)(args[0] >> 10); + + +#define DO_FLIPON \ + CUR.GS.auto_flip = TRUE; + + +#define DO_FLIPOFF \ + CUR.GS.auto_flip = FALSE; + + +#define DO_SDB \ + CUR.GS.delta_base = (Short)args[0]; + + +#define DO_SDS \ + CUR.GS.delta_shift = (Short)args[0]; + + +#define DO_MD /* nothing */ + + +#define DO_MPPEM \ + args[0] = CURRENT_Ppem(); + + +#define DO_MPS \ + args[0] = CUR.metrics.pointSize; + + +#define DO_DUP \ + args[1] = args[0]; + + +#define DO_CLEAR \ + CUR.new_top = 0; + + +#define DO_SWAP \ + { \ + Long L; \ + \ + L = args[0]; \ + args[0] = args[1]; \ + args[1] = L; \ + } + + +#define DO_DEPTH \ + args[0] = CUR.top; + + +#define DO_CINDEX \ + { \ + Long L; \ + \ + \ + L = args[0]; \ + \ + if ( L <= 0 || L > CUR.args ) \ + CUR.error = TT_Err_Invalid_Reference; \ + else \ + args[0] = CUR.stack[CUR.args - L]; \ + } + + +#define DO_JROT \ + if ( args[1] != 0 ) \ + { \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; \ + } + + +#define DO_JMPR \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; + + +#define DO_JROF \ + if ( args[1] == 0 ) \ + { \ + CUR.IP += args[0]; \ + CUR.step_ins = FALSE; \ + } + + +#define DO_LT \ + args[0] = (args[0] < args[1]); + + +#define DO_LTEQ \ + args[0] = (args[0] <= args[1]); + + +#define DO_GT \ + args[0] = (args[0] > args[1]); + + +#define DO_GTEQ \ + args[0] = (args[0] >= args[1]); + + +#define DO_EQ \ + args[0] = (args[0] == args[1]); + + +#define DO_NEQ \ + args[0] = (args[0] != args[1]); + + +#define DO_ODD \ + args[0] = ( (CUR_Func_round( args[0], 0 ) & 127) == 64 ); + + +#define DO_EVEN \ + args[0] = ( (CUR_Func_round( args[0], 0 ) & 127) == 0 ); + + +#define DO_AND \ + args[0] = ( args[0] && args[1] ); + + +#define DO_OR \ + args[0] = ( args[0] || args[1] ); + + +#define DO_NOT \ + args[0] = !args[0]; + + +#define DO_ADD \ + args[0] += args[1]; + + +#define DO_SUB \ + args[0] -= args[1]; + + +#define DO_DIV \ + if ( args[1] == 0 ) \ + CUR.error = TT_Err_Divide_By_Zero; \ + else \ + args[0] = TT_MulDiv( args[0], 64L, args[1] ); + + +#define DO_MUL \ + args[0] = TT_MulDiv( args[0], args[1], 64L ); + + +#define DO_ABS \ + args[0] = ABS( args[0] ); + + +#define DO_NEG \ + args[0] = -args[0]; + + +#define DO_FLOOR \ + args[0] &= -64; + + +#define DO_CEILING \ + args[0] = (args[0] + 63) & (-64); + + +#define DO_RS \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + else \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR.storage[I]; \ + } + + +#define DO_WS \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.storage[I] = args[1]; \ + } + + + +#define DO_RCVT \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + else \ + args[0] = 0; \ + } \ + else \ + args[0] = CUR_Func_read_cvt(I); \ + } + + +#define DO_WCVTP \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR_Func_write_cvt( I, args[1] ); \ + } + + +#define DO_WCVTF \ + { \ + ULong I = (ULong)args[0]; \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.cvt[I] = FUnits_To_Pixels( EXEC_ARGS (Short)args[1] ); \ + } + + +#define DO_DEBUG \ + CUR.error = TT_Err_Debug_OpCode; + + +#define DO_ROUND \ + args[0] = CUR_Func_round( args[0], \ + CUR.metrics.compensations[CUR.opcode-0x68] ); + + +#define DO_NROUND \ + args[0] = Round_None( EXEC_ARGS \ + args[0], \ + CUR.metrics.compensations[CUR.opcode - 0x6C] ); + + +#define DO_MAX \ + if ( args[1] > args[0] ) \ + args[0] = args[1]; + + +#define DO_MIN \ + if ( args[1] < args[0] ) \ + args[0] = args[1]; + + +#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH + + +#undef ARRAY_BOUND_ERROR +#define ARRAY_BOUND_ERROR \ + { \ + CUR.error = TT_Err_Invalid_Reference; \ + return; \ + } + + +/*******************************************/ +/* SVTCA[a] : Set F and P vectors to axis */ +/* CodeRange : $00-$01 */ +/* Stack : --> */ + + static void Ins_SVTCA( INS_ARG ) + { + DO_SVTCA + } + + +/*******************************************/ +/* SPVTCA[a] : Set PVector to Axis */ +/* CodeRange : $02-$03 */ +/* Stack : --> */ + + static void Ins_SPVTCA( INS_ARG ) + { + DO_SPVTCA + } + + +/*******************************************/ +/* SFVTCA[a] : Set FVector to Axis */ +/* CodeRange : $04-$05 */ +/* Stack : --> */ + + static void Ins_SFVTCA( INS_ARG ) + { + DO_SFVTCA + } + +/*******************************************/ +/* SPVTL[a] : Set PVector to Line */ +/* CodeRange : $06-$07 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_SPVTL( INS_ARG ) + { + DO_SPVTL + } + + +/*******************************************/ +/* SFVTL[a] : Set FVector to Line */ +/* CodeRange : $08-$09 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_SFVTL( INS_ARG ) + { + DO_SFVTL + } + + +/*******************************************/ +/* SFVTPV[] : Set FVector to PVector */ +/* CodeRange : $0E */ +/* Stack : --> */ + + static void Ins_SFVTPV( INS_ARG ) + { + DO_SFVTPV + } + + +/*******************************************/ +/* SPVFS[] : Set PVector From Stack */ +/* CodeRange : $0A */ +/* Stack : f2.14 f2.14 --> */ + + static void Ins_SPVFS( INS_ARG ) + { + DO_SPVFS + } + + +/*******************************************/ +/* SFVFS[] : Set FVector From Stack */ +/* CodeRange : $0B */ +/* Stack : f2.14 f2.14 --> */ + + static void Ins_SFVFS( INS_ARG ) + { + DO_SFVFS + } + + +/*******************************************/ +/* GPV[] : Get Projection Vector */ +/* CodeRange : $0C */ +/* Stack : ef2.14 --> ef2.14 */ + + static void Ins_GPV( INS_ARG ) + { + DO_GPV + } + + +/*******************************************/ +/* GFV[] : Get Freedom Vector */ +/* CodeRange : $0D */ +/* Stack : ef2.14 --> ef2.14 */ + + static void Ins_GFV( INS_ARG ) + { + DO_GFV + } + + +/*******************************************/ +/* SRP0[] : Set Reference Point 0 */ +/* CodeRange : $10 */ +/* Stack : uint32 --> */ + + static void Ins_SRP0( INS_ARG ) + { + DO_SRP0 + } + + +/*******************************************/ +/* SRP1[] : Set Reference Point 1 */ +/* CodeRange : $11 */ +/* Stack : uint32 --> */ + + static void Ins_SRP1( INS_ARG ) + { + DO_SRP1 + } + + +/*******************************************/ +/* SRP2[] : Set Reference Point 2 */ +/* CodeRange : $12 */ +/* Stack : uint32 --> */ + + static void Ins_SRP2( INS_ARG ) + { + DO_SRP2 + } + + +/*******************************************/ +/* RTHG[] : Round To Half Grid */ +/* CodeRange : $19 */ +/* Stack : --> */ + + static void Ins_RTHG( INS_ARG ) + { + DO_RTHG + } + + +/*******************************************/ +/* RTG[] : Round To Grid */ +/* CodeRange : $18 */ +/* Stack : --> */ + + static void Ins_RTG( INS_ARG ) + { + DO_RTG + } + + +/*******************************************/ +/* RTDG[] : Round To Double Grid */ +/* CodeRange : $3D */ +/* Stack : --> */ + + static void Ins_RTDG( INS_ARG ) + { + DO_RTDG + } + + +/*******************************************/ +/* RUTG[] : Round Up To Grid */ +/* CodeRange : $7C */ +/* Stack : --> */ + + static void Ins_RUTG( INS_ARG ) + { + DO_RUTG + } + + +/*******************************************/ +/* RDTG[] : Round Down To Grid */ +/* CodeRange : $7D */ +/* Stack : --> */ + + static void Ins_RDTG( INS_ARG ) + { + DO_RDTG + } + + +/*******************************************/ +/* ROFF[] : Round OFF */ +/* CodeRange : $7A */ +/* Stack : --> */ + + static void Ins_ROFF( INS_ARG ) + { + DO_ROFF + } + + +/*******************************************/ +/* SROUND[] : Super ROUND */ +/* CodeRange : $76 */ +/* Stack : Eint8 --> */ + + static void Ins_SROUND( INS_ARG ) + { + DO_SROUND + } + + +/*******************************************/ +/* S45ROUND[]: Super ROUND 45 degrees */ +/* CodeRange : $77 */ +/* Stack : uint32 --> */ + + static void Ins_S45ROUND( INS_ARG ) + { + DO_S45ROUND + } + + +/*******************************************/ +/* SLOOP[] : Set LOOP variable */ +/* CodeRange : $17 */ +/* Stack : int32? --> */ + + static void Ins_SLOOP( INS_ARG ) + { + DO_SLOOP + } + + +/*******************************************/ +/* SMD[] : Set Minimum Distance */ +/* CodeRange : $1A */ +/* Stack : f26.6 --> */ + + static void Ins_SMD( INS_ARG ) + { + DO_SMD + } + + +/**********************************************/ +/* SCVTCI[] : Set Control Value Table Cut In */ +/* CodeRange : $1D */ +/* Stack : f26.6 --> */ + + static void Ins_SCVTCI( INS_ARG ) + { + DO_SCVTCI + } + + +/**********************************************/ +/* SSWCI[] : Set Single Width Cut In */ +/* CodeRange : $1E */ +/* Stack : f26.6 --> */ + + static void Ins_SSWCI( INS_ARG ) + { + DO_SSWCI + } + + +/**********************************************/ +/* SSW[] : Set Single Width */ +/* CodeRange : $1F */ +/* Stack : int32? --> */ + + static void Ins_SSW( INS_ARG ) + { + DO_SSW + } + + +/**********************************************/ +/* FLIPON[] : Set Auto_flip to On */ +/* CodeRange : $4D */ +/* Stack : --> */ + + static void Ins_FLIPON( INS_ARG ) + { + DO_FLIPON + } + + +/**********************************************/ +/* FLIPOFF[] : Set Auto_flip to Off */ +/* CodeRange : $4E */ +/* Stack : --> */ + + static void Ins_FLIPOFF( INS_ARG ) + { + DO_FLIPOFF + } + + +/**********************************************/ +/* SANGW[] : Set Angle Weight */ +/* CodeRange : $7E */ +/* Stack : uint32 --> */ + + static void Ins_SANGW( INS_ARG ) + { + /* instruction not supported anymore */ + } + + +/**********************************************/ +/* SDB[] : Set Delta Base */ +/* CodeRange : $5E */ +/* Stack : uint32 --> */ + + static void Ins_SDB( INS_ARG ) + { + DO_SDB + } + + +/**********************************************/ +/* SDS[] : Set Delta Shift */ +/* CodeRange : $5F */ +/* Stack : uint32 --> */ + + static void Ins_SDS( INS_ARG ) + { + DO_SDS + } + + +/**********************************************/ +/* MPPEM[] : Measure Pixel Per EM */ +/* CodeRange : $4B */ +/* Stack : --> Euint16 */ + + static void Ins_MPPEM( INS_ARG ) + { + DO_MPPEM + } + + +/**********************************************/ +/* MPS[] : Measure PointSize */ +/* CodeRange : $4C */ +/* Stack : --> Euint16 */ + + static void Ins_MPS( INS_ARG ) + { + DO_MPS + } + +/*******************************************/ +/* DUP[] : Duplicate top stack element */ +/* CodeRange : $20 */ +/* Stack : StkElt --> StkElt StkElt */ + + static void Ins_DUP( INS_ARG ) + { + DO_DUP + } + + +/*******************************************/ +/* POP[] : POPs the stack's top elt. */ +/* CodeRange : $21 */ +/* Stack : StkElt --> */ + + static void Ins_POP( INS_ARG ) + { + /* nothing to do */ + } + + +/*******************************************/ +/* CLEAR[] : Clear the entire stack */ +/* CodeRange : $22 */ +/* Stack : StkElt... --> */ + + static void Ins_CLEAR( INS_ARG ) + { + DO_CLEAR + } + + +/*******************************************/ +/* SWAP[] : Swap the top two elements */ +/* CodeRange : $23 */ +/* Stack : 2 * StkElt --> 2 * StkElt */ + + static void Ins_SWAP( INS_ARG ) + { + DO_SWAP + } + + +/*******************************************/ +/* DEPTH[] : return the stack depth */ +/* CodeRange : $24 */ +/* Stack : --> uint32 */ + + static void Ins_DEPTH( INS_ARG ) + { + DO_DEPTH + } + + +/*******************************************/ +/* CINDEX[] : copy indexed element */ +/* CodeRange : $25 */ +/* Stack : int32 --> StkElt */ + + static void Ins_CINDEX( INS_ARG ) + { + DO_CINDEX + } + + +/*******************************************/ +/* EIF[] : End IF */ +/* CodeRange : $59 */ +/* Stack : --> */ + + static void Ins_EIF( INS_ARG ) + { + /* nothing to do */ + } + + +/*******************************************/ +/* JROT[] : Jump Relative On True */ +/* CodeRange : $78 */ +/* Stack : StkElt int32 --> */ + + static void Ins_JROT( INS_ARG ) + { + DO_JROT + } + + +/*******************************************/ +/* JMPR[] : JuMP Relative */ +/* CodeRange : $1C */ +/* Stack : int32 --> */ + + static void Ins_JMPR( INS_ARG ) + { + DO_JMPR + } + + +/*******************************************/ +/* JROF[] : Jump Relative On False */ +/* CodeRange : $79 */ +/* Stack : StkElt int32 --> */ + + static void Ins_JROF( INS_ARG ) + { + DO_JROF + } + + +/*******************************************/ +/* LT[] : Less Than */ +/* CodeRange : $50 */ +/* Stack : int32? int32? --> bool */ + + static void Ins_LT( INS_ARG ) + { + DO_LT + } + + +/*******************************************/ +/* LTEQ[] : Less Than or EQual */ +/* CodeRange : $51 */ +/* Stack : int32? int32? --> bool */ + + static void Ins_LTEQ( INS_ARG ) + { + DO_LTEQ + } + + +/*******************************************/ +/* GT[] : Greater Than */ +/* CodeRange : $52 */ +/* Stack : int32? int32? --> bool */ + + static void Ins_GT( INS_ARG ) + { + DO_GT + } + + +/*******************************************/ +/* GTEQ[] : Greater Than or EQual */ +/* CodeRange : $53 */ +/* Stack : int32? int32? --> bool */ + + static void Ins_GTEQ( INS_ARG ) + { + DO_GTEQ + } + + +/*******************************************/ +/* EQ[] : EQual */ +/* CodeRange : $54 */ +/* Stack : StkElt StkElt --> bool */ + + static void Ins_EQ( INS_ARG ) + { + DO_EQ + } + + +/*******************************************/ +/* NEQ[] : Not EQual */ +/* CodeRange : $55 */ +/* Stack : StkElt StkElt --> bool */ + + static void Ins_NEQ( INS_ARG ) + { + DO_NEQ + } + + +/*******************************************/ +/* ODD[] : Odd */ +/* CodeRange : $56 */ +/* Stack : f26.6 --> bool */ + + static void Ins_ODD( INS_ARG ) + { + DO_ODD + } + + +/*******************************************/ +/* EVEN[] : Even */ +/* CodeRange : $57 */ +/* Stack : f26.6 --> bool */ + + static void Ins_EVEN( INS_ARG ) + { + DO_EVEN + } + + +/*******************************************/ +/* AND[] : logical AND */ +/* CodeRange : $5A */ +/* Stack : uint32 uint32 --> uint32 */ + + static void Ins_AND( INS_ARG ) + { + DO_AND + } + + +/*******************************************/ +/* OR[] : logical OR */ +/* CodeRange : $5B */ +/* Stack : uint32 uint32 --> uint32 */ + + static void Ins_OR( INS_ARG ) + { + DO_OR + } + + +/*******************************************/ +/* NOT[] : logical NOT */ +/* CodeRange : $5C */ +/* Stack : StkElt --> uint32 */ + + static void Ins_NOT( INS_ARG ) + { + DO_NOT + } + + +/*******************************************/ +/* ADD[] : ADD */ +/* CodeRange : $60 */ +/* Stack : f26.6 f26.6 --> f26.6 */ + + static void Ins_ADD( INS_ARG ) + { + DO_ADD + } + + +/*******************************************/ +/* SUB[] : SUBstract */ +/* CodeRange : $61 */ +/* Stack : f26.6 f26.6 --> f26.6 */ + + static void Ins_SUB( INS_ARG ) + { + DO_SUB + } + + +/*******************************************/ +/* DIV[] : DIVide */ +/* CodeRange : $62 */ +/* Stack : f26.6 f26.6 --> f26.6 */ + + static void Ins_DIV( INS_ARG ) + { + DO_DIV + } + + +/*******************************************/ +/* MUL[] : MULtiply */ +/* CodeRange : $63 */ +/* Stack : f26.6 f26.6 --> f26.6 */ + + static void Ins_MUL( INS_ARG ) + { + DO_MUL + } + + +/*******************************************/ +/* ABS[] : ABSolute value */ +/* CodeRange : $64 */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_ABS( INS_ARG ) + { + DO_ABS + } + + +/*******************************************/ +/* NEG[] : NEGate */ +/* CodeRange : $65 */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_NEG( INS_ARG ) + { + DO_NEG + } + + +/*******************************************/ +/* FLOOR[] : FLOOR */ +/* CodeRange : $66 */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_FLOOR( INS_ARG ) + { + DO_FLOOR + } + + +/*******************************************/ +/* CEILING[] : CEILING */ +/* CodeRange : $67 */ +/* f26.6 --> f26.6 */ + + static void Ins_CEILING( INS_ARG ) + { + DO_CEILING + } + +/*******************************************/ +/* RS[] : Read Store */ +/* CodeRange : $43 */ +/* Stack : uint32 --> uint32 */ + + static void Ins_RS( INS_ARG ) + { + DO_RS + } + + +/*******************************************/ +/* WS[] : Write Store */ +/* CodeRange : $42 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_WS( INS_ARG ) + { + DO_WS + } + + +/*******************************************/ +/* WCVTP[] : Write CVT in Pixel units */ +/* CodeRange : $44 */ +/* Stack : f26.6 uint32 --> */ + + static void Ins_WCVTP( INS_ARG ) + { + DO_WCVTP + } + + +/*******************************************/ +/* WCVTF[] : Write CVT in FUnits */ +/* CodeRange : $70 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_WCVTF( INS_ARG ) + { + DO_WCVTF + } + + +/*******************************************/ +/* RCVT[] : Read CVT */ +/* CodeRange : $45 */ +/* Stack : uint32 --> f26.6 */ + + static void Ins_RCVT( INS_ARG ) + { + DO_RCVT + } + + +/********************************************/ +/* AA[] : Adjust Angle */ +/* CodeRange : $7F */ +/* Stack : uint32 --> */ + + static void Ins_AA( INS_ARG ) + { + /* Intentional - no longer supported */ + } + + +/********************************************/ +/* DEBUG[] : DEBUG. Unsupported */ +/* CodeRange : $4F */ +/* Stack : uint32 --> */ + +/* NOTE : The original instruction pops a value from the stack */ + + static void Ins_DEBUG( INS_ARG ) + { + DO_DEBUG + } + +/*******************************************/ +/* ROUND[ab] : ROUND value */ +/* CodeRange : $68-$6B */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_ROUND( INS_ARG ) + { + DO_ROUND + } + +/*******************************************/ +/* NROUND[ab]: No ROUNDing of value */ +/* CodeRange : $6C-$6F */ +/* Stack : f26.6 --> f26.6 */ + + static void Ins_NROUND( INS_ARG ) + { + DO_NROUND + } + + + +/*******************************************/ +/* MAX[] : MAXimum */ +/* CodeRange : $68 */ +/* Stack : int32? int32? --> int32 */ + + static void Ins_MAX( INS_ARG ) + { + DO_MAX + } + + +/*******************************************/ +/* MIN[] : MINimum */ +/* CodeRange : $69 */ +/* Stack : int32? int32? --> int32 */ + + static void Ins_MIN( INS_ARG ) + { + DO_MIN + } + + +#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + +/* The following functions are called as is within the switch statement */ + +/*******************************************/ +/* MINDEX[] : move indexed element */ +/* CodeRange : $26 */ +/* Stack : int32? --> StkElt */ + + static void Ins_MINDEX( INS_ARG ) + { + Long L, K; + + + L = args[0]; + + if ( L <= 0 || L > CUR.args ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + K = CUR.stack[CUR.args - L]; + + MEM_Move( (&CUR.stack[CUR.args - L ]), + (&CUR.stack[CUR.args - L + 1]), + (L - 1) * sizeof ( Long ) ); + + CUR.stack[CUR.args - 1] = K; + } + + +/*******************************************/ +/* ROLL[] : roll top three elements */ +/* CodeRange : $8A */ +/* Stack : 3 * StkElt --> 3 * StkElt */ + + static void Ins_ROLL( INS_ARG ) + { + Long A, B, C; + + + A = args[2]; + B = args[1]; + C = args[0]; + + args[2] = C; + args[1] = A; + args[0] = B; + } + + + +/****************************************************************/ +/* */ +/* MANAGING THE FLOW OF CONTROL */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + + static Bool SkipCode( EXEC_OP ) + { + CUR.IP += CUR.length; + + if ( CUR.IP < CUR.codeSize ) + if ( CALC_Length() == SUCCESS ) + return SUCCESS; + + CUR.error = TT_Err_Code_Overflow; + return FAILURE; + } + + +/*******************************************/ +/* IF[] : IF test */ +/* CodeRange : $58 */ +/* Stack : StkElt --> */ + + static void Ins_IF( INS_ARG ) + { + Int nIfs; + Bool Out; + + + if ( args[0] != 0 ) + return; + + nIfs = 1; + Out = 0; + + do + { + if ( SKIP_Code() == FAILURE ) + return; + + switch ( CUR.opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + + case 0x1b: /* ELSE */ + Out = (nIfs == 1); + break; + + case 0x59: /* EIF */ + nIfs--; + Out = (nIfs == 0); + break; + } + } while ( Out == 0 ); + } + + +/*******************************************/ +/* ELSE[] : ELSE */ +/* CodeRange : $1B */ +/* Stack : --> */ + + static void Ins_ELSE( INS_ARG ) + { + Int nIfs; + + + nIfs = 1; + + do + { + if ( SKIP_Code() == FAILURE ) + return; + + switch ( CUR.opcode ) + { + case 0x58: /* IF */ + nIfs++; + break; + + case 0x59: /* EIF */ + nIfs--; + break; + } + } while ( nIfs != 0 ); + } + + +/****************************************************************/ +/* */ +/* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + + static PDefRecord Locate_FDef( EXEC_OPS Int n, Bool new_def ) + { + PDefRecord def; + UShort hash; + UShort cnt; + + /* The function table is interpreted as a simple hash table */ + /* with indexes computed modulo maxFDefs and the linear search */ + /* of free cells in the case of a collision. */ + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font fit into 0..maxFDefs - 1 range and the lookup is */ + /* reduced to a single step. */ + + /* Minor optimization. */ + if ( !new_def && ( n < 0 || n > CUR.maxFunc ) ) + return NULL; + + for ( cnt = 0; cnt < CUR.maxFDefs; ++cnt ) + { + hash = ( (UShort)n + cnt ) % CUR.maxFDefs; + def = &CUR.FDefs[ hash ]; + if ( !def->Active ) + return new_def ? def : NULL; + if ( def->Opc == n ) + return def; + } + + /* The table is full and the entry has not been found. */ + return NULL; + } + + +/*******************************************/ +/* FDEF[] : Function DEFinition */ +/* CodeRange : $2C */ +/* Stack : uint32 --> */ + + static void Ins_FDEF( INS_ARG ) + { + Int n; + PDefRecord def; + + + /* check that there is enough room */ + if ( CUR.numFDefs >= CUR.maxFDefs ) + { + /* We could introduce a new error message, but we're too close */ + /* from the release to change all the 'po' files again.. */ + CUR.error = TT_Err_Too_Many_Ins; + return; + } + + n = (Int)args[0]; + if ( n < 0 || (ULong)n != args[0] ) + { + /* Gotcha. Function index is uint32 according to the specs */ + /* but TDefRecord.Opc is defined as Int. We cannot store */ + /* the definition of this function. */ + CUR.error = TT_Err_Bad_Argument; + return; + } + + def = Locate_FDef( EXEC_ARGS n, TRUE ); + if ( !def ) + { + /* Oh, oh. Something is wrong. Locate_FDef should never fail here. */ + CUR.error = TT_Err_Too_Many_Ins; + return; + } + + /* Some font programs are broken enough to redefine functions! */ + if ( !def->Active ) + CUR.numFDefs++; + + def->Range = CUR.curRange; + def->Opc = n; + def->Start = CUR.IP + 1; + def->Active = TRUE; + + if ( n > CUR.maxFunc ) + CUR.maxFunc = n; + + /* Now skip the whole function definition. */ + /* We don't allow nested IDEFS & FDEFs. */ + + while ( SKIP_Code() == SUCCESS ) + { + switch ( CUR.opcode ) + { + case 0x89: /* IDEF */ + case 0x2c: /* FDEF */ + CUR.error = TT_Err_Nested_DEFS; + return; + case 0x2d: /* ENDF */ + return; + } + } + } + + +/*******************************************/ +/* ENDF[] : END Function definition */ +/* CodeRange : $2D */ +/* Stack : --> */ + + static void Ins_ENDF( INS_ARG ) + { + PCallRecord pRec; + + + if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ + { + CUR.error = TT_Err_ENDF_In_Exec_Stream; + return; + } + + CUR.callTop--; + + pRec = &CUR.callStack[CUR.callTop]; + + pRec->Cur_Count--; + + CUR.step_ins = FALSE; + + if ( pRec->Cur_Count > 0 ) + { + CUR.callTop++; + CUR.IP = pRec->Cur_Restart; + } + else + /* Loop through the current function */ + INS_Goto_CodeRange( pRec->Caller_Range, + pRec->Caller_IP ); + + /* Exit the current call frame. */ + + /* NOTE: When the last intruction of a program */ + /* is a CALL or LOOPCALL, the return address */ + /* is always out of the code range. This is */ + /* a valid address, and it's why we do not test */ + /* the result of Ins_Goto_CodeRange() here! */ + } + + +/*******************************************/ +/* CALL[] : CALL function */ +/* CodeRange : $2B */ +/* Stack : uint32? --> */ + + static void Ins_CALL( INS_ARG ) + { + Int n; + PDefRecord def; + PCallRecord pCrec; + + + n = (Int)args[0]; + def = Locate_FDef( EXEC_ARGS n, FALSE ); + if ( !def ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* check call stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = 1; + pCrec->Cur_Restart = def->Start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->Range, + def->Start ); + + CUR.step_ins = FALSE; + } + + +/*******************************************/ +/* LOOPCALL[]: LOOP and CALL function */ +/* CodeRange : $2A */ +/* Stack : uint32? Eint16? --> */ + + static void Ins_LOOPCALL( INS_ARG ) + { + Int n; + Long count; + PDefRecord def; + PCallRecord pTCR; + + + n = (Int)args[1]; + def = Locate_FDef( EXEC_ARGS n, FALSE ); + if ( !def ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + count = (Long)args[0]; + if ( count <= 0 ) + return; + + pTCR = &CUR.callStack[CUR.callTop]; + + pTCR->Caller_Range = CUR.curRange; + pTCR->Caller_IP = CUR.IP + 1; + pTCR->Cur_Count = count; + pTCR->Cur_Restart = def->Start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->Range, + def->Start ); + + CUR.step_ins = FALSE; + } + + +/*******************************************/ +/* IDEF[] : Instruction DEFinition */ +/* CodeRange : $89 */ +/* Stack : Eint8 --> */ + + static void Ins_IDEF( INS_ARG ) + { + Byte opcode; + PDefRecord def; + PDefRecord limit; + + + opcode = (Byte)args[0]; + + /* First of all, look for the same instruction in our table */ + def = CUR.IDefs; + limit = def + CUR.numIDefs; + for ( ; def < limit; def++ ) + if ( def->Opc == opcode ) + break; + + if ( def == limit ) + { + /* check that there is enough room for a new instruction */ + if ( CUR.numIDefs >= CUR.maxIDefs ) + { + /* XXX Bad error code. See FDEF[]. */ + CUR.error = TT_Err_Too_Many_Ins; + return; + } + CUR.numIDefs++; + } + + def->Opc = opcode; + def->Start = CUR.IP + 1; + def->Range = CUR.curRange; + def->Active = TRUE; + + if ( opcode > CUR.maxIns ) + CUR.maxIns = opcode; + + /* Now skip the whole function definition */ + /* We don't allow nested IDEFs & FDEFs. */ + + while ( SKIP_Code() == SUCCESS ) + { + switch ( CUR.opcode ) + { + case 0x89: /* IDEF */ + case 0x2c: /* FDEF */ + CUR.error = TT_Err_Nested_DEFS; + return; + case 0x2d: /* ENDF */ + return; + } + } + } + + +/****************************************************************/ +/* */ +/* PUSHING DATA ONTO THE INTERPRETER STACK */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + +/*******************************************/ +/* NPUSHB[] : PUSH N Bytes */ +/* CodeRange : $40 */ +/* Stack : --> uint32... */ + + static void Ins_NPUSHB( INS_ARG ) + { + UShort L, K; + + + L = (UShort)CUR.code[CUR.IP + 1]; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + for ( K = 1; K <= L; K++ ) + args[K - 1] = CUR.code[CUR.IP + K + 1]; + + CUR.new_top += L; + } + + +/*******************************************/ +/* NPUSHW[] : PUSH N Words */ +/* CodeRange : $41 */ +/* Stack : --> int32... */ + + static void Ins_NPUSHW( INS_ARG ) + { + UShort L, K; + + + L = (UShort)CUR.code[CUR.IP + 1]; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + CUR.IP += 2; + + for ( K = 0; K < L; K++ ) + args[K] = GET_ShortIns(); + + CUR.step_ins = FALSE; + CUR.new_top += L; + } + + +/*******************************************/ +/* PUSHB[abc]: PUSH Bytes */ +/* CodeRange : $B0-$B7 */ +/* Stack : --> uint32... */ + + static void Ins_PUSHB( INS_ARG ) + { + UShort L, K; + + + L = (UShort)CUR.opcode - 0xB0 + 1; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + for ( K = 1; K <= L; K++ ) + args[K - 1] = CUR.code[CUR.IP + K]; + } + + +/*******************************************/ +/* PUSHW[abc]: PUSH Words */ +/* CodeRange : $B8-$BF */ +/* Stack : --> int32... */ + + static void Ins_PUSHW( INS_ARG ) + { + UShort L, K; + + + L = (UShort)CUR.opcode - 0xB8 + 1; + + if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + CUR.IP++; + + for ( K = 0; K < L; K++ ) + args[K] = GET_ShortIns(); + + CUR.step_ins = FALSE; + } + + + +/****************************************************************/ +/* */ +/* MANAGING THE GRAPHICS STATE */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + +/**********************************************/ +/* GC[a] : Get Coordinate projected onto */ +/* CodeRange : $46-$47 */ +/* Stack : uint32 --> f26.6 */ + +/* BULLSHIT: Measures from the original glyph must be taken */ +/* along the dual projection vector! */ + + static void Ins_GC( INS_ARG ) + { + ULong L; + TT_F26Dot6 R; + + + L = (ULong)args[0]; + + if ( BOUNDS( L, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + else + R = 0; + } + else + { + if ( CUR.opcode & 1 ) + R = CUR_Func_dualproj( CUR.zp2.org + L, NULL_Vector ); + else + R = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector ); + } + + args[0] = R; + } + + +/**********************************************/ +/* SCFS[] : Set Coordinate From Stack */ +/* CodeRange : $48 */ +/* Stack : f26.6 uint32 --> */ +/* */ +/* Formula: */ +/* */ +/* OA := OA + ( value - OA.p )/( f.p ) * f */ +/* */ + + static void Ins_SCFS( INS_ARG ) + { + Long K; + UShort L; + + + L = (UShort)args[0]; + + if ( BOUNDS( L, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + K = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector ); + + CUR_Func_move( &CUR.zp2, L, args[1] - K ); + + /* not part of the specs, but here for safety */ + + if ( CUR.GS.gep2 == 0 ) + CUR.zp2.org[L] = CUR.zp2.cur[L]; + } + + +/**********************************************/ +/* MD[a] : Measure Distance */ +/* CodeRange : $49-$4A */ +/* Stack : uint32 uint32 --> f26.6 */ + +/* BULLSHIT: Measure taken in the original glyph must be along */ +/* the dual projection vector. */ + +/* Second BULLSHIT: Flag attributes are inverted! */ +/* 0 => measure distance in original outline */ +/* 1 => measure distance in grid-fitted outline */ + +/* Third one !! : zp0 - zp1, and not "zp2 - zp1" !!! */ +/* */ + + static void Ins_MD( INS_ARG ) + { + UShort K, L; + TT_F26Dot6 D; + + + K = (UShort)args[1]; + L = (UShort)args[0]; + + if( BOUNDS( L, CUR.zp0.n_points ) || + BOUNDS( K, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + else + D = 0; + } + else + { + if ( CUR.opcode & 1 ) + D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); + else + D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K ); + } + + args[0] = D; + } + + +/*******************************************/ +/* SDPVTL[a] : Set Dual PVector to Line */ +/* CodeRange : $86-$87 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_SDPVTL( INS_ARG ) + { + Long A, B, C; + UShort p1, p2; /* was Int in pas type ERROR */ + + + p1 = (UShort)args[1]; + p2 = (UShort)args[0]; + + if ( BOUNDS( p2, CUR.zp1.n_points ) || + BOUNDS( p1, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + { + TT_Vector* v1 = CUR.zp1.org + p2; + TT_Vector* v2 = CUR.zp2.org + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + } + + if ( (CUR.opcode & 1) != 0 ) + { + C = B; /* CounterClockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.dualVector ); + + { + TT_Vector* v1 = CUR.zp1.cur + p2; + TT_Vector* v2 = CUR.zp2.cur + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + } + + if ( (CUR.opcode & 1) != 0 ) + { + C = B; /* CounterClockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.projVector ); + + COMPUTE_Funcs(); + } + + +/*******************************************/ +/* SZP0[] : Set Zone Pointer 0 */ +/* CodeRange : $13 */ +/* Stack : uint32 --> */ + + static void Ins_SZP0( INS_ARG ) + { + switch ( (Int)args[0] ) + { + case 0: + CUR.zp0 = CUR.twilight; + break; + + case 1: + CUR.zp0 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep0 = (UShort)args[0]; + } + + +/*******************************************/ +/* SZP1[] : Set Zone Pointer 1 */ +/* CodeRange : $14 */ +/* Stack : uint32 --> */ + + static void Ins_SZP1( INS_ARG ) + { + switch ( (Int)args[0] ) + { + case 0: + CUR.zp1 = CUR.twilight; + break; + + case 1: + CUR.zp1 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep1 = (UShort)args[0]; + } + + +/*******************************************/ +/* SZP2[] : Set Zone Pointer 2 */ +/* CodeRange : $15 */ +/* Stack : uint32 --> */ + + static void Ins_SZP2( INS_ARG ) + { + switch ( (Int)args[0] ) + { + case 0: + CUR.zp2 = CUR.twilight; + break; + + case 1: + CUR.zp2 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.GS.gep2 = (UShort)args[0]; + } + + +/*******************************************/ +/* SZPS[] : Set Zone Pointers */ +/* CodeRange : $16 */ +/* Stack : uint32 --> */ + + static void Ins_SZPS( INS_ARG ) + { + switch ( (Int)args[0] ) + { + case 0: + CUR.zp0 = CUR.twilight; + break; + + case 1: + CUR.zp0 = CUR.pts; + break; + + default: + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + CUR.zp1 = CUR.zp0; + CUR.zp2 = CUR.zp0; + + CUR.GS.gep0 = (UShort)args[0]; + CUR.GS.gep1 = (UShort)args[0]; + CUR.GS.gep2 = (UShort)args[0]; + } + + +/*******************************************/ +/* INSTCTRL[]: INSTruction ConTRol */ +/* CodeRange : $8e */ +/* Stack : int32 int32 --> */ + + static void Ins_INSTCTRL( INS_ARG ) + { + Long K, L; + + + K = args[1]; + L = args[0]; + + if ( K < 1 || K > 2 ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( L != 0 ) + L = K; + + CUR.GS.instruct_control = + (Byte)( CUR.GS.instruct_control & ~(Byte)K ) | (Byte)L; + } + + +/*******************************************/ +/* SCANCTRL[]: SCAN ConTRol */ +/* CodeRange : $85 */ +/* Stack : uint32? --> */ + + static void Ins_SCANCTRL( INS_ARG ) + { + Int A; + + + /* Get Threshold */ + A = (Int)(args[0] & 0xFF); + + if ( A == 0xFF ) + { + CUR.GS.scan_control = TRUE; + return; + } + else if ( A == 0 ) + { + CUR.GS.scan_control = FALSE; + return; + } + + A *= 64; + + if ( (args[0] & 0x100) != 0 && CUR.metrics.pointSize <= A ) + CUR.GS.scan_control = TRUE; + + if ( (args[0] & 0x200) != 0 && CUR.metrics.rotated ) + CUR.GS.scan_control = TRUE; + + if ( (args[0] & 0x400) != 0 && CUR.metrics.stretched ) + CUR.GS.scan_control = TRUE; + + if ( (args[0] & 0x800) != 0 && CUR.metrics.pointSize > A ) + CUR.GS.scan_control = FALSE; + + if ( (args[0] & 0x1000) != 0 && CUR.metrics.rotated ) + CUR.GS.scan_control = FALSE; + + if ( (args[0] & 0x2000) != 0 && CUR.metrics.stretched ) + CUR.GS.scan_control = FALSE; +} + + +/*******************************************/ +/* SCANTYPE[]: SCAN TYPE */ +/* CodeRange : $8D */ +/* Stack : uint32? --> */ + + static void Ins_SCANTYPE( INS_ARG ) + { + /* For compatibility with future enhancements, */ + /* we must ignore new modes */ + + if ( args[0] >= 0 && args[0] <= 5 ) + { + if ( args[0] == 3 ) + args[0] = 2; + + CUR.GS.scan_type = (Int)args[0]; + } + } + + + +/****************************************************************/ +/* */ +/* MANAGING OUTLINES */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + +/**********************************************/ +/* FLIPPT[] : FLIP PoinT */ +/* CodeRange : $80 */ +/* Stack : uint32... --> */ + + static void Ins_FLIPPT( INS_ARG ) + { + UShort point; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + CUR.pts.touch[point] ^= TT_Flag_On_Curve; + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* FLIPRGON[]: FLIP RanGe ON */ +/* CodeRange : $81 */ +/* Stack : uint32 uint32 --> */ +/* (but UShorts are sufficient) */ + + static void Ins_FLIPRGON( INS_ARG ) + { + UShort I, K, L; + + + K = (UShort)args[1]; + L = (UShort)args[0]; + + if ( BOUNDS( K, CUR.pts.n_points ) || + BOUNDS( L, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + for ( I = L; I <= K; I++ ) + CUR.pts.touch[I] |= TT_Flag_On_Curve; + } + + +/**********************************************/ +/* FLIPRGOFF : FLIP RanGe OFF */ +/* CodeRange : $82 */ +/* Stack : uint32 uint32 --> */ +/* (but UShorts are sufficient) */ + + static void Ins_FLIPRGOFF( INS_ARG ) + { + UShort I, K, L; + + + K = (UShort)args[1]; + L = (UShort)args[0]; + + if ( BOUNDS( K, CUR.pts.n_points ) || + BOUNDS( L, CUR.pts.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + for ( I = L; I <= K; I++ ) + CUR.pts.touch[I] &= ~TT_Flag_On_Curve; + } + + + static Bool Compute_Point_Displacement( EXEC_OPS + PCoordinates x, + PCoordinates y, + PGlyph_Zone zone, + UShort* refp ) + { + TGlyph_Zone zp; + UShort p; + TT_F26Dot6 d; + + + if ( CUR.opcode & 1 ) + { + zp = CUR.zp0; + p = CUR.GS.rp1; + } + else + { + zp = CUR.zp1; + p = CUR.GS.rp2; + } + + if ( BOUNDS( p, zp.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Displacement; + return FAILURE; + } + + *zone = zp; + *refp = p; + + d = CUR_Func_project( zp.cur + p, zp.org + p ); + + *x = TT_MulDiv(d, (Long)CUR.GS.freeVector.x * 0x10000L, CUR.F_dot_P ); + *y = TT_MulDiv(d, (Long)CUR.GS.freeVector.y * 0x10000L, CUR.F_dot_P ); + + return SUCCESS; + } + + + static void Move_Zp2_Point( EXEC_OPS + UShort point, + TT_F26Dot6 dx, + TT_F26Dot6 dy, + Bool touch ) + { + if ( CUR.GS.freeVector.x != 0 ) + { + CUR.zp2.cur[point].x += dx; + if ( touch ) + CUR.zp2.touch[point] |= TT_Flag_Touched_X; + } + + if ( CUR.GS.freeVector.y != 0 ) + { + CUR.zp2.cur[point].y += dy; + if ( touch ) + CUR.zp2.touch[point] |= TT_Flag_Touched_Y; + } + } + + +/**********************************************/ +/* SHP[a] : SHift Point by the last point */ +/* CodeRange : $32-33 */ +/* Stack : uint32... --> */ + + static void Ins_SHP( INS_ARG ) + { + TGlyph_Zone zp; + UShort refp; + + TT_F26Dot6 dx, + dy; + UShort point; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + point = (UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + /* UNDOCUMENTED! SHP touches the points */ + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* SHC[a] : SHift Contour */ +/* CodeRange : $34-35 */ +/* Stack : uint32 --> */ + + static void Ins_SHC( INS_ARG ) + { + TGlyph_Zone zp; + UShort refp; + TT_F26Dot6 dx, + dy; + + Short contour; + UShort first_point, last_point, i; + + + contour = (UShort)args[0]; + + if ( BOUNDS( contour, CUR.pts.n_contours ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + if ( contour == 0 ) + first_point = 0; + else + first_point = CUR.pts.contours[contour - 1] + 1; + + last_point = CUR.pts.contours[contour]; + + /* XXX: this is probably wrong... at least it prevents memory */ + /* corruption when zp2 is the twilight zone */ + if ( last_point > CUR.zp2.n_points ) + { + if ( CUR.zp2.n_points > 0 ) + last_point = CUR.zp2.n_points - 1; + else + last_point = 0; + } + + /* UNDOCUMENTED! SHC doesn't touch the points */ + for ( i = first_point; i <= last_point; i++ ) + { + if ( zp.cur != CUR.zp2.cur || refp != i ) + MOVE_Zp2_Point( i, dx, dy, FALSE ); + } + } + + +/**********************************************/ +/* SHZ[a] : SHift Zone */ +/* CodeRange : $36-37 */ +/* Stack : uint32 --> */ + + static void Ins_SHZ( INS_ARG ) + { + TGlyph_Zone zp; + UShort refp; + TT_F26Dot6 dx, + dy; + + UShort last_point, i; + + + if ( BOUNDS( args[0], 2 ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) + return; + + if ( CUR.zp2.n_points > 0 ) + last_point = CUR.zp2.n_points - 1; + else + last_point = 0; + + /* UNDOCUMENTED! SHZ doesn't touch the points */ + for ( i = 0; i <= last_point; i++ ) + { + if ( zp.cur != CUR.zp2.cur || refp != i ) + MOVE_Zp2_Point( i, dx, dy, FALSE ); + } + } + + +/**********************************************/ +/* SHPIX[] : SHift points by a PIXel amount */ +/* CodeRange : $38 */ +/* Stack : f26.6 uint32... --> */ + + static void Ins_SHPIX( INS_ARG ) + { + TT_F26Dot6 dx, dy; + UShort point; + + + if ( CUR.top < CUR.GS.loop + 1 ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + dx = TT_MulDiv( args[0], + (Long)CUR.GS.freeVector.x, + 0x4000 ); + dy = TT_MulDiv( args[0], + (Long)CUR.GS.freeVector.y, + 0x4000 ); + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + MOVE_Zp2_Point( point, dx, dy, TRUE ); + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* MSIRP[a] : Move Stack Indirect Relative */ +/* CodeRange : $3A-$3B */ +/* Stack : f26.6 uint32 --> */ + + static void Ins_MSIRP( INS_ARG ) + { + UShort point; + TT_F26Dot6 distance; + + + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: UNDOCUMENTED! behaviour */ + if ( CUR.GS.gep0 == 0 ) /* if in twilight zone */ + { + CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; + CUR.zp1.cur[point] = CUR.zp1.org[point]; + } + + distance = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, args[1] - distance ); + + CUR.GS.rp1 = CUR.GS.rp0; + CUR.GS.rp2 = point; + + if ( (CUR.opcode & 1) != 0 ) + CUR.GS.rp0 = point; + } + + +/**********************************************/ +/* MDAP[a] : Move Direct Absolute Point */ +/* CodeRange : $2E-$2F */ +/* Stack : uint32 --> */ + + static void Ins_MDAP( INS_ARG ) + { + UShort point; + TT_F26Dot6 cur_dist, + distance; + + + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: Is there some undocumented feature while in the */ + /* twilight zone? ? */ + if ( (CUR.opcode & 1) != 0 ) + { + cur_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector ); + distance = CUR_Func_round( cur_dist, + CUR.metrics.compensations[0] ) - cur_dist; + } + else + distance = 0; + + CUR_Func_move( &CUR.zp0, point, distance ); + + CUR.GS.rp0 = point; + CUR.GS.rp1 = point; + } + + +/**********************************************/ +/* MIAP[a] : Move Indirect Absolute Point */ +/* CodeRange : $3E-$3F */ +/* Stack : uint32 uint32 --> */ + + static void Ins_MIAP( INS_ARG ) + { + ULong cvtEntry; + UShort point; + TT_F26Dot6 distance, + org_dist; + + + cvtEntry = (ULong)args[1]; + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) || + BOUNDS( cvtEntry, CUR.cvtSize ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* UNDOCUMENTED! */ + /* */ + /* The behaviour of an MIAP instruction is quite */ + /* different when used in the twilight zone. */ + /* */ + /* First, no control value cutin test is performed */ + /* as it would fail anyway. Second, the original */ + /* point, i.e. (org_x,org_y) of zp0.point, is set */ + /* to the absolute, unrounded distance found in */ + /* the CVT. */ + /* */ + /* This is used in the CVT programs of the Microsoft */ + /* fonts Arial, Times, etc., in order to re-adjust */ + /* some key font heights. It allows the use of the */ + /* IP instruction in the twilight zone, which */ + /* otherwise would be "illegal" according to the */ + /* specs :) */ + /* */ + /* We implement it with a special sequence for the */ + /* twilight zone. This is a bad hack, but it seems */ + /* to work. */ + + distance = CUR_Func_read_cvt( cvtEntry ); + + if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ + { + CUR.zp0.org[point].x = TT_MulDiv( CUR.GS.freeVector.x, + distance, 0x4000L ); + CUR.zp0.org[point].y = TT_MulDiv( CUR.GS.freeVector.y, + distance, 0x4000L ); + CUR.zp0.cur[point] = CUR.zp0.org[point]; + } + + org_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector ); + + if ( (CUR.opcode & 1) != 0 ) /* rounding and control cutin flag */ + { + if ( ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) + distance = org_dist; + + distance = CUR_Func_round( distance, CUR.metrics.compensations[0] ); + } + + CUR_Func_move( &CUR.zp0, point, distance - org_dist ); + + CUR.GS.rp0 = point; + CUR.GS.rp1 = point; + } + + +/**********************************************/ +/* MDRP[abcde] : Move Direct Relative Point */ +/* CodeRange : $C0-$DF */ +/* Stack : uint32 --> */ + + static void Ins_MDRP( INS_ARG ) + { + UShort point; + TT_F26Dot6 org_dist, distance; + + + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: Is there some undocumented feature while in the */ + /* twilight zone? */ + + org_dist = CUR_Func_dualproj( CUR.zp1.org + point, + CUR.zp0.org + CUR.GS.rp0 ); + + /* single width cutin test */ + + if ( ABS( org_dist ) < CUR.GS.single_width_cutin ) + { + if ( org_dist >= 0 ) + org_dist = CUR.GS.single_width_value; + else + org_dist = -CUR.GS.single_width_value; + } + + /* round flag */ + + if ( (CUR.opcode & 4) != 0 ) + distance = CUR_Func_round( org_dist, + CUR.metrics.compensations[CUR.opcode & 3] ); + else + distance = Round_None( EXEC_ARGS + org_dist, + CUR.metrics.compensations[CUR.opcode & 3] ); + + /* minimum distance flag */ + + if ( (CUR.opcode & 8) != 0 ) + { + if ( org_dist >= 0 ) + { + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; + } + else + { + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; + } + } + + /* now move the point */ + + org_dist = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, distance - org_dist ); + + CUR.GS.rp1 = CUR.GS.rp0; + CUR.GS.rp2 = point; + + if ( (CUR.opcode & 16) != 0 ) + CUR.GS.rp0 = point; + } + + +/**********************************************/ +/* MIRP[abcde] : Move Indirect Relative Point */ +/* CodeRange : $E0-$FF */ +/* Stack : int32? uint32 --> */ + + static void Ins_MIRP( INS_ARG ) + { + UShort point; + ULong cvtEntry; + + TT_F26Dot6 cvt_dist, + distance, + cur_dist, + org_dist; + + + point = (UShort)args[0]; + cvtEntry = (ULong)(args[1] + 1); + + /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ + + if ( BOUNDS( point, CUR.zp1.n_points ) || + BOUNDS( cvtEntry, CUR.cvtSize + 1 ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + if ( !cvtEntry ) + cvt_dist = 0; + else + cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); + + /* single width test */ + + if ( ABS( cvt_dist ) < CUR.GS.single_width_cutin ) + { + if ( cvt_dist >= 0 ) + cvt_dist = CUR.GS.single_width_value; + else + cvt_dist = -CUR.GS.single_width_value; + } + + /* XXX : UNDOCUMENTED! -- twilight zone */ + + if ( CUR.GS.gep1 == 0 ) + { + CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + + TT_MulDiv( cvt_dist, + CUR.GS.freeVector.x, + 0x4000 ); + + CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + + TT_MulDiv( cvt_dist, + CUR.GS.freeVector.y, + 0x4000 ); + + CUR.zp1.cur[point] = CUR.zp1.org[point]; + } + + org_dist = CUR_Func_dualproj( CUR.zp1.org + point, + CUR.zp0.org + CUR.GS.rp0 ); + + cur_dist = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + /* auto-flip test */ + + if ( CUR.GS.auto_flip ) + { + if ( (org_dist ^ cvt_dist) < 0 ) + cvt_dist = -cvt_dist; + } + + /* control value cutin and round */ + + if ( (CUR.opcode & 4) != 0 ) + { + /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ + /* refer to the same zone. */ + + if ( CUR.GS.gep0 == CUR.GS.gep1 ) + if ( ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) + cvt_dist = org_dist; + + distance = CUR_Func_round( cvt_dist, + CUR.metrics.compensations[CUR.opcode & 3] ); + } + else + distance = Round_None( EXEC_ARGS + cvt_dist, + CUR.metrics.compensations[CUR.opcode & 3] ); + + /* minimum distance test */ + + if ( (CUR.opcode & 8) != 0 ) + { + if ( org_dist >= 0 ) + { + if ( distance < CUR.GS.minimum_distance ) + distance = CUR.GS.minimum_distance; + } + else + { + if ( distance > -CUR.GS.minimum_distance ) + distance = -CUR.GS.minimum_distance; + } + } + + CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); + + CUR.GS.rp1 = CUR.GS.rp0; + + if ( (CUR.opcode & 16) != 0 ) + CUR.GS.rp0 = point; + + /* UNDOCUMENTED! */ + + CUR.GS.rp2 = point; + } + + +/**********************************************/ +/* ALIGNRP[] : ALIGN Relative Point */ +/* CodeRange : $3C */ +/* Stack : uint32 uint32... --> */ + + static void Ins_ALIGNRP( INS_ARG ) + { + UShort point; + TT_F26Dot6 distance; + + + if ( CUR.top < CUR.GS.loop || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp1.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + { + distance = CUR_Func_project( CUR.zp1.cur + point, + CUR.zp0.cur + CUR.GS.rp0 ); + + CUR_Func_move( &CUR.zp1, point, -distance ); + } + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* ISECT[] : moves point to InterSECTion */ +/* CodeRange : $0F */ +/* Stack : 5 * uint32 --> */ + + static void Ins_ISECT( INS_ARG ) + { + UShort point, + a0, a1, + b0, b1; + + TT_F26Dot6 discriminant; + + TT_F26Dot6 dx, dy, + dax, day, + dbx, dby; + + TT_F26Dot6 val; + + TT_Vector R; + + + point = (UShort)args[0]; + + a0 = (UShort)args[1]; + a1 = (UShort)args[2]; + b0 = (UShort)args[3]; + b1 = (UShort)args[4]; + + if ( BOUNDS( b0, CUR.zp0.n_points ) || + BOUNDS( b1, CUR.zp0.n_points ) || + BOUNDS( a0, CUR.zp1.n_points ) || + BOUNDS( a1, CUR.zp1.n_points ) || + BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; + dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; + + dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; + day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; + + dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; + dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; + + CUR.zp2.touch[point] |= TT_Flag_Touched_Both; + + discriminant = TT_MulDiv( dax, -dby, 0x40L ) + + TT_MulDiv( day, dbx, 0x40L ); + + if ( ABS( discriminant ) >= 0x40 ) + { + val = TT_MulDiv( dx, -dby, 0x40L ) + TT_MulDiv( dy, dbx, 0x40L ); + + R.x = TT_MulDiv( val, dax, discriminant ); + R.y = TT_MulDiv( val, day, discriminant ); + + CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; + CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; + } + else + { + /* else, take the middle of the middles of A and B */ + + CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + + CUR.zp1.cur[a1].x + + CUR.zp0.cur[b0].x + + CUR.zp0.cur[b1].x ) / 4; + CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + + CUR.zp1.cur[a1].y + + CUR.zp0.cur[b0].y + + CUR.zp0.cur[b1].y ) / 4; + } + } + + +/**********************************************/ +/* ALIGNPTS[] : ALIGN PoinTS */ +/* CodeRange : $27 */ +/* Stack : uint32 uint32 --> */ + + static void Ins_ALIGNPTS( INS_ARG ) + { + UShort p1, p2; + TT_F26Dot6 distance; + + + p1 = (UShort)args[0]; + p2 = (UShort)args[1]; + + if ( BOUNDS( args[0], CUR.zp1.n_points ) || + BOUNDS( args[1], CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + distance = CUR_Func_project( CUR.zp0.cur + p2, + CUR.zp1.cur + p1 ) / 2; + + CUR_Func_move( &CUR.zp1, p1, distance ); + CUR_Func_move( &CUR.zp0, p2, -distance ); + } + + +/**********************************************/ +/* IP[] : Interpolate Point */ +/* CodeRange : $39 */ +/* Stack : uint32... --> */ + + static void Ins_IP( INS_ARG ) + { + TT_F26Dot6 org_a, org_b, org_x, + cur_a, cur_b, cur_x, + distance; + UShort point; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + /* XXX: there are some glyphs in some braindead but popular */ + /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ + /* calling IP[] with bad values of rp[12] */ + /* do something sane when this odd thing happens */ + + if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || + BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) + { + org_a = cur_a = 0; + org_b = cur_b = 0; + } + else + { + org_a = CUR_Func_dualproj( CUR.zp0.org + CUR.GS.rp1, NULL_Vector ); + org_b = CUR_Func_dualproj( CUR.zp1.org + CUR.GS.rp2, NULL_Vector ); + + cur_a = CUR_Func_project( CUR.zp0.cur + CUR.GS.rp1, NULL_Vector ); + cur_b = CUR_Func_project( CUR.zp1.cur + CUR.GS.rp2, NULL_Vector ); + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (UShort)CUR.stack[CUR.args]; + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + { + org_x = CUR_Func_dualproj( CUR.zp2.org + point, NULL_Vector ); + cur_x = CUR_Func_project ( CUR.zp2.cur + point, NULL_Vector ); + + if ( ( org_a <= org_b && org_x <= org_a ) || + ( org_a > org_b && org_x >= org_a ) ) + + distance = ( cur_a - org_a ) + ( org_x - cur_x ); + + else if ( ( org_a <= org_b && org_x >= org_b ) || + ( org_a > org_b && org_x < org_b ) ) + + distance = ( cur_b - org_b ) + ( org_x - cur_x ); + + else + /* note: it seems that rounding this value isn't a good */ + /* idea (cf. width of capital 'S' in Times) */ + + distance = TT_MulDiv( cur_b - cur_a, + org_x - org_a, + org_b - org_a ) + ( cur_a - cur_x ); + + CUR_Func_move( &CUR.zp2, point, distance ); + } + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* UTP[a] : UnTouch Point */ +/* CodeRange : $29 */ +/* Stack : uint32 --> */ + + static void Ins_UTP( INS_ARG ) + { + UShort point; + Byte mask; + + + point = (UShort)args[0]; + + if ( BOUNDS( point, CUR.zp0.n_points ) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + + mask = 0xFF; + + if ( CUR.GS.freeVector.x != 0 ) + mask &= ~TT_Flag_Touched_X; + + if ( CUR.GS.freeVector.y != 0 ) + mask &= ~TT_Flag_Touched_Y; + + CUR.zp0.touch[point] &= mask; + } + + + /* Local variables for Ins_IUP: */ + struct LOC_Ins_IUP + { + TT_Vector* orgs; /* original and current coordinate */ + TT_Vector* curs; /* arrays */ + }; + + + static void Shift( UShort p1, + UShort p2, + UShort p, + struct LOC_Ins_IUP* LINK ) + { + UShort i; + TT_F26Dot6 x; + + + x = LINK->curs[p].x - LINK->orgs[p].x; + + for ( i = p1; i < p; i++ ) + LINK->curs[i].x += x; + + for ( i = p + 1; i <= p2; i++ ) + LINK->curs[i].x += x; + } + + + static void Interp( UShort p1, + UShort p2, + UShort ref1, + UShort ref2, + struct LOC_Ins_IUP* LINK ) + { + UShort i; + TT_F26Dot6 x, x1, x2, d1, d2; + + + if ( p1 > p2 ) + return; + + x1 = LINK->orgs[ref1].x; + d1 = LINK->curs[ref1].x - LINK->orgs[ref1].x; + x2 = LINK->orgs[ref2].x; + d2 = LINK->curs[ref2].x - LINK->orgs[ref2].x; + + if ( x1 == x2 ) + { + for ( i = p1; i <= p2; i++ ) + { + x = LINK->orgs[i].x; + + if ( x <= x1 ) + x += d1; + else + x += d2; + + LINK->curs[i].x = x; + } + return; + } + + if ( x1 < x2 ) + { + for ( i = p1; i <= p2; i++ ) + { + x = LINK->orgs[i].x; + + if ( x <= x1 ) + x += d1; + else + { + if ( x >= x2 ) + x += d2; + else + x = LINK->curs[ref1].x + + TT_MulDiv( x - x1, + LINK->curs[ref2].x - LINK->curs[ref1].x, + x2 - x1 ); + } + LINK->curs[i].x = x; + } + return; + } + + /* x2 < x1 */ + + for ( i = p1; i <= p2; i++ ) + { + x = LINK->orgs[i].x; + if ( x <= x2 ) + x += d2; + else + { + if ( x >= x1 ) + x += d1; + else + x = LINK->curs[ref1].x + + TT_MulDiv( x - x1, + LINK->curs[ref2].x - LINK->curs[ref1].x, + x2 - x1 ); + } + LINK->curs[i].x = x; + } + } + + +/**********************************************/ +/* IUP[a] : Interpolate Untouched Points */ +/* CodeRange : $30-$31 */ +/* Stack : --> */ + + static void Ins_IUP( INS_ARG ) + { + struct LOC_Ins_IUP V; + Byte mask; + + UShort first_point; /* first point of contour */ + UShort end_point; /* end point (last+1) of contour */ + + UShort first_touched; /* first touched point in contour */ + UShort cur_touched; /* current touched point in contour */ + + UShort point; /* current point */ + Short contour; /* current contour */ + + + if ( CUR.opcode & 1 ) + { + mask = TT_Flag_Touched_X; + V.orgs = CUR.pts.org; + V.curs = CUR.pts.cur; + } + else + { + mask = TT_Flag_Touched_Y; + V.orgs = (TT_Vector*)( ((TT_F26Dot6*)CUR.pts.org) + 1 ); + V.curs = (TT_Vector*)( ((TT_F26Dot6*)CUR.pts.cur) + 1 ); + } + + contour = 0; + point = 0; + + do + { + end_point = CUR.pts.contours[contour]; + first_point = point; + + while ( point <= end_point && (CUR.pts.touch[point] & mask) == 0 ) + point++; + + if ( point <= end_point ) + { + first_touched = point; + cur_touched = point; + + point++; + + while ( point <= end_point ) + { + if ( (CUR.pts.touch[point] & mask) != 0 ) + { + if ( point > 0 ) + Interp( cur_touched + 1, + point - 1, + cur_touched, + point, + &V ); + cur_touched = point; + } + + point++; + } + + if ( cur_touched == first_touched ) + Shift( first_point, end_point, cur_touched, &V ); + else + { + Interp( cur_touched + 1, + end_point, + cur_touched, + first_touched, + &V ); + + if ( first_touched > 0 ) + Interp( first_point, + first_touched - 1, + cur_touched, + first_touched, + &V ); + } + } + contour++; + } while ( contour < CUR.pts.n_contours ); + } + + +/**********************************************/ +/* DELTAPn[] : DELTA Exceptions P1, P2, P3 */ +/* CodeRange : $5D,$71,$72 */ +/* Stack : uint32 (2 * uint32)... --> */ + + static void Ins_DELTAP( INS_ARG ) + { + ULong nump, k; + UShort A; + ULong C; + Long B; + + + nump = (ULong)args[0]; /* some points theoretically may occur more + than once, thus UShort isn't enough */ + + for ( k = 1; k <= nump; k++ ) + { + if ( CUR.args < 2 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= 2; + + A = (UShort)CUR.stack[CUR.args + 1]; + B = CUR.stack[CUR.args]; + + /* XXX : because some popular fonts contain some invalid DeltaP */ + /* instructions, we simply ignore them when the stacked */ + /* point reference is off limit, rather than returning an */ + /* error. As a delta instruction doesn't change a glyph */ + /* in great ways, this shouldn't be a problem.. */ + + if ( !BOUNDS( A, CUR.zp0.n_points ) ) + { + C = ((ULong)B & 0xF0) >> 4; + + switch ( CUR.opcode ) + { + case 0x5d: + break; + + case 0x71: + C += 16; + break; + + case 0x72: + C += 32; + break; + } + + C += CUR.GS.delta_base; + + if ( CURRENT_Ppem() == (Long)C ) + { + B = ((ULong)B & 0xF) - 8; + if ( B >= 0 ) + B++; + B = B * 64L / (1L << CUR.GS.delta_shift); + + CUR_Func_move( &CUR.zp0, A, B ); + } + } + else + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + } + + CUR.new_top = CUR.args; + } + + +/**********************************************/ +/* DELTACn[] : DELTA Exceptions C1, C2, C3 */ +/* CodeRange : $73,$74,$75 */ +/* Stack : uint32 (2 * uint32)... --> */ + + static void Ins_DELTAC( INS_ARG ) + { + ULong nump, k; + ULong A, C; + Long B; + + + nump = (ULong)args[0]; + + for ( k = 1; k <= nump; k++ ) + { + if ( CUR.args < 2 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= 2; + + A = (ULong)CUR.stack[CUR.args + 1]; + B = CUR.stack[CUR.args]; + + if ( BOUNDS( A, CUR.cvtSize ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + { + C = ((ULong)B & 0xF0) >> 4; + + switch ( CUR.opcode ) + { + case 0x73: + break; + + case 0x74: + C += 16; + break; + + case 0x75: + C += 32; + break; + } + + C += CUR.GS.delta_base; + + if ( CURRENT_Ppem() == (Long)C ) + { + B = ((ULong)B & 0xF) - 8; + if ( B >= 0 ) + B++; + B = B * 64L / (1L << CUR.GS.delta_shift); + + CUR_Func_move_cvt( A, B ); + } + } + } + + CUR.new_top = CUR.args; + } + + + +/****************************************************************/ +/* */ +/* MISC. INSTRUCTIONS */ +/* */ +/****************************************************************/ + + +/**********************************************/ +/* GETINFO[] : GET INFOrmation */ +/* CodeRange : $88 */ +/* Stack : uint32 --> uint32 */ + +/* XXX According to Apple specs, bits 1 & 2 of the argument ought to be */ +/* consulted before rotated / stretched info is returned */ + + static void Ins_GETINFO( INS_ARG ) + { + Long K; + + + K = 0; + + /* We return then Windows 3.1 version number */ + /* for the font scaler */ + if ( (args[0] & 1) != 0 ) + K = 3; + + /* Has the glyph been rotated ? */ + if ( CUR.metrics.rotated ) + K |= 0x80; + + /* Has the glyph been stretched ? */ + if ( CUR.metrics.stretched ) + K |= 0x100; + + args[0] = K; + } + + + static void Ins_UNKNOWN( INS_ARG ) + { + /* look up the current instruction in our table */ + PDefRecord def, limit; + + def = CUR.IDefs; + limit = def + CUR.numIDefs; + for ( ; def < limit; def++ ) + { + if ( def->Opc == CUR.opcode && def->Active ) + { + PCallRecord pCrec; + + /* implement instruction as a function call */ + + /* check call stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = 1; + pCrec->Cur_Restart = def->Start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->Range, + def->Start ); + + CUR.step_ins = FALSE; + return; + } + } + + CUR.error = TT_Err_Invalid_Opcode; + } + + +#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH + static TInstruction_Function Instruct_Dispatch[256] = + { + /* Opcodes are gathered in groups of 16. */ + /* Please keep the spaces as they are. */ + + /* SVTCA y */ Ins_SVTCA, + /* SVTCA x */ Ins_SVTCA, + /* SPvTCA y */ Ins_SPVTCA, + /* SPvTCA x */ Ins_SPVTCA, + /* SFvTCA y */ Ins_SFVTCA, + /* SFvTCA x */ Ins_SFVTCA, + /* SPvTL // */ Ins_SPVTL, + /* SPvTL + */ Ins_SPVTL, + /* SFvTL // */ Ins_SFVTL, + /* SFvTL + */ Ins_SFVTL, + /* SPvFS */ Ins_SPVFS, + /* SFvFS */ Ins_SFVFS, + /* GPV */ Ins_GPV, + /* GFV */ Ins_GFV, + /* SFvTPv */ Ins_SFVTPV, + /* ISECT */ Ins_ISECT, + + /* SRP0 */ Ins_SRP0, + /* SRP1 */ Ins_SRP1, + /* SRP2 */ Ins_SRP2, + /* SZP0 */ Ins_SZP0, + /* SZP1 */ Ins_SZP1, + /* SZP2 */ Ins_SZP2, + /* SZPS */ Ins_SZPS, + /* SLOOP */ Ins_SLOOP, + /* RTG */ Ins_RTG, + /* RTHG */ Ins_RTHG, + /* SMD */ Ins_SMD, + /* ELSE */ Ins_ELSE, + /* JMPR */ Ins_JMPR, + /* SCvTCi */ Ins_SCVTCI, + /* SSwCi */ Ins_SSWCI, + /* SSW */ Ins_SSW, + + /* DUP */ Ins_DUP, + /* POP */ Ins_POP, + /* CLEAR */ Ins_CLEAR, + /* SWAP */ Ins_SWAP, + /* DEPTH */ Ins_DEPTH, + /* CINDEX */ Ins_CINDEX, + /* MINDEX */ Ins_MINDEX, + /* AlignPTS */ Ins_ALIGNPTS, + /* INS_$28 */ Ins_UNKNOWN, + /* UTP */ Ins_UTP, + /* LOOPCALL */ Ins_LOOPCALL, + /* CALL */ Ins_CALL, + /* FDEF */ Ins_FDEF, + /* ENDF */ Ins_ENDF, + /* MDAP[0] */ Ins_MDAP, + /* MDAP[1] */ Ins_MDAP, + + /* IUP[0] */ Ins_IUP, + /* IUP[1] */ Ins_IUP, + /* SHP[0] */ Ins_SHP, + /* SHP[1] */ Ins_SHP, + /* SHC[0] */ Ins_SHC, + /* SHC[1] */ Ins_SHC, + /* SHZ[0] */ Ins_SHZ, + /* SHZ[1] */ Ins_SHZ, + /* SHPIX */ Ins_SHPIX, + /* IP */ Ins_IP, + /* MSIRP[0] */ Ins_MSIRP, + /* MSIRP[1] */ Ins_MSIRP, + /* AlignRP */ Ins_ALIGNRP, + /* RTDG */ Ins_RTDG, + /* MIAP[0] */ Ins_MIAP, + /* MIAP[1] */ Ins_MIAP, + + /* NPushB */ Ins_NPUSHB, + /* NPushW */ Ins_NPUSHW, + /* WS */ Ins_WS, + /* RS */ Ins_RS, + /* WCvtP */ Ins_WCVTP, + /* RCvt */ Ins_RCVT, + /* GC[0] */ Ins_GC, + /* GC[1] */ Ins_GC, + /* SCFS */ Ins_SCFS, + /* MD[0] */ Ins_MD, + /* MD[1] */ Ins_MD, + /* MPPEM */ Ins_MPPEM, + /* MPS */ Ins_MPS, + /* FlipON */ Ins_FLIPON, + /* FlipOFF */ Ins_FLIPOFF, + /* DEBUG */ Ins_DEBUG, + + /* LT */ Ins_LT, + /* LTEQ */ Ins_LTEQ, + /* GT */ Ins_GT, + /* GTEQ */ Ins_GTEQ, + /* EQ */ Ins_EQ, + /* NEQ */ Ins_NEQ, + /* ODD */ Ins_ODD, + /* EVEN */ Ins_EVEN, + /* IF */ Ins_IF, + /* EIF */ Ins_EIF, + /* AND */ Ins_AND, + /* OR */ Ins_OR, + /* NOT */ Ins_NOT, + /* DeltaP1 */ Ins_DELTAP, + /* SDB */ Ins_SDB, + /* SDS */ Ins_SDS, + + /* ADD */ Ins_ADD, + /* SUB */ Ins_SUB, + /* DIV */ Ins_DIV, + /* MUL */ Ins_MUL, + /* ABS */ Ins_ABS, + /* NEG */ Ins_NEG, + /* FLOOR */ Ins_FLOOR, + /* CEILING */ Ins_CEILING, + /* ROUND[0] */ Ins_ROUND, + /* ROUND[1] */ Ins_ROUND, + /* ROUND[2] */ Ins_ROUND, + /* ROUND[3] */ Ins_ROUND, + /* NROUND[0] */ Ins_NROUND, + /* NROUND[1] */ Ins_NROUND, + /* NROUND[2] */ Ins_NROUND, + /* NROUND[3] */ Ins_NROUND, + + /* WCvtF */ Ins_WCVTF, + /* DeltaP2 */ Ins_DELTAP, + /* DeltaP3 */ Ins_DELTAP, + /* DeltaCn[0] */ Ins_DELTAC, + /* DeltaCn[1] */ Ins_DELTAC, + /* DeltaCn[2] */ Ins_DELTAC, + /* SROUND */ Ins_SROUND, + /* S45Round */ Ins_S45ROUND, + /* JROT */ Ins_JROT, + /* JROF */ Ins_JROF, + /* ROFF */ Ins_ROFF, + /* INS_$7B */ Ins_UNKNOWN, + /* RUTG */ Ins_RUTG, + /* RDTG */ Ins_RDTG, + /* SANGW */ Ins_SANGW, + /* AA */ Ins_AA, + + /* FlipPT */ Ins_FLIPPT, + /* FlipRgON */ Ins_FLIPRGON, + /* FlipRgOFF */ Ins_FLIPRGOFF, + /* INS_$83 */ Ins_UNKNOWN, + /* INS_$84 */ Ins_UNKNOWN, + /* ScanCTRL */ Ins_SCANCTRL, + /* SDPVTL[0] */ Ins_SDPVTL, + /* SDPVTL[1] */ Ins_SDPVTL, + /* GetINFO */ Ins_GETINFO, + /* IDEF */ Ins_IDEF, + /* ROLL */ Ins_ROLL, + /* MAX */ Ins_MAX, + /* MIN */ Ins_MIN, + /* ScanTYPE */ Ins_SCANTYPE, + /* InstCTRL */ Ins_INSTCTRL, + /* INS_$8F */ Ins_UNKNOWN, + + /* INS_$90 */ Ins_UNKNOWN, + /* INS_$91 */ Ins_UNKNOWN, + /* INS_$92 */ Ins_UNKNOWN, + /* INS_$93 */ Ins_UNKNOWN, + /* INS_$94 */ Ins_UNKNOWN, + /* INS_$95 */ Ins_UNKNOWN, + /* INS_$96 */ Ins_UNKNOWN, + /* INS_$97 */ Ins_UNKNOWN, + /* INS_$98 */ Ins_UNKNOWN, + /* INS_$99 */ Ins_UNKNOWN, + /* INS_$9A */ Ins_UNKNOWN, + /* INS_$9B */ Ins_UNKNOWN, + /* INS_$9C */ Ins_UNKNOWN, + /* INS_$9D */ Ins_UNKNOWN, + /* INS_$9E */ Ins_UNKNOWN, + /* INS_$9F */ Ins_UNKNOWN, + + /* INS_$A0 */ Ins_UNKNOWN, + /* INS_$A1 */ Ins_UNKNOWN, + /* INS_$A2 */ Ins_UNKNOWN, + /* INS_$A3 */ Ins_UNKNOWN, + /* INS_$A4 */ Ins_UNKNOWN, + /* INS_$A5 */ Ins_UNKNOWN, + /* INS_$A6 */ Ins_UNKNOWN, + /* INS_$A7 */ Ins_UNKNOWN, + /* INS_$A8 */ Ins_UNKNOWN, + /* INS_$A9 */ Ins_UNKNOWN, + /* INS_$AA */ Ins_UNKNOWN, + /* INS_$AB */ Ins_UNKNOWN, + /* INS_$AC */ Ins_UNKNOWN, + /* INS_$AD */ Ins_UNKNOWN, + /* INS_$AE */ Ins_UNKNOWN, + /* INS_$AF */ Ins_UNKNOWN, + + /* PushB[0] */ Ins_PUSHB, + /* PushB[1] */ Ins_PUSHB, + /* PushB[2] */ Ins_PUSHB, + /* PushB[3] */ Ins_PUSHB, + /* PushB[4] */ Ins_PUSHB, + /* PushB[5] */ Ins_PUSHB, + /* PushB[6] */ Ins_PUSHB, + /* PushB[7] */ Ins_PUSHB, + /* PushW[0] */ Ins_PUSHW, + /* PushW[1] */ Ins_PUSHW, + /* PushW[2] */ Ins_PUSHW, + /* PushW[3] */ Ins_PUSHW, + /* PushW[4] */ Ins_PUSHW, + /* PushW[5] */ Ins_PUSHW, + /* PushW[6] */ Ins_PUSHW, + /* PushW[7] */ Ins_PUSHW, + + /* MDRP[00] */ Ins_MDRP, + /* MDRP[01] */ Ins_MDRP, + /* MDRP[02] */ Ins_MDRP, + /* MDRP[03] */ Ins_MDRP, + /* MDRP[04] */ Ins_MDRP, + /* MDRP[05] */ Ins_MDRP, + /* MDRP[06] */ Ins_MDRP, + /* MDRP[07] */ Ins_MDRP, + /* MDRP[08] */ Ins_MDRP, + /* MDRP[09] */ Ins_MDRP, + /* MDRP[10] */ Ins_MDRP, + /* MDRP[11] */ Ins_MDRP, + /* MDRP[12] */ Ins_MDRP, + /* MDRP[13] */ Ins_MDRP, + /* MDRP[14] */ Ins_MDRP, + /* MDRP[15] */ Ins_MDRP, + + /* MDRP[16] */ Ins_MDRP, + /* MDRP[17] */ Ins_MDRP, + /* MDRP[18] */ Ins_MDRP, + /* MDRP[19] */ Ins_MDRP, + /* MDRP[20] */ Ins_MDRP, + /* MDRP[21] */ Ins_MDRP, + /* MDRP[22] */ Ins_MDRP, + /* MDRP[23] */ Ins_MDRP, + /* MDRP[24] */ Ins_MDRP, + /* MDRP[25] */ Ins_MDRP, + /* MDRP[26] */ Ins_MDRP, + /* MDRP[27] */ Ins_MDRP, + /* MDRP[28] */ Ins_MDRP, + /* MDRP[29] */ Ins_MDRP, + /* MDRP[30] */ Ins_MDRP, + /* MDRP[31] */ Ins_MDRP, + + /* MIRP[00] */ Ins_MIRP, + /* MIRP[01] */ Ins_MIRP, + /* MIRP[02] */ Ins_MIRP, + /* MIRP[03] */ Ins_MIRP, + /* MIRP[04] */ Ins_MIRP, + /* MIRP[05] */ Ins_MIRP, + /* MIRP[06] */ Ins_MIRP, + /* MIRP[07] */ Ins_MIRP, + /* MIRP[08] */ Ins_MIRP, + /* MIRP[09] */ Ins_MIRP, + /* MIRP[10] */ Ins_MIRP, + /* MIRP[11] */ Ins_MIRP, + /* MIRP[12] */ Ins_MIRP, + /* MIRP[13] */ Ins_MIRP, + /* MIRP[14] */ Ins_MIRP, + /* MIRP[15] */ Ins_MIRP, + + /* MIRP[16] */ Ins_MIRP, + /* MIRP[17] */ Ins_MIRP, + /* MIRP[18] */ Ins_MIRP, + /* MIRP[19] */ Ins_MIRP, + /* MIRP[20] */ Ins_MIRP, + /* MIRP[21] */ Ins_MIRP, + /* MIRP[22] */ Ins_MIRP, + /* MIRP[23] */ Ins_MIRP, + /* MIRP[24] */ Ins_MIRP, + /* MIRP[25] */ Ins_MIRP, + /* MIRP[26] */ Ins_MIRP, + /* MIRP[27] */ Ins_MIRP, + /* MIRP[28] */ Ins_MIRP, + /* MIRP[29] */ Ins_MIRP, + /* MIRP[30] */ Ins_MIRP, + /* MIRP[31] */ Ins_MIRP + }; +#endif + + +/****************************************************************/ +/* */ +/* RUN */ +/* */ +/* This function executes a run of opcodes. It will exit */ +/* in the following cases: */ +/* */ +/* - Errors (in which case it returns FALSE) */ +/* */ +/* - Reaching the end of the main code range (returns TRUE). */ +/* Reaching the end of a code range within a function */ +/* call is an error. */ +/* */ +/* - After executing one single opcode, if the flag */ +/* 'Instruction_Trap' is set to TRUE (returns TRUE). */ +/* */ +/* On exit whith TRUE, test IP < CodeSize to know wether it */ +/* comes from a instruction trap or a normal termination. */ +/* */ +/* */ +/* Note: The documented DEBUG opcode pops a value from */ +/* the stack. This behaviour is unsupported, here */ +/* a DEBUG opcode is always an error. */ +/* */ +/* */ +/* THIS IS THE INTERPRETER'S MAIN LOOP */ +/* */ +/* Instructions appear in the specs' order. */ +/* */ +/****************************************************************/ + + LOCAL_FUNC +#ifndef DEBUG_INTERPRETER + TT_Error RunIns( PExecution_Context exc ) +#else + TT_Error RunIns2( PExecution_Context exc ) +#endif + { + UShort A; + PDefRecord WITH; + PCallRecord WITH1; + + Long ins_counter = 0; /* executed instructions counter */ + +#ifdef TT_CONFIG_OPTION_STATIC_INTERPRETER + cur = *exc; +#endif + + /* set CVT functions */ + CUR.metrics.ratio = 0; + if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) + { + /* non-square pixels, use the stretched routines */ + CUR.func_read_cvt = Read_CVT_Stretched; + CUR.func_write_cvt = Write_CVT_Stretched; + CUR.func_move_cvt = Move_CVT_Stretched; + } + else + { + /* square pixels, use normal routines */ + CUR.func_read_cvt = Read_CVT; + CUR.func_write_cvt = Write_CVT; + CUR.func_move_cvt = Move_CVT; + } + + COMPUTE_Funcs(); + Compute_Round( EXEC_ARGS (Byte)exc->GS.round_state ); + + do + { + if ( CALC_Length() != SUCCESS ) + { + CUR.error = TT_Err_Code_Overflow; + goto LErrorLabel_; + } + + /* First, let's check for empty stack and overflow */ + + CUR.args = CUR.top - (Pop_Push_Count[CUR.opcode] >> 4); + + /* `args' is the top of the stack once arguments have been popped. */ + /* One can also interpret it as the index of the last argument. */ + + if ( CUR.args < 0 ) + { + CUR.error = TT_Err_Too_Few_Arguments; + goto LErrorLabel_; + } + + CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15); + + /* `new_top' is the new top of the stack, after the instruction's */ + /* execution. `top' will be set to `new_top' after the 'switch' */ + /* statement. */ + + if ( CUR.new_top > CUR.stackSize ) + { + CUR.error = TT_Err_Stack_Overflow; + goto LErrorLabel_; + } + + CUR.step_ins = TRUE; + CUR.error = TT_Err_Ok; + +#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH + { + PStorage args = CUR.stack + CUR.args; + Byte opcode = CUR.opcode; + + +#undef ARRAY_BOUND_ERROR +#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref + + switch ( opcode ) + { + case 0x00: /* SVTCA y */ + case 0x01: /* SVTCA x */ + case 0x02: /* SPvTCA y */ + case 0x03: /* SPvTCA x */ + case 0x04: /* SFvTCA y */ + case 0x05: /* SFvTCA x */ + { + Short AA, BB; + + + AA = (Short)(opcode & 1) << 14; + BB = AA ^ (Short)0x4000; + + if ( opcode < 4 ) + { + CUR.GS.projVector.x = AA; + CUR.GS.projVector.y = BB; + + CUR.GS.dualVector.x = AA; + CUR.GS.dualVector.y = BB; + } + + if ( (opcode & 2) == 0 ) + { + CUR.GS.freeVector.x = AA; + CUR.GS.freeVector.y = BB; + } + + COMPUTE_Funcs(); + } + break; + + case 0x06: /* SPvTL // */ + case 0x07: /* SPvTL + */ + DO_SPVTL + break; + + case 0x08: /* SFvTL // */ + case 0x09: /* SFvTL + */ + DO_SFVTL + break; + + case 0x0A: /* SPvFS */ + DO_SPVFS + break; + + case 0x0B: /* SFvFS */ + DO_SFVFS + break; + + case 0x0C: /* GPV */ + DO_GPV + break; + + case 0x0D: /* GFV */ + DO_GFV + break; + + case 0x0E: /* SFvTPv */ + DO_SFVTPV + break; + + case 0x0F: /* ISECT */ + Ins_ISECT( EXEC_ARGS args ); + break; + + case 0x10: /* SRP0 */ + DO_SRP0 + break; + + case 0x11: /* SRP1 */ + DO_SRP1 + break; + + case 0x12: /* SRP2 */ + DO_SRP2 + break; + + case 0x13: /* SZP0 */ + Ins_SZP0( EXEC_ARGS args ); + break; + + case 0x14: /* SZP1 */ + Ins_SZP1( EXEC_ARGS args ); + break; + + case 0x15: /* SZP2 */ + Ins_SZP2( EXEC_ARGS args ); + break; + + case 0x16: /* SZPS */ + Ins_SZPS( EXEC_ARGS args ); + break; + + case 0x17: /* SLOOP */ + DO_SLOOP + break; + + case 0x18: /* RTG */ + DO_RTG + break; + + case 0x19: /* RTHG */ + DO_RTHG + break; + + case 0x1A: /* SMD */ + DO_SMD + break; + + case 0x1B: /* ELSE */ + Ins_ELSE( EXEC_ARGS args ); + break; + + case 0x1C: /* JMPR */ + DO_JMPR + break; + + case 0x1D: /* SCVTCI */ + DO_SCVTCI + break; + + case 0x1E: /* SSWCI */ + DO_SSWCI + break; + + case 0x1F: /* SSW */ + DO_SSW + break; + + case 0x20: /* DUP */ + DO_DUP + break; + + case 0x21: /* POP */ + /* nothing :-) !! */ + break; + + case 0x22: /* CLEAR */ + DO_CLEAR + break; + + case 0x23: /* SWAP */ + DO_SWAP + break; + + case 0x24: /* DEPTH */ + DO_DEPTH + break; + + case 0x25: /* CINDEX */ + DO_CINDEX + break; + + case 0x26: /* MINDEX */ + Ins_MINDEX( EXEC_ARGS args ); + break; + + case 0x27: /* ALIGNPTS */ + Ins_ALIGNPTS( EXEC_ARGS args ); + break; + + case 0x28: /* ???? */ + Ins_UNKNOWN( EXEC_ARGS args ); + break; + + case 0x29: /* UTP */ + Ins_UTP( EXEC_ARGS args ); + break; + + case 0x2A: /* LOOPCALL */ + Ins_LOOPCALL( EXEC_ARGS args ); + break; + + case 0x2B: /* CALL */ + Ins_CALL( EXEC_ARGS args ); + break; + + case 0x2C: /* FDEF */ + Ins_FDEF( EXEC_ARGS args ); + break; + + case 0x2D: /* ENDF */ + Ins_ENDF( EXEC_ARGS args ); + break; + + case 0x2E: /* MDAP */ + case 0x2F: /* MDAP */ + Ins_MDAP( EXEC_ARGS args ); + break; + + + case 0x30: /* IUP */ + case 0x31: /* IUP */ + Ins_IUP( EXEC_ARGS args ); + break; + + case 0x32: /* SHP */ + case 0x33: /* SHP */ + Ins_SHP( EXEC_ARGS args ); + break; + + case 0x34: /* SHC */ + case 0x35: /* SHC */ + Ins_SHC( EXEC_ARGS args ); + break; + + case 0x36: /* SHZ */ + case 0x37: /* SHZ */ + Ins_SHZ( EXEC_ARGS args ); + break; + + case 0x38: /* SHPIX */ + Ins_SHPIX( EXEC_ARGS args ); + break; + + case 0x39: /* IP */ + Ins_IP( EXEC_ARGS args ); + break; + + case 0x3A: /* MSIRP */ + case 0x3B: /* MSIRP */ + Ins_MSIRP( EXEC_ARGS args ); + break; + + case 0x3C: /* AlignRP */ + Ins_ALIGNRP( EXEC_ARGS args ); + break; + + case 0x3D: /* RTDG */ + DO_RTDG + break; + + case 0x3E: /* MIAP */ + case 0x3F: /* MIAP */ + Ins_MIAP( EXEC_ARGS args ); + break; + + case 0x40: /* NPUSHB */ + Ins_NPUSHB( EXEC_ARGS args ); + break; + + case 0x41: /* NPUSHW */ + Ins_NPUSHW( EXEC_ARGS args ); + break; + + case 0x42: /* WS */ + DO_WS + break; + + Set_Invalid_Ref: + CUR.error = TT_Err_Invalid_Reference; + break; + + case 0x43: /* RS */ + DO_RS + break; + + case 0x44: /* WCVTP */ + DO_WCVTP + break; + + case 0x45: /* RCVT */ + DO_RCVT + break; + + case 0x46: /* GC */ + case 0x47: /* GC */ + Ins_GC( EXEC_ARGS args ); + break; + + case 0x48: /* SCFS */ + Ins_SCFS( EXEC_ARGS args ); + break; + + case 0x49: /* MD */ + case 0x4A: /* MD */ + Ins_MD( EXEC_ARGS args ); + break; + + case 0x4B: /* MPPEM */ + DO_MPPEM + break; + + case 0x4C: /* MPS */ + DO_MPS + break; + + case 0x4D: /* FLIPON */ + DO_FLIPON + break; + + case 0x4E: /* FLIPOFF */ + DO_FLIPOFF + break; + + case 0x4F: /* DEBUG */ + DO_DEBUG + break; + + case 0x50: /* LT */ + DO_LT + break; + + case 0x51: /* LTEQ */ + DO_LTEQ + break; + + case 0x52: /* GT */ + DO_GT + break; + + case 0x53: /* GTEQ */ + DO_GTEQ + break; + + case 0x54: /* EQ */ + DO_EQ + break; + + case 0x55: /* NEQ */ + DO_NEQ + break; + + case 0x56: /* ODD */ + DO_ODD + break; + + case 0x57: /* EVEN */ + DO_EVEN + break; + + case 0x58: /* IF */ + Ins_IF( EXEC_ARGS args ); + break; + + case 0x59: /* EIF */ + /* do nothing */ + break; + + case 0x5A: /* AND */ + DO_AND + break; + + case 0x5B: /* OR */ + DO_OR + break; + + case 0x5C: /* NOT */ + DO_NOT + break; + + case 0x5D: /* DELTAP1 */ + Ins_DELTAP( EXEC_ARGS args ); + break; + + case 0x5E: /* SDB */ + DO_SDB + break; + + case 0x5F: /* SDS */ + DO_SDS + break; + + case 0x60: /* ADD */ + DO_ADD + break; + + case 0x61: /* SUB */ + DO_SUB + break; + + case 0x62: /* DIV */ + DO_DIV + break; + + case 0x63: /* MUL */ + DO_MUL + break; + + case 0x64: /* ABS */ + DO_ABS + break; + + case 0x65: /* NEG */ + DO_NEG + break; + + case 0x66: /* FLOOR */ + DO_FLOOR + break; + + case 0x67: /* CEILING */ + DO_CEILING + break; + + case 0x68: /* ROUND */ + case 0x69: /* ROUND */ + case 0x6A: /* ROUND */ + case 0x6B: /* ROUND */ + DO_ROUND + break; + + case 0x6C: /* NROUND */ + case 0x6D: /* NROUND */ + case 0x6E: /* NRRUND */ + case 0x6F: /* NROUND */ + DO_NROUND + break; + + case 0x70: /* WCVTF */ + DO_WCVTF + break; + + case 0x71: /* DELTAP2 */ + case 0x72: /* DELTAP3 */ + Ins_DELTAP( EXEC_ARGS args ); + break; + + case 0x73: /* DELTAC0 */ + case 0x74: /* DELTAC1 */ + case 0x75: /* DELTAC2 */ + Ins_DELTAC( EXEC_ARGS args ); + break; + + case 0x76: /* SROUND */ + DO_SROUND + break; + + case 0x77: /* S45Round */ + DO_S45ROUND + break; + + case 0x78: /* JROT */ + DO_JROT + break; + + case 0x79: /* JROF */ + DO_JROF + break; + + case 0x7A: /* ROFF */ + DO_ROFF + break; + + case 0x7B: /* ???? */ + Ins_UNKNOWN( EXEC_ARGS args ); + break; + + case 0x7C: /* RUTG */ + DO_RUTG + break; + + case 0x7D: /* RDTG */ + DO_RDTG + break; + + case 0x7E: /* SANGW */ + case 0x7F: /* AA */ + /* nothing - obsolete */ + break; + + case 0x80: /* FLIPPT */ + Ins_FLIPPT( EXEC_ARGS args ); + break; + + case 0x81: /* FLIPRGON */ + Ins_FLIPRGON( EXEC_ARGS args ); + break; + + case 0x82: /* FLIPRGOFF */ + Ins_FLIPRGOFF( EXEC_ARGS args ); + break; + + case 0x83: /* UNKNOWN */ + case 0x84: /* UNKNOWN */ + Ins_UNKNOWN( EXEC_ARGS args ); + break; + + case 0x85: /* SCANCTRL */ + Ins_SCANCTRL( EXEC_ARGS args ); + break; + + case 0x86: /* SDPVTL */ + case 0x87: /* SDPVTL */ + Ins_SDPVTL( EXEC_ARGS args ); + break; + + case 0x88: /* GETINFO */ + Ins_GETINFO( EXEC_ARGS args ); + break; + + case 0x89: /* IDEF */ + Ins_IDEF( EXEC_ARGS args ); + break; + + case 0x8A: /* ROLL */ + Ins_ROLL( EXEC_ARGS args ); + break; + + case 0x8B: /* MAX */ + DO_MAX + break; + + case 0x8C: /* MIN */ + DO_MIN + break; + + case 0x8D: /* SCANTYPE */ + Ins_SCANTYPE( EXEC_ARGS args ); + break; + + case 0x8E: /* INSTCTRL */ + Ins_INSTCTRL( EXEC_ARGS args ); + break; + + case 0x8F: + Ins_UNKNOWN( EXEC_ARGS args ); + break; + + default: + if ( opcode >= 0xE0 ) + Ins_MIRP( EXEC_ARGS args ); + else if ( opcode >= 0xC0 ) + Ins_MDRP( EXEC_ARGS args ); + else if ( opcode >= 0xB8 ) + Ins_PUSHW( EXEC_ARGS args ); + else if ( opcode >= 0xB0 ) + Ins_PUSHB( EXEC_ARGS args ); + else + Ins_UNKNOWN( EXEC_ARGS args ); + } + + } +#else + Instruct_Dispatch[CUR.opcode]( EXEC_ARGS &CUR.stack[CUR.args] ); +#endif + if ( CUR.error != TT_Err_Ok ) + { + switch ( (Int)(CUR.error) ) + { + case TT_Err_Invalid_Opcode: /* looking for redefined instructions */ + A = 0; + + while ( A < CUR.numIDefs ) + { + WITH = &CUR.IDefs[A]; + + if ( WITH->Active && CUR.opcode == WITH->Opc ) + { + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Invalid_Reference; + goto LErrorLabel_; + } + + WITH1 = &CUR.callStack[CUR.callTop]; + + WITH1->Caller_Range = CUR.curRange; + WITH1->Caller_IP = CUR.IP + 1; + WITH1->Cur_Count = 1; + WITH1->Cur_Restart = WITH->Start; + + if ( INS_Goto_CodeRange( WITH->Range, WITH->Start ) == FAILURE ) + goto LErrorLabel_; + + goto LSuiteLabel_; + } + else + { + A++; + continue; + } + } + + CUR.error = TT_Err_Invalid_Opcode; + goto LErrorLabel_; +/* break; Unreachable code warning suppress. Leave in case a later + change to remind the editor to consider break; */ + + default: + goto LErrorLabel_; +/* break; */ + } + } + + CUR.top = CUR.new_top; + + if ( CUR.step_ins ) + CUR.IP += CUR.length; + + /* increment instruction counter and check if we didn't */ + /* run this program for too long ?? (e.g. infinite loops) */ + if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + { + CUR.error = TT_Err_Execution_Too_Long; + goto LErrorLabel_; + } + + LSuiteLabel_: + + if ( CUR.IP >= CUR.codeSize ) + { + if ( CUR.callTop > 0 ) + { + CUR.error = TT_Err_Code_Overflow; + goto LErrorLabel_; + } + else + goto LNo_Error_; + } + } while ( !CUR.instruction_trap ); + + LNo_Error_: + CUR.error = TT_Err_Ok; + + LErrorLabel_: + +#ifdef TT_CONFIG_OPTION_STATIC_INTERPRETER + *exc = cur; +#endif + + return CUR.error; + + + } + + +#ifdef DEBUG_INTERPRETER + + /* This function must be declared by the debugger front end */ + /* in order to specify which code range to debug. */ + + int debug_coderange = TT_CodeRange_Glyph; + + + LOCAL_FUNC + TT_Error RunIns( PExecution_Context exc ) + { + Int A, diff; + ULong next_IP; + Char ch, oldch; + char *temp; + int key; + + TT_Error error = 0; + + TGlyph_Zone save; + TGlyph_Zone pts; + +#define TT_Round_Off 5 +#define TT_Round_To_Half_Grid 0 +#define TT_Round_To_Grid 1 +#define TT_Round_To_Double_Grid 2 +#define TT_Round_Up_To_Grid 4 +#define TT_Round_Down_To_Grid 3 +#define TT_Round_Super 6 +#define TT_Round_Super_45 7 + + const String* round_str[8] = + { + "to half-grid", + "to grid", + "to double grid", + "down to grid", + "up to grid", + "off", + "super", + "super 45" + }; + + /* Check that we're running the code range that is effectively */ + /* asked by the debugger front end. */ + if ( exc->curRange != debug_coderange ) + return RunIns2( exc ); + + pts = exc->pts; + + save.n_points = pts.n_points; + save.n_contours = pts.n_contours; + + MEM_Alloc( save.org, sizeof ( TT_Vector ) * save.n_points ); + MEM_Alloc( save.cur, sizeof ( TT_Vector ) * save.n_points ); + MEM_Alloc( save.touch, sizeof ( Byte ) * save.n_points ); + + exc->instruction_trap = 1; + + oldch = '\0'; + + do + { + if ( exc->IP < exc->codeSize ) + { +#ifdef TT_CONFIG_OPTION_STATIC_INTERPRETER + cur = *exc; +#endif + CALC_Length(); + + exc->args = exc->top - (Pop_Push_Count[exc->opcode] >> 4); + + /* `args' is the top of the stack once arguments have been popped. */ + /* One can also interpret it as the index of the last argument. */ + + /* Print the current line. We use a 80-columns console with the */ + /* following formatting: */ + /* */ + /* [loc]:[addr] [opcode] [disassemby] [a][b]|[c][d] */ + /* */ + + { + char temp[80]; + int n, col, pop; + int args = CUR.args; + + + sprintf( temp, "%78c\n", ' ' ); + + /* first letter of location */ + switch ( CUR.curRange ) + { + case TT_CodeRange_Glyph: + temp[0] = 'g'; + break; + case TT_CodeRange_Cvt: + temp[0] = 'c'; + break; + default: + temp[0] = 'f'; + } + + /* current IP */ + sprintf( temp+1, "%04lx: %02x %-36.36s", + CUR.IP, + CUR.opcode, + Cur_U_Line(&CUR) ); + + strncpy( temp+46, " (", 2 ); + + args = CUR.top - 1; + pop = Pop_Push_Count[CUR.opcode] >> 4; + col = 48; + for ( n = 6; n > 0; n-- ) + { + if ( pop == 0 ) + temp[col-1] = (temp[col-1] == '(' ? ' ' : ')' ); + + if ( args < CUR.top && args >= 0 ) + sprintf( temp+col, "%04lx", CUR.stack[args] ); + else + sprintf( temp+col, " " ); + + temp[col+4] = ' '; + col += 5; + pop--; + args--; + } + temp[78] = '\n'; + temp[79] = '\0'; + PTRACE0(( temp )); + } + + /* First, check for empty stack and overflow */ + if ( CUR.args < 0 ) + { + PTRACE0(( "ERROR : Too few arguments\n" )); + exc->error = TT_Err_Too_Few_Arguments; + goto LErrorLabel_; + } + + CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15); + + /* new_top is the new top of the stack, after the instruction's */ + /* execution. top will be set to new_top after the 'case' */ + + if ( CUR.new_top > CUR.stackSize ) + { + PTRACE0(( "ERROR : Stack overflow\n" )); + exc->error = TT_Err_Stack_Overflow; + goto LErrorLabel_; + } + } + else + PTRACE0(( "End of program reached.\n" )); + + key = 0; + do + { + /* read keyboard */ + + ch = getch(); + + switch ( ch ) + { + /* Help - show keybindings */ + case '?': + PTRACE0(( "FDebug Help\n\n" )); + PTRACE0(( "? Show this page\n" )); + PTRACE0(( "q Quit debugger\n" )); + PTRACE0(( "n Skip to next instruction\n" )); + PTRACE0(( "s Step into\n" )); + PTRACE0(( "v Show vector info\n" )); + PTRACE0(( "g Show graphics state\n" )); + PTRACE0(( "p Show points zone\n\n" )); + break; + + /* Show vectors */ + case 'v': + PTRACE0(( "freedom (%04hx,%04hx)\n", exc->GS.freeVector.x, + exc->GS.freeVector.y )); + PTRACE0(( "projection (%04hx,%04hx)\n", exc->GS.projVector.x, + exc->GS.projVector.y )); + PTRACE0(( "dual (%04hx,%04hx)\n\n", exc->GS.dualVector.x, + exc->GS.dualVector.y )); + break; + + /* Show graphics state */ + case 'g': + PTRACE0(( "rounding %s\n", round_str[exc->GS.round_state] )); + PTRACE0(( "min dist %04lx\n", exc->GS.minimum_distance )); + PTRACE0(( "cvt_cutin %04lx\n", exc->GS.control_value_cutin )); + break; + + /* Show points table */ + case 'p': + for ( A = 0; A < exc->pts.n_points; A++ ) + { + PTRACE0(( "%02hx ", A )); + PTRACE0(( "%08lx,%08lx - ", pts.org[A].x, pts.org[A].y )); + PTRACE0(( "%08lx,%08lx\n", pts.cur[A].x, pts.cur[A].y )); + } + PTRACE0(( "\n" )); + break; + + default: + key = 1; + } + } while ( !key ); + + MEM_Copy( save.org, pts.org, pts.n_points * sizeof ( TT_Vector ) ); + MEM_Copy( save.cur, pts.cur, pts.n_points * sizeof ( TT_Vector ) ); + MEM_Copy( save.touch, pts.touch, pts.n_points ); + + /* a return indicate the last command */ + if (ch == '\r') + ch = oldch; + + switch ( ch ) + { + /* Quit debugger */ + case 'q': + goto LErrorLabel_; + + /* Step over */ + case 'n': + if ( exc->IP < exc->codeSize ) + { + /* `step over' is equivalent to `step into' except if */ + /* the current opcode is a CALL or LOOPCALL */ + if ( CUR.opcode != 0x2a && CUR.opcode != 0x2b ) + goto Step_into; + + /* otherwise, loop execution until we reach the next opcode */ + next_IP = CUR.IP + CUR.length; + while ( exc->IP != next_IP ) + { + if ( ( error = RunIns2( exc ) ) ) + goto LErrorLabel_; + } + } + oldch = ch; + break; + + /* Step into */ + case 's': + if ( exc->IP < exc->codeSize ) + + Step_into: + if ( ( error = RunIns2( exc ) ) ) + goto LErrorLabel_; + oldch = ch; + break; + + default: + PTRACE0(( "unknown command. Press ? for help\n" )); + oldch = '\0'; + } + + for ( A = 0; A < pts.n_points; A++ ) + { + diff = 0; + if ( save.org[A].x != pts.org[A].x ) diff |= 1; + if ( save.org[A].y != pts.org[A].y ) diff |= 2; + if ( save.cur[A].x != pts.cur[A].x ) diff |= 4; + if ( save.cur[A].y != pts.cur[A].y ) diff |= 8; + if ( save.touch[A] != pts.touch[A] ) diff |= 16; + + if ( diff ) + { + PTRACE0(( "%02hx ", A )); + + if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx "; + PTRACE0(( temp, save.touch[A] & 7 )); + + if ( diff & 1 ) temp = "(%08lx)"; else temp = " %08lx "; + PTRACE0(( temp, save.org[A].x )); + + if ( diff & 2 ) temp = "(%08lx)"; else temp = " %08lx "; + PTRACE0(( temp, save.org[A].y )); + + if ( diff & 4 ) temp = "(%08lx)"; else temp = " %08lx "; + PTRACE0(( temp, save.cur[A].x )); + + if ( diff & 8 ) temp = "(%08lx)"; else temp = " %08lx "; + PTRACE0(( temp, save.cur[A].y )); + + PTRACE0(( "\n" )); + + PTRACE0(( "%02hx ", A )); + + if ( diff & 16 ) temp = "[%01hx]"; else temp = " %01hx "; + PTRACE0(( temp, pts.touch[A] & 7 )); + + if ( diff & 1 ) temp = "[%08lx]"; else temp = " %08lx "; + PTRACE0(( temp, pts.org[A].x )); + + if ( diff & 2 ) temp = "[%08lx]"; else temp = " %08lx "; + PTRACE0(( temp, pts.org[A].y )); + + if ( diff & 4 ) temp = "[%08lx]"; else temp = " %08lx "; + PTRACE0(( temp, pts.cur[A].x )); + + if ( diff & 8 ) temp = "[%08lx]"; else temp = " %08lx "; + PTRACE0(( temp, pts.cur[A].y )); + + PTRACE0(( "\n\n" )); + } + } + } while ( TRUE ); + + LErrorLabel_: + + return error; + } + +#endif /* DEBUG_INTERPRETER */ + + +#endif /* TT_CONFIG_OPTION_NO_INTERPRETER */ + +/* END */ diff --git a/lib/ttinterp.h b/lib/ttinterp.h new file mode 100644 index 0000000..d991fa0 --- /dev/null +++ b/lib/ttinterp.h @@ -0,0 +1,54 @@ +/******************************************************************* + * + * ttinterp.h 2.2 + * + * TrueType bytecode intepreter. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 2.2 and 2.1: + * + * - a small bugfix in the Push opcodes + * + * Changes between 2.1 and 2.0: + * + * - created the TTExec component to take care of all execution + * context management. The interpreter has now one single + * function. + * + * - made some changes to support re-entrancy. The re-entrant + * interpreter is smaller! + * + ******************************************************************/ + +#ifndef TTINTERP_H +#define TTINTERP_H + +#include "ttconfig.h" +#include "ttobjs.h" + + +#ifdef __cplusplus + extern "C" { +#endif + + /* Run instructions in current execution context */ + + LOCAL_DEF TT_Error RunIns( PExecution_Context exc ); + +#ifdef __cplusplus + } +#endif + +#endif /* TTINTERP_H */ + + +/* END */ diff --git a/lib/ttload.c b/lib/ttload.c new file mode 100644 index 0000000..282828f --- /dev/null +++ b/lib/ttload.c @@ -0,0 +1,1574 @@ + +/******************************************************************* + * + * ttload.c 1.0 + * + * TrueType Tables Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "tttypes.h" +#include "ttdebug.h" +#include "ttcalc.h" +#include "ttfile.h" + +#include "tttables.h" +#include "ttobjs.h" + +#include "ttmemory.h" +#include "tttags.h" +#include "ttload.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_load + +/* In all functions, the stream is taken from the 'face' object */ +#define DEFINE_LOCALS DEFINE_LOAD_LOCALS( face->stream ) +#define DEFINE_LOCALS_WO_FRAME DEFINE_LOAD_LOCALS_WO_FRAME( face->stream ) + + +/******************************************************************* + * + * Function : LookUp_TrueType_Table + * + * Description : Looks for a TrueType table by name. + * + * Input : face face table to look for + * tag searched tag + * + * Output : Index of table if found, -1 otherwise. + * + ******************************************************************/ + + EXPORT_FUNC + Long TT_LookUp_Table( PFace face, + ULong tag ) + { + UShort i; + + + PTRACE4(( "TT_LookUp_Table( %08lx, %c%c%c%c )\n", + (Long)face, + (Char)(tag >> 24), + (Char)(tag >> 16), + (Char)(tag >> 8), + (Char)(tag) )); + + for ( i = 0; i < face->numTables; i++ ) + if ( face->dirTables[i].Tag == tag ) + return i; + + PTRACE4(( " Could not find table!\n" )); + return -1; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Collection + * + * Description : Loads the TTC table directory into face table. + * + * Input : face face record to look for + * + * Output : Error code. + * + ******************************************************************/ + + static TT_Error Load_TrueType_Collection( PFace face ) + { + DEFINE_LOCALS; + + ULong n; + + + PTRACE3(( "Load_TrueType_Collection( %08lx )\n", (long)face )); + + if ( FILE_Seek ( 0L ) || + ACCESS_Frame( 12L ) ) + return error; + + face->ttcHeader.Tag = GET_Tag4(); + face->ttcHeader.version = GET_Long(); + face->ttcHeader.DirCount = GET_Long(); + + FORGET_Frame(); + + if ( face->ttcHeader.Tag != TTAG_ttcf ) + { + face->ttcHeader.Tag = 0; + face->ttcHeader.version = 0; + face->ttcHeader.DirCount = 0; + + face->ttcHeader.TableDirectory = NULL; + + PTRACE3(("skipped.\n")); + + return TT_Err_File_Is_Not_Collection; + } + + if ( ALLOC_ARRAY( face->ttcHeader.TableDirectory, + face->ttcHeader.DirCount, + ULong ) || + ACCESS_Frame( face->ttcHeader.DirCount * 4L ) ) + return error; + + for ( n = 0; n < face->ttcHeader.DirCount; n++ ) + face->ttcHeader.TableDirectory[n] = GET_ULong(); + + FORGET_Frame(); + + PTRACE3(( "collections directory loaded.\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Directory + * + * Description : Loads the table directory into face table. + * + * Input : face face record to look for + * + * faceIndex the index of the TrueType font, when + * we're opening a collection. + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Directory( PFace face, ULong faceIndex ) + { + DEFINE_LOCALS; + + UShort n, limit; + TTableDir tableDir; + + PTableDirEntry entry; + + + PTRACE2(("Load_TT_Directory( %08lx, %ld )\n", (long)face, faceIndex)); + + error = Load_TrueType_Collection( face ); + + if ( error ) + { + if ( error != TT_Err_File_Is_Not_Collection ) + return error; + + /* the file isn't a collection, exit if we're asking */ + /* for a collected font */ + if ( faceIndex != 0 ) + return error; + + /* Now skip to the beginning of the file */ + if ( FILE_Seek( 0L ) ) + return error; + } + else + { + /* The file is a collection. Check the font index */ + if ( faceIndex >= face->ttcHeader.DirCount ) + return TT_Err_Invalid_Argument; + + /* select a TrueType font in the ttc file */ + if ( FILE_Seek( face->ttcHeader.TableDirectory[faceIndex] ) ) + return error; + } + + if ( ACCESS_Frame( 12L ) ) + return error; + + tableDir.version = GET_Long(); + tableDir.numTables = GET_UShort(); + + tableDir.searchRange = GET_UShort(); + tableDir.entrySelector = GET_UShort(); + tableDir.rangeShift = GET_UShort(); + + FORGET_Frame(); + + PTRACE2(( "-- Tables count : %12u\n", tableDir.numTables )); + PTRACE2(( "-- Format version : %08lx\n", tableDir.version )); + + /* Check that we have a 'sfnt' format there */ + + if ( tableDir.version != 0x00010000 && /* MS fonts */ + tableDir.version != 0x74727565 && /* Mac fonts */ + tableDir.version != 0x00000000 ) /* some Korean fonts */ + { + PERROR(( "!! invalid file format" )); + return TT_Err_Invalid_File_Format; + } + + face->numTables = tableDir.numTables; + + if ( ALLOC_ARRAY( face->dirTables, + face->numTables, + TTableDirEntry ) ) + return error; + + if ( ACCESS_Frame( face->numTables * 16L ) ) + return error; + + limit = face->numTables; + entry = face->dirTables; + + for ( n = 0; n < limit; n++ ) + { /* loop through the tables and get all entries */ + entry->Tag = GET_Tag4(); + entry->CheckSum = GET_ULong(); + entry->Offset = GET_Long(); + entry->Length = GET_Long(); + + PTRACE2(( " %c%c%c%c - %08lx - %08lx\n", + (Char)(entry->Tag >> 24), + (Char)(entry->Tag >> 16), + (Char)(entry->Tag >> 8 ), + (Char)(entry->Tag), + entry->Offset, + entry->Length )); + entry++; + } + + FORGET_Frame(); + + PTRACE2(( "Directory loaded\n\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_MaxProfile + * + * Description : Loads the maxp table into face table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_MaxProfile( PFace face ) + { + DEFINE_LOCALS; + + Long i; + PMaxProfile maxProfile = &face->maxProfile; + + + PTRACE2(( "Load_TT_MaxProfile( %08lx )\n", (long)face )); + + if ( ( i = TT_LookUp_Table( face, TTAG_maxp ) ) < 0 ) + return TT_Err_Max_Profile_Missing; + + if ( FILE_Seek( face->dirTables[i].Offset ) ) /* seek to maxprofile */ + return error; + + if ( ACCESS_Frame( 32L ) ) /* read into frame */ + return error; + + /* read frame data into face table */ + maxProfile->version = GET_ULong(); + + maxProfile->numGlyphs = GET_UShort(); + + maxProfile->maxPoints = GET_UShort(); + maxProfile->maxContours = GET_UShort(); + maxProfile->maxCompositePoints = GET_UShort(); + maxProfile->maxCompositeContours = GET_UShort(); + + maxProfile->maxZones = GET_UShort(); + maxProfile->maxTwilightPoints = GET_UShort(); + + maxProfile->maxStorage = GET_UShort(); + maxProfile->maxFunctionDefs = GET_UShort(); + maxProfile->maxInstructionDefs = GET_UShort(); + maxProfile->maxStackElements = GET_UShort(); + maxProfile->maxSizeOfInstructions = GET_UShort(); + maxProfile->maxComponentElements = GET_UShort(); + maxProfile->maxComponentDepth = GET_UShort(); + + FORGET_Frame(); + + /* XXX : an adjustement that is necessary to load certain */ + /* broken fonts like "Keystrokes MT" :-( */ + /* */ + /* We allocate 64 function entries by default when */ + /* the maxFunctionDefs field is null. */ + + if (maxProfile->maxFunctionDefs == 0) + maxProfile->maxFunctionDefs = 64; + + face->numGlyphs = maxProfile->numGlyphs; + + face->maxPoints = MAX( maxProfile->maxCompositePoints, + maxProfile->maxPoints ); + face->maxContours = MAX( maxProfile->maxCompositeContours, + maxProfile->maxContours ); + face->maxComponents = maxProfile->maxComponentElements + + maxProfile->maxComponentDepth; + + /* XXX: Some fonts have maxComponents set to 0; we will */ + /* then use 16 of them by default. */ + if ( face->maxComponents == 0 ) + face->maxComponents = 16; + + /* We also increase maxPoints and maxContours in order to support */ + /* some broken fonts. */ + face->maxPoints += 8; + face->maxContours += 4; + + PTRACE2(( "GASP loaded.\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Gasp + * + * Description : Loads the TrueType Gasp table into the face + * table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Gasp( PFace face ) + { + DEFINE_LOCALS; + + Long i; + UShort j; + TGasp* gas; + GaspRange* gaspranges; + + + PTRACE2(( "Load_TT_Gasp( %08lx )\n", (long)face )); + + if ( ( i = TT_LookUp_Table( face, TTAG_gasp ) ) < 0 ) + return TT_Err_Ok; /* gasp table is not required */ + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 4L ) ) + return error; + + gas = &face->gasp; + + gas->version = GET_UShort(); + gas->numRanges = GET_UShort(); + + FORGET_Frame(); + + PTRACE3(( "number of ranges = %d\n", gas->numRanges )); + + if ( ALLOC_ARRAY( gaspranges, gas->numRanges, GaspRange ) || + ACCESS_Frame( gas->numRanges * 4L ) ) + goto Fail; + + face->gasp.gaspRanges = gaspranges; + + for ( j = 0; j < gas->numRanges; j++ ) + { + gaspranges[j].maxPPEM = GET_UShort(); + gaspranges[j].gaspFlag = GET_UShort(); + + PTRACE3(( " [max:%d flag:%d]", + gaspranges[j].maxPPEM, + gaspranges[j].gaspFlag )); + } + PTRACE3(("\n")); + + FORGET_Frame(); + + PTRACE2(( "GASP loaded\n" )); + return TT_Err_Ok; + + Fail: + FREE( gaspranges ); + gas->numRanges = 0; + return error; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Header + * + * Description : Loads the TrueType header table into the face + * table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Header( PFace face ) + { + DEFINE_LOCALS; + + Long i; + TT_Header* header; + + + PTRACE2(( "Load_TT_Header( %08lx )\n", (long)face )); + + if ( ( i = TT_LookUp_Table( face, TTAG_head ) ) < 0 ) + { + PTRACE0(( "Font Header is missing !!\n" )); + return TT_Err_Header_Table_Missing; + } + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 54L ) ) + return error; + + header = &face->fontHeader; + + header->Table_Version = GET_ULong(); + header->Font_Revision = GET_ULong(); + + header->CheckSum_Adjust = GET_Long(); + header->Magic_Number = GET_Long(); + + header->Flags = GET_UShort(); + header->Units_Per_EM = GET_UShort(); + + header->Created [0] = GET_Long(); + header->Created [1] = GET_Long(); + header->Modified[0] = GET_Long(); + header->Modified[1] = GET_Long(); + + header->xMin = GET_Short(); + header->yMin = GET_Short(); + header->xMax = GET_Short(); + header->yMax = GET_Short(); + + header->Mac_Style = GET_UShort(); + header->Lowest_Rec_PPEM = GET_UShort(); + + header->Font_Direction = GET_Short(); + header->Index_To_Loc_Format = GET_Short(); + header->Glyph_Data_Format = GET_Short(); + + FORGET_Frame(); + + PTRACE2(( " Units per EM : %8u\n", header->Units_Per_EM )); + PTRACE2(( " IndexToLoc : %8d\n", header->Index_To_Loc_Format )); + PTRACE2(( "Font Header Loaded.\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Metrics + * + * Description : Loads the horizontal or vertical metrics table + * into face object. + * + * Input : face + * vertical set to true when loading the vmtx table, + * or false for hmtx + * + * Output : Error code. + * + ******************************************************************/ + + static + TT_Error Load_TrueType_Metrics( PFace face, + Bool vertical ) + { + DEFINE_LOCALS; + + Long n, num_shorts, num_shorts_checked, num_longs; + + PLongMetrics* longs; + PShortMetrics* shorts; + + PLongMetrics long_metric; + + + PTRACE2(( "Load_TT_%s_Metrics( %08lx )\n", + vertical ? "Vertical" : "Horizontal", + (long)face )); + + if ( vertical ) + { + /* The table is optional, quit silently if it wasn't found */ + /* XXX : Some fonts have a valid vertical header with a non-null */ + /* "number_of_VMetrics" fields, but no corresponding */ + /* 'vmtx' table to get the metrics from (e.g. mingliu) */ + /* */ + /* For safety, we set the field to 0 ! */ + /* */ + n = TT_LookUp_Table( face, TTAG_vmtx ); + if ( n < 0 ) + { + /* Set the number_Of_VMetrics to 0! */ + PTRACE2(( " no vertical header in file.\n" )); + face->verticalHeader.number_Of_VMetrics = 0; + return TT_Err_Ok; + } + + num_longs = face->verticalHeader.number_Of_VMetrics; + longs = (PLongMetrics*)&face->verticalHeader.long_metrics; + shorts = (PShortMetrics*)&face->verticalHeader.short_metrics; + } + else + { + if ( ( n = TT_LookUp_Table( face, TTAG_hmtx ) ) < 0 ) + { + PERROR(( "!! No Horizontal metrics in file !!\n" )); + return TT_Err_Hmtx_Table_Missing; + } + + num_longs = face->horizontalHeader.number_Of_HMetrics; + longs = (PLongMetrics*)&face->horizontalHeader.long_metrics; + shorts = (PShortMetrics*)&face->horizontalHeader.short_metrics; + } + + /* never trust derived values! */ + + num_shorts = face->maxProfile.numGlyphs - num_longs; + num_shorts_checked = ( face->dirTables[n].Length - num_longs * 4 ) / 2; + + if ( num_shorts < 0 ) /* sanity check */ + { + PERROR(( "!! more metrics than glyphs!\n" )); + if ( vertical ) + return TT_Err_Invalid_Vert_Metrics; + else + return TT_Err_Invalid_Horiz_Metrics; + } + + if ( ALLOC_ARRAY( *longs, num_longs, TLongMetrics ) || + ALLOC_ARRAY( *shorts, num_shorts, TShortMetrics ) ) + return error; + + if ( FILE_Seek( face->dirTables[n].Offset ) || + ACCESS_Frame( face->dirTables[n].Length ) ) + return error; + + long_metric = *longs; + for ( n = 0; n < num_longs; n++ ) + { + long_metric->advance = GET_UShort(); + long_metric->bearing = GET_Short(); + long_metric++; + } + + /* do we have an inconsistent number of metric values? */ + + if ( num_shorts > num_shorts_checked ) + { + for ( n = 0; n < num_shorts_checked; n++ ) + (*shorts)[n] = GET_Short(); + + /* we fill up the missing left side bearings with the */ + /* last valid value. Since this will occur for buggy CJK */ + /* fonts usually, nothing serious will happen. */ + + for ( n = num_shorts_checked; n < num_shorts; n++ ) + (*shorts)[n] = (*shorts)[num_shorts_checked - 1]; + } + else + { + for ( n = 0; n < num_shorts; n++ ) + (*shorts)[n] = GET_Short(); + } + + FORGET_Frame(); + + PTRACE2(( "loaded\n" )); + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Metrics_Header + * + * Description : Loads either the "hhea" or "vhea" table in memory + * + * Input : face face table to look for + * vertical a boolean. When set, queries the optional + * "vhea" table. Otherwise, load the mandatory + * "hhea" horizontal header. + * + * Output : Error code. + * + * Note : This function now loads the corresponding metrics table + * (either hmtx or vmtx) and attaches it to the header. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Metrics_Header( PFace face, + Bool vertical ) + { + DEFINE_LOCALS; + + Long i; + + TT_Horizontal_Header* header; + + + PTRACE2(( vertical ? "Vertical header" : "Horizontal header " )); + + if ( vertical ) + { + face->verticalInfo = 0; + + /* The vertical header table is optional, so return quietly if */ + /* we don't find it.. */ + if ( ( i = TT_LookUp_Table( face, TTAG_vhea ) ) < 0 ) + return TT_Err_Ok; + + face->verticalInfo = 1; + header = (TT_Horizontal_Header*)&face->verticalHeader; + } + else + { + /* The orizontal header is mandatory, return an error if we */ + /* don't find it. */ + if ( ( i = TT_LookUp_Table( face, TTAG_hhea ) ) < 0 ) + return TT_Err_Horiz_Header_Missing; + + header = &face->horizontalHeader; + } + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 36L ) ) + return error; + + header->Version = GET_ULong(); + header->Ascender = GET_Short(); + header->Descender = GET_Short(); + header->Line_Gap = GET_Short(); + + header->advance_Width_Max = GET_UShort(); + + header->min_Left_Side_Bearing = GET_Short(); + header->min_Right_Side_Bearing = GET_Short(); + header->xMax_Extent = GET_Short(); + header->caret_Slope_Rise = GET_Short(); + header->caret_Slope_Run = GET_Short(); + + header->Reserved0 = GET_Short(); /* this is caret_Offset for + vertical headers */ + header->Reserved1 = GET_Short(); + header->Reserved2 = GET_Short(); + header->Reserved3 = GET_Short(); + header->Reserved4 = GET_Short(); + + header->metric_Data_Format = GET_Short(); + header->number_Of_HMetrics = GET_UShort(); + + FORGET_Frame(); + + header->long_metrics = NULL; + header->short_metrics = NULL; + + PTRACE2(( "loaded\n" )); + + /* Now try to load the corresponding metrics */ + + return Load_TrueType_Metrics( face, vertical ); + } + + +/******************************************************************* + * + * Function : Load_TrueType_Locations + * + * Description : Loads the location table into face table. + * + * Input : face face table to look for + * + * Output : Error code. + * + * NOTE: + * The Font Header *must* be loaded in the leading segment + * calling this function. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Locations( PFace face ) + { + DEFINE_LOCALS; + + Long n, limit; + Short LongOffsets; + + + PTRACE2(( "Locations " )); + + LongOffsets = face->fontHeader.Index_To_Loc_Format; + + if ( ( n = TT_LookUp_Table( face, TTAG_loca ) ) < 0 ) + return TT_Err_Locations_Missing; + + if ( FILE_Seek( face->dirTables[n].Offset ) ) + return error; + + if ( LongOffsets != 0 ) + { + face->numLocations = face->dirTables[n].Length >> 2; + + PTRACE2(( "(32 bit offsets): %12lu ", + face->numLocations )); + + if ( ALLOC_ARRAY( face->glyphLocations, + face->numLocations, + Long ) ) + return error; + + if ( ACCESS_Frame( face->numLocations * 4L ) ) + return error; + + limit = face->numLocations; + + for ( n = 0; n < limit; n++ ) + face->glyphLocations[n] = GET_Long(); + + FORGET_Frame(); + } + else + { + face->numLocations = face->dirTables[n].Length >> 1; + + PTRACE2(( "(16 bit offsets): %12lu ", + face->numLocations )); + + if ( ALLOC_ARRAY( face->glyphLocations, + face->numLocations, + Long ) ) + return error; + + if ( ACCESS_Frame( face->numLocations * 2L ) ) + return error; + + limit = face->numLocations; + + for ( n = 0; n < limit; n++ ) + face->glyphLocations[n] = + (Long)((ULong)GET_UShort() * 2); + + FORGET_Frame(); + } + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Names + * + * Description : Loads the name table into face table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Names( PFace face ) + { + DEFINE_LOCALS; + + UShort i, bytes; + Long n; + PByte storage; + + TName_Table* names; + TNameRec* namerec; + + + PTRACE2(( "Names " )); + + if ( ( n = TT_LookUp_Table( face, TTAG_name ) ) < 0 ) + { + /* The name table is required so indicate failure. */ + PTRACE2(( "is missing!\n" )); + + return TT_Err_Name_Table_Missing; + } + + /* Seek to the beginning of the table and check the frame access. */ + /* The names table has a 6 byte header. */ + if ( FILE_Seek( face->dirTables[n].Offset ) || + ACCESS_Frame( 6L ) ) + return error; + + names = &face->nameTable; + + /* Load the initial names data. */ + names->format = GET_UShort(); + names->numNameRecords = GET_UShort(); + names->storageOffset = GET_UShort(); + + FORGET_Frame(); + + /* Allocate the array of name records. */ + if ( ALLOC_ARRAY( names->names, + names->numNameRecords, + TNameRec ) || + ACCESS_Frame( names->numNameRecords * 12L ) ) + { + names->numNameRecords = 0; + goto Fail; + } + + /* Load the name records and determine how much storage is needed */ + /* to hold the strings themselves. */ + + for ( i = bytes = 0; i < names->numNameRecords; i++ ) + { + namerec = names->names + i; + namerec->platformID = GET_UShort(); + namerec->encodingID = GET_UShort(); + namerec->languageID = GET_UShort(); + namerec->nameID = GET_UShort(); + namerec->stringLength = GET_UShort(); + namerec->stringOffset = GET_UShort(); + +#if 0 + /* check the ids */ + if ( namerec->platformID <= 3 ) + { +#endif + /* this test takes care of 'holes' in the names tables, as */ + /* reported by Erwin */ + if ( (namerec->stringOffset + namerec->stringLength) > bytes ) + bytes = namerec->stringOffset + namerec->stringLength; +#if 0 + } +#endif + } + + FORGET_Frame(); + + /* Allocate storage for the strings if they exist. */ + + names->storage = NULL; + + if ( bytes > 0 ) + { + if ( ALLOC( storage, bytes ) || + FILE_Read_At( face->dirTables[n].Offset + names->storageOffset, + (void*)storage, + bytes ) ) + goto Fail_Storage; + + names->storage = storage; + + /* Go through and assign the string pointers to the name records. */ + + for ( i = 0; i < names->numNameRecords; i++ ) + { + namerec = names->names + i; + namerec->string = storage + names->names[i].stringOffset; + +/* It is possible (but rather unlikely) that a new platform ID will be */ +/* added by Apple, so we can't rule out IDs > 3. */ + +#if 0 + if ( namerec->platformID <= 3 ) + namerec->string = storage + names->names[i].stringOffset; + else + { + namerec->string = NULL; + namerec->stringLength = 0; + } +#endif + } + } + +#ifdef DEBUG_LEVEL_TRACE + + for ( i = 0; i < names->numNameRecords; i++ ) + { + int j; + + + PTRACE2(( "%d %d %x %d ", + names->names[i].platformID, + names->names[i].encodingID, + names->names[i].languageID, + names->names[i].nameID )); + + /* I know that M$ encoded strings are Unicode, */ + /* but this works reasonable well for debugging purposes. */ + for ( j = 0; j < names->names[i].stringLength; j++ ) + { + if (names->names[i].string) + { + Char c = *(names->names[i].string + j); + + + if ( (Byte)c < 128 ) + PTRACE2(( "%c", c )); + } + } + + PTRACE2(( "\n" )); + } + +#endif /* DEBUG_LEVEL_TRACE */ + + PTRACE2(( "loaded\n" )); + return TT_Err_Ok; + + Fail_Storage: + FREE( storage ); + + Fail: + Free_TrueType_Names( face ); + return error; + } + + +/******************************************************************* + * + * Function : Free_TrueType_Names + * + * Description : Frees a name table. + * + * Input : face face table to look for + * + * Output : TT_Err_Ok. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Free_TrueType_Names( PFace face ) + { + TName_Table* names = &face->nameTable; + + + /* free strings table */ + FREE( names->names ); + + /* free strings storage */ + FREE( names->storage ); + + names->numNameRecords = 0; + names->format = 0; + names->storageOffset = 0; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_CVT + * + * Description : Loads cvt table into resident table. + * + * Input : face face table to look for + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_CVT( PFace face ) + { + DEFINE_LOCALS; + + Long n, limit; + + + PTRACE2(( "CVT " )); + + if ( ( n = TT_LookUp_Table( face, TTAG_cvt ) ) < 0 ) + { + PTRACE2(( "is missing!\n" )); + + face->cvtSize = 0; + face->cvt = NULL; + return TT_Err_Ok; + } + + face->cvtSize = face->dirTables[n].Length / 2; + + if ( ALLOC_ARRAY( face->cvt, + face->cvtSize, + Short ) ) + return error; + + if ( FILE_Seek( face->dirTables[n].Offset ) || + ACCESS_Frame( face->cvtSize * 2L ) ) + return error; + + limit = face->cvtSize; + + for ( n = 0; n < limit; n++ ) + face->cvt[n] = GET_Short(); + + FORGET_Frame(); + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_CMap + * + * Description : Loads the cmap directory in memory. + * The cmaps themselves are loaded in ttcmap.c . + * + * Input : face + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_CMap( PFace face ) + { + DEFINE_LOCALS; + + Long off, table_start; + Long n, limit; + + TCMapDir cmap_dir; + TCMapDirEntry entry_; + PCMapTable cmap; + + + PTRACE2(( "CMaps " )); + + if ( ( n = TT_LookUp_Table( face, TTAG_cmap ) ) < 0 ) + return TT_Err_CMap_Table_Missing; + + table_start = face->dirTables[n].Offset; + + if ( ( FILE_Seek( table_start ) ) || + ( ACCESS_Frame( 4L ) ) ) /* 4 bytes cmap header */ + return error; + + cmap_dir.tableVersionNumber = GET_UShort(); + cmap_dir.numCMaps = GET_UShort(); + + FORGET_Frame(); + + off = FILE_Pos(); /* save offset to cmapdir[] which follows */ + + /* save space in face table for cmap tables */ + if ( ALLOC_ARRAY( face->cMaps, + cmap_dir.numCMaps, + TCMapTable ) ) + return error; + + face->numCMaps = cmap_dir.numCMaps; + + limit = face->numCMaps; + cmap = face->cMaps; + + for ( n = 0; n < limit; n++ ) + { + if ( FILE_Seek( off ) || + ACCESS_Frame( 8L ) ) + return error; + + /* extra code using entry_ for platxxx could be cleaned up later */ + cmap->loaded = FALSE; + cmap->platformID = entry_.platformID = GET_UShort(); + cmap->platformEncodingID = entry_.platformEncodingID = GET_UShort(); + + entry_.offset = GET_Long(); + + FORGET_Frame(); + + off = FILE_Pos(); + + if ( FILE_Seek( table_start + entry_.offset ) || + ACCESS_Frame( 6L ) ) + return error; + + cmap->format = GET_UShort(); + cmap->length = GET_UShort(); + cmap->version = GET_UShort(); + + FORGET_Frame(); + + cmap->offset = FILE_Pos(); + + cmap++; + } + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Programs + * + * Description : Loads the font (fpgm) and cvt programs into the + * face table. + * + * Input : face + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Programs( PFace face ) + { + DEFINE_LOCALS_WO_FRAME; + + Long n; + + + PTRACE2(( "Font program " )); + + /* The font program is optional */ + if ( ( n = TT_LookUp_Table( face, TTAG_fpgm ) ) < 0 ) + { + face->fontProgram = NULL; + face->fontPgmSize = 0; + + PTRACE2(( "is missing!\n" )); + } + else + { + face->fontPgmSize = face->dirTables[n].Length; + + if ( ALLOC( face->fontProgram, + face->fontPgmSize ) || + FILE_Read_At( face->dirTables[n].Offset, + (void*)face->fontProgram, + face->fontPgmSize ) ) + return error; + + PTRACE2(( "loaded, %12d bytes\n", face->fontPgmSize )); + } + + PTRACE2(( "Prep program " )); + + if ( ( n = TT_LookUp_Table( face, TTAG_prep ) ) < 0 ) + { + face->cvtProgram = NULL; + face->cvtPgmSize = 0; + + PTRACE2(( "is missing!\n" )); + } + else + { + face->cvtPgmSize = face->dirTables[n].Length; + + if ( ALLOC( face->cvtProgram, + face->cvtPgmSize ) || + FILE_Read_At( face->dirTables[n].Offset, + (void*)face->cvtProgram, + face->cvtPgmSize ) ) + return error; + + PTRACE2(( "loaded, %12d bytes\n", face->cvtPgmSize )); + } + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_OS2 + * + * Description : Loads the OS2 Table. + * + * Input : face + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_OS2( PFace face ) + { + DEFINE_LOCALS; + + Long i; + TT_OS2* os2; + + + PTRACE2(( "OS/2 Table " )); + + /* We now support old Mac fonts where the OS/2 table doesn't */ + /* exist. Simply put, we set the `version' field to 0xFFFF */ + /* and test this value each time we need to access the table. */ + if ( ( i = TT_LookUp_Table( face, TTAG_OS2 ) ) < 0 ) + { + PTRACE2(( "is missing\n!" )); + face->os2.version = 0xFFFF; + error = TT_Err_Ok; + return TT_Err_Ok; + } + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 78L ) ) + return error; + + os2 = &face->os2; + + os2->version = GET_UShort(); + os2->xAvgCharWidth = GET_Short(); + os2->usWeightClass = GET_UShort(); + os2->usWidthClass = GET_UShort(); + os2->fsType = GET_Short(); + os2->ySubscriptXSize = GET_Short(); + os2->ySubscriptYSize = GET_Short(); + os2->ySubscriptXOffset = GET_Short(); + os2->ySubscriptYOffset = GET_Short(); + os2->ySuperscriptXSize = GET_Short(); + os2->ySuperscriptYSize = GET_Short(); + os2->ySuperscriptXOffset = GET_Short(); + os2->ySuperscriptYOffset = GET_Short(); + os2->yStrikeoutSize = GET_Short(); + os2->yStrikeoutPosition = GET_Short(); + os2->sFamilyClass = GET_Short(); + + for ( i = 0; i < 10; i++ ) + os2->panose[i] = GET_Byte(); + + os2->ulUnicodeRange1 = GET_ULong(); + os2->ulUnicodeRange2 = GET_ULong(); + os2->ulUnicodeRange3 = GET_ULong(); + os2->ulUnicodeRange4 = GET_ULong(); + + for ( i = 0; i < 4; i++ ) + os2->achVendID[i] = GET_Byte(); + + os2->fsSelection = GET_UShort(); + os2->usFirstCharIndex = GET_UShort(); + os2->usLastCharIndex = GET_UShort(); + os2->sTypoAscender = GET_Short(); + os2->sTypoDescender = GET_Short(); + os2->sTypoLineGap = GET_Short(); + os2->usWinAscent = GET_UShort(); + os2->usWinDescent = GET_UShort(); + + FORGET_Frame(); + + if ( os2->version >= 0x0001 ) + { + /* only version 1 tables */ + + if ( ACCESS_Frame( 8L ) ) /* read into frame */ + return error; + + os2->ulCodePageRange1 = GET_ULong(); + os2->ulCodePageRange2 = GET_ULong(); + + FORGET_Frame(); + } + else + { + os2->ulCodePageRange1 = 0; + os2->ulCodePageRange2 = 0; + } + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_PostScript + * + * Description : Loads the post table into face table. + * + * Input : face face table to look for + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_PostScript( PFace face ) + { + DEFINE_LOCALS; + + Long i; + + TT_Postscript* post = &face->postscript; + + + PTRACE2(( "PostScript " )); + + if ( ( i = TT_LookUp_Table( face, TTAG_post ) ) < 0 ) + return TT_Err_Post_Table_Missing; + + if ( FILE_Seek( face->dirTables[i].Offset ) || + ACCESS_Frame( 32L ) ) + return error; + + /* read frame data into face table */ + + post->FormatType = GET_ULong(); + post->italicAngle = GET_ULong(); + post->underlinePosition = GET_Short(); + post->underlineThickness = GET_Short(); + post->isFixedPitch = GET_ULong(); + post->minMemType42 = GET_ULong(); + post->maxMemType42 = GET_ULong(); + post->minMemType1 = GET_ULong(); + post->maxMemType1 = GET_ULong(); + + FORGET_Frame(); + + /* we don't load the glyph names, we do that in a */ + /* library extension (ftxpost). */ + + PTRACE2(( "loaded\n" )); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Hdmx + * + * Description : Loads the horizontal device metrics table. + * + * Input : face face object to look for + * + * Output : SUCCESS on success. FAILURE on error. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Hdmx( PFace face ) + { + DEFINE_LOCALS; + + TT_Hdmx_Record* rec; + TT_Hdmx hdmx; + Long table; + UShort n, num_glyphs; + Long record_size; + + + hdmx.version = 0; + hdmx.num_records = 0; + hdmx.records = 0; + + face->hdmx = hdmx; + + if ( ( table = TT_LookUp_Table( face, TTAG_hdmx ) ) < 0 ) + return TT_Err_Ok; + + if ( FILE_Seek( face->dirTables[table].Offset ) || + ACCESS_Frame( 8L ) ) + return error; + + hdmx.version = GET_UShort(); + hdmx.num_records = GET_Short(); + record_size = GET_Long(); + + FORGET_Frame(); + + /* Only recognize format 0 */ + + if ( hdmx.version != 0 ) + return TT_Err_Ok; + + if ( ALLOC( hdmx.records, sizeof ( TT_Hdmx_Record ) * hdmx.num_records ) ) + return error; + + num_glyphs = face->numGlyphs; + record_size -= num_glyphs+2; + rec = hdmx.records; + + for ( n = 0; n < hdmx.num_records; n++ ) + { + /* read record */ + + if ( ACCESS_Frame( 2L ) ) + goto Fail; + + rec->ppem = GET_Byte(); + rec->max_width = GET_Byte(); + + FORGET_Frame(); + + if ( ALLOC( rec->widths, num_glyphs ) || + FILE_Read( rec->widths, num_glyphs ) ) + goto Fail; + + /* skip padding bytes */ + if ( record_size > 0 ) + if ( FILE_Skip( record_size ) ) + goto Fail; + + rec++; + } + + face->hdmx = hdmx; + + return TT_Err_Ok; + + Fail: + for ( n = 0; n < hdmx.num_records; n++ ) + FREE( hdmx.records[n].widths ); + + FREE( hdmx.records ); + return error; + } + + +/******************************************************************* + * + * Function : Free_TrueType_Hdmx + * + * Description : Frees the horizontal device metrics table. + * + * Input : face face object to look for + * + * Output : TT_Err_Ok. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Free_TrueType_Hdmx( PFace face ) + { + UShort n; + + + if ( !face ) + return TT_Err_Ok; + + for ( n = 0; n < face->hdmx.num_records; n++ ) + FREE( face->hdmx.records[n].widths ); + + FREE( face->hdmx.records ); + face->hdmx.num_records = 0; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Load_TrueType_Any + * + * Description : Loads any font table into client memory. Used by + * the TT_Get_Font_Data() API function. + * + * Input : face face object to look for + * + * tag tag of table to load. Use the value 0 if you + * want to access the whole font file, else set + * this parameter to a valid TrueType table tag + * that you can forge with the MAKE_TT_TAG + * macro. + * + * offset starting offset in the table (or the file + * if tag == 0 ) + * + * buffer address of target buffer + * + * length address of decision variable : + * + * if length == NULL : + * load the whole table. returns an + * an error if 'offset' == 0 !! + * + * if *length == 0 : + * exit immediately, returning the + * length of the given table, or of + * the font file, depending on the + * value of 'tag' + * + * if *length != 0 : + * load the next 'length' bytes of + * table or font, starting at offset + * 'offset' (in table or font too). + * + * Output : Error condition + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Load_TrueType_Any( PFace face, + ULong tag, + Long offset, + void* buffer, + Long* length ) + { + TT_Stream stream; + TT_Error error; + Long table; + ULong size; + + + if ( tag != 0 ) + { + /* look for tag in font directory */ + table = TT_LookUp_Table( face, tag ); + if ( table < 0 ) + return TT_Err_Table_Missing; + + offset += face->dirTables[table].Offset; + size = face->dirTables[table].Length; + } + else + /* tag = 0 -- the use want to access the font file directly */ + size = TT_Stream_Size( face->stream ); + + if ( length && *length == 0 ) + { + *length = size; + return TT_Err_Ok; + } + + if ( length ) + size = *length; + + if ( !USE_Stream( face->stream, stream ) ) + (void)FILE_Read_At( offset, buffer, size ); + DONE_Stream( stream ); + + return error; + } + + +/* END */ diff --git a/lib/ttload.h b/lib/ttload.h new file mode 100644 index 0000000..47acae9 --- /dev/null +++ b/lib/ttload.h @@ -0,0 +1,217 @@ +/******************************************************************* + * + * ttload.h 1.1 + * + * TrueType Tables Loader. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 1.1 and 1.0 : + * + * - add function Load_TrueType_Any used by TT_Get_Font_Data + * + ******************************************************************/ + +#ifndef TTLOAD_H +#define TTLOAD_H + +#include "ttconfig.h" +#include "tttypes.h" +#include "ttobjs.h" + +#ifdef __cplusplus + extern "C" { +#endif + + EXPORT_DEF + Long TT_LookUp_Table( PFace face, ULong tag ); + + LOCAL_DEF TT_Error Load_TrueType_Directory ( PFace face, + ULong faceIndex ); + + LOCAL_DEF TT_Error Load_TrueType_MaxProfile ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Gasp ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Header ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Locations ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Names ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_CVT ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_CMap ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Programs ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_OS2 ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_PostScript ( PFace face ); + LOCAL_DEF TT_Error Load_TrueType_Hdmx ( PFace face ); + + LOCAL_DEF TT_Error Load_TrueType_Metrics_Header( PFace face, + Bool vertical ); + + LOCAL_DEF TT_Error Load_TrueType_Any( PFace face, + ULong tag, + Long offset, + void* buffer, + Long* length ); + + LOCAL_DEF TT_Error Free_TrueType_Names( PFace face ); + LOCAL_DEF TT_Error Free_TrueType_Hdmx ( PFace face ); + + +/* The following macros are defined to simplify the writing of */ +/* the various table and glyph loaders. */ + +/* For examples see the code in ttload.c, ttgload.c etc. */ + +#define USE_Stream( original, duplicate ) \ + ( (error = TT_Use_Stream( original, &duplicate )) != TT_Err_Ok ) + +#define DONE_Stream( _stream ) \ + TT_Done_Stream( &_stream ) + +/* Define a file frame -- use it only when needed */ +#define DEFINE_A_FRAME TFileFrame frame = TT_Null_FileFrame + +/* Define a stream -- use it only when needed */ +#define DEFINE_A_STREAM TT_Stream stream + + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE /* re-entrant implementation */ + +/* The following macros define the necessary local */ +/* variables used to access streams and frames. */ + +/* Define stream locals with frame */ +#define DEFINE_STREAM_LOCALS \ + TT_Error error; \ + DEFINE_A_STREAM; \ + DEFINE_A_FRAME + +/* Define stream locals without frame */ +#define DEFINE_STREAM_LOCALS_WO_FRAME \ + TT_Error error; \ + DEFINE_A_STREAM + +/* Define locals with a predefined stream in reentrant mode -- see ttload.c */ +#define DEFINE_LOAD_LOCALS( STREAM ) \ + TT_Error error; \ + DEFINE_A_STREAM = (STREAM); \ + DEFINE_A_FRAME + +/* Define locals without frame with a predefined stream - see ttload.c */ +#define DEFINE_LOAD_LOCALS_WO_FRAME( STREAM ) \ + TT_Error error; \ + DEFINE_A_STREAM = (STREAM) + +/* Define all locals necessary to access a font file */ +#define DEFINE_ALL_LOCALS \ + TT_Error error; \ + DEFINE_A_STREAM; \ + DEFINE_A_FRAME + + +#define ACCESS_Frame( _size_ ) \ + ( (error = TT_Access_Frame( stream, \ + &frame, \ + (Long)(_size_) )) != TT_Err_Ok ) +#define CHECK_ACCESS_Frame( _size_ ) \ + ( (error = TT_Check_And_Access_Frame( stream, \ + &frame, \ + (Long)(_size_) )) != TT_Err_Ok ) +#define FORGET_Frame() \ + ( (void)TT_Forget_Frame( &frame ) ) + +#define GET_Byte() TT_Get_Byte ( &frame ) +#define GET_Char() TT_Get_Char ( &frame ) +#define GET_UShort() TT_Get_UShort( &frame ) +#define GET_Short() TT_Get_Short ( &frame ) +#define GET_Long() TT_Get_Long ( &frame ) +#define GET_ULong() TT_Get_ULong ( &frame ) +#define GET_Tag4() TT_Get_ULong ( &frame ) + +#define FILE_Pos() TT_File_Pos ( stream ) + +#define FILE_Seek( _position_ ) \ + ( (error = TT_Seek_File( stream, \ + (Long)(_position_) )) != TT_Err_Ok ) +#define FILE_Skip( _distance_ ) \ + ( (error = TT_Skip_File( stream, \ + (Long)(_distance_) )) != TT_Err_Ok ) +#define FILE_Read( buffer, count ) \ + ( (error = TT_Read_File ( stream, \ + buffer, \ + (Long)(count) )) != TT_Err_Ok ) +#define FILE_Read_At( pos, buffer, count ) \ + ( (error = TT_Read_At_File( stream, \ + (Long)(pos), \ + buffer, \ + (Long)(count) )) != TT_Err_Ok ) + +#else /* thread-safe implementation */ + +/* Define stream locals with frame -- nothing in thread-safe mode */ +#define DEFINE_STREAM_LOCALS \ + TT_Error error + +/* Define stream locals without frame -- nothing in thread-safe mode */ +#define DEFINE_STREAM_LOCALS_WO_FRAME \ + TT_Error error + +/* Define locals with a predefined stream in reentrant mode -- see ttload.c */ +#define DEFINE_LOAD_LOCALS( STREAM ) \ + TT_Error error + + +/* Define locals without frame with a predefined stream - see ttload.c */ +#define DEFINE_LOAD_LOCALS_WO_FRAME( STREAM ) \ + TT_Error error + +/* Define all locals necessary to access a font file */ +#define DEFINE_ALL_LOCALS \ + TT_Error error; \ + DEFINE_A_STREAM + + +#define ACCESS_Frame( _size_ ) \ + ( (error = TT_Access_Frame( (Long)(_size_) )) != TT_Err_Ok ) +#define CHECK_ACCESS_Frame( _size_ ) \ + ( (error = TT_Check_And_Access_Frame( (Long)(_size_) )) != TT_Err_Ok ) +#define FORGET_Frame() \ + ( (void)TT_Forget_Frame() ) + +#define GET_Byte() TT_Get_Byte () +#define GET_Char() TT_Get_Char () +#define GET_UShort() TT_Get_UShort() +#define GET_Short() TT_Get_Short () +#define GET_Long() TT_Get_Long () +#define GET_ULong() TT_Get_ULong () +#define GET_Tag4() TT_Get_ULong () + +#define FILE_Pos() TT_File_Pos() + +#define FILE_Seek( _position_ ) \ + ( (error = TT_Seek_File( (Long)(_position_) )) != TT_Err_Ok ) +#define FILE_Skip( _distance_ ) \ + ( (error = TT_Skip_File( (Long)(_distance_) )) != TT_Err_Ok ) +#define FILE_Read( buffer, count ) \ + ( (error = TT_Read_File ( buffer, \ + (Long)(count) )) != TT_Err_Ok ) +#define FILE_Read_At( pos, buffer, count ) \ + ( (error = TT_Read_At_File( (Long)(pos), \ + buffer, \ + (Long)(count) )) != TT_Err_Ok ) + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + +#ifdef __cplusplus + } +#endif + +#endif /* TTLOAD_H */ + + +/* END */ diff --git a/lib/ttmemory.c b/lib/ttmemory.c new file mode 100644 index 0000000..280c05f --- /dev/null +++ b/lib/ttmemory.c @@ -0,0 +1,397 @@ +/******************************************************************* + * + * ttmemory.c 1.2 + * + * Memory management component (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 1.1 and 1.2: + * + * - the font pool is gone. + * + * - introduced the FREE macro and the Free function for + * future use in destructors. + * + * - Init_FontPool() is now a macro to allow the compilation of + * 'legacy' applications (all four test programs have been updated). + * + ******************************************************************/ + +#include "ttdebug.h" +#include "ttmemory.h" +#include "ttengine.h" + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_memory + + +#ifdef DEBUG_MEMORY + +#include + +#define MAX_TRACKED_BLOCKS 1024 + + struct TMemRec_ + { + void* base; + Long size; + }; + + typedef struct TMemRec_ TMemRec; + + static TMemRec pointers[MAX_TRACKED_BLOCKS + 1]; + + static Int num_alloc; + static Int num_free; + static Int num_realloc; /* counts only `real' reallocations + (i.e., an existing buffer will be resized + to a value larger than zero */ + + static Int fail_alloc; + static Int fail_realloc; + static Int fail_free; + +#endif /* DEBUG_MEMORY */ + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + Long TTMemory_Allocated; + Long TTMemory_MaxAllocated; +#endif + + +/******************************************************************* + * + * Function : TT_Alloc + * + * Description : Allocates memory from the heap buffer. + * + * Input : Size size of the memory to be allocated + * P pointer to a buffer pointer + * + * Output : Error code. + * + * NOTE : The newly allocated block should _always_ be zeroed + * on return. Many parts of the engine rely on this to + * work properly. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Alloc( ULong Size, void** P ) + { +#ifdef DEBUG_MEMORY + Int i; +#endif + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( Size > (size_t)-1 ) + return TT_Err_Out_Of_Memory; + if ( Size > 0 ) + { + *P = (void*)malloc( Size ); + if ( !*P ) + return TT_Err_Out_Of_Memory; + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size; + TTMemory_MaxAllocated += Size; +#endif + +#ifdef DEBUG_MEMORY + + num_alloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != NULL ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_alloc++; + else + { + pointers[i].base = *P; + pointers[i].size = Size; + } + +#endif /* DEBUG_MEMORY */ + + MEM_Set( *P, 0, Size ); + } + else + *P = NULL; + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + +/******************************************************************* + * + * Function : TT_Realloc + * + * Description : Reallocates memory from the heap buffer. + * + * Input : Size new size of the memory to be allocated; + * if zero, TT_Free() will be called + * P pointer to a buffer pointer; if *P == NULL, + * TT_Alloc() will be called + * + * Output : Error code. + * + * NOTES : It's not necessary to zero the memory in case the + * reallocated buffer is larger than before -- the + * application has to take care of this. + * + * If the memory request fails, TT_Free() will be + * called on *P, and TT_Err_Out_Of_Memory returned. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Realloc( ULong Size, void** P ) + { + void* Q; + +#ifdef DEBUG_MEMORY + Int i; +#endif + + + if ( !P ) + return TT_Err_Invalid_Argument; + + if ( !*P ) + return TT_Alloc( Size, P ); + + if ( Size == 0 ) + return TT_Free( P ); + + if ( Size > (size_t)-1 ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + + Q = (void*)realloc( *P, Size ); + if ( !Q ) + { + TT_Free( *P ); + return TT_Err_Out_Of_Memory; + } + +#ifdef DEBUG_MEMORY + + num_realloc++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_realloc++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated += Size - pointers[i].size; + if ( Size > pointers[i].size ) + TTMemory_MaxAllocated += Size - pointers[i].size; +#endif + + pointers[i].base = Q; + pointers[i].size = size; + } +#endif /* DEBUG_MEMORY */ + + *P = Q; + + return TT_Err_Ok; + } + + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + +/******************************************************************* + * + * Function : TT_Free + * + * Description : Releases a previously allocated block of memory. + * + * Input : P pointer to memory block + * + * Output : Always SUCCESS. + * + * Note : The pointer must _always_ be set to NULL by this function. + * + ******************************************************************/ + + EXPORT_FUNC + TT_Error TT_Free( void** P ) + { +#ifdef DEBUG_MEMORY + Int i; +#endif /* DEBUG_MEMORY */ + + + if ( !P || !*P ) + return TT_Err_Ok; + +#ifdef DEBUG_MEMORY + + num_free++; + + i = 0; + while ( i < MAX_TRACKED_BLOCKS && pointers[i].base != *P ) + i++; + + if ( i >= MAX_TRACKED_BLOCKS ) + fail_free++; + else + { +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated -= pointers[i].size; +#endif + + pointers[i].base = NULL; + pointers[i].size = 0; + } +#endif /* DEBUG_MEMORY */ + + free( *P ); + + *P = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the memory. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Init( void ) + { +#ifdef DEBUG_MEMORY + Int i; + + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + pointers[i].base = NULL; + pointers[i].size = 0; + } + + num_alloc = 0; + num_realloc = 0; + num_free = 0; + + fail_alloc = 0; + fail_realloc = 0; + fail_free = 0; +#endif + + +#ifndef TT_CONFIG_OPTION_THREAD_SAFE + TTMemory_Allocated = 0; + TTMemory_MaxAllocated = 0; +#endif + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalizes memory usage. + * + * Output : Always SUCCESS. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTMemory_Done( void ) + { +#ifdef DEBUG_MEMORY + Int i, num_leaked, tot_leaked; + + + num_leaked = 0; + tot_leaked = 0; + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + num_leaked ++; + tot_leaked += pointers[i].size; + } + } + + fprintf( stderr, + "%d memory allocations, of which %d failed\n", + num_alloc, + fail_alloc ); + + fprintf( stderr, + "%d memory reallocations, of which %d failed\n", + num_realloc, + fail_realloc ); + + fprintf( stderr, + "%d memory frees, of which %d failed\n", + num_free, + fail_free ); + + if ( num_leaked > 0 ) + { + fprintf( stderr, + "There are %d leaked memory blocks, totalizing %d bytes\n", + num_leaked, tot_leaked ); + + for ( i = 0; i < MAX_TRACKED_BLOCKS; i++ ) + { + if ( pointers[i].base ) + { + fprintf( stderr, + "index: %4d (base: $%08lx, size: %08ld)\n", + i, + (long)pointers[i].base, + pointers[i].size ); + } + } + } + else + fprintf( stderr, "No memory leaks !\n" ); + +#endif /* DEBUG_MEMORY */ + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/ttmemory.h b/lib/ttmemory.h new file mode 100644 index 0000000..8cdae23 --- /dev/null +++ b/lib/ttmemory.h @@ -0,0 +1,125 @@ +/******************************************************************* + * + * ttmemory.h 1.2 + * + * Memory management component (specification). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Changes between 1.2 and 1.1: + * + * - the font pool is gone! All allocations are now performed + * with malloc() and free(). + * + * - introduced the FREE() macro and the Free() function for + * future use in destructors. + * + * - Init_FontPool() is now a macro to allow the compilation of + * 'legacy' applications (all four test programs have been updated). + * + ******************************************************************/ + +#ifndef TTMEMORY_H +#define TTMEMORY_H + +#include "ttconfig.h" +#include "tttypes.h" +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +#define MEM_Set( dest, byte, count ) memset( dest, byte, count ) + +#ifdef HAVE_MEMCPY +#define MEM_Copy( dest, source, count ) memcpy( dest, source, count ) +#else +#define MEM_Copy( dest, source, count ) bcopy( source, dest, count ) +#endif + +#ifdef HAVE_MEMMOVE +#define MEM_Move( dest, source, count ) memmove( dest, source, count ) +#else +#define MEM_Move( dest, source, count ) bcopy( source, dest, count ) +#endif + + +#define MEM_Alloc( _pointer_, _size_ ) \ + TT_Alloc( _size_, (void**)&(_pointer_) ) + +#define MEM_Realloc( _pointer_, _size_ ) \ + TT_Realloc( _size_, (void**)&(_pointer_) ) + +#define ALLOC( _pointer_, _size_ ) \ + ( ( error = MEM_Alloc( _pointer_, _size_ ) ) != TT_Err_Ok ) + +#define ALLOC_ARRAY( _pointer_, _count_, _type_ ) \ + ( ( error = MEM_Alloc( _pointer_, \ + (_count_) * sizeof ( _type_ ) ) ) != TT_Err_Ok ) + +#define REALLOC( _pointer_, _size_ ) \ + ( ( error = MEM_Realloc( _pointer_, _size_ ) ) != TT_Err_Ok ) + +#define REALLOC_ARRAY( _pointer_, _count_, _type_ ) \ + ( (error = MEM_Realloc( _pointer_, \ + (_count_) * sizeof ( _type_ ) ) ) != TT_Err_Ok ) + +#define FREE( _pointer_ ) \ + TT_Free( (void**)&(_pointer_) ) + + + /* Allocate a block of memory of 'Size' bytes from the heap, and */ + /* sets the pointer '*P' to its address. If 'Size' is 0, or in */ + /* case of error, the pointer is always set to NULL. */ + + EXPORT_DEF + TT_Error TT_Alloc( ULong Size, void** P ); + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + + /* Reallocates a block of memory pointed to by '*P' to 'Size' */ + /* bytes from the heap, possibly changing '*P'. If 'Size' is 0, */ + /* TT_Free() is called, if '*P' is NULL, TT_Alloc() is called. */ + /* '*P' is freed (if it's non-NULL) in case of error. */ + + EXPORT_DEF + TT_Error TT_Realloc( ULong Size, void** P ); + +#endif /* TT_CONFIG_OPTION_EXTEND_ENGINE */ + + /* Releases a block that was previously allocated through Alloc. */ + /* Note that the function returns successfully when P or *P are */ + /* already NULL. The pointer '*P' is set to NULL on exit in */ + /* case of success. */ + + EXPORT_DEF + TT_Error TT_Free( void** P ); + + + /* For "legacy" applications, that should be re-coded. */ + /* Note that this won't release the previously allocated font pool. */ + +#define Init_FontPool( x, y ) while( 0 ) { } + + + LOCAL_DEF TT_Error TTMemory_Init( void ); + LOCAL_DEF TT_Error TTMemory_Done( void ); + + +#ifdef __cplusplus + } +#endif + +#endif /* TTMEMORY_H */ + + +/* END */ diff --git a/lib/ttmutex.c b/lib/ttmutex.c new file mode 100644 index 0000000..2f4b920 --- /dev/null +++ b/lib/ttmutex.c @@ -0,0 +1,85 @@ +/******************************************************************* + * + * ttmutex.c 1.0 + * + * Mutual exclusion object, single-threaded implementation + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTE: This is a generic non-functional implementation + * that you are welcome to refine for your own system. + * + * Please name your system-specific source with a + * different name (like ttmutex-os2.c or ttmutex-linux.c) + * and change your makefile accordingly. + * + ******************************************************************/ + +#include "ttmutex.h" + + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_mutex + + +/* ANSI C prevents the compilation of empty units. We thus introduce */ +/* a dummy typedef to get rid of compiler warnings/errors. */ +/* Note that gcc's -ansi -pedantic does not report any error here. */ +/* Watcom, VC++ or Borland C++ do however. */ + + typedef void _ttmutex_to_satisfy_ANSI_C_; + + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE + + LOCAL_FUNC + void TT_Mutex_Create ( TMutex* mutex ) + { + *mutex = (void*)-1; + /* Replace this line with your own mutex creation code */ + } + + + LOCAL_FUNC + void TT_Mutex_Delete ( TMutex* mutex ) + { + *mutex = (void*)0; + /* Replace this line with your own mutex destruction code */ + } + + + LOCAL_FUNC + void TT_Mutex_Lock ( TMutex* mutex ) + { + /* NOTE: It is legal to call this function with a NULL argument */ + /* in which case an immediate return is appropriate. */ + if ( !mutex ) + return; + + ; /* Insert your own mutex locking code here */ + } + + + LOCAL_FUNC + void TT_Mutex_Release( TMutex* mutex ) + { + /* NOTE: It is legal to call this function with a NULL argument */ + /* in which case an immediate return is appropriate */ + if ( !mutex ) + return; + + ; /* Insert your own mutex release code here */ + } + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + + +/* END */ diff --git a/lib/ttmutex.h b/lib/ttmutex.h new file mode 100644 index 0000000..097385b --- /dev/null +++ b/lib/ttmutex.h @@ -0,0 +1,59 @@ +/******************************************************************* + * + * ttmutex.h 1.0 + * + * Mutual exclusion object / dummy generic interface. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Note: This file provides a generic interface. The implementation + * to compile depends on your system and the type of + * library you want to build (either singly-threaded, + * thread-safe or re-entrant). + * + * Please read the technical documentation for more details. + * + ******************************************************************/ + +#ifndef TTMUTEX_H +#define TTMUTEX_H + +#include "ttconfig.h" + + + typedef void* TMutex; /* typeless reference to a mutex */ + +#ifdef TT_CONFIG_OPTION_THREAD_SAFE /* thread-safe and re-entrant builds */ + +#define MUTEX_Create( mutex ) TT_Mutex_Create ( &(mutex) ) +#define MUTEX_Destroy( mutex ) TT_Mutex_Delete ( &(mutex) ) +#define MUTEX_Lock( mutex ) TT_Mutex_Lock ( &(mutex) ) +#define MUTEX_Release( mutex ) TT_Mutex_Release( &(mutex) ) + + LOCAL_DEF void TT_Mutex_Create ( TMutex* mutex ); /* Create a new mutex */ + LOCAL_DEF void TT_Mutex_Delete ( TMutex* mutex ); /* Delete a mutex */ + LOCAL_DEF void TT_Mutex_Lock ( TMutex* mutex ); /* Lock a mutex. */ + LOCAL_DEF void TT_Mutex_Release( TMutex* mutex ); /* Release a mutex */ + +#else /* for the single-thread build */ + +#define MUTEX_Create( mutex ) /* nothing */ +#define MUTEX_Destroy( mutex ) /* nothing */ +#define MUTEX_Lock( mutex ) /* nothing */ +#define MUTEX_Release( mutex ) /* nothing */ + + /* No code will be generated for mutex operations */ + +#endif /* TT_CONFIG_OPTION_THREAD_SAFE */ + +#endif /* TTMUTEX_H */ + + +/* END */ diff --git a/lib/ttobjs.c b/lib/ttobjs.c new file mode 100644 index 0000000..9ce1101 --- /dev/null +++ b/lib/ttobjs.c @@ -0,0 +1,1495 @@ +/******************************************************************* + * + * ttobjs.c 1.0 + * + * Objects manager. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "ttobjs.h" +#include "ttfile.h" +#include "ttcalc.h" +#include "ttmemory.h" +#include "ttload.h" +#include "ttinterp.h" +#include "ttdebug.h" + + +/* Add extensions definition */ +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE +#include "ttextend.h" +#endif + +/* Required by tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_objs + +/******************************************************************* + * + * Function : New_Context + * + * Description : Creates a new execution context for a given + * face object. + * + ******************************************************************/ + + LOCAL_FUNC + PExecution_Context New_Context( PFace face ) + { + PEngine_Instance engine; + PExecution_Context exec; + + + if ( !face ) + return NULL; + + engine = face->engine; + CACHE_New( engine->objs_exec_cache, exec, face ); + return exec; + } + + +/******************************************************************* + * + * Function : Done_Context + * + * Description : Discards an execution context. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Done_Context( PExecution_Context exec ) + { + PEngine_Instance engine; + + + if ( !exec ) + return TT_Err_Ok; + + engine = exec->face->engine; + return CACHE_Done( engine->objs_exec_cache, exec ); + } + + +#if 0 + +/******************************************************************* + * + * Function : New_Instance + * + * Description : Creates a new instance for a given face object. + * + ******************************************************************/ + + LOCAL_FUNC + PInstance New_Instance( PFace face ) + { + PInstance ins; + + + if ( !face ) + return NULL; + + CACHE_New( &face->instances, ins, face ); + + return ins; + } + + +/******************************************************************* + * + * Function : Done_Instance + * + * Description : Discards an instance. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Done_Instance( PInstance instance ) + { + return CACHE_Done( &instance->owner->instances, instance ); + } + +#endif + + +/******************************************************************* + * * + * GLYPH ZONE FUNCTIONS * + * * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : New_Glyph_Zone + * + * Description : Allocates a new glyph zone + * + * Input : pts pointer to the target glyph zone record + * maxPoints capacity of glyph zone in points + * maxContours capacity of glyph zone in contours + * + * Return : Error code. + * + *****************************************************************/ + + static + TT_Error New_Glyph_Zone( PGlyph_Zone pts, + UShort maxPoints, + UShort maxContours ) + { + TT_Error error; + + + if ( ALLOC( pts->org, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) || + ALLOC( pts->cur, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) || + ALLOC( pts->touch, maxPoints * sizeof ( Byte ) ) || + ALLOC( pts->contours, maxContours * sizeof ( Short ) ) ) + return error; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Done_Glyph_Zone + * + * Description : Deallocates a glyph zone + * + * Input : pts pointer to the target glyph zone record + * + * Return : Error code. + * + *****************************************************************/ + + static + TT_Error Done_Glyph_Zone( PGlyph_Zone pts ) + { + FREE( pts->contours ); + FREE( pts->touch ); + FREE( pts->cur ); + FREE( pts->org ); + + return TT_Err_Ok; + } + + + +/******************************************************************* + * * + * CODERANGE FUNCTIONS * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : Goto_CodeRange + * + * Description : Switch to a new code range (updates Code and IP). + * + * Input : exec target execution context + * range new execution code range + * IP new IP in new code range + * + * Output : SUCCESS on success. FAILURE on error (no code range). + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Goto_CodeRange( PExecution_Context exec, + Int range, + ULong IP ) + { + PCodeRange cr; + + + if ( range < 1 || range > 3 ) + return TT_Err_Bad_Argument; + + cr = &exec->codeRangeTable[range - 1]; + + if ( cr->Base == NULL ) + return TT_Err_Invalid_CodeRange; + + /* NOTE: Because the last instruction of a program may be a CALL */ + /* which will return to the first byte *after* the code */ + /* range, we test for IP <= Size, instead of IP < Size. */ + + if ( IP > cr->Size ) + return TT_Err_Code_Overflow; + + exec->code = cr->Base; + exec->codeSize = cr->Size; + exec->IP = IP; + exec->curRange = range; + + return TT_Err_Ok; + } + + +#if 0 + +/******************************************************************* + * + * Function : Get_CodeRange + * + * Description : Returns a pointer to a given code range. Should + * be used only by the debugger. Returns NULL if + * 'range' is out of current bounds. + * + * Input : exec target execution context + * range new execution code range + * + * Output : Pointer to the code range record. NULL on failure. + * + *****************************************************************/ + + LOCAL_FUNC + PCodeRange Get_CodeRange( PExecution_Context exec, Int range ) + { + if ( range < 1 || range > 3 ) + return NULL; + else /* arrays start with 1 in Pascal, and with 0 in C */ + return &exec->codeRangeTable[range - 1]; + } + +#endif + + +/******************************************************************* + * + * Function : Set_CodeRange + * + * Description : Sets a code range. + * + * Input : exec target execution context + * range code range index + * base new code base + * length range size in bytes + * + * Output : SUCCESS on success. FAILURE on error. + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Set_CodeRange( PExecution_Context exec, + Int range, + void* base, + ULong length ) + { + if ( range < 1 || range > 3 ) + return TT_Err_Bad_Argument; + + exec->codeRangeTable[range - 1].Base = (Byte*)base; + exec->codeRangeTable[range - 1].Size = length; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Clear_CodeRange + * + * Description : Clears a code range. + * + * Input : exec target execution context + * range code range index + * + * Output : SUCCESS on success. FAILURE on error. + * + * Note : Does not set the Error variable. + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Clear_CodeRange( PExecution_Context exec, Int range ) + { + if ( range < 1 || range > 3 ) + return TT_Err_Bad_Argument; + + exec->codeRangeTable[range - 1].Base = NULL; + exec->codeRangeTable[range - 1].Size = 0; + + return TT_Err_Ok; + } + + + +/******************************************************************* + * * + * EXECUTION CONTEXT ROUTINES * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : Context_Destroy + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Context_Destroy( void* _context ) + { + PExecution_Context exec = (PExecution_Context)_context; + + if ( !exec ) + return TT_Err_Ok; + + /* free composite load stack */ + FREE( exec->loadStack ); + exec->loadSize = 0; + + /* points zone */ + Done_Glyph_Zone( &exec->pts ); + exec->maxPoints = 0; + exec->maxContours = 0; + + /* free stack */ + FREE( exec->stack ); + exec->stackSize = 0; + + /* free call stack */ + FREE( exec->callStack ); + exec->callSize = 0; + exec->callTop = 0; + + /* free glyph code range */ + FREE( exec->glyphIns ); + exec->glyphSize = 0; + + exec->instance = NULL; + exec->face = NULL; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Context_Create + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Context_Create( void* _context, void* _face ) + { + PExecution_Context exec = (PExecution_Context)_context; + + PFace face = (PFace)_face; + TT_Error error; + + + /* XXX : We don't reserve arrays anymore, this is done automatically */ + /* during a "Context_Load".. */ + + exec->callSize = 32; + if ( ALLOC_ARRAY( exec->callStack, exec->callSize, TCallRecord ) ) + goto Fail_Memory; + + /* all values in the context are set to 0 already, but this is */ + /* here as a remainder */ + exec->maxPoints = 0; + exec->maxContours = 0; + + exec->stackSize = 0; + exec->loadSize = 0; + exec->glyphSize = 0; + + exec->stack = NULL; + exec->loadStack = NULL; + exec->glyphIns = NULL; + + exec->face = face; + exec->instance = NULL; + + return TT_Err_Ok; + + Fail_Memory: + Context_Destroy( exec ); + return error; + } + + +/******************************************************************* + * + * Function : Context_Load + * + *****************************************************************/ + +/****************************************************************/ +/* */ +/* Update_Max : Reallocate a buffer if it needs to */ +/* */ +/* input: size address of buffer's current size */ +/* expressed in elements */ +/* */ +/* multiplier size in bytes of each element in the */ +/* buffer */ +/* */ +/* buff address of the buffer base pointer */ +/* */ +/* new_max new capacity (size) of the buffer */ + + static + TT_Error Update_Max( ULong* size, + ULong multiplier, + void** buff, + ULong new_max ) + { + TT_Error error; + + if ( *size < new_max ) + { + FREE( *buff ); + if ( ALLOC( *buff, new_max * multiplier ) ) + return error; + *size = new_max; + } + return TT_Err_Ok; + } + + +/****************************************************************/ +/* */ +/* Update_Zone: Reallocate a zone if it needs to */ +/* */ +/* input: zone address of the target zone */ +/* */ +/* maxPoints address of the zone's current capacity */ +/* in points */ +/* */ +/* maxContours address of the zone's current capacity */ +/* in contours */ +/* */ +/* newPoints new capacity in points */ +/* */ +/* newContours new capacity in contours */ +/* */ + + static + TT_Error Update_Zone( PGlyph_Zone zone, + UShort* maxPoints, + UShort* maxContours, + UShort newPoints, + UShort newContours ) + { + if ( *maxPoints < newPoints || *maxContours < newContours ) + { + TT_Error error; + + + Done_Glyph_Zone( zone ); + + error = New_Glyph_Zone( zone, newPoints, newContours ); + if ( error ) + return error; + + *maxPoints = newPoints; + *maxContours = newContours; + } + return TT_Err_Ok; + } + + + LOCAL_FUNC + TT_Error Context_Load( PExecution_Context exec, + PFace face, + PInstance ins ) + { + Int i; + TMaxProfile* maxp; + TT_Error error; + + exec->face = face; + maxp = &face->maxProfile; + + exec->instance = ins; + + if ( ins ) + { + exec->numFDefs = ins->numFDefs; + exec->numIDefs = ins->numIDefs; + exec->maxFDefs = ins->maxFDefs; + exec->maxIDefs = ins->maxIDefs; + exec->FDefs = ins->FDefs; + exec->IDefs = ins->IDefs; + exec->metrics = ins->metrics; + + exec->maxFunc = ins->maxFunc; + exec->maxIns = ins->maxIns; + + for ( i = 0; i < MAX_CODE_RANGES; i++ ) + exec->codeRangeTable[i] = ins->codeRangeTable[i]; + + /* set graphics state */ + exec->GS = ins->GS; + + exec->cvtSize = ins->cvtSize; + exec->cvt = ins->cvt; + + exec->storeSize = ins->storeSize; + exec->storage = ins->storage; + + exec->twilight = ins->twilight; + } + + error = Update_Max( &exec->loadSize, + sizeof ( TSubglyph_Record ), + (void**)&exec->loadStack, + face->maxComponents + 1 ); + if ( error ) + return error; + + error = Update_Max( &exec->stackSize, + sizeof ( TT_F26Dot6 ), + (void**)&exec->stack, + maxp->maxStackElements + 32 ); + /* XXX : We reserve a little more elements on the stack to deal safely */ + /* with broken fonts like arialbs, courbs, timesbs... */ + if ( error ) + return error; + + error = Update_Max( &exec->glyphSize, + sizeof ( Byte ), + (void**)&exec->glyphIns, + maxp->maxSizeOfInstructions ); + if ( error ) + return error; + + error = Update_Zone( &exec->pts, + &exec->maxPoints, + &exec->maxContours, + exec->face->maxPoints + 2, + exec->face->maxContours ); + /* XXX : We reserve two positions for the phantom points! */ + if ( error ) + return error; + + exec->pts.n_points = 0; + exec->pts.n_contours = 0; + + exec->instruction_trap = FALSE; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Context_Save + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Context_Save( PExecution_Context exec, + PInstance ins ) + { + Int i; + + /* XXXX : Will probably disappear soon with all the coderange */ + /* management, which is now rather obsolete. */ + + ins->numFDefs = exec->numFDefs; + ins->numIDefs = exec->numIDefs; + ins->maxFunc = exec->maxFunc; + ins->maxIns = exec->maxIns; + + for ( i = 0; i < MAX_CODE_RANGES; i++ ) + ins->codeRangeTable[i] = exec->codeRangeTable[i]; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Context_Run + * + *****************************************************************/ + + LOCAL_FUNC + TT_Error Context_Run( PExecution_Context exec, + Bool debug ) + { + TT_Error error; + + + if ( (error = Goto_CodeRange( exec, + TT_CodeRange_Glyph, 0 )) != TT_Err_Ok ) + return error; + + exec->zp0 = exec->pts; + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + + exec->GS.gep0 = 1; + exec->GS.gep1 = 1; + exec->GS.gep2 = 1; + + exec->GS.projVector.x = 0x4000; + exec->GS.projVector.y = 0x0000; + + exec->GS.freeVector = exec->GS.projVector; + exec->GS.dualVector = exec->GS.projVector; + + exec->GS.round_state = 1; + exec->GS.loop = 1; + + /* some glyphs leave something on the stack. so we clean it */ + /* before a new execution. */ + exec->top = 0; + exec->callTop = 0; + + if ( !debug ) + return RunIns( exec ); + else + return TT_Err_Ok; + } + + + LOCAL_FUNC + const TGraphicsState Default_GraphicsState = + { + 0, 0, 0, + { 0x4000, 0 }, + { 0x4000, 0 }, + { 0x4000, 0 }, + 1, 64, 1, + TRUE, 68, 0, 0, 9, 3, + 0, FALSE, 2, 1, 1, 1 + }; + + + +/******************************************************************* + * * + * INSTANCE FUNCTIONS * + * * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : Instance_Destroy + * + * Description : + * + * Input : _instance the instance object to destroy + * + * Output : error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Instance_Destroy( void* _instance ) + { + PInstance ins = (PInstance)_instance; + + + if ( !_instance ) + return TT_Err_Ok; + + if ( ins->debug ) + { + /* the debug context must be deleted by the debugger itself */ + ins->context = NULL; + ins->debug = FALSE; + } + + FREE( ins->cvt ); + ins->cvtSize = 0; + + /* free storage area */ + FREE( ins->storage ); + ins->storeSize = 0; + + /* twilight zone */ + Done_Glyph_Zone( &ins->twilight ); + + FREE( ins->FDefs ); + FREE( ins->IDefs ); + ins->numFDefs = 0; + ins->numIDefs = 0; + ins->maxFDefs = 0; + ins->maxIDefs = 0; + ins->maxFunc = -1; + ins->maxIns = -1; + + ins->owner = NULL; + ins->valid = FALSE; + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Instance_Create + * + * Description : + * + * Input : _instance instance record to initialize + * _face parent face object + * + * Output : Error code. All partially built subtables are + * released on error. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Instance_Create( void* _instance, + void* _face ) + { + PInstance ins = (PInstance)_instance; + PFace face = (PFace)_face; + TT_Error error; + Int i; + UShort n_twilight; + + PMaxProfile maxp = &face->maxProfile; + + + ins->owner = face; + ins->valid = FALSE; + + ins->maxFDefs = maxp->maxFunctionDefs; + ins->maxIDefs = maxp->maxInstructionDefs; + ins->cvtSize = face->cvtSize; + ins->storeSize = maxp->maxStorage; + + /* Set default metrics */ + { + PIns_Metrics metrics = &ins->metrics; + + + metrics->pointSize = 10 * 64; /* default pointsize = 10pts */ + + metrics->x_resolution = 96; /* default resolution = 96dpi */ + metrics->y_resolution = 96; + + metrics->x_ppem = 0; + metrics->y_ppem = 0; + + metrics->rotated = FALSE; + metrics->stretched = FALSE; + + /* set default compensation ( all 0 ) */ + for ( i = 0; i < 4; i++ ) + metrics->compensations[i] = 0; + } + + /* allocate function defs, instruction defs, cvt and storage area */ + if ( ALLOC_ARRAY( ins->FDefs, ins->maxFDefs, TDefRecord ) || + ALLOC_ARRAY( ins->IDefs, ins->maxIDefs, TDefRecord ) || + ALLOC_ARRAY( ins->cvt, ins->cvtSize, Long ) || + ALLOC_ARRAY( ins->storage, ins->storeSize, Long ) ) + goto Fail_Memory; + + /* reserve twilight zone */ + n_twilight = maxp->maxTwilightPoints; + error = New_Glyph_Zone( &ins->twilight, n_twilight, 0 ); + if (error) + goto Fail_Memory; + + ins->twilight.n_points = n_twilight; + + return TT_Err_Ok; + + Fail_Memory: + Instance_Destroy( ins ); + return error; + } + + +/******************************************************************* + * + * Function : Instance_Init + * + * Description : Initialize a fresh new instance. + * Executes the font program if any is found. + * + * Input : _instance the instance object to destroy + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Instance_Init( PInstance ins ) + { + PExecution_Context exec; + + TT_Error error; + PFace face = ins->owner; + + + if ( ins->debug ) + exec = ins->context; + else + exec = New_Context( face ); + /* debugging instances have their own context */ + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + ins->GS = Default_GraphicsState; + + ins->numFDefs = 0; + ins->numIDefs = 0; + ins->maxFunc = -1; + ins->maxIns = -1; + + Context_Load( exec, face, ins ); + + exec->callTop = 0; + exec->top = 0; + + exec->period = 64; + exec->phase = 0; + exec->threshold = 0; + + { + PIns_Metrics metrics = &exec->metrics; + + + metrics->x_ppem = 0; + metrics->y_ppem = 0; + metrics->pointSize = 0; + metrics->x_scale1 = 0; + metrics->x_scale2 = 1; + metrics->y_scale1 = 0; + metrics->y_scale2 = 1; + + metrics->ppem = 0; + metrics->scale1 = 0; + metrics->scale2 = 1; + metrics->ratio = 1L << 16; + } + + exec->instruction_trap = FALSE; + + exec->cvtSize = ins->cvtSize; + exec->cvt = ins->cvt; + + exec->F_dot_P = 0x10000; + + /* allow font program execution */ + Set_CodeRange( exec, + TT_CodeRange_Font, + face->fontProgram, + face->fontPgmSize ); + + /* disable CVT and glyph programs coderange */ + Clear_CodeRange( exec, TT_CodeRange_Cvt ); + Clear_CodeRange( exec, TT_CodeRange_Glyph ); + + if ( face->fontPgmSize > 0 ) + { + error = Goto_CodeRange( exec, TT_CodeRange_Font, 0 ); + if ( error ) + goto Fin; + + error = RunIns( exec ); + } + else + error = TT_Err_Ok; + + Fin: + Context_Save( exec, ins ); + + if ( !ins->debug ) + Done_Context( exec ); + /* debugging instances keep their context */ + + ins->valid = FALSE; + + return error; + } + + +/******************************************************************* + * + * Function : Instance_Reset + * + * Description : Resets an instance to a new pointsize/transform. + * Executes the cvt program if any is found. + * + * Input : _instance the instance object to destroy + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Instance_Reset( PInstance ins ) + { + PExecution_Context exec; + + TT_Error error; + ULong i; + UShort j; + PFace face; + + + if ( !ins ) + return TT_Err_Invalid_Instance_Handle; + + if ( ins->valid ) + return TT_Err_Ok; + + face = ins->owner; + + if ( ins->metrics.x_ppem < 1 || + ins->metrics.y_ppem < 1 ) + return TT_Err_Invalid_PPem; + + /* compute new transformation */ + if ( ins->metrics.x_ppem >= ins->metrics.y_ppem ) + { + ins->metrics.scale1 = ins->metrics.x_scale1; + ins->metrics.scale2 = ins->metrics.x_scale2; + ins->metrics.ppem = ins->metrics.x_ppem; + ins->metrics.x_ratio = 1L << 16; + ins->metrics.y_ratio = TT_MulDiv( ins->metrics.y_ppem, + 0x10000, + ins->metrics.x_ppem ); + } + else + { + ins->metrics.scale1 = ins->metrics.y_scale1; + ins->metrics.scale2 = ins->metrics.y_scale2; + ins->metrics.ppem = ins->metrics.y_ppem; + ins->metrics.x_ratio = TT_MulDiv( ins->metrics.x_ppem, + 0x10000, + ins->metrics.y_ppem ); + ins->metrics.y_ratio = 1L << 16; + } + + /* Scale the cvt values to the new ppem. */ + /* We use by default the y ppem to scale the CVT. */ + + for ( i = 0; i < ins->cvtSize; i++ ) + ins->cvt[i] = TT_MulDiv( face->cvt[i], + ins->metrics.scale1, + ins->metrics.scale2 ); + + /* All twilight points are originally zero */ + for ( j = 0; j < ins->twilight.n_points; j++ ) + { + ins->twilight.org[j].x = 0; + ins->twilight.org[j].y = 0; + ins->twilight.cur[j].x = 0; + ins->twilight.cur[j].y = 0; + } + + /* clear storage area */ + for ( i = 0; i < ins->storeSize; i++ ) + ins->storage[i] = 0; + + ins->GS = Default_GraphicsState; + + /* get execution context and run prep program */ + + if ( ins->debug ) + exec = ins->context; + else + exec = New_Context(face); + /* debugging instances have their own context */ + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + Context_Load( exec, face, ins ); + + Set_CodeRange( exec, + TT_CodeRange_Cvt, + face->cvtProgram, + face->cvtPgmSize ); + + Clear_CodeRange( exec, TT_CodeRange_Glyph ); + + exec->instruction_trap = FALSE; + + exec->top = 0; + exec->callTop = 0; + + if ( face->cvtPgmSize > 0 ) + { + error = Goto_CodeRange( exec, TT_CodeRange_Cvt, 0 ); + if ( error ) + goto Fin; + + if ( !ins->debug ) + error = RunIns( exec ); + } + else + error = TT_Err_Ok; + + ins->GS = exec->GS; + /* save default graphics state */ + + Fin: + Context_Save( exec, ins ); + + if ( !ins->debug ) + Done_Context( exec ); + /* debugging instances keep their context */ + + if ( !error ) + ins->valid = TRUE; + + return error; + } + + + +/******************************************************************* + * * + * FACE FUNCTIONS * + * * + * * + *******************************************************************/ + +/******************************************************************* + * + * Function : Face_Destroy + * + * Description : The face object destructor. + * + * Input : _face typeless pointer to the face object to destroy + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Face_Destroy( void* _face ) + { + PFace face = (PFace)_face; + UShort n; + + + if ( !face ) + return TT_Err_Ok; + + /* well, we assume that no other thread is using the face */ + /* at this moment, but one is never sure enough. */ + MUTEX_Lock( face->lock ); + + /* first of all, destroys the cached sub-objects */ + Cache_Destroy( &face->instances ); + Cache_Destroy( &face->glyphs ); + + /* destroy the extensions */ +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + Extension_Destroy( face ); +#endif + + /* freeing the collection table */ + FREE( face->ttcHeader.TableDirectory ); + face->ttcHeader.DirCount = 0; + + /* freeing table directory */ + FREE( face->dirTables ); + face->numTables = 0; + + /* freeing the locations table */ + FREE( face->glyphLocations ); + face->numLocations = 0; + + /* freeing the character mapping tables */ + for ( n = 0; n < face->numCMaps; n++ ) + CharMap_Free( face->cMaps + n ); + + FREE( face->cMaps ); + face->numCMaps = 0; + + /* freeing the CVT */ + FREE( face->cvt ); + face->cvtSize = 0; + + /* freeing the horizontal metrics */ + FREE( face->horizontalHeader.long_metrics ); + FREE( face->horizontalHeader.short_metrics ); + + /* freeing the vertical ones, if any */ + if (face->verticalInfo) + { + FREE( face->verticalHeader.long_metrics ); + FREE( face->verticalHeader.short_metrics ); + face->verticalInfo = 0; + } + + /* freeing the programs */ + FREE( face->fontProgram ); + FREE( face->cvtProgram ); + face->fontPgmSize = 0; + face->cvtPgmSize = 0; + + /* freeing the gasp table */ + FREE( face->gasp.gaspRanges ); + face->gasp.numRanges = 0; + + /* freeing the name table */ + Free_TrueType_Names( face ); + + /* freeing the hdmx table */ + Free_TrueType_Hdmx( face ); + + /* TT_Close_Stream( &face->stream ); -- this is performed by the API */ + + /* destroy the mutex */ + MUTEX_Destroy(face->lock); + + return TT_Err_Ok; + } + + +/******************************************************************* + * + * Function : Face_Create + * + * Description : The face object constructor. + * + * Input : _face face record to build + * _input input stream where to load font data + * + * Output : Error code. + * + * NOTE : The input stream is kept in the face object. The + * caller shouldn't destroy it after calling Face_Create(). + * + ******************************************************************/ + +#undef LOAD_ +#define LOAD_( table ) \ + (error = Load_TrueType_##table (face)) != TT_Err_Ok + + + LOCAL_FUNC + TT_Error Face_Create( void* _face, + void* _input ) + { + PEngine_Instance engine; + + TFont_Input* input = (TFont_Input*)_input; + PFace face = (PFace)_face; + TT_Error error; + + + face->stream = input->stream; + face->engine = input->engine; + + engine = face->engine; + + MUTEX_Create( face->lock ); + + Cache_Create( engine, + engine->objs_instance_class, + &face->instances, + &face->lock ); + + Cache_Create( engine, + engine->objs_glyph_class, + &face->glyphs, + &face->lock ); + + /* Load collection directory if present, then font directory */ + + error = Load_TrueType_Directory( face, input->fontIndex ); + if ( error ) + goto Fail; + + /* Load tables */ + + if ( LOAD_( Header ) || + LOAD_( MaxProfile ) || + LOAD_( Locations ) || + + (error = Load_TrueType_Metrics_Header( face, 0 )) != TT_Err_Ok || + /* load the 'hhea' & 'hmtx' tables at once */ + + LOAD_( CMap ) || + LOAD_( CVT ) || + LOAD_( Programs ) || + LOAD_( Gasp ) || + LOAD_( Names ) || + LOAD_( OS2 ) || + LOAD_( PostScript ) || + + (error = Load_TrueType_Metrics_Header( face, 1 )) != TT_Err_Ok || + /* try to load the 'vhea' & 'vmtx' at once if present */ + + LOAD_( Hdmx ) ) + + goto Fail; + +#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE + if ( ( error = Extension_Create( face ) ) != TT_Err_Ok ) + return error; +#endif + + return TT_Err_Ok; + + Fail : + Face_Destroy( face ); + return error; + } + +#undef LOAD_ + + +/******************************************************************* + * + * Function : Glyph_Destroy + * + * Description : The glyph object destructor. + * + * Input : _glyph typeless pointer to the glyph record to destroy + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Glyph_Destroy( void* _glyph ) + { + PGlyph glyph = (PGlyph)_glyph; + + + if ( !glyph ) + return TT_Err_Ok; + + glyph->outline.owner = TRUE; + return TT_Done_Outline( &glyph->outline ); + } + + +/******************************************************************* + * + * Function : Glyph_Create + * + * Description : The glyph object constructor. + * + * Input : _glyph glyph record to build. + * _face the glyph's parent face. + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error Glyph_Create( void* _glyph, + void* _face ) + { + PFace face = (PFace)_face; + PGlyph glyph = (PGlyph)_glyph; + + + if ( !face ) + return TT_Err_Invalid_Face_Handle; + + if ( !glyph ) + return TT_Err_Invalid_Glyph_Handle; + + glyph->face = face; + + /* XXX: Don't forget the space for the 2 phantom points */ + return TT_New_Outline( glyph->face->maxPoints + 2, + glyph->face->maxContours, + &glyph->outline ); + } + + +/******************************************************************* + * + * Function : Scale_X + * + * Description : scale an horizontal distance from font + * units to 26.6 pixels + * + * Input : metrics pointer to metrics + * x value to scale + * + * Output : scaled value + * + ******************************************************************/ + + LOCAL_FUNC + TT_Pos Scale_X( PIns_Metrics metrics, TT_Pos x ) + { + return TT_MulDiv( x, metrics->x_scale1, metrics->x_scale2 ); + } + + +/******************************************************************* + * + * Function : Scale_Y + * + * Description : scale a vertical distance from font + * units to 26.6 pixels + * + * Input : metrics pointer to metrics + * y value to scale + * + * Output : scaled value + * + ******************************************************************/ + + LOCAL_FUNC + TT_Pos Scale_Y( PIns_Metrics metrics, TT_Pos y ) + { + return TT_MulDiv( y, metrics->y_scale1, metrics->y_scale2 ); + } + + +/******************************************************************* + * + * Function : TTObjs_Init + * + * Description : The TTObjs component initializer. Creates the + * object cache classes, as well as the face record + * cache. + * + * Input : engine engine instance + * + * Output : Error code. + * + ******************************************************************/ + + static + const TCache_Class objs_face_class = + { + sizeof ( TFace ), + -1, + Face_Create, + Face_Destroy, + NULL, + NULL + }; + + static + const TCache_Class objs_instance_class = + { + sizeof ( TInstance ), + -1, + Instance_Create, + Instance_Destroy, + NULL, + NULL + }; + + /* Note that we use a cache size of 1 for the execution context. */ + /* This is to avoid re-creating a new context each time we */ + /* change one instance's attribute (resolution and/or char sizes) */ + /* or when we load a glyph. */ + + static + const TCache_Class objs_exec_class = + { + sizeof ( TExecution_Context ), + 1, + Context_Create, + Context_Destroy, + NULL, + NULL + }; + + static + const TCache_Class objs_glyph_class = + { + sizeof ( TGlyph ), + -1, + Glyph_Create, + Glyph_Destroy, + NULL, + NULL + }; + + + LOCAL_FUNC + TT_Error TTObjs_Init( PEngine_Instance engine ) + { + PCache face_cache, exec_cache; + TT_Error error; + + + face_cache = 0; + exec_cache = 0; + + if ( ALLOC( face_cache, sizeof ( TCache ) ) || + ALLOC( exec_cache, sizeof ( TCache ) ) ) + goto Fail; + + /* create face cache */ + error = Cache_Create( engine, (PCache_Class)&objs_face_class, + face_cache, &engine->lock ); + if ( error ) + goto Fail; + + engine->objs_face_cache = face_cache; + + error = Cache_Create( engine, (PCache_Class)&objs_exec_class, + exec_cache, &engine->lock ); + if ( error ) + goto Fail; + + engine->objs_exec_cache = exec_cache; + + engine->objs_face_class = (PCache_Class)&objs_face_class; + engine->objs_instance_class = (PCache_Class)&objs_instance_class; + engine->objs_execution_class = (PCache_Class)&objs_exec_class; + engine->objs_glyph_class = (PCache_Class)&objs_glyph_class; + + goto Exit; + + Fail: + FREE( face_cache ); + FREE( exec_cache ); + + Exit: + return error; + } + + +/******************************************************************* + * + * Function : TTObjs_Done + * + * Description : The TTObjs component finalizer. + * + * Input : engine engine instance + * + * Output : Error code. + * + ******************************************************************/ + + LOCAL_FUNC + TT_Error TTObjs_Done( PEngine_Instance engine ) + { + /* destroy all active faces and contexts before releasing the */ + /* caches */ + Cache_Destroy( (TCache*)engine->objs_exec_cache ); + Cache_Destroy( (TCache*)engine->objs_face_cache ); + + /* Now frees caches and cache classes */ + FREE( engine->objs_exec_cache ); + FREE( engine->objs_face_cache ); + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/ttobjs.h b/lib/ttobjs.h new file mode 100644 index 0000000..a5ba1ff --- /dev/null +++ b/lib/ttobjs.h @@ -0,0 +1,873 @@ +/******************************************************************* + * + * ttobjs.h 1.0 + * + * Objects definition unit. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTOBJS_H +#define TTOBJS_H + +#include "ttconfig.h" +#include "ttengine.h" +#include "ttmutex.h" +#include "ttcache.h" +#include "tttables.h" +#include "ttcmap.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* */ +/* This file contains the definitions and methods of the four */ +/* kinds of objects managed by the FreeType engine. These are: */ +/* */ +/* */ +/* Face objects: */ +/* */ +/* There is always one face object per opened TrueType font */ +/* file, and only one. The face object contains data that is */ +/* independent of current transform/scaling/rotation and */ +/* pointsize, or glyph index. This data is made of several */ +/* critical tables that are loaded on face object creation. */ +/* */ +/* A face object tracks all active and recycled objects of */ +/* the instance and execution context classes. Destroying a face */ +/* object will automatically destroy all associated instances. */ +/* */ +/* */ +/* Instance objects: */ +/* */ +/* An instance object always relates to a given face object, */ +/* known as its 'parent' or 'owner', and contains only the */ +/* data that is specific to one given pointsize/transform of */ +/* the face. You can only create an instance from a face object. */ +/* */ +/* An instance's current transform/pointsize can be changed */ +/* at any time using a single high-level API call, */ +/* TT_Reset_Instance(). */ +/* */ +/* Execution Context objects: */ +/* */ +/* An execution context (or context in short) relates to a face. */ +/* It contains the data and tables that are necessary to load */ +/* and hint (i.e. execute the glyph instructions of) one glyph. */ +/* A context is a transient object that is queried/created on */ +/* the fly: client applications never deal with them directly. */ +/* */ +/* */ +/* Glyph objects: */ +/* */ +/* A glyph object contains only the minimal glyph information */ +/* needed to render one glyph correctly. This means that a glyph */ +/* object really contains tables that are sized to hold the */ +/* contents of _any_ glyph of a given face. A client application */ +/* can usually create one glyph object for a given face, then use */ +/* it for all subsequent loads. */ +/* */ +/* Here is an example of a client application : */ +/* (NOTE: No error checking performed here!) */ +/* */ +/* */ +/* TT_Face face; -- face handle */ +/* TT_Instance ins1, ins2; -- two instance handles */ +/* TT_Glyph glyph; -- glyph handle */ +/* */ +/* TT_Init_FreeType(); */ +/* */ +/* -- Initialize the engine. This must be done prior to _any_ */ +/* operation. */ +/* */ +/* TT_Open_Face( "/some/face/name.ttf", &face ); */ +/* */ +/* -- create the face object. This call opens the font file */ +/* */ +/* TT_New_Instance( face, &ins1 ); */ +/* TT_New_Instance( face, &ins2 ); */ +/* */ +/* TT_Set_Instance_PointSize( ins1, 8 ); */ +/* TT_Set_Instance_PointSize( ins2, 12 ); */ +/* */ +/* -- create two distinct instances of the same face */ +/* -- ins1 is pointsize 8 at resolution 96 dpi */ +/* -- ins2 is pointsize 12 at resolution 96 dpi */ +/* */ +/* TT_New_Glyph( face, &glyph ); */ +/* */ +/* -- create a new glyph object which will receive the contents */ +/* of any glyph of 'face' */ +/* */ +/* TT_Load_Glyph( ins1, glyph, 64, DEFAULT_GLYPH_LOAD ); */ +/* */ +/* -- load glyph indexed 64 at pointsize 8 in the 'glyph' object */ +/* -- NOTE: This call will fail if the instance and the glyph */ +/* do not relate to the same face object. */ +/* */ +/* TT_Get_Outline( glyph, &outline ); */ +/* */ +/* -- extract the glyph outline from the object and copies it */ +/* to the 'outline' record */ +/* */ +/* TT_Get_Metrics( glyph, &metrics ); */ +/* */ +/* -- extract the glyph metrics and put them into the 'metrics' */ +/* record */ +/* */ +/* TT_Load_Glyph( ins2, glyph, 64, DEFAULT_GLYPH_LOAD ); */ +/* */ +/* -- load the same glyph at pointsize 12 in the 'glyph' object */ +/* */ +/* */ +/* TT_Close_Face( &face ); */ +/* */ +/* -- destroy the face object. This will destroy 'ins1' and */ +/* 'ins2'. However, the glyph object will still be available */ +/* */ +/* TT_Done_FreeType(); */ +/* */ +/* -- Finalize the engine. This will also destroy all pending */ +/* glyph objects (here 'glyph'). */ + + struct TFace_; + struct TInstance_; + struct TExecution_Context_; + struct TGlyph_; + + typedef struct TFace_ TFace; + typedef TFace* PFace; + + typedef struct TInstance_ TInstance; + typedef TInstance* PInstance; + + typedef struct TExecution_Context_ TExecution_Context; + typedef TExecution_Context* PExecution_Context; + + typedef struct TGlyph_ TGlyph; + typedef TGlyph* PGlyph; + + + /*************************************************************/ + /* */ + /* ADDITIONAL SUBTABLES */ + /* */ + /* These tables are not precisely defined by the specs */ + /* but their structures is implied by the TrueType font */ + /* file layout. */ + /* */ + /*************************************************************/ + + /* Graphics State */ + /* */ + /* The Graphics State (GS) is managed by the */ + /* instruction field, but does not come from */ + /* the font file. Thus, we can use 'int's */ + /* where needed. */ + + struct TGraphicsState_ + { + UShort rp0; + UShort rp1; + UShort rp2; + + TT_UnitVector dualVector; + TT_UnitVector projVector; + TT_UnitVector freeVector; + + Long loop; + TT_F26Dot6 minimum_distance; + Int round_state; + + Bool auto_flip; + TT_F26Dot6 control_value_cutin; + TT_F26Dot6 single_width_cutin; + TT_F26Dot6 single_width_value; + Short delta_base; + Short delta_shift; + + Byte instruct_control; + Bool scan_control; + Int scan_type; + + UShort gep0; + UShort gep1; + UShort gep2; + }; + + typedef struct TGraphicsState_ TGraphicsState; + + + LOCAL_DEF + const TGraphicsState Default_GraphicsState; + + + /*************************************************************/ + /* */ + /* EXECUTION SUBTABLES */ + /* */ + /* These sub-tables relate to instruction execution. */ + /* */ + /*************************************************************/ + +#define MAX_CODE_RANGES 3 + +/* There can only be 3 active code ranges at once: */ +/* - the Font Program */ +/* - the CVT Program */ +/* - a glyph's instructions set */ + +#define TT_CodeRange_Font 1 +#define TT_CodeRange_Cvt 2 +#define TT_CodeRange_Glyph 3 + + + struct TCodeRange_ + { + PByte Base; + ULong Size; + }; + + typedef struct TCodeRange_ TCodeRange; + typedef TCodeRange* PCodeRange; + + + /* Defintion of a code range */ + /* */ + /* Code ranges can be resident to a glyph (i.e. the Font Program) */ + /* while some others are volatile (Glyph instructions). */ + /* Tracking the state and presence of code ranges allows function */ + /* and instruction definitions within a code range to be forgotten */ + /* when the range is discarded. */ + + typedef TCodeRange TCodeRangeTable[MAX_CODE_RANGES]; + + /* defines a function/instruction definition record */ + + struct TDefRecord_ + { + Int Range; /* in which code range is it located ? */ + ULong Start; /* where does it start ? */ + Int Opc; /* function #, or instruction code */ + Bool Active; /* is it active ? */ + }; + + typedef struct TDefRecord_ TDefRecord; + typedef TDefRecord* PDefRecord; + typedef TDefRecord* PDefArray; + + /* defines a call record, used to manage function calls. */ + + struct TCallRecord_ + { + Int Caller_Range; + ULong Caller_IP; + Long Cur_Count; + ULong Cur_Restart; + }; + + typedef struct TCallRecord_ TCallRecord; + typedef TCallRecord* PCallRecord; + typedef TCallRecord* PCallStack; /* defines a simple call stack */ + + + /* This type defining a set of glyph points will be used to represent */ + /* each zone (regular and twilight) during instructions decoding. */ + struct TGlyph_Zone_ + { + UShort n_points; /* number of points in zone */ + Short n_contours; /* number of contours */ + + TT_Vector* org; /* original points coordinates */ + TT_Vector* cur; /* current points coordinates */ + + Byte* touch; /* current touch flags */ + UShort* contours; /* contour end points */ + }; + + typedef struct TGlyph_Zone_ TGlyph_Zone; + typedef TGlyph_Zone* PGlyph_Zone; + + + +#ifndef TT_STATIC_INTEPRETER /* indirect implementation */ + +#define EXEC_OPS PExecution_Context exc, +#define EXEC_OP PExecution_Context exc +#define EXEC_ARGS exc, +#define EXEC_ARG exc + +#else /* static implementation */ + +#define EXEC_OPS /* void */ +#define EXEC_OP /* void */ +#define EXEC_ARGS /* void */ +#define EXEC_ARG /* void */ + +#endif + + /* Rounding function, as used by the interpreter */ + typedef TT_F26Dot6 (*TRound_Function)( EXEC_OPS TT_F26Dot6 distance, + TT_F26Dot6 compensation ); + + /* Point displacement along the freedom vector routine, as */ + /* used by the interpreter */ + typedef void (*TMove_Function)( EXEC_OPS PGlyph_Zone zone, + UShort point, + TT_F26Dot6 distance ); + + /* Distance projection along one of the proj. vectors, as used */ + /* by the interpreter */ + typedef TT_F26Dot6 (*TProject_Function)( EXEC_OPS TT_Vector* v1, + TT_Vector* v2 ); + + /* reading a cvt value. Take care of non-square pixels when needed */ + typedef TT_F26Dot6 (*TGet_CVT_Function)( EXEC_OPS ULong index ); + + /* setting or moving a cvt value. Take care of non-square pixels */ + /* when needed */ + typedef void (*TSet_CVT_Function)( EXEC_OPS ULong index, + TT_F26Dot6 value ); + + /* subglyph transformation record */ + struct TTransform_ + { + TT_Fixed xx, xy; /* transformation */ + TT_Fixed yx, yy; /* matrix */ + TT_F26Dot6 ox, oy; /* offsets */ + }; + + typedef struct TTransform_ TTransform; + typedef TTransform* PTransform; + + /* subglyph loading record. Used to load composite components */ + struct TSubglyph_Record_ + { + Long index; /* subglyph index; initialized with -1 */ + Bool is_scaled; /* is the subglyph scaled? */ + Bool is_hinted; /* should it be hinted? */ + Bool preserve_pps; /* preserve phantom points? */ + + Long file_offset; + + TT_Big_Glyph_Metrics metrics; + + TGlyph_Zone zone; + + Long arg1; /* first argument */ + Long arg2; /* second argument */ + + UShort element_flag; /* current load element flag */ + + TTransform transform; /* transform */ + + TT_Vector pp1, pp2; /* phantom points */ + + }; + + typedef struct TSubglyph_Record_ TSubglyph_Record; + typedef TSubglyph_Record* PSubglyph_Record; + typedef TSubglyph_Record* PSubglyph_Stack; + + /* A note regarding non-squared pixels: */ + /* */ + /* (This text will probably go into some docs at some time, for */ + /* now, it is kept there to explain some definitions in the */ + /* TIns_Metrics record). */ + /* */ + /* The CVT is a one-dimensional array containing values that */ + /* control certain important characteristics in a font, like */ + /* the height of all capitals, all lowercase letter, default */ + /* spacing or stem width/height. */ + /* */ + /* These values are found in FUnits in the font file, and must be */ + /* scaled to pixel coordinates before being used by the CVT and */ + /* glyph programs. Unfortunately, when using distinct x and y */ + /* resolutions (or distinct x and y pointsizes), there are two */ + /* possible scalings. */ + /* */ + /* A first try was to implement a 'lazy' scheme where all values */ + /* were scaled when first used. However, while some values are always */ + /* used in the same direction, and some other are used in many */ + /* different circumstances and orientations. */ + /* */ + /* I have found a simpler way to do the same, and it even seems to */ + /* work in most of the cases: */ + /* */ + /* - all CVT values are scaled to the maximum ppem size */ + /* */ + /* - when performing a read or write in the CVT, a ratio factor */ + /* is used to perform adequate scaling. Example: */ + /* */ + /* x_ppem = 14 */ + /* y_ppem = 10 */ + /* */ + /* we choose ppem = x_ppem = 14 as the CVT scaling size. All cvt */ + /* entries are scaled to it. */ + /* */ + /* x_ratio = 1.0 */ + /* y_ratio = y_ppem/ppem (< 1.0) */ + /* */ + /* we compute the current ratio like: */ + /* */ + /* - if projVector is horizontal, */ + /* ratio = x_ratio = 1.0 */ + /* - if projVector is vertical, */ + /* ratop = y_ratio */ + /* - else, */ + /* ratio = sqrt((proj.x*x_ratio)^2 + (proj.y*y_ratio)^2) */ + /* */ + /* reading a cvt value returns ratio * cvt[index] */ + /* writing a cvt value in pixels cvt[index] / ratio */ + /* */ + /* the current ppem is simply ratio * ppem */ + /* */ + + /* metrics used by the instance and execution context objects */ + struct TIns_Metrics_ + { + TT_F26Dot6 pointSize; /* point size. 1 point = 1/72 inch. */ + + UShort x_resolution; /* device horizontal resolution in dpi. */ + UShort y_resolution; /* device vertical resolution in dpi. */ + + UShort x_ppem; /* horizontal pixels per EM */ + UShort y_ppem; /* vertical pixels per EM */ + + Long x_scale1; + Long x_scale2; /* used to scale FUnits to fractional pixels */ + + Long y_scale1; + Long y_scale2; /* used to scale FUnits to fractional pixels */ + + /* for non-square pixels */ + Long x_ratio; + Long y_ratio; + + UShort ppem; /* maximum ppem size */ + Long ratio; /* current ratio */ + Long scale1; + Long scale2; /* scale for ppem */ + + TT_F26Dot6 compensations[4]; /* device-specific compensations */ + + Bool rotated; /* `is the glyph rotated?'-flag */ + Bool stretched; /* `is the glyph stretched?'-flag */ + }; + + typedef struct TIns_Metrics_ TIns_Metrics; + typedef TIns_Metrics* PIns_Metrics; + + + + /***********************************************************************/ + /* */ + /* FreeType Face Type */ + /* */ + /***********************************************************************/ + + struct TFace_ + { + /* parent engine instance for the face object */ + PEngine_Instance engine; + + /* i/o stream */ + TT_Stream stream; + + /* used only by the threaded builds of the library */ + TMutex lock; + + /* TrueType collection header, if any was found */ + TTTCHeader ttcHeader; + + /* maximum profile table, as found in the TrueType file */ + TMaxProfile maxProfile; + + /* Note: */ + /* it seems that some maximum values cannot be */ + /* taken directly from this table, but rather by */ + /* combining some of its fields; e.g. the max. */ + /* number of points seems to be given by */ + /* MAX( maxPoints, maxCompositePoints ) */ + /* */ + /* For this reason, we define later our own */ + /* max values that are used to load and allocate */ + /* further tables. */ + + TT_Header fontHeader; /* the font header, as */ + /* found in the TTF file */ + TT_Horizontal_Header horizontalHeader; /* the horizontal header */ + + Bool verticalInfo; /* True when vertical table */ + TT_Vertical_Header verticalHeader; /* is present in the font */ + + TT_OS2 os2; /* 'OS/2' table */ + + TT_Postscript postscript; /* 'Post' table */ + + TT_Hdmx hdmx; /* 'Hdmx' table */ + + TName_Table nameTable; /* name table */ + + TGasp gasp; /* the 'gasp' table */ + + /* The directory of TrueType tables for this typeface */ + UShort numTables; + PTableDirEntry dirTables; + + /* The directory of character mappings table for */ + /* this typeface */ + UShort numCMaps; + PCMapTable cMaps; + + /* The glyph locations table */ + ULong numLocations; /* UShort is not enough */ +#ifndef TT_HUGE_PTR + PStorage glyphLocations; +#else + Storage TT_HUGE_PTR * glyphLocations; +#endif + + /* NOTE : The "hmtx" is now part of the horizontal header */ + + /* the font program, if any */ + ULong fontPgmSize; + PByte fontProgram; + + /* the cvt program, if any */ + ULong cvtPgmSize; + PByte cvtProgram; + + /* the original, unscaled, control value table */ + ULong cvtSize; + PShort cvt; + + /* The following values _must_ be set by the */ + /* maximum profile loader */ + + UShort numGlyphs; /* the face's total number of glyphs */ + UShort maxPoints; /* max glyph points number, simple and composite */ + UShort maxContours; /* max glyph contours numb, simple and composite */ + UShort maxComponents; /* max components in a composite glyph */ + + /* the following are object caches to track active */ + /* and recycled instances and execution contexts */ + /* objects. See 'ttcache.h' */ + + TCache instances; /* current instances for this face */ + TCache glyphs; /* current glyph containers for this face */ + + + /* A typeless pointer to the face object extensions defined */ + /* in the 'ttextend.*' files. */ + void* extension; + Int n_extensions; /* number of extensions */ + + /* Use extensions to provide additional capabilities to the */ + /* engine. Read the developer's guide in the documentation */ + /* directory to know how to do that. */ + + /* a generic pointer for client use - see TT_Set/Get_Face_Pointer */ + void* generic; + }; + + + + /***********************************************************************/ + /* */ + /* FreeType Instance Type */ + /* */ + /***********************************************************************/ + + struct TInstance_ + { + PFace owner; /* face object */ + + Bool valid; + + TIns_Metrics metrics; + + UShort numFDefs; /* number of function definitions */ + UShort maxFDefs; + PDefArray FDefs; /* table of FDefs entries */ + + UShort numIDefs; /* number of instruction definitions */ + UShort maxIDefs; + PDefArray IDefs; /* table of IDefs entries */ + + Int maxFunc; /* maximum function definition id */ + Int maxIns; /* maximum instruction definition id */ + + TCodeRangeTable codeRangeTable; + + TGraphicsState GS; + TGraphicsState default_GS; + + ULong cvtSize; /* the scaled control value table */ + PLong cvt; + + ULong storeSize; /* The storage area is now part of the */ + PLong storage; /* instance */ + + TGlyph_Zone twilight; /* The instance's twilight zone */ + + /* debugging variables */ + + /* When using the debugger, we must keep the */ + /* execution context tied to the instance */ + /* object rather than asking it on demand */ + + Bool debug; + PExecution_Context context; + + /* a generic pointer for client use - see TT_Set/Get_Instance_Pointer */ + void* generic; + }; + + + /***********************************************************************/ + /* */ + /* FreeType Execution Context Type */ + /* */ + /***********************************************************************/ + + struct TExecution_Context_ + { + PFace face; + PInstance instance; + + /* instructions state */ + + TT_Error error; /* last execution error */ + + Long top; /* top of exec. stack */ + + ULong stackSize; /* size of exec. stack */ + PStorage stack; /* current exec. stack */ + + Long args; + ULong new_top; /* new top after exec. */ + + TGlyph_Zone zp0, /* zone records */ + zp1, + zp2, + pts, + twilight; + + TIns_Metrics metrics; /* instance metrics */ + + TGraphicsState GS; /* current graphics state */ + + Int curRange; /* current code range number */ + PByte code; /* current code range */ + ULong IP; /* current instruction pointer */ + ULong codeSize; /* size of current range */ + + Byte opcode; /* current opcode */ + Int length; /* length of current opcode */ + + Bool step_ins; /* true if the interpreter must */ + /* increment IP after ins. exec */ + ULong cvtSize; + PLong cvt; + + ULong glyphSize; /* glyph instructions buffer size */ + PByte glyphIns; /* glyph instructions buffer */ + + UShort numFDefs; /* number of function defs */ + UShort maxFDefs; /* maximum number of function defs */ + PDefRecord FDefs; /* table of FDefs entries */ + + UShort numIDefs; /* number of instruction defs */ + UShort maxIDefs; /* maximum number of instruction defs */ + PDefRecord IDefs; /* table of IDefs entries */ + + Int maxFunc; + Int maxIns; + + Int callTop, /* top of call stack during execution */ + callSize; /* size of call stack */ + PCallStack callStack; /* call stack */ + + UShort maxPoints; /* capacity of this context's "pts" */ + UShort maxContours; /* record, expressed in points and */ + /* contours.. */ + + TCodeRangeTable codeRangeTable; /* table of valid coderanges */ + /* useful for the debugger */ + + ULong storeSize; /* size of current storage */ + PLong storage; /* storage area */ + + TT_F26Dot6 period; /* values used for the */ + TT_F26Dot6 phase; /* 'SuperRounding' */ + TT_F26Dot6 threshold; + + /* this seems to be unused */ +#if 0 + Int cur_ppem; /* ppem along the current proj vector */ +#endif + Long scale1; /* scaling values along the current */ + Long scale2; /* projection vector too.. */ + Bool cached_metrics; /* the ppem is computed lazily. used */ + /* to trigger computation when needed */ + + Bool instruction_trap; /* If True, the interpreter will */ + /* exit after each instruction */ + + TGraphicsState default_GS; /* graphics state resulting from */ + /* the prep program */ + Bool is_composite; /* ture if the glyph is composite */ + + Bool pedantic_hinting; /* if true, read and write array */ + /* bounds faults halt the hinting */ + + /* latest interpreter additions */ + + Long F_dot_P; /* dot product of freedom and projection */ + /* vectors */ + TRound_Function func_round; /* current rounding function */ + + TProject_Function func_project, /* current projection function */ + func_dualproj, /* current dual proj. function */ + func_freeProj; /* current freedom proj. func */ + + TMove_Function func_move; /* current point move function */ + + TGet_CVT_Function func_read_cvt; /* read a cvt entry */ + TSet_CVT_Function func_write_cvt; /* write a cvt entry (in pixels) */ + TSet_CVT_Function func_move_cvt; /* incr a cvt entry (in pixels) */ + + ULong loadSize; + PSubglyph_Stack loadStack; /* loading subglyph stack */ + + }; + + + /***********************************************************************/ + /* */ + /* FreeType Glyph Object Type */ + /* */ + /***********************************************************************/ + + struct TGlyph_ + { + PFace face; + TT_Big_Glyph_Metrics metrics; + TT_Outline outline; + }; + + + /* The following type is used to load a font from a collection. */ + /* See Face_Create in ttobjs.c */ + + struct TFont_Input_ + { + TT_Stream stream; /* input stream */ + ULong fontIndex; /* index of font in collection */ + PEngine_Instance engine; /* parent engine instance */ + + }; + + typedef struct TFont_Input_ TFont_Input; + + + /********************************************************************/ + /* */ + /* Code Range Functions */ + /* */ + /********************************************************************/ + + /* Goto a specified coderange */ + LOCAL_DEF + TT_Error Goto_CodeRange( PExecution_Context exec, + Int range, + ULong IP ); + +#if 0 + /* Return a pointer to a given coderange record. */ + /* Used only by the debugger. */ + LOCAL_DEF + PCodeRange Get_CodeRange( PExecution_Context exec, + Int range ); +#endif + + /* Set a given code range properties */ + LOCAL_DEF + TT_Error Set_CodeRange( PExecution_Context exec, + Int range, + void* base, + ULong length ); + + /* Clear a given coderange */ + LOCAL_DEF + TT_Error Clear_CodeRange( PExecution_Context exec, Int range ); + + + LOCAL_DEF + PExecution_Context New_Context( PFace face ); + + LOCAL_DEF + TT_Error Done_Context( PExecution_Context exec ); + + + LOCAL_DEF + TT_Error Context_Load( PExecution_Context exec, + PFace face, + PInstance ins ); + + LOCAL_DEF + TT_Error Context_Save( PExecution_Context exec, + PInstance ins ); + + LOCAL_DEF + TT_Error Context_Run( PExecution_Context exec, + Bool debug ); + + LOCAL_DEF + TT_Error Instance_Init( PInstance ins ); + + LOCAL_DEF + TT_Error Instance_Reset( PInstance ins ); + + + /********************************************************************/ + /* */ + /* Handy scaling functions */ + /* */ + /********************************************************************/ + + LOCAL_DEF TT_Pos Scale_X( PIns_Metrics metrics, TT_Pos x ); + LOCAL_DEF TT_Pos Scale_Y( PIns_Metrics metrics, TT_Pos y ); + + /********************************************************************/ + /* */ + /* Component Initializer/Finalizer */ + /* */ + /* Called from 'freetype.c' */ + /* The component must create and register the face, instance and */ + /* execution context cache classes before any object can be */ + /* managed. */ + /* */ + /********************************************************************/ + + LOCAL_DEF TT_Error TTObjs_Init( PEngine_Instance engine ); + LOCAL_DEF TT_Error TTObjs_Done( PEngine_Instance engine ); + +#ifdef __cplusplus + } +#endif + +#endif /* TTOBJS_H */ + + +/* END */ diff --git a/lib/ttraster.c b/lib/ttraster.c new file mode 100644 index 0000000..90f9a90 --- /dev/null +++ b/lib/ttraster.c @@ -0,0 +1,2727 @@ +/******************************************************************* + * + * ttraster.c 1.5 + * + * The FreeType glyph rasterizer (body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES: + * + * This version supports the following: + * + * - direct grayscaling + * - sub-banding + * - drop-out modes 4 and 5 + * - second pass for complete drop-out control (bitmap only) + * - variable precision + * + * Changes between 1.5 and 1.4: + * + * Performance tuning. + * + * Changes between 1.4 and 1.3: + * + * Mainly performance tunings: + * + * - Line_Down() and Bezier_Down() now use the functions Line_Up() + * and Bezier_Up() to do their work. + * - optimized Split_Bezier() + * - optimized linked lists used during sweeps + * + ******************************************************************/ + +#include "ttraster.h" +#include "ttdebug.h" +#include "tttypes.h" +#include "ttengine.h" +#include "ttcalc.h" /* for TT_MulDiv only */ + +#include "ttmemory.h" /* only used to allocate memory on engine init */ + +/* required by the tracing mode */ +#undef TT_COMPONENT +#define TT_COMPONENT trace_raster + + +/* The default render pool size */ +#define RASTER_RENDER_POOL 64000 + +/* The size of the two-lines intermediate bitmap used */ +/* for anti-aliasing */ +#define RASTER_GRAY_LINES 2048 + + +#define Raster_Err_None TT_Err_Ok +#define Raster_Err_Not_Ini TT_Err_Raster_Not_Initialized +#define Raster_Err_Overflow TT_Err_Raster_Pool_Overflow +#define Raster_Err_Neg_Height TT_Err_Raster_Negative_Height +#define Raster_Err_Invalid TT_Err_Raster_Invalid_Value +#define Raster_Err_Gray_Unsupported TT_Err_Raster_Gray_Unsupported + + +/* FMulDiv means "Fast MulDiv", it is uses in case where 'b' is typically */ +/* a small value and the result of (a*b) is known to fit in 32 bits. */ +#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) + +/* On the other hand, SMulDiv is for "Slow MulDiv", and is used typically */ +/* for clipping computations. It simply uses the TT_MulDiv() function */ +/* defined in "ttcalc.h" */ +/* */ +/* So, the following definition fits the bill nicely, and we don't need */ +/* to use the one in 'ttcalc' anymore, even for 16-bit systems... */ +#define SMulDiv TT_MulDiv + + +/* Define DEBUG_RASTER if you want to generate a debug version of the */ +/* rasterizer. This will progressively draw the glyphs while all the */ +/* computation are done directly on the graphics screen (the glyphs */ +/* will be inverted). */ + +/* Note that DEBUG_RASTER should only be used for debugging with b/w */ +/* rendering, not with gray levels. */ + +/* The definition of DEBUG_RASTER should appear in the file */ +/* "ttconfig.h". */ + +#ifdef DEBUG_RASTER + extern Char* Vio; /* A pointer to VRAM or display buffer */ +#endif + + +/* The rasterizer is a very general purpose component, please leave */ +/* the following redefinitions there (you never know your target */ +/* environment). */ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + +#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ + /* Setting this constant to more than 32 is a */ + /* pure waste of space. */ + +#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ + + /* States of each line, arc and profile */ + enum TStates_ + { + Unknown, + Ascending, + Descending, + Flat + }; + + typedef enum TStates_ TStates; + + struct TProfile_; + typedef struct TProfile_ TProfile; + typedef TProfile* PProfile; + + struct TProfile_ + { + TT_F26Dot6 X; /* current coordinate during sweep */ + PProfile link; /* link to next profile - various purpose */ + PStorage offset; /* start of profile's data in render pool */ + Int flow; /* Profile orientation: Asc/Descending */ + Long height; /* profile's height in scanlines */ + Long start; /* profile's starting scanline */ + + UShort countL; /* number of lines to step before this */ + /* profile becomes drawable */ + + PProfile next; /* next profile in same contour, used */ + /* during drop-out control */ + }; + + typedef PProfile TProfileList; + typedef PProfile* PProfileList; + + + /* I use the classic trick of two dummy records for the head and tail */ + /* of a linked list; this reduces tests in insertion/deletion/sorting. */ + /* NOTE: used during sweeps only. */ + + /* Simple record used to implement a stack of bands, required */ + /* by the sub-banding mechanism */ + + struct TBand_ + { + Short y_min; /* band's minimum */ + Short y_max; /* band's maximum */ + }; + + typedef struct TBand_ TBand; + + +#define AlignProfileSize \ + (( sizeof(TProfile)+sizeof(long)-1 ) / sizeof(long)) + + + /* Left fill bitmask */ + static const Byte LMask[8] = + { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 }; + + /* Right fill bitmask */ + static const Byte RMask[8] = + { 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF }; + + /* prototypes used for sweep function dispatch */ + typedef void Function_Sweep_Init( RAS_ARGS Short* min, + Short* max ); + + typedef void Function_Sweep_Span( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ); + + typedef void Function_Sweep_Step( RAS_ARG ); + + +/* NOTE: These operations are only valid on 2's complement processors */ + +#define FLOOR( x ) ( (x) & -ras.precision ) +#define CEILING( x ) ( ((x) + ras.precision - 1) & -ras.precision ) +#define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits ) +#define FRAC( x ) ( (x) & (ras.precision - 1) ) +#define SCALED( x ) ( ((x) << ras.scale_shift) - ras.precision_half ) + +#ifdef DEBUG_RASTER +#define DEBUG_PSET Pset() +#else +#define DEBUG_PSET +#endif + + struct TPoint_ + { + Long x, y; + }; + + typedef struct TPoint_ TPoint; + + + /* Note that I have moved the location of some fields in the */ + /* structure to ensure that the most used variables are used */ + /* at the top. Thus, their offset can be coded with less */ + /* opcodes, and it results in a smaller executable. */ + + struct TRaster_Instance_ + { + Int precision_bits; /* precision related variables */ + Int precision; + Int precision_half; + Long precision_mask; + Int precision_shift; + Int precision_step; + Int precision_jitter; + + Int scale_shift; /* == precision_shift for bitmaps */ + /* == precision_shift+1 for pixmaps */ + + PStorage buff; /* The profiles buffer */ + PStorage sizeBuff; /* Render pool size */ + PStorage maxBuff; /* Profiles buffer size */ + PStorage top; /* Current cursor in buffer */ + + TT_Error error; + + PByte flags; /* current flags table */ + PUShort outs; /* current outlines table */ + + UShort nPoints; /* number of points in current glyph */ + Short nContours; /* number of contours in current glyph */ + Int numTurns; /* number of Y-turns in outline */ + + TPoint* arc; /* current Bezier arc pointer */ + + UShort bWidth; /* target bitmap width */ + PByte bTarget; /* target bitmap buffer */ + PByte gTarget; /* target pixmap buffer */ + + Long lastX, lastY, minY, maxY; + + UShort num_Profs; /* current number of profiles */ + + Bool fresh; /* signals a fresh new profile which */ + /* 'start' field must be completed */ + Bool joint; /* signals that the last arc ended */ + /* exactly on a scanline. Allows */ + /* removal of doublets */ + PProfile cProfile; /* current profile */ + PProfile fProfile; /* head of linked list of profiles */ + PProfile gProfile; /* contour's first profile in case */ + /* of impact */ + TStates state; /* rendering state */ + + TT_Raster_Map target; /* description of target bit/pixmap */ + + Long traceOfs; /* current offset in target bitmap */ + Long traceG; /* current offset in target pixmap */ + + Short traceIncr; /* sweep's increment in target bitmap */ + + Short gray_min_x; /* current min x during gray rendering */ + Short gray_max_x; /* current max x during gray rendering */ + + /* dispatch variables */ + + Function_Sweep_Init* Proc_Sweep_Init; + Function_Sweep_Span* Proc_Sweep_Span; + Function_Sweep_Span* Proc_Sweep_Drop; + Function_Sweep_Step* Proc_Sweep_Step; + + TT_Vector* coords; + + Byte dropOutControl; /* current drop_out control method */ + + Byte grays[5]; /* Palette of gray levels used for render */ + + Byte* gray_lines; /* Intermediate table used to render the */ + /* graylevels pixmaps. */ + /* gray_lines is a buffer holding two */ + /* monochrome scanlines */ + Short gray_width; /* width in bytes of one monochrome */ + /* intermediate scanline of gray_lines. */ + /* Each gray pixel takes 2 bits long there */ + + /* The gray_lines must hold 2 lines, thus with size */ + /* in bytes of at least 'gray_width*2' */ + + Bool second_pass; /* indicates wether a horizontal pass */ + /* should be performed to control drop-out */ + /* accurately when calling Render_Glyph. */ + /* Note that there is no horizontal pass */ + /* during gray rendering. */ + TPoint arcs[2 * MaxBezier + 1]; /* The Bezier stack */ + + TBand band_stack[16]; /* band stack used for sub-banding */ + Int band_top; /* band stack top */ + + Int count_table[256]; /* Look-up table used to quickly count */ + /* set bits in a gray 2x2 cell */ + }; + + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + + static TRaster_Instance cur_ras; +#define ras cur_ras + +#else + +#define ras (*raster) + +#endif /* TT_STATIC_RASTER */ + + +#ifdef DEBUG_RASTER + + /************************************************/ + /* */ + /* Pset: */ + /* */ + /* Used for debugging only. Plots a point */ + /* in VRAM during rendering (not afterwards). */ + /* */ + /* NOTE: This procedure relies on the value */ + /* of cProfile->start, which may not */ + /* be set when Pset is called sometimes. */ + /* This will usually result in a dot */ + /* plotted on the first screen scanline */ + /* (far away its original position). */ + /* */ + /* This "bug" reflects nothing wrong */ + /* in the current implementation, and */ + /* the bitmap is rendered correctly, */ + /* so don't panic if you see 'flying' */ + /* dots in debugging mode. */ + /* */ + /* - David */ + /* */ + /************************************************/ + + static void Pset( RAS_ARG ) + { + Long o; + Long x; + + + x = ras.top[-1]; + + switch ( ras.cProfile->flow ) + { + case TT_Flow_Up: + o = Vio_ScanLineWidth * + ( ras.top-ras.cProfile->offset + ras.cProfile->start ) + + ( x / (ras.precision*8) ); + break; + + case TT_Flow_Down: + o = Vio_ScanLineWidth * + ( ras.cProfile->start-ras.top + ras.cProfile->offset ) + + ( x / (ras.precision*8) ); + break; + } + + if ( o > 0 ) + Vio[o] |= (unsigned)0x80 >> ( (x/ras.precision) & 7 ); + } + + + static void Clear_Band( RAS_ARGS Int y1, Int y2 ) + { + MEM_Set( Vio + y1*Vio_ScanLineWidth, (y2-y1+1)*Vio_ScanLineWidth, 0 ); + } + +#endif /* DEBUG_RASTER */ + + +/************************************************************************/ +/* */ +/* Function: Set_High_Precision */ +/* */ +/* Description: Sets precision variables according to param flag. */ +/* */ +/* Input: High set to True for high precision (typically for */ +/* ppem < 18), false otherwise. */ +/* */ +/************************************************************************/ + + static void Set_High_Precision( RAS_ARGS Bool High ) + { + if ( High ) + { + ras.precision_bits = 10; + ras.precision_step = 128; + ras.precision_jitter = 24; + } + else + { + ras.precision_bits = 6; + ras.precision_step = 32; + ras.precision_jitter = 2; + } + + PTRACE7(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); + + ras.precision = 1 << ras.precision_bits; + ras.precision_half = ras.precision / 2; + ras.precision_shift = ras.precision_bits - Pixel_Bits; + ras.precision_mask = -ras.precision; + } + + +/****************************************************************************/ +/* */ +/* Function: New_Profile */ +/* */ +/* Description: Creates a new Profile in the render pool. */ +/* */ +/* Input: aState state/orientation of the new Profile */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE in case of overflow or of incoherent Profile. */ +/* */ +/****************************************************************************/ + + static Bool New_Profile( RAS_ARGS TStates aState ) + { + if ( !ras.fProfile ) + { + ras.cProfile = (PProfile)ras.top; + ras.fProfile = ras.cProfile; + ras.top += AlignProfileSize; + } + + if ( ras.top >= ras.maxBuff ) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + switch ( aState ) + { + case Ascending: + ras.cProfile->flow = TT_Flow_Up; + PTRACE7(( "New ascending profile = %lx\n", (long)ras.cProfile )); + break; + + case Descending: + ras.cProfile->flow = TT_Flow_Down; + PTRACE7(( "New descending profile = %lx\n", (long)ras.cProfile )); + break; + + default: + PTRACE0(( "Invalid profile direction in Raster:New_Profile !!\n" )); + ras.error = Raster_Err_Invalid; + return FAILURE; + } + + ras.cProfile->start = 0; + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + ras.cProfile->link = (PProfile)0; + ras.cProfile->next = (PProfile)0; + + if ( !ras.gProfile ) + ras.gProfile = ras.cProfile; + + ras.state = aState; + ras.fresh = TRUE; + ras.joint = FALSE; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: End_Profile */ +/* */ +/* Description: Finalizes the current Profile. */ +/* */ +/* Input: None */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE in case of overflow or incoherency. */ +/* */ +/****************************************************************************/ + + static Bool End_Profile( RAS_ARG ) + { + Long h; + PProfile oldProfile; + + + h = ras.top - ras.cProfile->offset; + + if ( h < 0 ) + { + PTRACE0(( "Negative height encountered in End_Profile!\n" )); + ras.error = Raster_Err_Neg_Height; + return FAILURE; + } + + if ( h > 0 ) + { + PTRACE1(( "Ending profile %lx, start = %ld, height = %ld\n", + (long)ras.cProfile, ras.cProfile->start, h )); + + oldProfile = ras.cProfile; + ras.cProfile->height = h; + ras.cProfile = (PProfile)ras.top; + + ras.top += AlignProfileSize; + + ras.cProfile->height = 0; + ras.cProfile->offset = ras.top; + oldProfile->next = ras.cProfile; + ras.num_Profs++; + } + + if ( ras.top >= ras.maxBuff ) + { + PTRACE1(( "overflow in End_Profile\n" )); + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + ras.joint = FALSE; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Insert_Y_Turn */ +/* */ +/* Description: Insert a salient into the sorted list placed on top */ +/* of the render pool */ +/* */ +/* Input: New y scanline position */ +/* */ +/****************************************************************************/ + + static + Bool Insert_Y_Turn( RAS_ARGS Int y ) + { + PStorage y_turns; + Int y2, n; + + n = ras.numTurns-1; + y_turns = ras.sizeBuff - ras.numTurns; + + /* look for first y value that is <= */ + while ( n >= 0 && y < y_turns[n] ) + n--; + + /* if it is <, simply insert it, ignore if == */ + if ( n >= 0 && y > y_turns[n] ) + while ( n >= 0 ) + { + y2 = y_turns[n]; + y_turns[n] = y; + y = y2; + n--; + } + + if ( n < 0 ) + { + if (ras.maxBuff <= ras.top) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + ras.maxBuff--; + ras.numTurns++; + ras.sizeBuff[-ras.numTurns] = y; + } + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Finalize_Profile_Table */ +/* */ +/* Description: Adjusts all links in the Profiles list. */ +/* */ +/* Input: None */ +/* */ +/* Returns: None. */ +/* */ +/****************************************************************************/ + + static + Bool Finalize_Profile_Table( RAS_ARG ) + { + Int bottom, top; + UShort n; + PProfile p; + + + n = ras.num_Profs; + + if ( n > 1 ) + { + p = ras.fProfile; + while ( n > 0 ) + { + if ( n > 1 ) + p->link = (PProfile)( p->offset + p->height ); + else + p->link = NULL; + + switch ( p->flow ) + { + case TT_Flow_Down: + bottom = p->start - p->height+1; + top = p->start; + p->start = bottom; + p->offset += p->height-1; + break; + + case TT_Flow_Up: + default: + bottom = p->start; + top = p->start + p->height-1; + } + + if ( Insert_Y_Turn( RAS_VARS bottom ) || + Insert_Y_Turn( RAS_VARS top+1 ) ) + return FAILURE; + + p = p->link; + n--; + } + } + else + ras.fProfile = NULL; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Split_Bezier */ +/* */ +/* Description: Subdivides one Bezier arc into two joint */ +/* sub-arcs in the Bezier stack. */ +/* */ +/* Input: None (subdivided bezier is taken from the top of the */ +/* stack). */ +/* */ +/* Returns: None. */ +/* */ +/* */ +/* Note: This routine is the 'beef' of this component. It is _the_ */ +/* inner loop that should be optimized to hell to get the */ +/* best performance. */ +/* */ +/****************************************************************************/ + + static void Split_Bezier( TPoint* base ) + { + Long a, b; + + + base[4].x = base[2].x; + b = base[1].x; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; + + base[4].y = base[2].y; + b = base[1].y; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; + + /* hand optimized. gcc doesn't seem too good at common expression */ + /* substitution and instruction scheduling ;-) */ + } + + +/****************************************************************************/ +/* */ +/* Function: Push_Bezier */ +/* */ +/* Description: Clears the Bezier stack and pushes a new arc on top of it. */ +/* */ +/* Input: x1,y1 x2,y2 x3,y3 new Bezier arc */ +/* */ +/* Returns: None. */ +/* */ +/****************************************************************************/ + + static void Push_Bezier( RAS_ARGS Long x1, Long y1, + Long x2, Long y2, + Long x3, Long y3 ) + { + ras.arc = ras.arcs; + ras.arc[2].x = x1; ras.arc[2].y = y1; + ras.arc[1].x = x2; ras.arc[1].y = y2; + ras.arc[0].x = x3; ras.arc[0].y = y3; + } + + +/****************************************************************************/ +/* */ +/* Function: Line_Up */ +/* */ +/* Description: Computes the x-coordinates of an ascending line segment */ +/* and stores them in the render pool. */ +/* */ +/* Input: x1,y1,x2,y2 Segment start (x1,y1) and end (x2,y2) points */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow. */ +/* */ +/****************************************************************************/ + + static Bool Line_Up( RAS_ARGS Long x1, Long y1, + Long x2, Long y2, + Long miny, Long maxy ) + { + Long Dx, Dy; + Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ + Long Ix, Rx, Ax; + + PStorage top; + + + Dx = x2 - x1; + Dy = y2 - y1; + + if ( Dy <= 0 || y2 < miny || y1 > maxy ) + return SUCCESS; + + if ( y1 < miny ) + { + /* Take care : miny-y1 can be a very large value, we use */ + /* a slow MulDiv function to avoid clipping bugs */ + x1 += SMulDiv( Dx, miny - y1, Dy ); + e1 = TRUNC( miny ); + f1 = 0; + } + else + { + e1 = TRUNC( y1 ); + f1 = FRAC( y1 ); + } + + if ( y2 > maxy ) + { + /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ + e2 = TRUNC( maxy ); + f2 = 0; + } + else + { + e2 = TRUNC( y2 ); + f2 = FRAC( y2 ); + } + + if ( f1 > 0 ) + { + if ( e1 == e2 ) return SUCCESS; + else + { + x1 += FMulDiv( Dx, ras.precision - f1, Dy ); + e1 += 1; + } + } + else + if ( ras.joint ) + { + ras.top--; + ras.joint = FALSE; + } + + ras.joint = ( f2 == 0 ); + + if ( ras.fresh ) + { + ras.cProfile->start = e1; + ras.fresh = FALSE; + } + + size = e2 - e1 + 1; + if ( ras.top + size >= ras.maxBuff ) + { + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + if ( Dx > 0 ) + { + Ix = (ras.precision*Dx) / Dy; + Rx = (ras.precision*Dx) % Dy; + Dx = 1; + } + else + { + Ix = -( (ras.precision*-Dx) / Dy ); + Rx = (ras.precision*-Dx) % Dy; + Dx = -1; + } + + Ax = -Dy; + top = ras.top; + + while ( size > 0 ) + { + *top++ = x1; + + DEBUG_PSET; + + x1 += Ix; + Ax += Rx; + if ( Ax >= 0 ) + { + Ax -= Dy; + x1 += Dx; + } + size--; + } + + ras.top = top; + return SUCCESS; + } + + + static Bool Line_Down( RAS_ARGS Long x1, Long y1, + Long x2, Long y2, + Long miny, Long maxy ) + { + Bool result, fresh; + + + fresh = ras.fresh; + + result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); + + if ( fresh && !ras.fresh ) + ras.cProfile->start = -ras.cProfile->start; + + return result; + } + + +/****************************************************************************/ +/* */ +/* Function: Bezier_Up */ +/* */ +/* Description: Computes thes x-coordinates of an ascending bezier arc */ +/* and stores them in the render pool. */ +/* */ +/* Input: None. The arc is taken from the top of the Bezier stack. */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow. */ +/* */ +/****************************************************************************/ + + static Bool Bezier_Up( RAS_ARGS Long miny, Long maxy ) + { + Long y1, y2, e, e2, e0; + Short f1; + + TPoint* arc; + TPoint* start_arc; + + PStorage top; + + + arc = ras.arc; + y1 = arc[2].y; + y2 = arc[0].y; + top = ras.top; + + if ( y2 < miny || y1 > maxy ) + goto Fin; + + e2 = FLOOR( y2 ); + + if ( e2 > maxy ) + e2 = maxy; + + e0 = miny; + + if ( y1 < miny ) + e = miny; + else + { + e = CEILING( y1 ); + f1 = FRAC( y1 ); + e0 = e; + + if ( f1 == 0 ) + { + if ( ras.joint ) + { + top--; + ras.joint = FALSE; + } + + *top++ = arc[2].x; + + DEBUG_PSET; + + e += ras.precision; + } + } + + if ( ras.fresh ) + { + ras.cProfile->start = TRUNC( e0 ); + ras.fresh = FALSE; + } + + if ( e2 < e ) + goto Fin; + + if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) + { + ras.top = top; + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + start_arc = arc; + + while ( arc >= start_arc && e <= e2 ) + { + ras.joint = FALSE; + + y2 = arc[0].y; + + if ( y2 > e ) + { + y1 = arc[2].y; + if ( y2 - y1 >= ras.precision_step ) + { + Split_Bezier( arc ); + arc += 2; + } + else + { + *top++ = arc[2].x + FMulDiv( arc[0].x - arc[2].x, + e - y1, + y2 - y1 ); + DEBUG_PSET; + + arc -= 2; + e += ras.precision; + } + } + else + { + if ( y2 == e ) + { + ras.joint = TRUE; + *top++ = arc[0].x; + + DEBUG_PSET; + + e += ras.precision; + } + arc -= 2; + } + } + + Fin: + ras.top = top; + ras.arc -= 2; + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Bezier_Down */ +/* */ +/* Description: Computes the x-coordinates of a descending bezier arc */ +/* and stores them in the render pool. */ +/* */ +/* Input: None. Arc is taken from the top of the Bezier stack. */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow. */ +/* */ +/****************************************************************************/ + + static Bool Bezier_Down( RAS_ARGS Long miny, Long maxy ) + { + TPoint* arc = ras.arc; + Bool result, fresh; + + + arc[0].y = -arc[0].y; + arc[1].y = -arc[1].y; + arc[2].y = -arc[2].y; + + fresh = ras.fresh; + + result = Bezier_Up( RAS_VARS -maxy, -miny ); + + if ( fresh && !ras.fresh ) + ras.cProfile->start = -ras.cProfile->start; + + arc[0].y = -arc[0].y; + return result; + } + + +/****************************************************************************/ +/* */ +/* Function: Line_To */ +/* */ +/* Description: Injects a new line segment and adjusts Profiles list. */ +/* */ +/* Input: x, y : segment endpoint (start point in LastX,LastY) */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow or Incorrect Profile. */ +/* */ +/****************************************************************************/ + + static Bool Line_To( RAS_ARGS Long x, Long y ) + { + /* First, detect a change of direction */ + + switch ( ras.state ) + { + case Unknown: + if ( y > ras.lastY ) + { + if ( New_Profile( RAS_VARS Ascending ) ) return FAILURE; + } + else + { + if ( y < ras.lastY ) + if ( New_Profile( RAS_VARS Descending ) ) return FAILURE; + } + break; + + case Ascending: + if ( y < ras.lastY ) + { + if ( End_Profile( RAS_VAR ) || + New_Profile( RAS_VARS Descending ) ) return FAILURE; + } + break; + + case Descending: + if ( y > ras.lastY ) + { + if ( End_Profile( RAS_VAR ) || + New_Profile( RAS_VARS Ascending ) ) return FAILURE; + } + break; + + default: + ; + } + + /* Then compute the lines */ + + switch ( ras.state ) + { + case Ascending: + if ( Line_Up ( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + case Descending: + if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + default: + ; + } + + ras.lastX = x; + ras.lastY = y; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Bezier_To */ +/* */ +/* Description: Injects a new bezier arc and adjusts the profile list. */ +/* */ +/* Input: x, y : arc endpoint (start point in LastX, LastY) */ +/* Cx, Cy : control point */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on Render Pool overflow or Incorrect Profile. */ +/* */ +/****************************************************************************/ + + static Bool Bezier_To( RAS_ARGS Long x, + Long y, + Long cx, + Long cy ) + { + Long y1, y2, y3, x3; + TStates state_bez; + + + Push_Bezier( RAS_VARS ras.lastX, ras.lastY, cx, cy, x, y ); + + do + { + y1 = ras.arc[2].y; + y2 = ras.arc[1].y; + y3 = ras.arc[0].y; + x3 = ras.arc[0].x; + + /* first, categorize the bezier arc */ + + if ( y1 == y2 ) + { + if ( y2 == y3 ) + state_bez = Flat; + else if ( y2 > y3 ) + state_bez = Descending; + else + state_bez = Ascending; + } + else if ( y1 > y2 ) + { + if ( y2 >= y3 ) + state_bez = Descending; + else + state_bez = Unknown; + } + else if ( y2 <= y3 ) + state_bez = Ascending; + else + state_bez = Unknown; + + /* split non-monotonic arcs, ignore flat ones, or */ + /* computes the up and down ones */ + + switch ( state_bez ) + { + case Flat: + ras.arc -= 2; + break; + + case Unknown: + Split_Bezier( ras.arc ); + ras.arc += 2; + break; + + default: + /* detect a change of direction */ + + if ( ras.state != state_bez ) + { + if ( ras.state != Unknown ) + if ( End_Profile( RAS_VAR ) ) return FAILURE; + + if ( New_Profile( RAS_VARS state_bez ) ) return FAILURE; + } + + /* compute */ + + switch ( ras.state ) + { + case Ascending: + if ( Bezier_Up ( RAS_VARS ras.minY, ras.maxY ) ) + return FAILURE; + break; + + case Descending: + if ( Bezier_Down( RAS_VARS ras.minY, ras.maxY ) ) + return FAILURE; + break; + + default: + ; + } + } + } while ( ras.arc >= ras.arcs ); + + ras.lastX = x3; + ras.lastY = y3; + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Decompose_Curve */ +/* */ +/* Description: Scans the outline arays in order to emit individual */ +/* segments and beziers by calling Line_To() and Bezier_To(). */ +/* It handles all weird cases, like when the first point */ +/* is off the curve, or when there are simply no 'on' */ +/* points in the contour! */ +/* */ +/* Input: first, last : indexes of first and last point in */ +/* contour. */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE on error. */ +/* */ +/****************************************************************************/ + +#undef SWAP_ +#define SWAP_(x,y) { Long swap = x; x = y; y = swap; } + + static Bool Decompose_Curve( RAS_ARGS UShort first, + UShort last, + Bool flipped ) + { + Long x, y; /* current point */ + Long cx, cy; /* current Bezier control point */ + Long mx, my; /* current middle point */ + + Long x_first, y_first; /* first point's coordinates */ + Long x_last, y_last; /* last point's coordinates */ + + UShort index; /* current point's index */ + Bool on_curve; /* current point's state */ + + x_first = SCALED( ras.coords[first].x ); + y_first = SCALED( ras.coords[first].y ); + + if ( flipped ) SWAP_( x_first,y_first ); + + x_last = SCALED( ras.coords[last].x ); + y_last = SCALED( ras.coords[last].y ); + + if ( flipped ) SWAP_( x_last,y_last ); + + ras.lastX = cx = x_first; + ras.lastY = cy = y_first; + + on_curve = (ras.flags[first] & 1); + index = first; + + /* check first point to determine origin */ + if ( !on_curve ) + { + /* first point is off the curve. Yes, this happens... */ + if ( ras.flags[last] & 1 ) + { + ras.lastX = x_last; /* start at last point if it */ + ras.lastY = y_last; /* is on the curve */ + } + else + { + /* if both first and last points are off the curve, */ + /* start at their middle and record its position */ + /* for closure */ + ras.lastX = (ras.lastX + x_last)/2; + ras.lastY = (ras.lastY + y_last)/2; + + x_last = ras.lastX; + y_last = ras.lastY; + } + } + + /* now process each contour point individually */ + while ( index < last ) + { + index++; + x = SCALED( ras.coords[index].x ); + y = SCALED( ras.coords[index].y ); + + if ( flipped ) SWAP_( x, y ); + + if ( on_curve ) + { + /* the previous point was on the curve */ + on_curve = ( ras.flags[index] & 1 ); + if ( on_curve ) + { + /* two successive on points => emit segment */ + if ( Line_To( RAS_VARS x, y ) ) return FAILURE; + } + else + { + /* else, keep current control point for next bezier */ + cx = x; + cy = y; + } + } + else + { + /* the previous point was off the curve */ + on_curve = ( ras.flags[index] & 1 ); + if ( on_curve ) + { + /* reaching an `on' point */ + if ( Bezier_To( RAS_VARS x, y, cx, cy ) ) return FAILURE; + } + else + { + /* two successive `off' points => create middle point */ + mx = ( cx + x ) / 2; + my = ( cy + y ) / 2; + + if ( Bezier_To( RAS_VARS mx, my, cx, cy ) ) return FAILURE; + + cx = x; + cy = y; + } + } + } + + /* end of contour, close curve cleanly */ + if ( ras.flags[first] & 1 ) + { + if ( on_curve ) + return Line_To( RAS_VARS x_first, y_first ); + else + return Bezier_To( RAS_VARS x_first, y_first, cx, cy ); + } + else + if ( !on_curve ) + return Bezier_To( RAS_VARS x_last, y_last, cx, cy ); + + return SUCCESS; + } + + +/****************************************************************************/ +/* */ +/* Function: Convert_Glyph */ +/* */ +/* Description: Converts a glyph into a series of segments and arcs */ +/* and makes a Profiles list with them. */ +/* */ +/* Input: _xCoord, _yCoord : coordinates tables. */ +/* */ +/* Uses the 'Flag' table too. */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE if any error was encountered during rendering. */ +/* */ +/****************************************************************************/ + + static Bool Convert_Glyph( RAS_ARGS int flipped ) + { + Short i; + UShort start; + + PProfile lastProfile; + + + ras.fProfile = NULL; + ras.joint = FALSE; + ras.fresh = FALSE; + + ras.maxBuff = ras.sizeBuff - AlignProfileSize; + + ras.numTurns = 0; + + ras.cProfile = (PProfile)ras.top; + ras.cProfile->offset = ras.top; + ras.num_Profs = 0; + + start = 0; + + for ( i = 0; i < ras.nContours; i++ ) + { + ras.state = Unknown; + ras.gProfile = NULL; + + if ( Decompose_Curve( RAS_VARS start, ras.outs[i], flipped ) ) + return FAILURE; + + start = ras.outs[i] + 1; + + /* We must now see if the extreme arcs join or not */ + if ( ( FRAC( ras.lastY ) == 0 && + ras.lastY >= ras.minY && + ras.lastY <= ras.maxY ) ) + if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow ) + ras.top--; + /* Note that ras.gProfile can be nil if the contour was too small */ + /* to be drawn. */ + + lastProfile = ras.cProfile; + if ( End_Profile( RAS_VAR ) ) return FAILURE; + + /* close the 'next profile in contour' linked list */ + if ( ras.gProfile ) + lastProfile->next = ras.gProfile; + } + + if (Finalize_Profile_Table( RAS_VAR )) + return FAILURE; + + return (ras.top < ras.maxBuff ? SUCCESS : FAILURE ); + } + + +/************************************************/ +/* */ +/* Init_Linked */ +/* */ +/* Inits an empty linked list. */ +/* */ +/************************************************/ + + static void Init_Linked( TProfileList* l ) + { + *l = NULL; + } + + +/************************************************/ +/* */ +/* InsNew : */ +/* */ +/* Inserts a new Profile in a linked list. */ +/* */ +/************************************************/ + + static void InsNew( PProfileList list, + PProfile profile ) + { + PProfile *old, current; + Long x; + + + old = list; + current = *old; + x = profile->X; + + while ( current ) + { + if ( x < current->X ) + break; + old = ¤t->link; + current = *old; + } + + profile->link = current; + *old = profile; + } + + +/*************************************************/ +/* */ +/* DelOld : */ +/* */ +/* Removes an old Profile from a linked list. */ +/* */ +/*************************************************/ + + static void DelOld( PProfileList list, + PProfile profile ) + { + PProfile *old, current; + + + old = list; + current = *old; + + while ( current ) + { + if ( current == profile ) + { + *old = current->link; + return; + } + + old = ¤t->link; + current = *old; + } + + /* we should never get there, unless the Profile was not part of */ + /* the list. */ + } + + +/************************************************/ +/* */ +/* Update : */ +/* */ +/* Update all X offsets of a drawing list */ +/* */ +/************************************************/ + + static void Update( PProfile first ) + { + PProfile current = first; + + + while ( current ) + { + current->X = *current->offset; + current->offset += current->flow; + current->height--; + current = current->link; + } + } + + +/************************************************/ +/* */ +/* Sort : */ +/* */ +/* Sorts a trace list. In 95%, the list */ +/* is already sorted. We need an algorithm */ +/* which is fast in this case. Bubble sort */ +/* is enough and simple. */ +/* */ +/************************************************/ + + static void Sort( PProfileList list ) + { + PProfile *old, current, next; + + + /* First, set the new X coordinate of each profile */ + Update( *list ); + + /* Then sort them */ + old = list; + current = *old; + + if ( !current ) + return; + + next = current->link; + + while ( next ) + { + if ( current->X <= next->X ) + { + old = ¤t->link; + current = *old; + + if ( !current ) + return; + } + else + { + *old = next; + current->link = next->link; + next->link = current; + + old = list; + current = *old; + } + + next = current->link; + } + } + + +/***********************************************************************/ +/* */ +/* Vertical Sweep Procedure Set : */ +/* */ +/* These three routines are used during the vertical black/white */ +/* sweep phase by the generic Draw_Sweep() function. */ +/* */ +/***********************************************************************/ + + static void Vertical_Sweep_Init( RAS_ARGS Short* min, Short* max ) + { + switch ( ras.target.flow ) + { + case TT_Flow_Up: + ras.traceOfs = *min * ras.target.cols; + ras.traceIncr = ras.target.cols; + break; + + default: + ras.traceOfs = ( ras.target.rows - 1 - *min ) * ras.target.cols; + ras.traceIncr = -ras.target.cols; + } + + ras.gray_min_x = 0; + ras.gray_max_x = 0; + } + + + static void Vertical_Sweep_Span( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + Short c1, c2; + Short f1, f2; + Byte* target; + + + /* Drop-out control */ + + e1 = TRUNC( CEILING( x1 ) ); + + if ( x2-x1-ras.precision <= ras.precision_jitter ) + e2 = e1; + else + e2 = TRUNC( FLOOR( x2 ) ); + + if ( e2 >= 0 && e1 < ras.bWidth ) + { + if ( e1 < 0 ) e1 = 0; + if ( e2 >= ras.bWidth ) e2 = ras.bWidth-1; + + c1 = (Short)(e1 >> 3); + c2 = (Short)(e2 >> 3); + + f1 = e1 & 7; + f2 = e2 & 7; + + if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; + if ( ras.gray_max_x < c2 ) ras.gray_max_x = c2; + + target = ras.bTarget + ras.traceOfs + c1; + + if ( c1 != c2 ) + { + *target |= LMask[f1]; + + if ( c2 > c1 + 1 ) + MEM_Set( target + 1, 0xFF, c2 - c1 - 1 ); + + target[c2 - c1] |= RMask[f2]; + } + else + *target |= ( LMask[f1] & RMask[f2] ); + } + } + + + static void Vertical_Sweep_Drop( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + Short c1, f1; + + + /* Drop-out control */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 > e2 ) + { + if ( e1 == e2 + ras.precision ) + { + switch ( ras.dropOutControl ) + { + case 1: + e1 = e2; + break; + + case 4: + e1 = CEILING( (x1 + x2 + 1) / 2 ); + break; + + case 2: + case 5: + /* Drop-out Control Rule #4 */ + + /* The spec is not very clear regarding rule #4. It */ + /* presents a method that is way too costly to implement */ + /* while the general idea seems to get rid of 'stubs'. */ + /* */ + /* Here, we only get rid of stubs recognized when: */ + /* */ + /* upper stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Right is the successor of P_Left in that contour */ + /* - y is the top of P_Left and P_Right */ + /* */ + /* lower stub: */ + /* */ + /* - P_Left and P_Right are in the same contour */ + /* - P_Left is the successor of P_Right in that contour */ + /* - y is the bottom of P_Left */ + /* */ + + /* FIXXXME : uncommenting this line solves the disappearing */ + /* bit problem in the '7' of verdana 10pts, but */ + /* makes a new one in the 'C' of arial 14pts */ + + /* if ( x2-x1 < ras.precision_half ) */ + { + /* upper stub test */ + + if ( left->next == right && left->height <= 0 ) return; + + /* lower stub test */ + + if ( right->next == left && left->start == y ) return; + } + + /* check that the rightmost pixel isn't set */ + + e1 = TRUNC( e1 ); + + c1 = (Short)(e1 >> 3); + f1 = e1 & 7; + + if ( e1 >= 0 && e1 < ras.bWidth && + ras.bTarget[ras.traceOfs + c1] & (0x80 >> f1) ) + return; + + if ( ras.dropOutControl == 2 ) + e1 = e2; + else + e1 = CEILING( (x1 + x2 + 1) / 2 ); + + break; + + default: + return; /* unsupported mode */ + } + } + else + return; + } + + e1 = TRUNC( e1 ); + + if ( e1 >= 0 && e1 < ras.bWidth ) + { + c1 = (Short)(e1 >> 3); + f1 = e1 & 7; + + if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; + if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1; + + ras.bTarget[ras.traceOfs + c1] |= (Char)(0x80 >> f1); + } + } + + + static void Vertical_Sweep_Step( RAS_ARG ) + { + ras.traceOfs += ras.traceIncr; + } + + +/***********************************************************************/ +/* */ +/* Horizontal Sweep Procedure Set : */ +/* */ +/* These three routines are used during the horizontal black/white */ +/* sweep phase by the generic Draw_Sweep() function. */ +/* */ +/***********************************************************************/ + + static void Horizontal_Sweep_Init( RAS_ARGS Short* min, Short* max ) + { + /* nothing, really */ + } + + + static void Horizontal_Sweep_Span( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte bits; + Byte f1; + + + if ( x2-x1 < ras.precision ) + { + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 == e2 ) + { + bits = ras.bTarget + (y >> 3); + f1 = (Byte)(0x80 >> (y & 7)); + + e1 = TRUNC( e1 ); + + if ( e1 >= 0 && e1 < ras.target.rows ) + { + if ( ras.target.flow == TT_Flow_Down ) + bits[(ras.target.rows-1 - e1) * ras.target.cols] |= f1; + else + bits[e1 * ras.target.cols] |= f1; + } + } + } +#if 0 + e2 = TRUNC( e2 ); + + if ( e2 >= 0 && e2 < ras.target.rows ) + if ( ras.target.flow == TT_Flow_Down ) + bits[(ras.target.rows-1-e2) * ras.target.cols] |= f1; + else + bits[e2 * ras.target.cols] |= f1; +#endif + } + + + static void Horizontal_Sweep_Drop( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte bits; + Byte f1; + + + /* During the horizontal sweep, we only take care of drop-outs */ + + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 > e2 ) + { + if ( e1 == e2 + ras.precision ) + { + switch ( ras.dropOutControl ) + { + case 1: + e1 = e2; + break; + + case 4: + e1 = CEILING( (x1 + x2 + 1) / 2 ); + break; + + case 2: + case 5: + + /* Drop-out Control Rule #4 */ + + /* The spec is not very clear regarding rule #4. It */ + /* presents a method that is way too costly to implement */ + /* while the general idea seems to get rid of 'stubs'. */ + /* */ + + /* rightmost stub test */ + + if ( left->next == right && left->height <= 0 ) return; + + /* leftmost stub test */ + + if ( right->next == left && left->start == y ) return; + + /* check that the rightmost pixel isn't set */ + + e1 = TRUNC( e1 ); + + bits = ras.bTarget + (y >> 3); + f1 = (Byte)(0x80 >> (y & 7)); + + if ( ras.target.flow == TT_Flow_Down ) + bits += (ras.target.rows-1-e1) * ras.target.cols; + else + bits += e1 * ras.target.cols; + + if ( e1 >= 0 && + e1 < ras.target.rows && + *bits & f1 ) + return; + + if ( ras.dropOutControl == 2 ) + e1 = e2; + else + e1 = CEILING( (x1 + x2 + 1) / 2 ); + + break; + + default: + return; /* unsupported mode */ + } + } + else + return; + } + + bits = ras.bTarget + (y >> 3); + f1 = (Byte)(0x80 >> (y & 7)); + + e1 = TRUNC( e1 ); + + if ( e1 >= 0 && e1 < ras.target.rows ) + { + if (ras.target.flow==TT_Flow_Down) + bits[(ras.target.rows-1-e1) * ras.target.cols] |= f1; + else + bits[e1 * ras.target.cols] |= f1; + } + } + + + static void Horizontal_Sweep_Step( RAS_ARG ) + { + /* Nothing, really */ + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/***********************************************************************/ +/* */ +/* Vertical Gray Sweep Procedure Set: */ +/* */ +/* These two routines are used during the vertical gray-levels */ +/* sweep phase by the generic Draw_Sweep() function. */ +/* */ +/* */ +/* NOTES: */ +/* */ +/* - The target pixmap's width *must* be a multiple of 4. */ +/* */ +/* - you have to use the function Vertical_Sweep_Span() for */ +/* the gray span call. */ +/* */ +/***********************************************************************/ + + static void Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, Short* max ) + { + *min = *min & -2; + *max = ( *max + 3 ) & -2; + + ras.traceOfs = 0; + + switch ( ras.target.flow ) + { + case TT_Flow_Up: + ras.traceG = (*min / 2) * ras.target.cols; + ras.traceIncr = ras.target.cols; + break; + + default: + ras.traceG = (ras.target.rows-1 - *min/2) * ras.target.cols; + ras.traceIncr = -ras.target.cols; + } + + ras.gray_min_x = ras.target.cols; + ras.gray_max_x = -ras.target.cols; + } + + + static void Vertical_Gray_Sweep_Step( RAS_ARG ) + { + Int c1, c2; + PByte pix, bit, bit2; + Int* count = ras.count_table; + Byte* grays; + + + ras.traceOfs += ras.gray_width; + + if ( ras.traceOfs > ras.gray_width ) + { + pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; + grays = ras.grays; + + if ( ras.gray_max_x >= 0 ) + { + if ( ras.gray_max_x >= ras.target.width ) + ras.gray_max_x = ras.target.width-1; + + if ( ras.gray_min_x < 0 ) + ras.gray_min_x = 0; + + bit = ras.bTarget + ras.gray_min_x; + bit2 = bit + ras.gray_width; + + c1 = ras.gray_max_x - ras.gray_min_x; + + while ( c1 >= 0 ) + { + c2 = count[*bit] + count[*bit2]; + + if ( c2 ) + { + pix[0] = grays[(c2 & 0xF000) >> 12]; + pix[1] = grays[(c2 & 0x0F00) >> 8]; + pix[2] = grays[(c2 & 0x00F0) >> 4]; + pix[3] = grays[(c2 & 0x000F) ]; + + *bit = 0; + *bit2 = 0; + } + + bit ++; + bit2++; + pix += 4; + c1 --; + } + } + + ras.traceOfs = 0; + ras.traceG += ras.traceIncr; + + ras.gray_min_x = ras.target.cols; + ras.gray_max_x = -ras.target.cols; + } + } + + + static void Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + /* nothing, really */ + } + + static void Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, + TT_F26Dot6 x1, + TT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte pixel; + Byte color; + + + /* During the horizontal sweep, we only take care of drop-outs */ + e1 = CEILING( x1 ); + e2 = FLOOR ( x2 ); + + if ( e1 > e2 ) + { + if ( e1 == e2 + ras.precision ) + { + switch ( ras.dropOutControl ) + { + case 1: + e1 = e2; + break; + + case 4: + e1 = CEILING( (x1 + x2 + 1) / 2 ); + break; + + case 2: + case 5: + + /* Drop-out Control Rule #4 */ + + /* The spec is not very clear regarding rule #4. It */ + /* presents a method that is way too costly to implement */ + /* while the general idea seems to get rid of 'stubs'. */ + /* */ + + /* rightmost stub test */ + if ( left->next == right && left->height <= 0 ) return; + + /* leftmost stub test */ + if ( right->next == left && left->start == y ) return; + + if ( ras.dropOutControl == 2 ) + e1 = e2; + else + e1 = CEILING( (x1 + x2 + 1) / 2 ); + + break; + + default: + return; /* unsupported mode */ + } + } + else + return; + } + + if ( e1 >= 0 ) + { + if ( x2 - x1 >= ras.precision_half ) + color = ras.grays[2]; + else + color = ras.grays[1]; + + e1 = TRUNC( e1 ) / 2; + if ( e1 < ras.target.rows ) + { + if ( ras.target.flow == TT_Flow_Down ) + pixel = ras.gTarget + + (ras.target.rows - 1 - e1) * ras.target.cols + y / 2; + else + pixel = ras.gTarget + + e1 * ras.target.cols + y / 2; + + if (pixel[0] == ras.grays[0]) + pixel[0] = color; + } + } + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + +/********************************************************************/ +/* */ +/* Generic Sweep Drawing routine */ +/* */ +/********************************************************************/ + + static Bool Draw_Sweep( RAS_ARG ) + { + Short y, y_change, y_height; + + PProfile P, Q, P_Left, P_Right; + + Short min_Y, max_Y, top, bottom, dropouts; + + Long x1, x2, xs, e1, e2; + + TProfileList wait; + TProfileList draw_left, draw_right; + + + /* Init empty linked lists */ + + Init_Linked( &wait ); + + Init_Linked( &draw_left ); + Init_Linked( &draw_right ); + + /* first, compute min and max Y */ + + P = ras.fProfile; + max_Y = (short)TRUNC( ras.minY ); + min_Y = (short)TRUNC( ras.maxY ); + + while ( P ) + { + Q = P->link; + + bottom = P->start; + top = P->start + P->height-1; + + if ( min_Y > bottom ) min_Y = bottom; + if ( max_Y < top ) max_Y = top; + + P->X = 0; + InsNew( &wait, P ); + + P = Q; + } + + /* Check the Y-turns */ + if ( ras.numTurns == 0 ) + { + ras.error = Raster_Err_Invalid; + return FAILURE; + } + + /* Now inits the sweep */ + + ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); + + /* Then compute the distance of each profile from min_Y */ + + P = wait; + + while ( P ) + { + P->countL = P->start - min_Y; + P = P->link; + } + + /* Let's go */ + + y = min_Y; + y_height = 0; + + if ( ras.numTurns > 0 && + ras.sizeBuff[-ras.numTurns] == min_Y ) + ras.numTurns--; + + while ( ras.numTurns > 0 ) + { + /* look in the wait list for new activations */ + + P = wait; + + while ( P ) + { + Q = P->link; + P->countL -= y_height; + if ( P->countL == 0 ) + { + DelOld( &wait, P ); + + switch ( P->flow ) + { + case TT_Flow_Up: InsNew( &draw_left, P ); break; + case TT_Flow_Down: InsNew( &draw_right, P ); break; + } + } + + P = Q; + } + + /* Sort the drawing lists */ + + Sort( &draw_left ); + Sort( &draw_right ); + + y_change = (Short)ras.sizeBuff[-ras.numTurns--]; + y_height = y_change - y; + + while ( y < y_change ) + { + + /* Let's trace */ + + dropouts = 0; + + P_Left = draw_left; + P_Right = draw_right; + + while ( P_Left ) + { + x1 = P_Left ->X; + x2 = P_Right->X; + + if ( x1 > x2 ) + { + xs = x1; + x1 = x2; + x2 = xs; + } + + if ( x2-x1 <= ras.precision ) + { + e1 = FLOOR( x1 ); + e2 = CEILING( x2 ); + + if ( ras.dropOutControl != 0 && + (e1 > e2 || e2 == e1 + ras.precision) ) + { + /* a drop out was detected */ + + P_Left ->X = x1; + P_Right->X = x2; + + /* mark profile for drop-out processing */ + P_Left->countL = 1; + dropouts++; + + goto Skip_To_Next; + } + } + + ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); + + Skip_To_Next: + + P_Left = P_Left->link; + P_Right = P_Right->link; + } + + /* now perform the dropouts _after_ the span drawing */ + /* drop-outs processing has been moved out of the loop */ + /* for performance tuning */ + if (dropouts > 0) + goto Scan_DropOuts; + + Next_Line: + + ras.Proc_Sweep_Step( RAS_VAR ); + + y++; + + if ( y < y_change ) + { + Sort( &draw_left ); + Sort( &draw_right ); + } + + } + + /* Now finalize the profiles that needs it */ + + { + PProfile Q, P; + P = draw_left; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_left, P ); + P = Q; + } + } + + { + PProfile Q, P = draw_right; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_right, P ); + P = Q; + } + } + } + + /* for gray-scaling, flushes the bitmap scanline cache */ + while ( y <= max_Y ) + { + ras.Proc_Sweep_Step( RAS_VAR ); + y++; + } + + return SUCCESS; + +Scan_DropOuts : + + P_Left = draw_left; + P_Right = draw_right; + + while ( P_Left ) + { + if ( P_Left->countL ) + { + P_Left->countL = 0; + /* dropouts--; -- this is useful when debugging only */ + ras.Proc_Sweep_Drop( RAS_VARS y, + P_Left->X, + P_Right->X, + P_Left, + P_Right ); + } + + P_Left = P_Left->link; + P_Right = P_Right->link; + } + + goto Next_Line; + } + + +/****************************************************************************/ +/* */ +/* Function: Render_Single_Pass */ +/* */ +/* Description: Performs one sweep with sub-banding. */ +/* */ +/* Input: _XCoord, _YCoord : x and y coordinates arrays */ +/* */ +/* Returns: SUCCESS on success */ +/* FAILURE if any error was encountered during render. */ +/* */ +/****************************************************************************/ + + static TT_Error Render_Single_Pass( RAS_ARGS Bool flipped ) + { + Short i, j, k; + + + while ( ras.band_top >= 0 ) + { + ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; + ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; + + ras.top = ras.buff; + + ras.error = Raster_Err_None; + + if ( Convert_Glyph( RAS_VARS flipped ) ) + { + if ( ras.error != Raster_Err_Overflow ) return FAILURE; + + ras.error = Raster_Err_None; + + /* sub-banding */ + +#ifdef DEBUG_RASTER + ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); +#endif + + i = ras.band_stack[ras.band_top].y_min; + j = ras.band_stack[ras.band_top].y_max; + + k = ( i + j ) / 2; + + if ( ras.band_top >= 7 || k < i ) + { + ras.band_top = 0; + ras.error = Raster_Err_Invalid; + return ras.error; + } + + ras.band_stack[ras.band_top+1].y_min = k; + ras.band_stack[ras.band_top+1].y_max = j; + + ras.band_stack[ras.band_top].y_max = k - 1; + + ras.band_top++; + } + else + { + if ( ras.fProfile ) + if ( Draw_Sweep( RAS_VAR ) ) return ras.error; + ras.band_top--; + } + } + + return TT_Err_Ok; + } + + +/****************************************************************************/ +/* */ +/* Function: Render_Glyph */ +/* */ +/* Description: Renders a glyph in a bitmap. Sub-banding if needed. */ +/* */ +/* Input: AGlyph Glyph record */ +/* */ +/* Returns: SUCCESS on success. */ +/* FAILURE if any error was encountered during rendering. */ +/* */ +/****************************************************************************/ + + LOCAL_FUNC + TT_Error Render_Glyph( RAS_ARGS TT_Outline* glyph, + TT_Raster_Map* target_map ) + { + TT_Error error; + + + if ( glyph->n_points == 0 || glyph->n_contours <= 0 ) + return TT_Err_Ok; + + if ( !ras.buff ) + { + ras.error = Raster_Err_Not_Ini; + return ras.error; + } + + if ( glyph->n_points < glyph->contours[glyph->n_contours - 1] ) + { + ras.error = TT_Err_Too_Many_Points; + return ras.error; + } + + if ( target_map ) + ras.target = *target_map; + + ras.outs = glyph->contours; + ras.flags = glyph->flags; + ras.nPoints = glyph->n_points; + ras.nContours = glyph->n_contours; + ras.coords = glyph->points; + + Set_High_Precision( RAS_VARS glyph->high_precision ); + ras.scale_shift = ras.precision_shift; + ras.dropOutControl = glyph->dropout_mode; + ras.second_pass = glyph->second_pass; + + + /* Vertical Sweep */ + ras.Proc_Sweep_Init = Vertical_Sweep_Init; + ras.Proc_Sweep_Span = Vertical_Sweep_Span; + ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; + ras.Proc_Sweep_Step = Vertical_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = ras.target.rows - 1; + + ras.bWidth = ras.target.width; + ras.bTarget = (Byte*)ras.target.bitmap; + + if ( (error = Render_Single_Pass( RAS_VARS 0 )) != 0 ) + return error; + + /* Horizontal Sweep */ + + if ( ras.second_pass && ras.dropOutControl != 0 ) + { + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; + ras.Proc_Sweep_Span = Horizontal_Sweep_Span; + ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; + ras.Proc_Sweep_Step = Horizontal_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = ras.target.width - 1; + + if ( (error = Render_Single_Pass( RAS_VARS 1 )) != 0 ) + return error; + } + + return TT_Err_Ok; + } + + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + +/****************************************************************************/ +/* */ +/* Function: Render_Gray_Glyph */ +/* */ +/* Description: Renders a glyph with grayscaling. Sub-banding if needed. */ +/* */ +/* Input: AGlyph Glyph record */ +/* */ +/* Returns: SUCCESS on success */ +/* FAILURE if any error was encountered during rendering. */ +/* */ +/****************************************************************************/ + + LOCAL_FUNC + TT_Error Render_Gray_Glyph( RAS_ARGS TT_Outline* glyph, + TT_Raster_Map* target_map, + Byte* palette ) + { + Int i; + TT_Error error; + + if ( !ras.buff ) + { + ras.error = Raster_Err_Not_Ini; + return ras.error; + } + + if ( glyph->n_points == 0 || glyph->n_contours <= 0 ) + return TT_Err_Ok; + + if ( glyph->n_points < glyph->contours[glyph->n_contours - 1] ) + { + ras.error = TT_Err_Too_Many_Points; + return ras.error; + } + + if ( palette ) + { + for ( i = 0; i < 5; i++ ) + ras.grays[i] = palette[i]; + } + + if ( target_map ) + ras.target = *target_map; + + ras.outs = glyph->contours; + ras.flags = glyph->flags; + ras.nPoints = glyph->n_points; + ras.nContours = glyph->n_contours; + ras.coords = glyph->points; + + Set_High_Precision( RAS_VARS glyph->high_precision ); + ras.scale_shift = ras.precision_shift+1; + ras.dropOutControl = glyph->dropout_mode; + ras.second_pass = glyph->second_pass; + + + /* Vertical Sweep */ + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = 2 * ras.target.rows - 1; + + ras.bWidth = ras.gray_width; + if ( ras.bWidth > ras.target.cols/4 ) + ras.bWidth = ras.target.cols/4; + + ras.bWidth = ras.bWidth * 8; + ras.bTarget = (Byte*)ras.gray_lines; + ras.gTarget = (Byte*)ras.target.bitmap; + + ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; + ras.Proc_Sweep_Span = Vertical_Sweep_Span; + ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; + ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; + + error = Render_Single_Pass( RAS_VARS 0 ); + if (error) + return error; + + /* Horizontal Sweep */ + + if ( ras.second_pass && ras.dropOutControl != 0 ) + { + ras.Proc_Sweep_Init = Horizontal_Sweep_Init; + ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; + ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; + ras.Proc_Sweep_Step = Horizontal_Sweep_Step; + + ras.band_top = 0; + ras.band_stack[0].y_min = 0; + ras.band_stack[0].y_max = ras.target.width * 2 - 1; + + error = Render_Single_Pass( RAS_VARS 1 ); + if (error) + return error; + } + + return TT_Err_Ok; + } + +#endif /* TT_CONFIG_OPTION_GRAY_SCALING */ + + +/************************************************/ +/* */ +/* InitRasterizer */ +/* */ +/* Raster Initialization. */ +/* Gets the bitmap description and render pool */ +/* addresses. */ +/* */ +/************************************************/ + +#undef ras + + LOCAL_FUNC + TT_Error TTRaster_Done( PEngine_Instance engine ) + { + TRaster_Instance* ras = (TRaster_Instance*)engine->raster_component; + + + if ( !ras ) + return TT_Err_Ok; + + FREE( ras->buff ); + FREE( ras->gray_lines ); + +#ifndef TT_CONFIG_OPTION_STATIC_RASTER + FREE( engine->raster_component ); +#endif + + return TT_Err_Ok; + } + + + LOCAL_FUNC + TT_Error TTRaster_Init( PEngine_Instance engine ) + { + TT_Error error; + + Int i, l, j, c; + + TRaster_Instance* ras; + + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + ras = engine->raster_component = &cur_ras; +#else + if ( ALLOC( engine->raster_component, sizeof ( TRaster_Instance ) ) ) + return error; + + ras = (TRaster_Instance*)engine->raster_component; +#endif + + if ( ALLOC( ras->buff, RASTER_RENDER_POOL ) || + ALLOC( ras->gray_lines, RASTER_GRAY_LINES ) ) + return error; + + ras->sizeBuff = ras->buff + ( RASTER_RENDER_POOL/sizeof(long) ); + ras->gray_width = RASTER_GRAY_LINES/2; + + /* Initialization of Count_Table */ + + for ( i = 0; i < 256; i++ ) + { + l = 0; + j = i; + + for ( c = 0; c < 4; c++ ) + { + l <<= 4; + + if ( j & 0x80 ) l++; + if ( j & 0x40 ) l++; + + j = ( j << 2 ) & 0xFF; + } + + ras->count_table[i] = l; + } + + ras->dropOutControl = 2; + ras->error = Raster_Err_None; + + return TT_Err_Ok; + } + + +/* END */ diff --git a/lib/ttraster.h b/lib/ttraster.h new file mode 100644 index 0000000..66c8fef --- /dev/null +++ b/lib/ttraster.h @@ -0,0 +1,127 @@ +/******************************************************************* + * + * ttraster.h v 1.4 + * + * The FreeType glyph rasterizer. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES: + * + * This version supports the following: + * + * - direct grayscaling + * - sub-banding + * - drop-out modes 4 and 5 + * - second pass for complete drop-out control (bitmap only) + * - variable precision + * + * + * Changes between 1.4 and 1.3: + * + * Mainly performance tunings: + * + * - Line_Down() and Bezier_Down() now use the functions Line_Up() + * and Bezier_Up() to do their work. + * - optimized Split_Bezier() + * - optimized linked lists used during sweeps + * + * Changes between 1.2 and 1.3: + * + * - made the engine optionaly re-entrant. Saves a lot + * of code for a moderate performance hit. + * + ******************************************************************/ + +#ifndef TTRASTER_H +#define TTRASTER_H + +#include "ttconfig.h" +#include "freetype.h" /* for TT_Outline */ +#include "ttengine.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* We provide two different builds of the scan-line converter */ + /* The static build uses global variables and isn't */ + /* re-entrant. */ + /* The indirect build is re-entrant but accesses all variables */ + /* indirectly. */ + /* */ + /* As a consequence, the indirect build is about 10% slower */ + /* than the static one on a _Pentium_ (this could get worse */ + /* on older processors), but the code size is reduced by */ + /* more than 30% ! */ + /* */ + /* The indirect build is now the default, defined in */ + /* ttconfig.h. Be careful if you experiment with this. */ + + /* Note also that, though its code can be re-entrant, the */ + /* component is always used in thread-safe mode. This is */ + /* simply due to the fact that we want to use a single */ + /* render pool (of 64 Kb), and not to waste memory. */ + +#ifdef TT_STATIC_RASTER + +#define RAS_ARGS /* void */ +#define RAS_ARG /* void */ + +#define RAS_VARS /* void */ +#define RAS_VAR /* void */ + +#else + +#define RAS_ARGS TRaster_Instance* raster, +#define RAS_ARG TRaster_Instance* raster + +#define RAS_VARS raster, +#define RAS_VAR raster + +#endif + + + struct TRaster_Instance_; + typedef struct TRaster_Instance_ TRaster_Instance; + + /* Render one glyph in the target bitmap, using drop-out control */ + /* mode 'scan'. */ + LOCAL_DEF + TT_Error Render_Glyph( RAS_ARGS TT_Outline* glyph, + TT_Raster_Map* target ); + +#ifdef TT_CONFIG_OPTION_GRAY_SCALING + /* Render one gray-level glyph in the target pixmap. */ + /* Palette points to an array of 5 colors used for the rendering. */ + /* Use NULL to reuse the last palette. Default is VGA graylevels. */ + LOCAL_DEF + TT_Error Render_Gray_Glyph( RAS_ARGS TT_Outline* glyph, + TT_Raster_Map* target, + Byte* palette ); +#endif + + /* Initialize rasterizer */ + LOCAL_DEF + TT_Error TTRaster_Init( PEngine_Instance engine ); + + /* Finalize it */ + LOCAL_DEF + TT_Error TTRaster_Done( PEngine_Instance engine ); + + +#ifdef __cplusplus +} +#endif + +#endif /* TTRASTER_H */ + + +/* END */ diff --git a/lib/tttables.h b/lib/tttables.h new file mode 100644 index 0000000..e3556fc --- /dev/null +++ b/lib/tttables.h @@ -0,0 +1,215 @@ +/******************************************************************* + * + * tttables.h 1.1 + * + * TrueType Tables structures and handling (specification). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTTABLES_H +#define TTTABLES_H + +#include "ttconfig.h" +#include "tttypes.h" + +#ifdef __cplusplus + extern "C" { +#endif + + /***********************************************************************/ + /* */ + /* TrueType Table Types */ + /* */ + /***********************************************************************/ + + /* TrueType Collection Header */ + + struct TTTCHeader_ + { + ULong Tag; + TT_Fixed version; + ULong DirCount; + PULong TableDirectory; + }; + + typedef struct TTTCHeader_ TTTCHeader; + typedef TTTCHeader* PTTCHeader; + + + /* TrueType Table Directory type */ + + struct TTableDir_ + { + TT_Fixed version; /* should be 0x10000 */ + UShort numTables; /* number of tables */ + + UShort searchRange; /* These parameters are only used */ + UShort entrySelector; /* for a dichotomy search in the */ + UShort rangeShift; /* directory. We ignore them. */ + }; + + typedef struct TTableDir_ TTableDir; + typedef TTableDir* PTableDir; + + + /* The 'TableDir' is followed by 'numTables' TableDirEntries */ + + struct TTableDirEntry_ + { + ULong Tag; /* table type */ + ULong CheckSum; /* table checksum */ + ULong Offset; /* table file offset */ + ULong Length; /* table length */ + }; + + typedef struct TTableDirEntry_ TTableDirEntry; + typedef TTableDirEntry* PTableDirEntry; + + + /* 'cmap' tables */ + + struct TCMapDir_ + { + UShort tableVersionNumber; + UShort numCMaps; + }; + + typedef struct TCMapDir_ TCMapDir; + typedef TCMapDir* PCMapDir; + + struct TCMapDirEntry_ + { + UShort platformID; + UShort platformEncodingID; + Long offset; + }; + + typedef struct TCMapDirEntry_ TCMapDirEntry; + typedef TCMapDirEntry* PCMapDirEntries; + + + /* 'maxp' Maximum Profiles table */ + + struct TMaxProfile_ + { + TT_Fixed version; + UShort numGlyphs, + maxPoints, + maxContours, + maxCompositePoints, + maxCompositeContours, + maxZones, + maxTwilightPoints, + maxStorage, + maxFunctionDefs, + maxInstructionDefs, + maxStackElements, + maxSizeOfInstructions, + maxComponentElements, + maxComponentDepth; + }; + + typedef struct TMaxProfile_ TMaxProfile; + typedef TMaxProfile* PMaxProfile; + + + /* table "gasp" */ + +#define GASP_GRIDFIT 0x01 +#define GASP_DOGRAY 0x02 + + struct GaspRange_ + { + UShort maxPPEM; + UShort gaspFlag; + }; + + typedef struct GaspRange_ GaspRange; + + + struct TGasp_ + { + UShort version; + UShort numRanges; + GaspRange* gaspRanges; + }; + + typedef struct TGasp_ TGasp; + + + /* table "head" - now defined in freetype.h */ + /* table "hhea" - now defined in freetype.h */ + + + /* tables "HMTX" and "VMTX" */ + + struct TLongMetrics_ + { + UShort advance; + Short bearing; + }; + + typedef struct TLongMetrics_ TLongMetrics, *PLongMetrics; + + typedef Short TShortMetrics, *PShortMetrics; + + /* 'loca' location table type */ + + struct TLoca_ + { + UShort Size; + PStorage Table; + }; + + typedef struct TLoca_ TLoca; + + + /* table "name" */ + + struct TNameRec_ + { + UShort platformID; + UShort encodingID; + UShort languageID; + UShort nameID; + UShort stringLength; + UShort stringOffset; + + /* this last field is not defined in the spec */ + /* but used by the FreeType engine */ + + PByte string; + }; + + typedef struct TNameRec_ TNameRec; + + + struct TName_Table_ + { + UShort format; + UShort numNameRecords; + UShort storageOffset; + TNameRec* names; + PByte storage; + }; + + typedef struct TName_Table_ TName_Table; + + +#ifdef __cplusplus + } +#endif + +#endif /* TTTABLES_H */ + + +/* END */ diff --git a/lib/tttags.h b/lib/tttags.h new file mode 100644 index 0000000..95347d1 --- /dev/null +++ b/lib/tttags.h @@ -0,0 +1,61 @@ +/******************************************************************* + * + * tttags.h + * + * tags for TrueType tables (specification only). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef TTAGS_H +#define TTAGS_H + +#include "ttconfig.h" +#include "freetype.h" /* for MAKE_TT_TAG() */ + +#define TTAG_BASE MAKE_TT_TAG( 'B', 'A', 'S', 'E' ) +#define TTAG_bloc MAKE_TT_TAG( 'b', 'l', 'o', 'c' ) +#define TTAG_bdat MAKE_TT_TAG( 'b', 'd', 'a', 't' ) +#define TTAG_cmap MAKE_TT_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_cvt MAKE_TT_TAG( 'c', 'v', 't', ' ' ) +#define TTAG_EBDT MAKE_TT_TAG( 'E', 'B', 'D', 'T' ) +#define TTAG_EBLC MAKE_TT_TAG( 'E', 'B', 'L', 'C' ) +#define TTAG_EBSC MAKE_TT_TAG( 'E', 'B', 'S', 'C' ) +#define TTAG_fpgm MAKE_TT_TAG( 'f', 'p', 'g', 'm' ) +#define TTAG_gasp MAKE_TT_TAG( 'g', 'a', 's', 'p' ) +#define TTAG_glyf MAKE_TT_TAG( 'g', 'l', 'y', 'f' ) +#define TTAG_GDEF MAKE_TT_TAG( 'G', 'D', 'E', 'F' ) +#define TTAG_GPOS MAKE_TT_TAG( 'G', 'P', 'O', 'S' ) +#define TTAG_GSUB MAKE_TT_TAG( 'G', 'S', 'U', 'B' ) +#define TTAG_hdmx MAKE_TT_TAG( 'h', 'd', 'm', 'x' ) +#define TTAG_head MAKE_TT_TAG( 'h', 'e', 'a', 'd' ) +#define TTAG_hhea MAKE_TT_TAG( 'h', 'h', 'e', 'a' ) +#define TTAG_hmtx MAKE_TT_TAG( 'h', 'm', 't', 'x' ) +#define TTAG_JSTF MAKE_TT_TAG( 'J', 'S', 'T', 'F' ) +#define TTAG_kern MAKE_TT_TAG( 'k', 'e', 'r', 'n' ) +#define TTAG_loca MAKE_TT_TAG( 'l', 'o', 'c', 'a' ) +#define TTAG_LTSH MAKE_TT_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_maxp MAKE_TT_TAG( 'm', 'a', 'x', 'p' ) +#define TTAG_name MAKE_TT_TAG( 'n', 'a', 'm', 'e' ) +#define TTAG_OS2 MAKE_TT_TAG( 'O', 'S', '/', '2' ) +#define TTAG_PCLT MAKE_TT_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_post MAKE_TT_TAG( 'p', 'o', 's', 't' ) +#define TTAG_prep MAKE_TT_TAG( 'p', 'r', 'e', 'p' ) +#define TTAG_ttc MAKE_TT_TAG( 't', 't', 'c', ' ' ) +#define TTAG_ttcf MAKE_TT_TAG( 't', 't', 'c', 'f' ) +#define TTAG_VDMX MAKE_TT_TAG( 'V', 'D', 'M', 'X' ) +#define TTAG_vhea MAKE_TT_TAG( 'v', 'h', 'e', 'a' ) +#define TTAG_vmtx MAKE_TT_TAG( 'v', 'm', 't', 'x' ) + +#endif /* TTAGS_H */ + + +/* END */ diff --git a/lib/tttypes.h b/lib/tttypes.h new file mode 100644 index 0000000..b324013 --- /dev/null +++ b/lib/tttypes.h @@ -0,0 +1,150 @@ +/******************************************************************* + * + * tttypes.h + * + * Freetype engine's common types specification + * (this spec has no associated body). + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTE: + * + * All these declarations are library internals, and *not* part + * of the high-level interface. See also 'freetype.h'. + * + ******************************************************************/ + +#ifndef TTTYPES_H +#define TTTYPES_H + +#include "ttconfig.h" +#include "freetype.h" + +#ifdef __MACTYPES__ +#error " have been included, and this prevents the proper\ + compilation of this library. Please remove the precompiled headers." +#endif + + typedef char String; + typedef signed char Char; + typedef unsigned char Byte; + + typedef unsigned short UShort; + typedef signed short Short; + + typedef unsigned long ULong; + typedef signed long Long; + + typedef TT_Int32 Fixed; + + typedef int Int; + + /* Simple access types: pointers and tables */ + + typedef Byte* PByte; + typedef UShort* PUShort; + typedef Short* PShort; + typedef ULong* PULong; + typedef Long* PLong; + + typedef Fixed* PFixed; + + typedef Int* PInt; + + typedef void* Pointer; + + typedef TT_F26Dot6* PCoordinates; + typedef unsigned char* PTouchTable; + + +#ifndef Bool + typedef int Bool; /* No boolean type in C */ +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + + typedef Long Storage; + typedef Storage* PStorage; + + +/* Rounding mode constants */ + +#define TT_Round_Off 5 +#define TT_Round_To_Half_Grid 0 +#define TT_Round_To_Grid 1 +#define TT_Round_To_Double_Grid 2 +#define TT_Round_Up_To_Grid 4 +#define TT_Round_Down_To_Grid 3 +#define TT_Round_Super 6 +#define TT_Round_Super_45 7 + + +/* Touch flag masks */ + +#define TT_Flag_On_Curve 1 +#define TT_Flag_Touched_X 2 +#define TT_Flag_Touched_Y 4 +#define TT_Flag_Touched_Both 6 + + +/* Error management constants :) */ + +#define SUCCESS 0 +#define FAILURE -1 + + +/* The min and max functions missing in C. As usual, be careful not to */ +/* write things like MIN( a++, b++ ) to avoid side effects. */ + +#ifndef MIN +#define MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#endif + +#ifndef MAX +#define MAX( a, b ) ( (a) > (b) ? (a) : (b) ) +#endif + +#ifndef ABS +#define ABS( a ) ( (a) < 0 ? -(a) : (a) ) +#endif + +/* conversion macros for the handles defined in freetype.h */ + +#define HANDLE_Val( handle ) ((handle).z) + +#define HANDLE_Engine( handle ) ((PEngine_Instance)HANDLE_Val( handle )) + +#define HANDLE_Face( handle ) ((PFace)HANDLE_Val( handle )) + +#define HANDLE_Instance( handle ) ((PInstance)HANDLE_Val( handle )) + +/* HANDLE_Stream( handle ) must be defined in ttfile.c */ + +#define HANDLE_Glyph( handle ) ((PGlyph)HANDLE_Val( handle )) + +#define HANDLE_CharMap( handle ) ((PCMapTable)HANDLE_Val( handle )) + +#define HANDLE_Set( handle, val ) ((handle).z = (void*)(val)) + + +#endif /* TTTYPES_H */ + + +/* END */ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..8dae609 --- /dev/null +++ b/license.txt @@ -0,0 +1,158 @@ + The FreeType Project LICENSE + ---------------------------- + + Copyright 1996-1999 by + David Turner, Robert Wilhelm, and Werner Lemberg + + + +Introduction +============ + + The FreeType Project is distributed in several archive packages; + some of them may contain, in addition to the FreeType font engine, + various tools and contributions which rely on, or relate to, the + FreeType Project. + + This license applies to all files found in such packages, and + which do not fall under their own explicit license. The license + affects thus the FreeType font engine, the test programs, + documentation and makefiles, at the very least. + + This license was inspired by the BSD, Artistic, and IJG + (Independent JPEG Group) licenses, which all encourage inclusion + and use of free software in commercial and freeware products + alike. As a consequence, its main points are that: + + o We don't promise that this software works. However, we are be + interested in any kind of bug reports. (`as is' distribution) + + o You can use this software for whatever you want, in parts or + full form, without having to pay us. (`royalty-free' usage) + + o You may not pretend that you wrote this software. If you use + it, or only parts of it, in a program, you must acknowledge + somewhere in your documentation that you've used the FreeType + code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products, + provided that all warranty or liability claims are assumed by the + product vendor. + + +Legal Terms +=========== + +0. Definitions +-------------- + + Throughout this license, the terms `package', `FreeType Project', + and `FreeType archive' refer to the set of files originally + distributed by the authors (David Turner, Robert Wilhelm, and + Werner Lemberg) as the `FreeType project', be they named as alpha, + beta or final release. + + `You' refers to the licensee, or person using the project, where + `using' is a generic term including compiling the project's source + code as well as linking it to form a `program' or `executable'. + This program is referred to as `a program using the FreeType + engine'. + + This license applies to all files distributed in the original + FreeType archive, including all source code, binaries and + documentation, unless otherwise stated in the file in its + original, unmodified form as distributed in the original archive. + If you are unsure whether or not a particular file is covered by + this license, you must contact us to verify this. + + The FreeType project is copyright (C) 1996-1999 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. + +1. No Warranty +-------------- + + THE FREETYPE ARCHIVE IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO + USE, OF THE FREETYPE PROJECT. + + As you have not signed this license, you are not required to + accept it. However, as the FreeType project is copyrighted + material, only this license, or another one contracted with the + authors, grants you the right to use, distribute, and modify it. + Therefore, by using, distributing, or modifying the FreeType + project, you indicate that you understand and accept all the terms + of this license. + +2. Redistribution +----------------- + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + o Redistribution of source code must retain this license file + (`licence.txt') unaltered; any additions, deletions or changes + to the original files must be clearly indicated in + accompanying documentation. The copyright notices of the + unaltered, original files must be preserved in all copies of + source files. + + o Redistribution in binary form must provide a disclaimer that + states that the software is based in part of the work of the + FreeType Team, in the distribution documentation. We also + encourage you to put an URL to the FreeType web page in your + documentation, though this isn't mandatory. + + These conditions apply to any software derived from or based on + the FreeType code, not just the unmodified files. If you use our + work, you must acknowledge us. However, no fee need be paid to + us. + +3. Advertising +-------------- + + The names of FreeType's authors and contributors may not be used + to endorse or promote products derived from this software without + specific prior written permission. + + We suggest, but do not require, that you use one or more of the + following phrases to refer to this software in your documentation + or advertising materials: `FreeType Project', `FreeType Engine', + `FreeType library', or `FreeType Distribution'. + +4. Contacts +----------- + + There are two mailing lists related to FreeType: + + o freetype@freetype.org + + Discusses general use and applications of FreeType, as well as + future and wanted additions to the library and distribution. + If you are looking for support, start in this list if you + haven't found anything to help you in the documentation. + + o devel@freetype.org + + Discusses bugs, as well as engine internals, design issues, + specific licenses, porting, etc. + + o http://www.freetype.org + + Holds the current FreeType web page, which will allow you to + download our latest development version and read online + documentation. + + You can also contact us individually at: + + David Turner + Robert Wilhelm + Werner Lemberg + + +--- end of license.txt --- diff --git a/ltconfig b/ltconfig new file mode 100644 index 0000000..71ef065 --- /dev/null +++ b/ltconfig @@ -0,0 +1,3017 @@ +#! /bin/sh + +# ltconfig - Create a system-specific libtool. +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A lot of this script is taken from autoconf-2.10. + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} +echo=echo +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec "$SHELL" "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null`} + case X$UNAME in + *-DOS) PATH_SEPARATOR=';' ;; + *) PATH_SEPARATOR=':' ;; + esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +if test "X${echo_test_string+set}" != "Xset"; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" != 'X\t' || + test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running ltconfig again with it. + ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf "%s\n"' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + # Cool, printf works + : + elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && + test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && + test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# The name of this program. +progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` + +# Constants: +PROGRAM=ltconfig +PACKAGE=libtool +VERSION=1.3.3 +TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)" +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5' +rm="rm -f" + +help="Try \`$progname --help' for more information." + +# Global variables: +default_ofile=libtool +can_build_shared=yes +enable_shared=yes +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +enable_static=yes +enable_fast_install=yes +enable_dlopen=unknown +enable_win32_dll=no +ltmain= +silent= +srcdir= +ac_config_guess= +ac_config_sub= +host= +nonopt= +ofile="$default_ofile" +verify_host=yes +with_gcc=no +with_gnu_ld=no +need_locks=yes +ac_ext=c +objext=o +libext=a +exeext= +cache_file= + +old_AR="$AR" +old_CC="$CC" +old_CFLAGS="$CFLAGS" +old_CPPFLAGS="$CPPFLAGS" +old_LDFLAGS="$LDFLAGS" +old_LD="$LD" +old_LN_S="$LN_S" +old_LIBS="$LIBS" +old_NM="$NM" +old_RANLIB="$RANLIB" +old_DLLTOOL="$DLLTOOL" +old_OBJDUMP="$OBJDUMP" +old_AS="$AS" + +# Parse the command line options. +args= +prev= +for option +do + case "$option" in + -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + eval "$prev=\$option" + prev= + continue + fi + + case "$option" in + --help) cat <&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + if test -z "$ltmain"; then + ltmain="$option" + elif test -z "$host"; then +# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 +# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then +# echo "$progname: warning \`$option' is not a valid host type" 1>&2 +# fi + host="$option" + else + echo "$progname: too many arguments" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac +done + +if test -z "$ltmain"; then + echo "$progname: you must specify a LTMAIN file" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +if test ! -f "$ltmain"; then + echo "$progname: \`$ltmain' does not exist" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +# Quote any args containing shell metacharacters. +ltconfig_args= +for arg +do + case "$arg" in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ltconfig_args="$ltconfig_args '$arg'" ;; + *) ltconfig_args="$ltconfig_args $arg" ;; + esac +done + +# A relevant subset of AC_INIT. + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 compiler messages saved in config.log +# 6 checking for... messages and results +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>>./config.log + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +if test -n "$cache_file" && test -r "$cache_file"; then + echo "loading cache $cache_file within ltconfig" + . $cache_file +fi + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + +if test -z "$srcdir"; then + # Assume the source directory is the same one as the path to LTMAIN. + srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` + test "$srcdir" = "$ltmain" && srcdir=. +fi + +trap "$rm conftest*; exit 1" 1 2 15 +if test "$verify_host" = yes; then + # Check for config.guess and config.sub. + ac_aux_dir= + for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/config.guess; then + ac_aux_dir=$ac_dir + break + fi + done + if test -z "$ac_aux_dir"; then + echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 + echo "$help" 1>&2 + exit 1 + fi + ac_config_guess=$ac_aux_dir/config.guess + ac_config_sub=$ac_aux_dir/config.sub + + # Make sure we can run config.sub. + if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : + else + echo "$progname: cannot run $ac_config_sub" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 + + host_alias=$host + case "$host_alias" in + "") + if host_alias=`$SHELL $ac_config_guess`; then : + else + echo "$progname: cannot guess host type; you must specify one" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac + host=`$SHELL $ac_config_sub $host_alias` + echo "$ac_t$host" 1>&6 + + # Make sure the host verified. + test -z "$host" && exit 1 + +elif test -z "$host"; then + echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 + echo "$help" 1>&2 + exit 1 +else + host_alias=$host +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case "$host_os" in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +case "$host_os" in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR cru $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +# Set a sane default for `AR'. +test -z "$AR" && AR=ar + +# Set a sane default for `OBJDUMP'. +test -z "$OBJDUMP" && OBJDUMP=objdump + +# If RANLIB is not set, then run the test. +if test "${RANLIB+set}" != "set"; then + result=no + + echo $ac_n "checking for ranlib... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then + RANLIB="ranlib" + result="ranlib" + break + fi + done + IFS="$save_ifs" + + echo "$ac_t$result" 1>&6 +fi + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" +fi + +# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin. +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$AS" && AS=as + +# Check to see if we are using GCC. +if test "$with_gcc" != yes || test -z "$CC"; then + # If CC is not set, then try to find GCC or a usable CC. + if test -z "$CC"; then + echo $ac_n "checking for gcc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then + CC="gcc" + break + fi + done + IFS="$save_ifs" + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + fi + + # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". + if test -z "$CC"; then + echo $ac_n "checking for cc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + cc_rejected=no + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/cc || test -f $dir/cc$ac_exeext; then + if test "$dir/cc" = "/usr/ucb/cc"; then + cc_rejected=yes + continue + fi + CC="cc" + break + fi + done + IFS="$save_ifs" + if test $cc_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same name, so the bogon will be chosen + # first if we set CC to just the name; use the full file name. + shift + set dummy "$dir/cc" "$@" + shift + CC="$@" + fi + fi + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$CC"; then + echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 + exit 1 + fi + fi + + # Now see if the compiler is really GCC. + with_gcc=no + echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 + echo "$progname:581: checking whether we are using GNU C" >&5 + + $rm conftest.c + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + with_gcc=yes + fi + $rm conftest.c + echo "$ac_t$with_gcc" 1>&6 +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +echo $ac_n "checking for object suffix... $ac_c" 1>&6 +$rm conftest* +echo 'int i = 1;' > conftest.c +echo "$progname:603: checking for object suffix" >& 5 +if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + cat conftest.err 1>&5 + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 +fi +$rm conftest* +echo "$ac_t$objext" 1>&6 + +echo $ac_n "checking for executable suffix... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_exeext="no" + $rm conftest* + echo 'main () { return 0; }' > conftest.c + echo "$progname:629: checking for executable suffix" >& 5 + if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + for ac_file in conftest.*; do + case $ac_file in + *.c | *.err | *.$objext ) ;; + *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;; + esac + done + else + cat conftest.err 1>&5 + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + $rm conftest* +fi +if test "X$ac_cv_exeext" = Xno; then + exeext="" +else + exeext="$ac_cv_exeext" +fi +echo "$ac_t$ac_cv_exeext" 1>&6 + +echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 +pic_flag= +special_shlib_compile_flags= +wl= +link_static_flag= +no_builtin_flag= + +if test "$with_gcc" = yes; then + wl='-Wl,' + link_static_flag='-static' + + case "$host_os" in + beos* | irix5* | irix6* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # we not sure about C++ programs. + link_static_flag="$link_static_flag ${wl}-lC" + ;; + cygwin* | mingw* | os2*) + # We can build DLLs from non-PIC. + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + pic_flag='-m68020 -resident32 -malways-restore-a4' + ;; + sysv4*MP*) + if test -d /usr/nec; then + pic_flag=-Kconform_pic + fi + ;; + *) + pic_flag='-fPIC' + ;; + esac +else + # PORTME Check for PIC flags for the system compiler. + case "$host_os" in + aix3* | aix4*) + # All AIX code is PIC. + link_static_flag='-bnso -bI:/lib/syscalls.exp' + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better link_static_flag that works with the bundled CC? + wl='-Wl,' + link_static_flag="${wl}-a ${wl}archive" + pic_flag='+Z' + ;; + + irix5* | irix6*) + wl='-Wl,' + link_static_flag='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | os2*) + # We can build DLLs from non-PIC. + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + wl='-Wl,' + link_static_flag='-non_shared' + ;; + + sco3.2v5*) + pic_flag='-Kpic' + link_static_flag='-dn' + special_shlib_compile_flags='-belf' + ;; + + solaris*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + sunos4*) + pic_flag='-PIC' + link_static_flag='-Bstatic' + wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + uts4*) + pic_flag='-pic' + link_static_flag='-Bstatic' + ;; + sysv4*MP*) + if test -d /usr/nec ;then + pic_flag='-Kconform_pic' + link_static_flag='-Bstatic' + fi + ;; + *) + can_build_shared=no + ;; + esac +fi + +if test -n "$pic_flag"; then + echo "$ac_t$pic_flag" 1>&6 + + # Check to make sure the pic_flag actually works. + echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $pic_flag -DPIC" + echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5 + if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + case "$host_os" in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then they + # create non-PIC objects. So, if there were any warnings, we assume that + # PIC is not supported. + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + can_build_shared=no + pic_flag= + else + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + fi + ;; + *) + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + ;; + esac + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + can_build_shared=no + pic_flag= + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + echo "$ac_t"none 1>&6 +fi + +# Check to see if options -o and -c are simultaneously supported by compiler +echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6 +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +$rm conftest* +echo "int some_variable = 0;" > conftest.c +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.o" +echo "$progname:829: checking if $compiler supports -c -o file.o" >&5 +if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + echo "$ac_t"no 1>&6 + compiler_c_o=no + else + echo "$ac_t"yes 1>&6 + compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&5 + compiler_c_o=no + echo "$ac_t"no 1>&6 +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5 +if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_o_lo=no + else + echo "$ac_t"yes 1>&6 + compiler_o_lo=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_o_lo=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$ac_t$hard_links" 1>&6 + $rm conftest* + if test "$hard_links" = no; then + echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 + need_locks=warn + fi +else + need_locks=no +fi + +if test "$with_gcc" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c" + echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_rtti_exceptions=no + else + echo "$ac_t"yes 1>&6 + compiler_rtti_exceptions=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_rtti_exceptions=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi + +fi + +# Check for any special shared library compilation flags. +if test -n "$special_shlib_compile_flags"; then + echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2 + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then : + else + echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2 + can_build_shared=no + fi +fi + +echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6 +$rm conftest* +echo 'main(){return(0);}' > conftest.c +save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS $link_static_flag" +echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5 +if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + echo "$ac_t$link_static_flag" 1>&6 +else + echo "$ac_t"none 1>&6 + link_static_flag= +fi +LDFLAGS="$save_LDFLAGS" +$rm conftest* + +if test -z "$LN_S"; then + # Check to see if we can use ln -s, or we need hard links. + echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 + $rm conftest.dat + if ln -s X conftest.dat 2>/dev/null; then + $rm conftest.dat + LN_S="ln -s" + else + LN_S=ln + fi + if test "$LN_S" = "ln -s"; then + echo "$ac_t"yes 1>&6 + else + echo "$ac_t"no 1>&6 + fi +fi + +# Make sure LD is an absolute path. +if test -z "$LD"; then + ac_prog=ld + if test "$with_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6 + echo "$progname:991: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we are not using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld... $ac_c" 1>&6 + echo "$progname:1015: checking for GNU ld" >&5 + else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 + echo "$progname:1018: checking for non-GNU ld" >&5 + fi + + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" + fi + + if test -n "$LD"; then + echo "$ac_t$LD" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$LD"; then + echo "$progname: error: no acceptable ld found in \$PATH" 1>&2 + exit 1 + fi +fi + +# Check to see if it really is or is not GNU ld. +echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6 +# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + with_gnu_ld=yes +else + with_gnu_ld=no +fi +echo "$ac_t$with_gnu_ld" 1>&6 + +# See if the linker supports building shared libraries. +echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. + +case "$host_os" in +cygwin* | mingw*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$with_gcc" != yes; then + with_gnu_ld=no + fi + ;; + +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case "$host_os" in + aix3* | aix4*) + # On AIX, the GNU linker is very broken + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ + test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ + $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols' + + archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~ + _lt_hint=1; + for symbol in `cat $export_symbols`; do + echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def; + _lt_hint=`expr 1 + \$_lt_hint`; + done~ + test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ + test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ + $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ + $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ + $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts' + + old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' + ;; + + netbsd*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib' + # can we support soname and/or expsyms with a.out? -oliva + fi + ;; + + solaris*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case "$host_os" in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$with_gcc" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4*) + hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib' + hardcode_libdir_separator=':' + if test "$with_gcc" = yes; then + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + shared_flag='-shared' + else + shared_flag='${wl}-bM:SRE' + hardcode_direct=yes + fi + allow_undefined_flag=' ${wl}-berok' + archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}' + archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}' + case "$host_os" in aix4.[01]|aix4.[01].*) + # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on + always_export_symbols=yes ;; + esac + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs' + fix_srcfile_path='`cygpath -w $srcfile`' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case "$host_os" in + hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6*) + if test "$with_gcc" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF + fi + hardcode_libdir_flag_spec='${wl}-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def' + ;; + + osf3* | osf4* | osf5*) + if test "$with_gcc" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case "$host_os" in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + # archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs' + archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + *) + ld_shlibs=no + ;; + esac +fi +echo "$ac_t$ld_shlibs" 1>&6 +test "$ld_shlibs" = no && can_build_shared=no + +if test -z "$NM"; then + echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6 + case "$NM" in + [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path. + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -p" + break + else + NM=${NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$NM" && NM=nm + ;; + esac + echo "$ac_t$NM" 1>&6 +fi + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case "$host_os" in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + symcode='[BCDEGRST]' + ;; +solaris*) + symcode='[BDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[ABCDGISTW]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + $rm conftest* + cat > conftest.c <&5 + if { (eval echo $progname:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then + # Now try to grab the symbols. + nlist=conftest.nm + if { echo "$progname:1596: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then + + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c' + + cat <> conftest.c +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c + cat <<\EOF >> conftest.c + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$objext conftstm.$objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo $progname:1648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + pipe_works=yes + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + LIBS="$save_LIBS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + $rm conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + global_symbol_pipe= + fi +done +if test "$pipe_works" = yes; then + echo "${ac_t}ok" 1>&6 +else + echo "${ac_t}failed" 1>&6 +fi + +if test -z "$global_symbol_pipe"; then + global_symbol_to_cdecl= +fi + +# Check hardcoding attributes. +echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$ac_t$hardcode_action" 1>&6 + + +reload_flag= +reload_cmds='$LD$reload_flag -o $output$reload_objs' +echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6 +# PORTME Some linkers may need a different reload flag. +reload_flag='-r' +echo "$ac_t$reload_flag" 1>&6 +test -n "$reload_flag" && reload_flag=" $reload_flag" + +# PORTME Fill in your ld.so characteristics +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +file_magic_cmd= +file_magic_test_file= +deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. +echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 +case "$host_os" in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4*) + version_type=linux + # AIX has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + # We preserve .a as extension for shared libraries though AIX4.2 + # and later linker supports .so + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a' + shlibpath_var=LIBPATH + deplibs_check_method=pass_all + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + deplibs_check_method=pass_all + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + +bsdi4*) + version_type=linux + library_names_spec='${libname}.so$major ${libname}.so' + soname_spec='${libname}.so' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + file_magic_cmd=/usr/bin/file + file_magic_test_file=/shlib/libc.so + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw*) + version_type=windows + need_version=no + need_lib_prefix=no + if test "$with_gcc" = yes; then + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a' + else + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' + fi + dynamic_linker='Win32 ld.exe' + deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + file_magic_cmd='${OBJDUMP} -f' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case "$version_type" in + freebsd-elf*) + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /usr/lib/libc.so*` + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + deplibs_check_method=unknown + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + finish_cmds='PATH="\$PATH:/sbin" OBJFORMAT="'"$objformat"'" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + case "$host_os" in + freebsd2* | freebsd3.[01]*) + shlibpath_overrides_runpath=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6*) + version_type=irix + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so.$major' + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so' + case "$host_os" in + irix5*) + libsuff= shlibsuff= + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case "$LD" in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /lib${libsuff}/libc.so*` + deplibs_check_method='pass_all' + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + + if test -f /lib/ld.so.1; then + dynamic_linker='GNU ld.so' + else + # Only the GNU ld.so supports shared libraries on MkLinux. + case "$host_cpu" in + powerpc*) dynamic_linker=no ;; + *) dynamic_linker='Linux ld.so' ;; + esac + fi + ;; + +netbsd*) + version_type=sunos + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + ;; + +openbsd*) + version_type=sunos + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + need_version=no + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method='file_magic COFF format alpha shared library' + file_magic_cmd=/usr/bin/file + file_magic_test_file=/shlib/libc.so + deplibs_check_method='pass_all' + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib" + file_magic_cmd=/usr/bin/file + file_magic_test_file=/lib/libc.so + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case "$host_vendor" in + ncr) + deplibs_check_method='pass_all' + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$ac_t$dynamic_linker" 1>&6 +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 + +# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in +# configure.in, otherwise build static only libraries. +case "$host_os" in +cygwin* | mingw* | os2*) + if test x$can_build_shared = xyes; then + test x$enable_win32_dll = xno && can_build_shared=no + echo "checking if package supports dlls... $can_build_shared" 1>&6 + fi +;; +esac + +if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then + case "$deplibs_check_method" in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac +fi + +echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + test "$enable_shared" = yes && enable_static=no + ;; +esac + +echo "$ac_t$enable_shared" 1>&6 + +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes + +echo "checking whether to build static libraries... $enable_static" 1>&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +echo $ac_n "checking for objdir... $ac_c" 1>&6 +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +echo "$ac_t$objdir" 1>&6 + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else +if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then + lt_cv_dlopen=no lt_cv_dlopen_libs= +echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "$progname:2170: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dlopen""... $ac_c" 1>&6 +echo "$progname:2207: checking for dlopen" >&5 +if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +dlopen(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_dlopen=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_dlopen=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 +echo "$progname:2251: checking for dld_link in -ldld" >&5 +ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load""... $ac_c" 1>&6 +echo "$progname:2288: checking for shl_load" >&5 +if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +shl_load(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_shl_load=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_shl_load=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 +echo "$progname:2333: checking for shl_load in -ldld" >&5 +ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +fi + + +fi + + +fi + +fi + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + fi + + case "$lt_cv_dlopen" in + dlopen) +for ac_hdr in dlfcn.h; do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "$progname:2395: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int fnord = 0; +EOF +ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo $progname:2405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +done + + if test "x$ac_cv_header_dlfcn_h" = xyes; then + CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + fi + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:2433: checking whether a program can dlopen itself" >&5 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self=cross + else + cat > conftest.c < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +fnord() { int i=42;} +main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self" 1>&6 + + if test "$lt_cv_dlopen_self" = yes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:2506: checking whether a statically linked program can dlopen itself" >&5 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self_static=cross + else + cat > conftest.c < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +fnord() { int i=42;} +main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self_static=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self_static=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 +fi + ;; + esac + + case "$lt_cv_dlopen_self" in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case "$lt_cv_dlopen_self_static" in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + +# Copy echo and quote the copy, instead of the original, because it is +# used later. +ltecho="$echo" +if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ltecho="$CONFIG_SHELL \$0 --fallback-echo" +fi +LTSHELL="$SHELL" + +LTCONFIG_VERSION="$VERSION" + +# Only quote variables if we're using ltmain.sh. +case "$ltmain" in +*.sh) + # Now quote all the things that may contain metacharacters. + for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \ + old_LD old_LDFLAGS old_LIBS \ + old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \ + AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \ + file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case "$var" in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case "$ltecho" in + *'\$0 --fallback-echo"') + ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + + trap "$rm \"$ofile\"; exit 1" 1 2 15 + echo "creating $ofile" + $rm "$ofile" + cat < "$ofile" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. +# +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +### BEGIN LIBTOOL CONFIG +EOF + cfgfile="$ofile" + ;; + +*) + # Double-quote the variables that need it (for aesthetics). + for var in old_CC old_CFLAGS old_CPPFLAGS \ + old_LD old_LDFLAGS old_LIBS \ + old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do + eval "$var=\\\"\$var\\\"" + done + + # Just create a config file. + cfgfile="$ofile.cfg" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + echo "creating $cfgfile" + $rm "$cfgfile" + cat < "$cfgfile" +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +EOF + ;; +esac + +cat <> "$cfgfile" +# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ +# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ +# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\ +# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\ +# $0$ltconfig_args +# +# Compiler and other test output produced by $progname, useful for +# debugging $progname, is in ./config.log if it exists. + +# The version of $progname that generated this script. +LTCONFIG_VERSION=$LTCONFIG_VERSION + +# Shell to use when invoking shell scripts. +SHELL=$LTSHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$ltecho + +# The archiver. +AR=$AR + +# The default C compiler. +CC=$CC + +# The linker used to build libraries. +LD=$LD + +# Whether we need hard or soft links. +LN_S=$LN_S + +# A BSD-compatible nm program. +NM=$NM + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$reload_flag +reload_cmds=$reload_cmds + +# How to pass a linker flag through the compiler. +wl=$wl + +# Object file suffix (normally "o"). +objext="$objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$pic_flag + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$RANLIB +old_archive_cmds=$old_archive_cmds +old_postinstall_cmds=$old_postinstall_cmds +old_postuninstall_cmds=$old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$old_archive_from_new_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$archive_cmds +archive_expsym_cmds=$archive_expsym_cmds +postinstall_cmds=$postinstall_cmds +postuninstall_cmds=$postuninstall_cmds + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$global_symbol_to_cdecl + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$include_expsyms + +EOF + +case "$ltmain" in +*.sh) + echo '### END LIBTOOL CONFIG' >> "$ofile" + echo >> "$ofile" + case "$host_os" in + aix3*) + cat <<\EOF >> "$ofile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # Append the ltmain.sh script. + sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1) + + chmod +x "$ofile" + ;; + +*) + # Compile the libtool program. + echo "FIXME: would compile $ltmain" + ;; +esac + +test -n "$cache_file" || exit 0 + +# AC_CACHE_SAVE +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 0000000..ae10cad --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,3975 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun ltconfig. +# +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + echo "$modename: not configured to build any kind of library" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case "$arg" in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + execute_dlfiles) + eval "$prev=\"\$$prev \$arg\"" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case "$arg" in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case "$nonopt" in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case "$arg" in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case "$mode" in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + # Accept any command-line options. + case "$arg" in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + esac + + case "$user_target" in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly in scan + # sets, so we specify it separately. + case "$lastarg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case "$user_target" in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case "$libobj" in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case "$libobj" in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $pic_flag -DPIC $srcfile" + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if test -z "$pic_flag" && test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + # Now arrange that obj and lo_libobj become the same file + $show "$LN_S $obj $lo_libobj" + if $run $LN_S $obj $lo_libobj; then + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + command="$base_compile $srcfile" + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link) + modename="$modename: link" + C_compiler="$CC" # save it, to compile generated C sources + CC="$nonopt" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (!dll) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case "$prev" in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case "$arg" in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case "$arg" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi + + prevarg="$arg" + + case "$arg" in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: not more than one -exported-symbols argument allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + absdir="$dir" + fi + dir="$absdir" + ;; + esac + case " $deplibs " in + *" $arg "*) ;; + *) deplibs="$deplibs $arg";; + esac + case " $lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir";; + esac + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + dllsearchdir=`cd "$dir" && pwd || echo "$dir"` + case ":$dllsearchpath:" in + ::) dllsearchpath="$dllsearchdir";; + *":$dllsearchdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dllsearchdir";; + esac + ;; + esac + ;; + + -l*) + if test "$arg" = "-lc"; then + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) + # These systems don't actually have c library (as such) + continue + ;; + esac + elif test "$arg" = "-lm"; then + case "$host" in + *-*-cygwin* | *-*-beos*) + # These systems don't actually have math library (as such) + continue + ;; + esac + fi + deplibs="$deplibs $arg" + ;; + + -module) + module=yes + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # If we have no pic_flag, then this is the same as -all-static. + if test -z "$pic_flag" && test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + + *.o | *.obj | *.a | *.lib) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A library object. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + fi + libobjs="$libobjs $arg" + ;; + + *.la) + # A libtool-controlled library. + + dlname= + libdir= + library_names= + old_library= + + # Check to see that this really is a libtool archive. + if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2 + exit 1 + fi + + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + # If there is no directory component, then add one. + case "$arg" in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$arg'" 1>&2 + exit 1 + fi + + # Find the relevant object directory and library name. + name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'` + + if test "X$installed" = Xyes; then + dir="$libdir" + else + dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$arg"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + fi + + if test -n "$dependency_libs"; then + # Extract -R and -L from dependency_libs + temp_deplibs= + for deplib in $dependency_libs; do + case "$deplib" in + -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + case " $rpath $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + -L*) case "$compile_command $temp_deplibs " in + *" $deplib "*) ;; + *) temp_deplibs="$temp_deplibs $deplib";; + esac + temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'` + case " $lib_search_path " in + *" $temp_dir "*) ;; + *) lib_search_path="$lib_search_path $temp_dir";; + esac + ;; + *) temp_deplibs="$temp_deplibs $deplib";; + esac + done + dependency_libs="$temp_deplibs" + fi + + if test -z "$libdir"; then + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$deplibs$dependency_libs" + compile_command="$compile_command $dir/$old_library$dependency_libs" + finalize_command="$finalize_command $dir/$old_library$dependency_libs" + continue + fi + + # This library was specified with -dlopen. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking statically, + # we need to preload. + prev=dlprefiles + else + # We should not create a dependency on this library, but we + # may need any libraries it requires. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + prev= + continue + fi + fi + + # The library was specified with -dlpreopen. + if test "$prev" = dlprefiles; then + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + dlprefiles="$dlprefiles $dir/$old_library" + else + dlprefiles="$dlprefiles $dir/$linklib" + fi + prev= + fi + + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + link_against_libtool_libs="$link_against_libtool_libs $arg" + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # We need an absolute path. + case "$dir" in + [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + absdir="$dir" + fi + ;; + esac + + # This is the magic to use -rpath. + # Skip directories that are in the system default run-time + # search path, unless they have been requested with -R. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + + lib_linked=yes + case "$hardcode_action" in + immediate | unsupported) + if test "$hardcode_direct" = no; then + compile_command="$compile_command $dir/$linklib" + deplibs="$deplibs $dir/$linklib" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + dllsearchdir=`cd "$dir" && pwd || echo "$dir"` + if test -n "$dllsearchpath"; then + dllsearchpath="$dllsearchpath:$dllsearchdir" + else + dllsearchpath="$dllsearchdir" + fi + ;; + esac + elif test "$hardcode_minus_L" = no; then + case "$host" in + *-*-sunos*) + compile_shlibpath="$compile_shlibpath$dir:" + ;; + esac + case "$compile_command " in + *" -L$dir "*) ;; + *) compile_command="$compile_command -L$dir";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -L$dir -l$name" + elif test "$hardcode_shlibpath_var" = no; then + case ":$compile_shlibpath:" in + *":$dir:"*) ;; + *) compile_shlibpath="$compile_shlibpath$dir:";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -l$name" + else + lib_linked=no + fi + ;; + + relink) + if test "$hardcode_direct" = yes; then + compile_command="$compile_command $absdir/$linklib" + deplibs="$deplibs $absdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + case "$compile_command " in + *" -L$absdir "*) ;; + *) compile_command="$compile_command -L$absdir";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -L$absdir -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case ":$compile_shlibpath:" in + *":$absdir:"*) ;; + *) compile_shlibpath="$compile_shlibpath$absdir:";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -l$name" + else + lib_linked=no + fi + ;; + + *) + lib_linked=no + ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + finalize_command="$finalize_command $libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + case "$finalize_command " in + *" -L$libdir "*) ;; + *) finalize_command="$finalize_command -L$libdir";; + esac + finalize_command="$finalize_command -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case ":$finalize_shlibpath:" in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:";; + esac + finalize_command="$finalize_command -l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + case "$finalize_command " in + *" -L$dir "*) ;; + *) finalize_command="$finalize_command -L$libdir";; + esac + finalize_command="$finalize_command -l$name" + fi + else + # Transform directly to old archives if we don't build new libraries. + if test -n "$pic_flag" && test -z "$old_library"; then + $echo "$modename: cannot find static library for \`$arg'" 1>&2 + exit 1 + fi + + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_command="$compile_command $dir/$linklib" + finalize_command="$finalize_command $dir/$linklib" + else + case "$compile_command " in + *" -L$dir "*) ;; + *) compile_command="$compile_command -L$dir";; + esac + compile_command="$compile_command -l$name" + case "$finalize_command " in + *" -L$dir "*) ;; + *) finalize_command="$finalize_command -L$dir";; + esac + finalize_command="$finalize_command -l$name" + fi + fi + + # Add in any libraries that this one depends upon. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + esac + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + case "$output" in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *.a | *.lib) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into archives" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + ;; + + *.la) + # Make sure we only generate libraries of the form `libNAME.la'. + case "$outputname" in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + + if test -n "$objs"; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1 + exit 1 + fi + + # How the heck are we supposed to write a wrapper for a shared library? + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2 + exit 1 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + dependency_libs="$deplibs" + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case "$current" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$revision" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$age" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case "$version_type" in + none) ;; + + irix) + major=`expr $current - $age + 1` + versuffix="$major.$revision" + verstring="sgi$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="sgi$major.$iface:$verstring" + done + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + windows) + # Like Linux, but with '-' rather than '.', since we only + # want one extension on Windows 95. + major=`expr $current - $age` + versuffix="-$major-$age-$revision" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + dependency_libs="$deplibs" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *) + # Add libc to deplibs on all other systems. + deplibs="$deplibs -lc" + ;; + esac + fi + + # Create the output directory, or remove our outputs if we need to. + if test -d $output_objdir; then + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + else + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + if test "$build_libtool_libs" = yes; then + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case "$deplibs_check_method" in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | sed 's/.* -> //'` + case "$potliblink" in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | sed 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) incase we are running --disable-static + for obj in $libobjs; do + oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"` + if test ! -f $oldobj; then + $show "${LN_S} $obj $oldobj" + $run ${LN_S} $obj $oldobj || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linkopts="$linkopts $flag" + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + *.lo | *.o | *.obj) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into objects" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case "$output" in + *.lo) + if test -n "$objs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" + + output="$obj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + $show "$LN_S $obj $libobj" + $run $LN_S $obj $libobj || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + # Anything else should be a program. + *) + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$compile_rpath " in + *" $libdir "*) ;; + *) compile_rpath="$compile_rpath $libdir" ;; + esac + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + + # Create the binary in the object directory, then wrap it. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case "$dlsyms" in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | sed -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{\ +" + + sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ + -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ + < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr_t) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case "$host" in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case "$0" in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|sed 's,.exe$,,'` ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + link_against_libtool_libs='$link_against_libtool_libs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname' + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if (cd \"\$thisdir\" && eval \$relink_command); then : + else + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname$exeext' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + *-*-cygwin* | *-*-mingw | *-*-os2*) + # win32 systems need to use the prog path for dll + # lookup to work + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place incase we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"` + $show "${LN_S} $obj $oldobj" + $run ${LN_S} $obj $oldobj || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case "$output" in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + if test -n "$xrpath"; then + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + done + dependency_libs="$temp_xrpath $dependency_libs" + fi + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + fi + $rm $output + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$dlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Directory that this library needs to be installed in: +libdir='$install_libdir'\ +" + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case "$arg" in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case "$file" in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case "$file" in + *.a | *.lib) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/" + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$realname $destdir/$realname" + $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $? + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case "$destfile" in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.o | *.obj) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + link_against_libtool_libs= + relink_command= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$link_against_libtool_libs"; then + $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $link_against_libtool_libs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case "$lib" in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`" + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec $SHELL $0 --finish$current_libdirs + exit 1 + fi + + exit 0 + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case "$file" in + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case "$file" in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now actually exec the command. + eval "exec \$cmd$args" + + $echo "$modename: cannot exec \$cmd$args" + exit 1 + else + # Display what would be done. + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool uninstall mode + uninstall) + modename="$modename: uninstall" + rm="$nonopt" + files= + + for arg + do + case "$arg" in + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + rmfiles="$file" + + case "$name" in + *.la) + # Possibly a libtool archive, so verify it. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $dir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library" + + $show "$rm $rmfiles" + $run $rm $rmfiles + + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + # FIXME: should reinstall the best remaining shared library. + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + + *) + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + esac + done + exit 0 + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 +fi # test -z "$show_help" + +# We need to display help for each of the modes. +case "$mode" in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100644 index 0000000..d005d49 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.2 1998/09/01 16:52:17 werner Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/net.m4 b/net.m4 new file mode 100644 index 0000000..254473b --- /dev/null +++ b/net.m4 @@ -0,0 +1,55 @@ +dnl +dnl The following was written by jhawk@mit.edu +dnl +dnl AC_LIBRARY_NET: Id: net.m4,v 1.4 1997/10/25 20:49:53 jhawk Exp +dnl +dnl This test is for network applications that need socket() and +dnl gethostbyname() -ish functions. Under Solaris, those applications need to +dnl link with "-lsocket -lnsl". Under IRIX, they should *not* link with +dnl "-lsocket" because libsocket.a breaks a number of things (for instance: +dnl gethostbyname() under IRIX 5.2, and snoop sockets under most versions of +dnl IRIX). +dnl +dnl Unfortunately, many application developers are not aware of this, and +dnl mistakenly write tests that cause -lsocket to be used under IRIX. It is +dnl also easy to write tests that cause -lnsl to be used under operating +dnl systems where neither are necessary (or useful), such as SunOS 4.1.4, which +dnl uses -lnsl for TLI. +dnl +dnl This test exists so that every application developer does not test this in +dnl a different, and subtly broken fashion. +dnl +dnl It has been argued that this test should be broken up into two seperate +dnl tests, one for the resolver libraries, and one for the libraries necessary +dnl for using Sockets API. Unfortunately, the two are carefully intertwined and +dnl allowing the autoconf user to use them independantly potentially results in +dnl unfortunate ordering dependancies -- as such, such component macros would +dnl have to carefully use indirection and be aware if the other components were +dnl executed. Since other autoconf macros do not go to this trouble, and almost +dnl no applications use sockets without the resolver, this complexity has not +dnl been implemented. +dnl +dnl The check for libresolv is in case you are attempting to link statically +dnl and happen to have a libresolv.a lying around (and no libnsl.a). +dnl +AC_DEFUN(AC_LIBRARY_NET, [ + # Most operating systems have gethostbyname() in the default searched + # libraries (i.e. libc): + AC_CHECK_FUNC(gethostbyname, , + # Some OSes (eg. Solaris) place it in libnsl: + AC_CHECK_LIB(nsl, gethostbyname, , + # Some strange OSes (SINIX) have it in libsocket: + AC_CHECK_LIB(socket, gethostbyname, , + # Unfortunately libsocket sometimes depends on libnsl. + # AC_CHECK_LIB's API is essentially broken so the following + # ugliness is necessary: + AC_CHECK_LIB(socket, gethostbyname, + LIBS="-lsocket -lnsl $LIBS", + AC_CHECK_LIB(resolv, gethostbyname), + -lnsl) + ) + ) + ) + AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, , + AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))) + ]) diff --git a/pascal/lib/freetype.pas b/pascal/lib/freetype.pas new file mode 100644 index 0000000..82bc46f --- /dev/null +++ b/pascal/lib/freetype.pas @@ -0,0 +1,1931 @@ +(******************************************************************* + * + * FreeType.Pas + * + * High-level interface specification. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Notes : + * + * This is the only file that should be included by client + * application sources for the final release. All other types + * and functions defined in the "tt*.h" files are library + * internals, and should not be included ( except of course + * during development, as now ) + * + ******************************************************************) + +unit FreeType; + +interface + +type + +{$IFDEF OS2} + TT_Int = Longint; +{$ELSE} + TT_Int = Integer; +{$ENDIF} + + TT_Long = longint; + TT_ULong = longint; (* there are no unsigned longs in Pascal :-( *) + (* it will probably be a good idea to use cardinals *) + (* with Delphi and Virtual a bit later.. *) + TT_Short = integer; + TT_UShort = word; + + TT_Fixed = LongInt; (* Signed Fixed 16.16 Float *) + + TT_FWord = Integer; (* Distance in FUnits *) + TT_UFWord = Word; (* Unsigned Distance *) + + TT_F2Dot14 = Integer; (* signed fixed float 2.14 used for *) + (* unary vectors, with layout : *) + (* *) + (* s : 1 -- sign bit *) + (* m : 1 -- mantissa bit *) + (* f : 14 -- unsigned fractional *) + (* *) + (* 's:m' is the 2-bit signed int *) + (* value to which the *positive* *) + (* fractional part should be *) + (* added. *) + (* *) + + TT_F26Dot6 = LongInt; (* 26.6 fixed float, used for pixel coordinates *) + + TT_Pos = Longint; (* funits or 26.6, depending on context *) + + (******************************************************) + (* a simple unit vector type *) + (* *) + TT_UnitVector = record + + x : TT_F2Dot14; + y : TT_F2Dot14; + end; + + (******************************************************) + (* a simple vector type *) + (* *) + TT_Vector = record + + x : TT_Pos; + y : TT_Pos; + end; + + (******************************************************) + (* a simple 2x2 matrix type *) + (* *) + TT_Matrix = record + + xx, xy : TT_Fixed; + yx, yy : TT_Fixed; + end; + + (******************************************************) + (* a glyph's bounding box *) + (* *) + TT_BBox = record + + xMin, yMin : TT_Pos; + xMax, yMax : TT_Pos; + end; + + (******************************************************) + (* the engine's error condition type - 0 always *) + (* means success. *) + (* *) + TT_Error = TT_Int; + + TT_Points_Table = array[0..99] of TT_Vector; + TT_Points = ^TT_Points_Table; + + TT_Coordinates = array[0..99] of TT_Pos; + TT_PCoordinates = ^TT_Coordinates; + + TT_TouchTable = array[0..9] of byte; + TT_PTouchTable = ^TT_TouchTable; + + TT_ConStarts = array[0..9] of word; + TT_PConStarts = ^TT_ConStarts; + + (******************************************************) + (* glyph outline description *) + (* *) + TT_Outline = record + + n_points : integer; + n_contours : integer; + + points : TT_Points; (* array of point coordinates *) + flags : TT_PTouchTable; (* array of point flags *) + conEnds : TT_PConStarts; (* array of contours ends *) + + owner : Boolean; (* this flag is set when the outline *) + (* owns the arrays it uses. *) + + high_precision : Boolean; + second_pass : Boolean; + dropout_mode : Byte; + end; + + (******************************************************) + (* glyph metrics structure *) + (* *) + TT_Glyph_Metrics = record + + bbox : TT_BBox; + bearingX : TT_Pos; + bearingY : TT_Pos; + advance : TT_Pos; + end; + + (******************************************************) + (* big glyph metrics structure *) + (* *) + TT_Big_Glyph_Metrics = record + + bbox : TT_BBox; + horiBearingX : TT_Pos; + horiBearingY : TT_Pos; + horiAdvance : TT_Pos; + vertBearingX : TT_Pos; + vertBearingY : TT_Pos; + vertAdvance : TT_Pos; + end; + + (******************************************************) + (* instance metrics. used to return information to *) + (* clients regarding an instance's important state *) + (* *) + TT_Instance_Metrics = record + + pointsize : integer; + + x_ppem : integer; + y_ppem : integer; + + x_scale : TT_Fixed; + y_scale : TT_Fixed; + + x_resolution : integer; + y_resolution : integer; + end; + +const + TT_Flow_Down = -1; + TT_Flow_Up = +1; + +type + + (******************************************************) + (* a record used to describe a bitmap or pixmap to *) + (* the rasterizer. *) + (* *) + TT_Raster_Map = record + + Rows : TT_Int; (* rows number of the bitmap *) + Cols : TT_Int; (* columns (bytes) per row *) + Width : TT_Int; (* pixels per row *) + Flow : TT_Int; (* bit/pixmap's flow *) + Buffer : pointer; (* bit/pixmap data *) + Size : longint; (* bit/pixmap data size (bytes) *) + end; + + (******************************************************) + (* The TrueType font header table structure *) + (* *) + TT_Header = record + + table_version : TT_Fixed; + font_revision : TT_Fixed; + + checksum_adjust : TT_Long; + magic_number : TT_Long; + + flags : TT_UShort; + units_per_EM : TT_UShort; + + created : array[0..1] of TT_Long; + modified : array[0..1] of TT_Long; + + xMin, yMin : TT_FWord; + xMax, yMax : TT_FWord; + + mac_style : TT_UShort; + lowest_rec_PPEM : TT_UShort; + font_direction : TT_Short; + + index_to_loc_format : TT_Short; + glyph_data_format : TT_Short; + end; + + (******************************************************) + (* The TrueType horizontal header table structure *) + (* *) + TT_Horizontal_Header = record + + version : TT_Fixed; + ascender : TT_FWord; + descender : TT_FWord; + line_gap : TT_FWord; + + advance_Width_Max : TT_UShort; + min_left_side_bearing : TT_Short; + min_right_side_bearing : TT_Short; + xMax_extent : TT_Short; + caret_slope_rise : TT_Short; + caret_slope_run : TT_Short; + + reserved : array[0..4] of TT_SHort; + + metric_data_format : TT_Short; + number_of_HMetrics : TT_UShort; + + (* the following are not part of the header in the file *) + + short_metrics : Pointer; + long_metrics : Pointer; + end; + + (******************************************************) + (* The TrueType vertical header table structure *) + (* *) + TT_Vertical_Header = record + + version : TT_Fixed; + ascender : TT_FWord; + descender : TT_FWord; + line_gap : TT_FWord; + + advance_Height_Max : TT_UShort; + min_top_side_bearing : TT_Short; + min_bottom_side_bearing : TT_Short; + yMax_extent : TT_Short; + caret_slope_rise : TT_Short; + caret_slope_run : TT_Short; + + reserved : array[0..4] of TT_SHort; + + metric_data_format : TT_Short; + number_of_VMetrics : TT_UShort; + + (* the following are not part of the header in the file *) + + short_metrics : Pointer; + long_metrics : Pointer; + end; + + (******************************************************) + (* The TrueType OS/2 table structure *) + (* *) + TT_OS2 = record + version : TT_UShort; (* $0001 *) + xAvgCharWidth : TT_Short; + usWeightClass : TT_UShort; + usWidthClass : TT_UShort; + fsType : TT_Short; + ySubscriptXSize : TT_Short; + ySubscriptYSize : TT_Short; + ySubScriptXOffset : TT_Short; + ySubscriptYOffset : TT_Short; + ySuperscriptXSize : TT_Short; + ySuperscriptYSize : TT_Short; + ySuperscriptXOffset : TT_Short; + ySuperscriptYOffset : TT_Short; + yStrikeoutSize : TT_Short; + yStrikeoutPosition : TT_Short; + sFamilyClass : TT_Short; + panose : array[0..9] of Byte; + ulUnicodeRange1 : TT_ULong; (* bits 0-31 *) + ulUnicodeRange2 : TT_ULong; (* bits 32-63 *) + ulUnicodeRange3 : TT_ULong; (* bits 64-95 *) + ulUnicodeRange4 : TT_ULong; (* bits 96-127 *) + achVendID : array[0..3] of Byte; + fsSelection : TT_UShort; + usFirstCharIndex : TT_UShort; + usLastCharIndex : TT_UShort; + sTypoAscender : TT_Short; + sTypoDescender : TT_Short; + sTypoLineGap : TT_Short; + usWinAscent : TT_UShort; + usWinDescent : TT_UShort; + + (* only version 1 tables *) + ulCodePageRange1 : TT_ULong; + ulCodePageRange2 : TT_ULong; + end; + + (******************************************************) + (* The TrueType Postscript table structure *) + (* *) + TT_Postscript = record + + FormatType : TT_Fixed; + italicAngle : TT_Fixed; + underlinePosition : TT_Short; + underlineThickness : TT_Short; + isFixedPitch : TT_ULong; + minMemType42 : TT_ULong; + maxMemType42 : TT_ULong; + minMemType1 : TT_ULong; + maxMemType1 : TT_ULong; + end; + + (******************************************************) + (* face properties. use to report important face *) + (* data to clients *) + (* *) + TT_Face_Properties = record + + num_glyphs : integer; + max_points : integer; + max_contours : integer; + max_faces : integer; + + header : ^TT_Header; + horizontal : ^TT_Horizontal_Header; + vertical : ^TT_Vertical_Header; + os2 : ^TT_OS2; + postscript : ^TT_Postscript; + end; + + (******************************************************) + (* Objects handle types *) + (* *) + TT_Stream = record z : Pointer; end; + TT_Face = record z : Pointer; end; + TT_Instance = record z : Pointer; end; + TT_Glyph = record z : Pointer; end; + TT_CharMap = record z : Pointer; end; + + TT_Gray_Palette = array[0..4] of byte; + + (******************************************************************) + (* *) + (* ERROR CODES *) + (* *) + (******************************************************************) + +const + (* ------------------- Success is always 0 ---------------------- *) + + TT_Err_Ok = 0; + + (* -------------------------------------------------------------- *) + + TT_Err_Invalid_Face_Handle = $0001; + TT_Err_Invalid_Instance_Handle = $0002; + TT_Err_Invalid_Glyph_Handle = $0003; + TT_Err_Invalid_CharMap_Handle = $0004; + TT_Err_Invalid_Result_Address = $0005; + TT_Err_Invalid_Glyph_Index = $0006; + TT_Err_Invalid_Argument = $0007; + TT_Err_Could_Not_Open_File = $0008; + TT_Err_File_Is_Not_Collection = $0009; + + TT_Err_Table_Missing = $000A; + TT_Err_Invalid_Horiz_Metrics = $000B; + TT_Err_Invalid_Vert_Metrics = $000B; + TT_Err_Invalid_CharMap_Format = $000C; + + TT_Err_Invalid_File_Format = $0010; + TT_Err_File_Error = $0011; + + TT_Err_Invalid_Engine = $0020; + TT_Err_Too_Many_Extensions = $0021; + TT_Err_Extensions_Unsupported = $0022; + TT_Err_Invalid_Extension_Id = $0023; + + TT_Err_No_Vertical_Data = $0030; + + TT_Err_Max_Profile_Missing = $0080; + TT_Err_Header_Table_Missing = $0081; + TT_Err_Horiz_Header_Missing = $0082; + TT_Err_Locations_Missing = $0083; + TT_Err_Name_Table_Missing = $0084; + TT_Err_CMap_Table_Missing = $0085; + TT_Err_Hmtx_Table_Missing = $0086; + TT_Err_OS2_Table_Missing = $0087; + TT_Err_Post_Table_Missing = $0088; + + (* -------------------------------------------------------------- *) + + TT_Err_Out_Of_Memory = $0100; + + (* -------------------------------------------------------------- *) + + TT_Err_Invalid_File_Offset = $0200; + TT_Err_Invalid_File_Read = $0201; + TT_Err_Invalid_Frame_Access = $0202; + + (* -------------------------------------------------------------- *) + + TT_Err_Too_Many_Points = $0300; + TT_Err_Too_Many_Contours = $0301; + TT_Err_Invalid_Composite = $0302; + TT_Err_Too_Many_Ins = $0303; + + (* -------------------------------------------------------------- *) + + TT_Err_Invalid_Opcode = $0400; + TT_Err_Too_Few_Arguments = $0401; + TT_Err_Stack_Overflow = $0402; + TT_Err_Code_Overflow = $0403; + TT_Err_Bad_Argument = $0404; + TT_Err_Divide_By_Zero = $0405; + TT_Err_Storage_Overflow = $0406; + TT_Err_Cvt_Overflow = $0407; + TT_Err_Invalid_Reference = $0408; + TT_Err_Invalid_Distance = $0409; + TT_Err_Interpolate_Twilight = $040A; + TT_Err_Debug_Opcode = $040B; + TT_Err_ENDF_In_Exec_Stream = $040C; + TT_Err_Out_Of_CodeRanges = $040D; + TT_Err_Nested_DEFs = $040E; + TT_Err_Invalid_CodeRange = $040F; + TT_Err_Invalid_Displacement = $0410; + TT_Err_Execution_Too_Long = $0411; + TT_Err_Too_Many_FuncDefs = $0412; + TT_Err_Too_Many_InsDefs = $0413; + + TT_Err_Nested_Frame_Access = $0500; + TT_Err_Invalid_Cache_List = $0501; + TT_Err_Could_Not_Find_Context = $0502; + TT_Err_UNlisted_Object = $0503; + + TT_Err_Raster_Pool_Overflow = $0600; + TT_Err_Raster_Negative_Height = $0601; + TT_Err_Invalid_Value = $0602; + TT_Err_Raster_Not_Initialised = $0603; + + (* -------------------------------------------------------------- *) + + (***********************************************************************) + (* *) + (* Base Library Functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Initialise the engine *) + (* *) + function TT_Init_FreeType : TT_Error; + + (*****************************************************************) + (* Finalise the engine - discards all objects *) + (* *) + procedure TT_Done_FreeType; + + (*****************************************************************) + (* Set the gray-level palette used for font-smoothing *) + (* *) + (* it is an array of 5 bytes following this convention : *) + (* *) + (* palette[0] := background (white) *) + (* palette[1] := light *) + (* palette[2] := medium *) + (* palette[3] := dark *) + (* palette[4] := foreground (black) *) + (* *) + function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error; + + (***********************************************************************) + (* *) + (* Face Management functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Open a new font file and returns a handle for it in '_face' *) + (* *) + (* The file can be a TrueType collection, in which case the *) + (* first embedded font will be loaded. *) + (* *) + function TT_Open_Face( fontname : string; + var _face : TT_Face ) : TT_Error; + + (*****************************************************************) + (* Open a font file embedded in a collection. *) + (* *) + function TT_Open_Collection( fontname : string; + faceIndex : integer; + var _face : TT_Face ) : TT_Error; + + (*****************************************************************) + (* Return face properties in 'prop' *) + (* *) + function TT_Get_Face_Properties( _face : TT_Face; + var prop : TT_Face_Properties ) : TT_Error; + + (*****************************************************************) + (* Set face's generic pointer *) + (* *) + function TT_Set_Face_Pointer( _face : TT_Face; + data : Pointer ) : TT_Error; + + (*****************************************************************) + (* Get face's generic pointer *) + (* *) + function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer; + + (*****************************************************************) + (* close a given face object. This releases all child objects *) + (* like instances and glyphs *) + (* *) + function TT_Close_Face( _face : TT_Face ) : TT_Error; + + (***********************************************************************) + (* *) + (* Instance management functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* open a new face instance and return a handle in '_ins' *) + (* *) + function TT_New_Instance( _face : TT_Face; + var _ins : TT_Instance ) : TT_Error; + + (*****************************************************************) + (* set an instance's device resolutions, expressed in dpi *) + (* *) + function TT_Set_Instance_Resolutions( _ins : TT_Instance; + x_resolution : Integer; + y_resolution : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's point size (assumes width==height) *) + (* *) + function TT_Set_Instance_PointSize( _ins : TT_Instance; + pointsize : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's point size (assumes width==height) *) + (* *) + function TT_Set_Instance_CharSize( _ins : TT_Instance; + charsize : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's point size (assumes width==height) *) + (* *) + function TT_Set_Instance_CharSizes( _ins : TT_Instance; + charsizex : Integer; + charsizey : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's height and width, expressed in pixels *) + (* *) + function TT_Set_Instance_PixelSizes( _ins : TT_Instance; + pixelX : Integer; + pixelY : Integer; + pointsize : Integer ) : TT_Error; + + (*****************************************************************) + (* set an instance's height and width, expressed in pixels *) + (* *) + + (*****************************************************************) + (* the core truetype engine doesn't provide _direct_ support *) + (* for rotation or stretching. This means that the transforms *) + (* must be applied on the glyph outline by a higher-level *) + (* library or the client application. However, we use two flags *) + (* to notice the TrueType hinter that the glyphs will be *) + (* transformed later. *) + (* *) + (* rotated : set if the glyphs are to be rotated *) + (* distorted : set if the glyphs are to be distorted *) + (* *) + (* an application is any transform that doesn't keep distances *) + (* constants. skewing and stretching are examples of distorsion *) + (* *) + function TT_Set_Instance_Transforms( _ins : TT_Instance; + rotated : Boolean; + distorted : Boolean ) : TT_Error; + + (*****************************************************************) + (* Return instance metrics in 'm' *) + (* *) + function TT_Get_Instance_Metrics( _ins : TT_Instance; + var m : TT_Instance_Metrics ) : TT_Error; + + (*****************************************************************) + (* Set instance generic pointer *) + (* *) + function TT_Set_Instance_Pointer( _ins : TT_Instance; + data : Pointer ) : TT_Error; + + (*****************************************************************) + (* Get instance generic pointer *) + (* *) + function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer; + + (*****************************************************************) + (* Close an instance *) + (* *) + function TT_Done_Instance( _ins : TT_Instance ) : TT_Error; + + (***********************************************************************) + (* *) + (* Glyph management functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Create a new glyph container, return a handle in '_glyph' *) + (* *) + function TT_New_Glyph( _face : TT_Face; + var _glyph : TT_Glyph ) : TT_Error; + + (*****************************************************************) + (* Releases a glyph container *) + (* *) + function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error; + + (*****************************************************************) + (* Load a glyph inside a container *) + (* *) + function TT_Load_Glyph( _instance : TT_Instance; + _glyph : TT_Glyph; + glyph_index : Word; + load_flags : Integer ) : TT_Error; + +const + TT_Load_Scale_Glyph = 1; (* ask the loader to scale the glyph *) + (* to the current pointsize/transform *) + + TT_Load_Hint_Glyph = 2; (* when scaling is on, ask the loader *) + (* to hint the glyph too.. *) + + TT_Load_Debug = 16; + + TT_Load_Default = TT_Load_Scale_Glyph or + TT_Load_Hint_Glyph; + + + (*****************************************************************) + (* Get a glyph's outline *) + (* *) + function TT_Get_Glyph_Outline( _glyph : TT_Glyph; + var outline : TT_Outline ) : TT_Error; + + (*****************************************************************) + (* Get a glyph's metrics *) + (* *) + function TT_Get_Glyph_Metrics( _glyph : TT_Glyph; + var gmetrics : TT_Glyph_Metrics ) : TT_Error; + + (*****************************************************************) + (* Get a glyph's big metrics *) + (* *) + function TT_Get_Glyph_Big_Metrics( _glyph : TT_Glyph; + var gmetrics : TT_Big_Glyph_Metrics + ) : TT_Error; + + (*****************************************************************) + (* Render a glyph's bitmap *) + (* *) + function TT_Get_Glyph_Bitmap( _glyph : TT_Glyph; + var map : TT_Raster_Map; + x_offset : TT_F26Dot6; + y_offset : TT_F26Dot6 ) : TT_Error; + + (*****************************************************************) + (* Render a glyph's pixmap (i.e. smoothed glyph ) *) + (* *) + function TT_Get_Glyph_Pixmap( _glyph : TT_Glyph; + var map : TT_Raster_Map; + x_offset : TT_F26Dot6; + y_offset : TT_F26Dot6 ) : TT_Error; + + (***********************************************************************) + (* *) + (* Outline functions *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Apply translation to an outline *) + (* *) + function TT_Translate_Outline( var out : TT_Outline; + x, y : TT_F26Dot6 ) : TT_Error; + + (*****************************************************************) + (* Apply a 2x2 transform to an outline *) + (* *) + function TT_Transform_Outline( var out : TT_Outline; + var mat : TT_Matrix ) : TT_Error; + + (*****************************************************************) + (* Apply a 2x2 transform to a vector *) + (* *) + function TT_Transform_Vector( var x, y : TT_F26Dot6; + var mat : TT_Matrix ) : TT_Error; + + (*****************************************************************) + (* Render an outline into a bitmap *) + (* *) + function TT_Get_Outline_Bitmap( var out : TT_Outline; + var map : TT_raster_Map ) : TT_Error; + + (*****************************************************************) + (* Render an outline into a pixmap *) + (* *) + function TT_Get_Outline_Pixmap( var out : TT_Outline; + var map : TT_raster_Map ) : TT_Error; + + + (*****************************************************************) + (* Get an outline's bounding box *) + (* *) + function TT_Get_Outline_BBox( var out : TT_Outline; + var bbox : TT_Bbox ) : TT_Error; + + (*****************************************************************) + (* Create a new glyph outline *) + (* *) + function TT_New_Outline( n_points : integer; + n_contours : integer; + var out : TT_Outline ) : TT_Error; + + (*****************************************************************) + (* Copy a glyph outline into another one *) + (* *) + function TT_Copy_Outline( var source : TT_Outline; + var target : TT_Outline ) : TT_Error; + + (*****************************************************************) + (* Clone a given outline. This will create the outline, then *) + (* copy the source in it *) + (* *) + function TT_Clone_Outline( var source : TT_Outline; + var target : TT_Outline ) : TT_Error; + + (*****************************************************************) + (* Discards a glyph outline *) + (* *) + function TT_Done_Outline( var out : TT_Outline ) : TT_Error; + + (***********************************************************************) + (* *) + (* Character Mapping support *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Get a face's number of character maps *) + (* *) + function TT_Get_CharMap_Count( face : TT_Face ) : integer; + + (*****************************************************************) + (* Get a given char. map's ID in a face *) + (* *) + function TT_Get_CharMap_ID( face : TT_Face; + charmapIndex : integer; + var platform : integer; + var encoding : integer ) : TT_Error; + + (*****************************************************************) + (* Get a handle to a given char. map *) + (* *) + function TT_Get_CharMap( face : TT_Face; + charmapIndex : integer; + var charMap : TT_CharMap ) : TT_Error; + + (*****************************************************************) + (* Translate from char. code to glyph index *) + (* *) + function TT_Char_Index( charmap : TT_CharMap; + charCode : Longint ) : Word; + + (***********************************************************************) + (* *) + (* Names Table support *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Return number of name table entries *) + (* *) + function TT_Get_Name_Count( face : TT_Face ) : integer; + + (*****************************************************************) + (* Return the ID of a given name table entry *) + (* *) + function TT_Get_Name_ID( face : TT_Face; + nameIndex : integer; + var platform : integer; + var encoding : integer; + var language : integer; + var nameid : integer ) : TT_Error; + + (*****************************************************************) + (* Return a given name table string *) + (* *) + function TT_Get_Name_String( face : TT_Face; + nameIndex : integer; + var str : Pointer; + var len : integer ) : TT_Error; + + (***********************************************************************) + (* *) + (* Font Storage Access *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* Access font data and copies it into user block *) + (* *) + function TT_Get_Font_Data( face : TT_Face; + tableTag : Longint; + offset : Longint; + var buffer; + var length : longint ) : TT_Error; + +implementation + +uses + TTTypes, + TTError, + TTCalc, + TTMemory, + TTTables, + TTCache, + TTFile, + TTCMap, + TTObjs, + TTLoad, + TTGLoad, + TTRaster, + TTInterp; + +var + raster_palette : TT_Gray_Palette; + + (*****************************************************************) + (* *) + (* *) + function TT_Init_FreeType : TT_Error; + begin + if TTMemory_Init or + TTCache_Init or + TTFile_Init or + TTObjs_Init or + TTRaster_Init then + begin + TT_Init_FreeType := error; + exit; + end; + + TT_Init_FreeType := TT_Err_Ok; + end; + + + (*****************************************************************) + (* *) + (* *) + procedure TT_Done_FreeType; + begin + TTRaster_Done; + TTObjs_Done; + TTFile_Done; + TTCache_Done; + TTMemory_Done; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error; + begin + raster_palette := palette; + TT_Set_Raster_Palette := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Open_Face( fontname : string; + var _face : TT_Face ) : TT_Error; + var + input : TFont_Input; + begin + input.fontIndex := 0; + + if TT_Open_Stream( fontname, input.stream ) then + begin + TT_Open_Face := error; + exit; + end; + + Cache_New( face_cache, Pointer(_face), @input ); + + TT_Open_Face := error; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Open_Collection( fontname : string; + faceIndex : integer; + var _face : TT_Face ) : TT_Error; + var + input : TFont_Input; + begin + input.fontIndex := faceIndex; + + if TT_Open_Stream( fontname, input.stream ) then + begin + TT_Open_Collection := error; + exit; + end; + + Cache_New( face_cache, Pointer(_face), @input ); + + TT_Open_Collection := error; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Face_Properties( _face : TT_Face; + var prop : TT_Face_Properties ) : TT_Error; + var + face : PFace; + begin + face := _face.z; + if face <> nil then + begin + with prop do + begin + num_Glyphs := face^.numGlyphs; + max_Points := face^.maxPoints; + max_Contours := face^.maxContours; + max_Faces := face^.ttcHeader.dirCount; + header := @face^.fontHeader; + horizontal := @face^.horizontalHeader; + + if face^.verticalInfo then + vertical := @face^.verticalHeader + else + vertical := nil; + + os2 := @face^.os2; + postscript := @face^.postscript; + end; + TT_Get_Face_Properties := TT_Err_Ok; + end + else + TT_Get_Face_Properties := TT_Err_Invalid_Face_Handle; + end; + + + (*****************************************************************) + (* Set face's generic pointer *) + (* *) + function TT_Set_Face_Pointer( _face : TT_Face; + data : Pointer ) : TT_Error; + var + face :PFace; + begin + face := PFace(_face.z); + if face <> nil then + begin + face^.generic := data; + TT_Set_Face_Pointer := TT_Err_Ok; + end + else + TT_Set_Face_Pointer := TT_Err_Invalid_Face_Handle; + end; + + (*****************************************************************) + (* Get face's generic pointer *) + (* *) + function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer; + var + face : PFace; + begin + face := PFace(_face.z); + if face <> nil then + TT_Get_Face_Pointer := face^.generic + else + TT_get_Face_Pointer := nil; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Close_Face( _face : TT_Face ) : TT_Error; + var + face : PFace; + begin + face := _face.z; + if face <> nil then + begin + error := TT_Err_Ok; + (* Note : the stream is closed by the face destructor !! *) + Cache_Done( face_cache, _face.z ); + TT_Close_Face := error; + end + else + TT_Close_Face := TT_Err_Invalid_Face_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_New_Instance( _face : TT_Face; + var _ins : TT_Instance ) : TT_Error; + var + face : PFace; + ins : PInstance; + begin + face := _face.z; + if face <> nil then + begin + error := TT_Err_Ok; + if not Cache_New( face^.instances, _ins.z, face ) then + Instance_Init( _ins.z ); + TT_New_Instance := error; + end + else + TT_New_Instance := TT_Err_Invalid_Face_Handle; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_Resolutions( _ins : TT_Instance; + x_resolution : Integer; + y_resolution : Integer ) : TT_Error; + var + ins : PInstance; + begin + ins := _ins.z; + if ins <> nil then + begin + ins^.metrics.x_resolution := x_resolution; + ins^.metrics.y_resolution := y_resolution; + ins^.valid := False; + TT_Set_Instance_Resolutions := TT_Err_Ok; + end + else + TT_Set_Instance_Resolutions := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_CharSize( _ins : TT_Instance; + charsize : Integer ) : TT_Error; + var + ins : PInstance; + begin + TT_Set_Instance_CharSize := + TT_Set_Instance_CharSizes( _ins, charsize, charsize ); + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_CharSizes( _ins : TT_Instance; + charsizex : Integer; + charsizey : Integer ) : TT_Error; + var + ins : PInstance; + begin + if (charsizex < 1*64) or (charsizey < 1*64) then + begin + TT_Set_Instance_CharSizes := TT_Err_Bad_Argument; + exit; + end; + + ins := _ins.z; + if ins <> nil then + begin + with ins^.metrics do + begin + x_scale1 := ( Long(charsizex) * x_resolution ) div 72; + x_scale2 := ins^.owner^.fontHeader.units_per_EM; + + y_scale1 := ( Long(charsizey) * y_resolution ) div 72; + y_scale2 := x_scale2; + + if ins^.owner^.fontHeader.flags and 8 <> 0 then + begin + x_scale1 := (x_scale1 + 32) and -64; + y_scale1 := (y_scale1 + 32) and -64; + end; + + x_ppem := x_scale1 div 64; + y_ppem := y_scale1 div 64; + end; + + if charsizex > charsizey then + ins^.metrics.pointsize := charsizex + else + ins^.metrics.pointsize := charsizey; + + ins^.valid := False; + TT_Set_Instance_CharSizes := TT_Err_Ok; + end + else + TT_Set_Instance_CharSizes := TT_Err_Invalid_Instance_Handle; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_PointSize( _ins : TT_Instance; + pointsize : integer ) : TT_Error; + begin + TT_Set_Instance_PointSize := + TT_Set_Instance_CharSize( _ins, pointsize*64 ); + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_PixelSizes( _ins : TT_Instance; + pixelX : Integer; + pixelY : Integer; + pointsize : Integer ) : TT_Error; + var + ins : PInstance; + begin + ins := _ins.z; + if ins <> nil then + begin + ins^.metrics.x_ppem := pixelX; + ins^.metrics.y_ppem := pixelY; + ins^.metrics.pointSize := pointsize; + + ins^.metrics.x_scale1 := ins^.metrics.x_ppem * 64; + ins^.metrics.x_scale2 := ins^.owner^.fontHeader.units_per_EM; + ins^.metrics.y_scale1 := ins^.metrics.y_ppem * 64; + ins^.metrics.y_scale2 := ins^.metrics.x_scale2; + + ins^.valid := false; + + TT_Set_Instance_PixelSizes := TT_Err_Ok; + end + else + TT_Set_Instance_PixelSizes := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Set_Instance_Transforms( _ins : TT_Instance; + rotated : Boolean; + distorted : Boolean ) : TT_Error; + var + ins : PInstance; + begin + ins := _ins.z; + if ins <> nil then + begin + ins^.metrics.rotated := rotated; + ins^.metrics.stretched := distorted; + TT_Set_Instance_Transforms := TT_Err_Ok; + end + else + TT_Set_Instance_Transforms := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Instance_Metrics( _ins : TT_Instance; + var m : TT_Instance_Metrics ) : TT_Error; + var + ins : PInstance; + begin + ins := _ins.z; + if ins <> nil then + begin + if not ins^.valid then + if Instance_Reset( ins, False ) then + begin + TT_Get_Instance_Metrics := error; + exit; + end; + + with m do + begin + pointSize := ins^.metrics.pointSize; + + x_scale := MulDiv_Round( $10000, + ins^.metrics.x_scale1, + ins^.metrics.x_scale2 ); + + y_scale := MulDiv_Round( $10000, + ins^.metrics.y_scale1, + ins^.metrics.y_scale2 ); + + x_resolution := ins^.metrics.x_resolution; + y_resolution := ins^.metrics.y_resolution; + + x_ppem := ins^.metrics.x_ppem; + y_ppem := ins^.metrics.y_ppem; + + TT_Get_Instance_Metrics := TT_Err_Ok; + end; + end + else + TT_Get_Instance_Metrics := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* Set instance generic pointer *) + (* *) + function TT_Set_Instance_Pointer( _ins : TT_Instance; + data : Pointer ) : TT_Error; + var + ins : PInstance; + begin + ins := PInstance(_ins.z); + if ins <> nil then + begin + ins^.generic := data; + TT_Set_Instance_Pointer := TT_Err_Ok; + end + else + TT_Set_Instance_Pointer := TT_Err_Invalid_Instance_Handle; + end; + + (*****************************************************************) + (* Get instance generic pointer *) + (* *) + function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer; + var + ins : PInstance; + begin + ins := PInstance(_ins.z); + if ins <> nil then + TT_Get_Instance_Pointer := ins^.generic + else + TT_Get_Instance_Pointer := nil; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Done_Instance( _ins : TT_Instance ) : TT_Error; + var + ins : PInstance; + begin + ins := PInstance(_ins.z); + if ins <> nil then + begin + error := TT_Err_Ok; + Cache_Done( ins^.owner^.instances, ins ); + TT_Done_Instance := error; + end + else + TT_Done_Instance := TT_Err_Invalid_Instance_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_New_Glyph( _face : TT_Face; + var _glyph : TT_Glyph ) : TT_Error; + var + face : PFace; + begin + face := PFace(_face.z); + if face <> nil then + begin + error := TT_Err_Ok; + Cache_New( face^.glyphs, _glyph.z, _face.z ); + TT_New_Glyph := error; + end + else + TT_New_Glyph := TT_Err_Invalid_Face_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph.z); + if glyph <> nil then + begin + error := TT_Err_Ok; + Cache_Done( glyph^.face^.glyphs, glyph ); + TT_Done_Glyph := error; + end + else + TT_Done_Glyph := TT_Err_Invalid_Glyph_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Load_Glyph( _instance : TT_Instance; + _glyph : TT_Glyph; + glyph_index : Word; + load_flags : Integer ) : TT_Error; + var + ins : PInstance; + glyph : PGlyph; + begin + ins := PInstance(_instance.z); + if ins = nil then + begin + TT_Load_Glyph := TT_Err_Invalid_Instance_Handle; + exit; + end; + + glyph := PGlyph(_glyph.z); + if glyph = nil then + begin + TT_Load_Glyph := TT_Err_Invalid_Glyph_Handle; + exit; + end; + + if ins^.owner <> glyph^.face then + begin + TT_Load_Glyph := TT_Err_Invalid_Face_Handle; + exit; + end; + + if not ins^.valid then + if Instance_Reset( ins, False ) then + begin + TT_Load_Glyph := error; + exit; + end; + + error := TT_Err_Ok; + Load_TrueType_Glyph( ins, glyph, glyph_index, load_flags ); + TT_Load_Glyph := error; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Glyph_Outline( _glyph : TT_Glyph; + var outline : TT_Outline ) : TT_Error; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph.z); + if glyph <> nil then + begin + outline := glyph^.outline; + outline.owner := false; + TT_Get_Glyph_Outline := TT_Err_Ok; + end + else + TT_Get_Glyph_Outline := TT_Err_Invalid_Glyph_Handle; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Glyph_Metrics( _glyph : TT_Glyph; + var gmetrics : TT_Glyph_Metrics ) : TT_Error; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph.z); + if glyph <> nil then + begin + gmetrics.bbox := glyph^.metrics.bbox; + gmetrics.bearingX := glyph^.metrics.horiBearingX; + gmetrics.bearingY := glyph^.metrics.horiBearingY; + gmetrics.advance := glyph^.metrics.horiAdvance; + TT_Get_Glyph_Metrics := TT_Err_Ok; + end + else + TT_Get_Glyph_Metrics := TT_Err_Invalid_Glyph_Handle; + end; + + (*****************************************************************) + (* Get a glyph's big metrics *) + (* *) + function TT_Get_Glyph_Big_Metrics( _glyph : TT_Glyph; + var gmetrics : TT_Big_Glyph_Metrics + ) : TT_Error; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph.z); + if glyph <> nil then + begin + gmetrics := glyph^.metrics; + TT_Get_Glyph_Big_Metrics := TT_Err_Ok; + end + else + TT_Get_Glyph_Big_Metrics := TT_Err_Invalid_Glyph_Handle; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Glyph_Bitmap( _glyph : TT_Glyph; + var map : TT_raster_Map; + x_offset : TT_F26Dot6; + y_offset : TT_F26Dot6 ) : TT_Error; + var + glyph : PGlyph; + outline : TT_Outline; + n : Int; + begin + glyph := _glyph.z; + if glyph <> nil then + begin + outline := glyph^.outline; + (* XXX: for now, we only use dropout mode #2 *) + outline.dropout_mode := 2; + + TT_Translate_Outline( outline, x_offset, y_offset ); + TT_Get_Glyph_Bitmap := TT_Get_Outline_Bitmap( outline, map ); + TT_Translate_Outline( outline, -x_offset, -y_offset ); + end + else + TT_Get_Glyph_Bitmap := TT_Err_Invalid_Glyph_Handle; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Glyph_Pixmap( _glyph : TT_Glyph; + var map : TT_raster_Map; + x_offset : TT_F26Dot6; + y_offset : TT_F26Dot6 ) : TT_Error; + var + glyph : PGlyph; + outline : TT_Outline; + n : Int; + begin + glyph := _glyph.z; + if glyph <> nil then + begin + outline := glyph^.outline; + (* XXX: for now, we only use dropout mode #2 *) + outline.dropout_mode := 2; + + TT_translate_Outline( outline, x_offset, y_offset ); + TT_Get_Glyph_Pixmap := TT_Get_Outline_Pixmap( outline, map ); + TT_translate_Outline( outline, -x_offset, -y_offset ); + end + else + TT_Get_Glyph_Pixmap := TT_Err_Invalid_Glyph_Handle; + end; + + (*****************************************************************) + (* Create a new glyph outline *) + (* *) + function TT_New_Outline( n_points : integer; + n_contours : integer; + var out : TT_Outline ) : TT_Error; + label + Fail; + begin + out.n_points := n_points; + out.n_contours := n_contours; + out.points := nil; + out.flags := nil; + out.conEnds := nil; + out.owner := true; + + if Alloc( Pointer(out.points), 2*n_points*sizeof(TT_Pos) ) or + Alloc( Pointer(out.flags), n_points*sizeof(Byte) ) or + Alloc( Pointer(out.conEnds), n_contours*sizeof(Short) ) then + goto Fail; + + TT_New_Outline := TT_Err_Ok; + exit; + + Fail: + TT_Done_Outline( out ); + TT_New_Outline := error; + end; + + (*****************************************************************) + (* Copy a glyph outline into another one *) + (* *) + function TT_Copy_Outline( var source : TT_Outline; + var target : TT_Outline ) : TT_Error; + begin + if (source.n_points = target.n_points) and + (source.n_contours = target.n_contours) then + begin + move( source.points^, target.points^, 2*source.n_points*4 ); + move( source.flags^, target.flags^, source.n_points ); + move( source.conEnds^,target.conEnds^, source.n_contours*2 ); + end + else + TT_Copy_Outline := TT_Err_Invalid_Argument; + end; + + (*****************************************************************) + (* Clone a given outline. This will create the outline, then *) + (* copy the source in it *) + (* *) + function TT_Clone_Outline( var source : TT_Outline; + var target : TT_Outline ) : TT_Error; + begin + error := TT_New_Outline( source.n_points, source.n_contours, target ); + if error = TT_Err_Ok then + TT_Copy_Outline( source, target ); + + TT_Clone_Outline := error; + end; + + (*****************************************************************) + (* Discards a glyph outline *) + (* *) + function TT_Done_Outline( var out : TT_Outline ) : TT_Error; + begin + if out.owner then + begin + Free( Pointer(out.conEnds) ); + Free( Pointer(out.flags) ); + Free( Pointer(out.points) ); + out.n_points := 0; + out.n_contours := 0; + TT_Done_Outline := TT_Err_Ok; + end + else + TT_Done_Outline := TT_Err_Invalid_Argument; + end; + + (*****************************************************************) + (* Render an outline into a bitmap *) + (* *) + function TT_Get_Outline_Bitmap( var out : TT_Outline; + var map : TT_raster_Map ) : TT_Error; + begin + if Render_Glyph( out, map ) then + TT_Get_Outline_Bitmap := error + else + TT_Get_Outline_Bitmap := TT_Err_Ok; + end; + + (*****************************************************************) + (* Render an outline into a pixmap *) + (* *) + function TT_Get_Outline_Pixmap( var out : TT_Outline; + var map : TT_raster_Map ) : TT_Error; + begin + if Render_Gray_Glyph( out, map ) then + TT_Get_Outline_Pixmap := error + else + TT_Get_Outline_Pixmap := TT_Err_Ok; + end; + + (*****************************************************************) + (* Compute an outline's bounding box *) + (* *) + function TT_Get_Outline_BBox( var out : TT_Outline; + var bbox : TT_Bbox ) : TT_Error; + var + x, y, + xMin, yMin, + xMax, yMax : TT_Pos; + n : Int; + begin + + with bbox do + begin + xMin := $7FFFFFFF; + xMax := $80000000; + yMin := $7FFFFFFF; + yMax := $80000000; + + for n := 0 to out.n_points-1 do + begin + x := out.points^[n].x; + if x < xMin then xMin := x; + if x > xMax then xMax := x; + y := out.points^[n].y; + if y < yMin then yMin := y; + if y > yMax then yMax := y; + end; + end; + + TT_Get_Outline_BBox := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Translate_Outline( var out : TT_Outline; + x, y : TT_F26Dot6 ) : TT_Error; + var + n : integer; + begin + if x <> 0 then + for n := 0 to out.n_points-1 do + inc( out.points^[n].x, x ); + + if y <> 0 then + for n := 0 to out.n_points-1 do + inc( out.points^[n].y, y ); + + TT_Translate_Outline := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Transform_Outline( var out : TT_Outline; + var mat : TT_Matrix ) : TT_Error; + var + n : integer; + x, y, nx, ny : TT_F26Dot6; + begin + for n := 0 to out.n_points-1 do + begin + x := out.points^[n].x; + y := out.points^[n].y; + + nx := MulDiv_Round( mat.xx, x, $10000 ) + + MulDiv_Round( mat.xy, y, $10000 ); + + ny := MulDiv_ROund( mat.yx, x, $10000 ) + + MulDiv_Round( mat.yy, y, $10000 ); + + out.points^[n].x := nx; + out.points^[n].y := ny; + end; + + TT_Transform_Outline := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Transform_Vector( var x, y : TT_F26Dot6; + var mat : TT_Matrix ) : TT_Error; + var + nx, ny : TT_F26Dot6; + begin + nx := MulDiv_Round( mat.xx, x, $10000 ) + + MulDiv_Round( mat.xy, y, $10000 ); + + ny := MulDiv_Round( mat.yx, x, $10000 ) + + MulDiv_Round( mat.yy, y, $10000 ); + + x := nx; + y := ny; + + TT_Transform_Vector := TT_Err_Ok; + end; + + (***********************************************************************) + (* *) + (* Character Mapping support *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* *) + (* *) + function TT_Get_CharMap_Count( face : TT_Face ) : integer; + var + faze : PFace; + begin + faze := PFace(face.z); + if faze = nil then + TT_Get_CharMap_Count := -1 + else + TT_Get_CharMap_Count := faze^.numCMaps; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_CharMap_ID( face : TT_Face; + charmapIndex : integer; + var platform : integer; + var encoding : integer ) : TT_Error; + var + faze : PFace; + cmap : PCMapTable; + begin + faze := PFace(face.z); + if faze = nil then + begin + TT_Get_CharMap_ID := TT_Err_Invalid_Face_Handle; + exit; + end; + + if (charmapIndex < 0) or (charmapIndex >= faze^.numCMaps) then + begin + TT_Get_CharMap_ID := TT_Err_Invalid_Argument; + exit; + end; + + cmap := @faze^.cMaps^[charmapIndex]; + platform := cmap^.platformID; + encoding := cmap^.platformEncodingID; + + TT_Get_CharMap_ID := TT_Err_Ok; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_CharMap( face : TT_Face; + charmapIndex : integer; + var charMap : TT_CharMap ) : TT_Error; + var + faze : PFace; + begin + faze := PFace(face.z); + if faze = nil then + begin + TT_Get_CharMap := TT_Err_Invalid_Face_Handle; + exit; + end; + + if (charmapIndex < 0) or (charmapIndex >= faze^.numCMaps) then + begin + TT_Get_CharMap := TT_Err_Invalid_Argument; + exit; + end; + + charmap.z := @faze^.cMaps^[charmapIndex]; + + TT_Get_CharMap := TT_Err_Ok; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Char_Index( charmap : TT_CharMap; + charCode : Longint ) : Word; + begin + TT_Char_Index := CharMap_Index( PCMapTable(charmap.z)^, charCode ); + end; + + (***********************************************************************) + (* *) + (* Names Table support *) + (* *) + (***********************************************************************) + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Name_Count( face : TT_Face ) : integer; + var + faze : PFace; + begin + TT_Get_Name_Count := 0; + + faze := PFace( face.z ); + if faze = nil then exit; + + TT_Get_Name_Count := faze^.nameTable.numNameRecords; + end; + + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Name_ID( face : TT_Face; + nameIndex : integer; + var platform : integer; + var encoding : integer; + var language : integer; + var nameid : integer ) : TT_Error; + var + faze : PFace; + table : PName_Table; + rec : PName_Record; + label + Fail; + begin + faze := PFace( face.z ); + if faze = nil then + begin + TT_Get_Name_Id := TT_Err_Invalid_Face_Handle; + goto Fail; + end; + + table := @faze^.nameTable; + if (nameIndex < 0) or (nameIndex > table^.numNameRecords) then + begin + TT_Get_Name_Id := TT_Err_Bad_Argument; + goto Fail; + end; + + rec := @table^.names^[nameIndex]; + + platform := rec^.platformID; + encoding := rec^.encodingID; + language := rec^.languageID; + nameid := rec^.nameID; + + TT_Get_Name_ID := TT_Err_Ok; + exit; + + Fail: + platform := -1; + encoding := -1; + language := -1; + nameid := -1; + end; + + (*****************************************************************) + (* *) + (* *) + function TT_Get_Name_String( face : TT_Face; + nameIndex : integer; + var str : Pointer; + var len : integer ) : TT_Error; + var + faze : PFace; + table : PName_Table; + rec : PName_Record; + label + Fail; + begin + faze := PFace( face.z ); + if faze = nil then + begin + TT_Get_Name_String := TT_Err_Invalid_Face_Handle; + goto Fail; + end; + + table := @faze^.nameTable; + if (nameIndex < 0) or (nameIndex > table^.numNameRecords) then + begin + TT_Get_Name_String := TT_Err_Bad_Argument; + goto Fail; + end; + + rec := @table^.names^[nameIndex]; + + str := @table^.storage^[rec^.offset]; + len := rec^.length; + + TT_Get_Name_String := TT_Err_Ok; + exit; + + Fail: + str := nil; + len := 0; + end; + + + (*****************************************************************) + (* Access font data and copies it into user block *) + (* *) + function TT_Get_Font_Data( face : TT_Face; + tableTag : Longint; + offset : Longint; + var buffer; + var length : longint ) : TT_Error; + var + faze : PFace; + begin + faze := PFace(face.z); + if faze = nil then + begin + TT_Get_Font_Data := TT_Err_Invalid_Face_Handle; + length := 0; + end + else + begin + TT_Get_Font_Data := TT_Err_Ok; + if Load_TrueType_Any( faze, tableTag, offset, buffer, length ) then + TT_Get_Font_Data := error; + end; + end; + + +end. + diff --git a/pascal/lib/ttcache.pas b/pascal/lib/ttcache.pas new file mode 100644 index 0000000..5af1fb9 --- /dev/null +++ b/pascal/lib/ttcache.pas @@ -0,0 +1,433 @@ +(******************************************************************* + * + * ttcache.pas 1.0 + * + * Generic object cache + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * This component defines and implement object caches. + * + * An object class is a structure layout that encapsulate one + * given type of data used by the FreeType engine. Each object + * class is completely described by : + * + * - a 'root' or 'leading' structure containing the first + * important fields of the class. The root structure is + * always of fixed size. + * + * It is implemented as a simple C structure, and may + * contain several pointers to sub-tables that can be + * sized and allocated dynamically. + * + * examples : TFace, TInstance, TGlyph & TExecution_Context + * ( defined in 'ttobjs.h' ) + * + * - we make a difference between 'child' pointers and 'peer' + * pointers. A 'child' pointer points to a sub-table that is + * owned by the object, while a 'peer' pointer points to any + * other kind of data the object isn't responsible for. + * + * An object class is thus usually a 'tree' of 'child' tables. + * + * - each object class needs a constructor and a destructor. + * + * A constructor is a function which receives the address of + * freshly allocated and zeroed object root structure and + * 'builds' all the valid child data that must be associated + * to the object before it becomes 'valid'. + * + * A destructor does the inverse job : given the address of + * a valid object, it must discards all its child data and + * zero its main fields (essentially the pointers and array + * sizes found in the root fields). + * + * + * + * + * + * + * + * + * + * + * + * + ******************************************************************) + +unit TTCache; + +interface + +uses TTError, TTTypes; + +type + + (* Simple list node record. A List element is said to be 'unlinked' *) + (* when it doesn't belong to any list *) + (* *) + PList_Element = ^TList_Element; + TList_Element = record + + next : PList_Element; (* Pointer to next element of list *) + data : Pointer; (* Pointer to the listed object *) + end; + + + (* Simple singly-linked list record *) + (* LIFO - style, no tail field *) + TSingle_List = PList_Element; + + + TConstructor = function( _object : Pointer; + _parent : Pointer ) : TError; + + TDestructor = function( _object : Pointer ) : TError; + + PCache_Class = ^TCache_Class; + TCache_Class = record + Object_Size : Int; + Idle_Limit : Int; + Init : TConstructor; + Done : TDestructor; + end; + (* A Cache class record holds the data necessary to define *) + (* a cache kind. *) + + PCache = ^TCache; + TCache = record + clazz : PCache_Class; (* 'class' reserved in VP & Delphi *) + active : TSingle_List; + idle : TSingle_List; + idle_count : Int; + end; + + (* An object cache holds two lists tracking the active and *) + (* idle objects that are currently created and used by the *) + (* engine. It can also be 'protected' by a mutex *) + + function Cache_Create( var clazz : TCache_Class; + var cache : TCache ) : TError; + (* Initialize a new cache named 'cache', of class 'clazz', and *) + (* protected by the 'lock' mutex. Note that the mutex is ignored *) + (* as the pascal version isn't thread-safe *) + + function Cache_Destroy( var cache : TCache ) : TError; + (* Destroys a cache and all its listed objects *) + + function Cache_New( var cache : TCache; + var new_object : Pointer; + parent_data : Pointer ) : TError; + (* Extracts a new object from the cache. *) + + function Cache_Done( var cache : TCache; obj : Pointer ) : TError; + (* returns an object to the cache, or discards it depending *) + (* on the cache class' "idle_limit" field *) + + (********************************************************) + (* *) + (* Two functions used to manage list elements *) + (* *) + (* Note that they're thread-safe in multi-threaded *) + (* builds. *) + (* *) + + function Element_New : PList_Element; + (* Returns a new list element, either fresh or recycled *) + (* Note : the returned element is unlinked *) + + procedure Element_Done( element : PList_Element ); + (* Recycles or discards an element. *) + (* Note : The element must be unlinked !! *) + + + + + function TTCache_Init : TError; + + function TTCache_Done : TError; + + +implementation + +uses TTMemory; + +const + Null_Single_List = nil; + +var + Free_Elements : PList_Element; + +(******************************************************************* + * + * Function : Element_New + * + * Description : Gets a new ( either fresh or recycled ) list + * element. The element is unlisted. + * + * Notes : returns nil if out of memory + * + *****************************************************************) + + function Element_New : PList_Element; + var + element : PList_Element; + begin + (* LOCK *) + + if Free_Elements <> nil then + begin + element := Free_Elements; + Free_Elements := element^.next; + end + else + begin + Alloc( element, sizeof(TList_Element) ); + (* by convention, an allocated block is always zeroed *) + (* the fields of element need not be set to NULL then *) + end; + + (* UNLOCK *) + + Element_New := element; + end; + +(******************************************************************* + * + * Function : Element_Done + * + * Description : recycles an unlisted list element + * + * Notes : Doesn't check that the element is unlisted + * + *****************************************************************) + + procedure Element_Done( element : PList_Element ); + begin + (* LOCK *) + + element^.next := Free_Elements; + Free_Elements := element; + + (* UNLOCK *) + end; + + +(******************************************************************* + * + * Function : Cache_Create + * + * Description : Create a new cache object + * + *****************************************************************) + function Cache_Create( var clazz : TCache_Class; + var cache : TCache ) : TError; + begin + cache.clazz := @clazz; + cache.idle_count := 0; + cache.active := Null_Single_List; + cache.idle := Null_Single_List; + + Cache_Create := Success; + end; + + +(******************************************************************* + * + * Function : Cache_Destroy + * + * Description : Destroy a given cache object + * + *****************************************************************) + function Cache_Destroy( var cache : TCache ) : TError; + var + destroy : TDestructor; + current : PList_Element; + next : PList_Element; + begin + (* now destroy all active and idle listed objects *) + + destroy := cache.clazz^.done; + + (* active list *) + current := cache.active; + while current <> nil do + begin + next := current^.next; + destroy( current^.data ); + Free( current^.data ); + Element_Done( current ); + current := next; + end; + cache.active := Null_SIngle_List; + + (* idle list *) + current := cache.idle; + while current <> nil do + begin + next := current^.next; + destroy( current^.data ); + Free( current^.data ); + Element_Done( current ); + current := next; + end; + cache.idle := Null_Single_List; + + cache.clazz := nil; + cache.idle_count := 0; + + Cache_Destroy := Success; + end; + + +(******************************************************************* + * + * Function : Cache_New + * + * Description : Extracts one 'new' object from a cache + * + * Notes : The 'parent_data' pointer is passed to the object's + * initialiser when the new object is created from + * scratch. Recycled objects do not use this pointer + * + *****************************************************************) + function Cache_New( var cache : TCache; + var new_object : Pointer; + parent_data : Pointer ) : TError; + var + error : TError; + current : PList_Element; + obj : Pointer; + label + Fail; + begin + (* LOCK *) + current := cache.idle; + if current <> nil then + begin + cache.idle := current^.next; + dec( cache.idle_count ) + end; + (* UNLOCK *) + + if current = nil then + begin + (* if no object was found in the cache, create a new one *) + if Alloc( obj, cache.clazz^.object_size ) then exit; + + current := Element_New; + if current = nil then goto Fail; + + current^.data := obj; + + error := cache.clazz^.init( obj, parent_data ); + if error then goto Fail; + end; + + (* LOCK *) + current^.next := cache.active; + cache.active := current; + (* UNLOCK *) + + new_object := current^.data; + + Cache_New := Success; + exit; + + Fail: + Free( obj ); + Cache_New := Failure; + end; + +(******************************************************************* + * + * Function : Cache_Done + * + * Description : Discards an object intro a cache + * + *****************************************************************) + + function Cache_Done( var cache : TCache; obj : Pointer ) : TError; + var + error : TError; + element : PList_Element; + parent : ^PList_Element; + label + Suite; + begin + Cache_Done := failure; + + (* find element in list *) + (* LOCK *) + parent := @cache.active; + element := parent^; + while element <> nil do + begin + if element^.data = obj then + begin + parent^ := element^.next; + (* UNLOCK *) + goto Suite; + end; + parent := @element^.next; + element := parent^; + end; + (* UNLOCK *) + + (* Element wasn't found !! *) + {$IFDEF DEBUG} + {$ENDIF} + exit; + + Suite: + if ( cache.idle_count >= cache.clazz^.idle_limit ) then + begin + (* destroy the object when the cache is full *) + cache.clazz^.done( element^.data ); + Free( element^.data ); + Element_Done( element ); + end + else + begin + (* simply add the object to the idle list *) + (* LOCK *) + element^.next := cache.idle; + cache.idle := element; + inc( cache.idle_count ); + (* UNLOCK *) + end; + + Cache_Done := Success; + end; + + + function TTCache_Init : TError; + begin + Free_Elements := nil; + TTCache_Init := Success; + end; + + + function TTCache_Done : TError; + var + current, next : PList_ELement; + begin + current := free_elements; + while current <> nil do + begin + next := current^.next; + Free( current ); + current := next; + end; + TTCache_Done := success; + end; + +end. diff --git a/pascal/lib/ttcalc.pas b/pascal/lib/ttcalc.pas new file mode 100644 index 0000000..2d08741 --- /dev/null +++ b/pascal/lib/ttcalc.pas @@ -0,0 +1,289 @@ +(******************************************************************* + * + * TTCalc.Pas 1.2 + * + * Arithmetic and Vectorial Computations (specification) + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +unit TTCalc; + +interface + +{$I TTCONFIG.INC} + +type + (* IntN types : *) + (* *) + (* These types are used as a way to garantee the size of some *) + (* specific integers. *) + (* *) + (* Of course, they are equivalent to Short, UShort, Long, etc .. *) + (* but parts of this unit could be used by different programs. *) + (* *) + + (* Define the 16-bit type *) +{$IFDEF BORLANDPASCAL} + Int16 = Integer; + Word16 = Word; (* 16-bits unsigned *) +{$ELSE} +{$IFDEF DELPHI16} + Int16 = Integer; + Word16 = Word; (* 16-bits unsigned *) +{$ELSE} +{$IFDEF DELPHI32} + Int16 = SmallInt; + Word16 = Word; (* 16-bits unsigned *) +{$ELSE} + Int16 = SmallInt; + Word16 = SmallWord; (* 16-bits unsigned *) +{$ENDIF} +{$ENDIF} +{$ENDIF} + + Int32 = LongInt; (* 32 bits integer *) + + Word32 = LongInt; (* 32 bits 'unsigned'. Note that there's *) + (* no unsigned long in Pascal.. *) + (* As cardinals are only 31 bits !! *) + + Int64 = record (* 64 "" *) + Lo, + Hi : LongInt; + end; + +function MulDiv( A, B, C : Int32 ): Int32; + +function MulDiv_Round( A, B, C : Int32 ): Int32; + +procedure Add64( var X, Y, Z : Int64 ); +procedure Sub64( var X, Y, Z : Int64 ); + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; + +function Order64( var Z : Int64 ) : integer; +function Order32( Z : Int32 ) : integer; + +function Sqrt32( L : Int32 ): LongInt; +function Sqrt64( L : Int64 ): LongInt; + +{$IFDEF TEST} + procedure Neg64( var x : Int64 ); + procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); +{$ENDIF} + +implementation + +(* add support for Virtual Pascal inline assembly *) +{$IFDEF VIRTUALPASCAL} +{$I TTCALC2.INC} +{$ENDIF} + +(* add support for Delphi 2 and 3 inline assembly *) +{$IFDEF DELPHI32} +{$I TTCALC3.INC} +{$ENDIF} + +(* add support for Borland Pascal and Turbo Pascal inline assembly *) +{$IFDEF BORLANDPASCAL} +{$I TTCALC1.INC} +{$ENDIF} + +(* Delphi 16 uses the same inline assembly than Borland Pascal *) +{$IFDEF DELPHI16} +{$I TTCALC1.INC} +{$ENDIF} + +(* add support for Free Pascal inline assembly *) +{$IFDEF FPK} +{$I TTCALC4.INC} +{$ENDIF} + + (*****************************************************************) + (* *) + (* MulDiv : computes A*B/C with an intermediate 64 bits *) + (* precision. *) + (* *) + (*****************************************************************) + + function MulDiv( a, b, c : Int32 ) : Int32; + var + s : Int32; + temp : Int64; + begin + s := a; a := abs(a); + s := s xor b; b := abs(b); + s := s xor c; c := abs(c); + + MulTo64( a, b, temp ); + c := Div64by32( temp, c ); + + if s < 0 then c := -c; + + MulDiv := c; + end; + + (*****************************************************************) + (* *) + (* MulDiv : computes A*B/C with an intermediate 64 bits *) + (* _Round precision and rounding. *) + (* *) + (*****************************************************************) + + function MulDiv_Round( a, b, c : Int32 ) : Int32; + var + s : Int32; + + temp, temp2 : Int64; + begin + s := a; a := abs(a); + s := s xor b; b := abs(b); + s := s xor c; c := abs(c); + + MulTo64( a, b, temp ); + + temp2.hi := 0; + temp2.lo := c div 2; + + Add64( temp, temp2, temp ); + + c := Div64by32( temp, c ); + + if s < 0 then c := -c; + + MulDiv_Round := c; + end; + + +(**********************************************************) +(* Negation *) + + procedure Neg64( var x : Int64 ); + begin + (* Remember that -(0x80000000) == 0x80000000 with 2-complement! *) + (* We take care of that here. *) + + x.hi := x.hi xor $FFFFFFFF; + x.lo := x.lo xor $FFFFFFFF; + inc( x.lo ); + + if x.lo = 0 then + begin + inc( x.hi ); + if x.hi = $80000000 then (* check -MaxInt32-1 *) + begin + dec( x.lo ); (* we return $7FFFFFFF *) + dec( x.hi ); + end; + end; + end; + + +(**********************************************************) +(* MSB index ( return -1 for 0 ) *) + +function Order64( var Z : Int64 ) : integer; +begin + if Z.Hi <> 0 then Order64 := 32 + Order32( Z.Hi ) + else Order64 := Order32( Z.Lo ); +end; + + +(**********************************************************) +(* MSB index ( return -1 for 0 ) *) + +function Order32( Z : Int32 ) : integer; +var b : integer; +begin + b := 0; + while Z <> 0 do begin Z := Z shr 1; inc( b ); end; + Order32 := b-1; +end; + + +const + Roots : array[0..62] of LongInt + = ( + 1, 1, 2, 3, 4, 5, 8, 11, + 16, 22, 32, 45, 64, 90, 128, 181, + 256, 362, 512, 724, 1024, 1448, 2048, 2896, + 4096, 5892, 8192, 11585, 16384, 23170, 32768, 46340, + + 65536, 92681, 131072, 185363, 262144, 370727, + 524288, 741455, 1048576, 1482910, 2097152, 2965820, + 4194304, 5931641, 8388608, 11863283, 16777216, 23726566, + + 33554432, 47453132, 67108864, 94906265, + 134217728, 189812531, 268435456, 379625062, + 536870912, 759250125, 1073741824, 1518500250, + 2147483647 + ); + + +(**************************************************) +(* Integer Square Root *) + +function Sqrt32( L : Int32 ): LongInt; +var + R, S : LongInt; +begin + if L<=0 then Sqrt32:=0 else + if L=1 then Sqrt32:=1 else + begin + R:=Roots[ Order32(L) ]; + + Repeat + S:=R; + R:=( R+ L div R ) shr 1; + until ( R <= S ) and ( R*R <= L ); + + Sqrt32:=R; + end; +end; + + +(**************************************************) +(* Integer Square Root *) + +function Sqrt64( L : Int64 ): LongInt; +var + L2 : Int64; + R, S : LongInt; +begin + if L.Hi < 0 then Sqrt64:=0 else + begin + S := Order64(L); + if S = 0 then Sqrt64:=1 else + begin + R := Roots[S]; + + Repeat + + S := R; + R := ( R+Div64by32(L,R) ) shr 1; + + if ( R > S ) then continue; + + MulTo64( R, R, L2 ); + Sub64 ( L, L2, L2 ); + + until ( L2.Hi >= 0 ); + + Sqrt64 := R; + end + end +end; + +end. diff --git a/pascal/lib/ttcalc1.inc b/pascal/lib/ttcalc1.inc new file mode 100644 index 0000000..4354f24 --- /dev/null +++ b/pascal/lib/ttcalc1.inc @@ -0,0 +1,124 @@ +(******************************************************************* + * + * TTCalc1.Inc 1.3 + * + * Arithmetic and Vectorial Computations (inline assembly) + * This version is used for 16-bit Turbo-Borland Pascal 6.0 & 7.0 + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +(**********************************************************) +(* *) +(* The following routines are inline assembly, they are *) +(* thus processor and bitness specific. Replace them *) +(* with your own if you want to port the TrueType Engine *) + +(* We need unsigned longints to perform correctly our additions *) +(* we include inline assembly to get them, baaahhh .. *) + +{**********************************************************} +{* 64 Bit Addition *} + +procedure Add64( var X, Y, Z : Int64 ); assembler; +asm + les si,[X] + + mov ax,es:[ si ].word + mov dx,es:[si+2].word + mov bx,es:[si+4].word + mov cx,es:[si+6].word + + les si,[Y] + add ax,es:[ si ].word + adc dx,es:[si+2].word + adc bx,es:[si+4].word + adc cx,es:[si+6].word + + les si,[Z] + mov es:[ si ].word,ax + mov es:[si+2].word,dx + mov es:[si+4].word,bx + mov es:[si+6].word,cx +end; + + +{**********************************************************} +{* 64 Bit Substraction *} + +procedure Sub64( var X, Y, Z : Int64 ); assembler; +asm + les si,[X] + + mov ax,es:[ si ].word + mov dx,es:[si+2].word + mov bx,es:[si+4].word + mov cx,es:[si+6].word + + les si,[Y] + sub ax,es:[ si ].word + sbb dx,es:[si+2].word + sbb bx,es:[si+4].word + sbb cx,es:[si+6].word + + les si,[Z] + mov es:[ si ].word,ax + mov es:[si+2].word,dx + mov es:[si+4].word,bx + mov es:[si+6].word,cx +end; + + +{**********************************************************} +{* Multiply two Int32 to an Int64 *} + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); assembler; +asm + les si,[Z] + db $66; mov ax,[X].word + db $66; imul [Y].word + db $66; mov es:[si],ax + db $66; mov es:[si+4],dx +end; + + +{**********************************************************} +{* Divide an Int64 by an Int32 *} + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; assembler; +asm + les si,[X] + + db $66; mov ax,es:[si] + db $66; mov dx,es:[si+4] + db $66; idiv [Y].word + + db $66; mov dx, ax + db $66; sar dx, 16 +end; + + +procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); assembler; +asm + les si,[X] + + db $66; mov ax,es:[si] + db $66; mov dx,es:[si+4] + db $66; idiv [Y].word + + les si, [Q] + db $66; mov es:[si], ax + + les si, [R] + db $66; mov es:[si], dx +end; + diff --git a/pascal/lib/ttcalc2.inc b/pascal/lib/ttcalc2.inc new file mode 100644 index 0000000..341c0e8 --- /dev/null +++ b/pascal/lib/ttcalc2.inc @@ -0,0 +1,107 @@ +(******************************************************************* + * + * TTCalc2.Inc 1.2 + * + * Arithmetic and Vectorial Computations (inline assembly) + * This version is used for the OS/2 Virtual Pascal compiler + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +(**********************************************************) +(* *) +(* The following routines are inline assembly, they are *) +(* thus processor and bitness specific. Replace them *) +(* with your own if you want to port the TrueType Engine *) + +(* We need unsigned longints to perform correctly our additions *) +(* we include inline assembly to get them, baaahhh .. *) + +(**********************************************************) +(* 64 Bit Addition *) + +procedure Add64( var X, Y, Z : Int64 ); assembler; +{&USES ebx, edx} +asm + mov ebx,[X].dword + mov eax,[ebx] + mov edx,[ebx+4] + + mov ebx,[Y].dword + add eax,[ebx] + adc edx,[ebx+4] + + mov ebx,[Z].dword + mov [ebx],eax + mov [ebx+4],edx +end; + + +(**********************************************************) +(* 64 Bit Substraction *) + +procedure Sub64( var X, Y, Z : Int64 ); assembler; +{&USES ebx, edx} +asm + mov ebx,[X].dword + mov eax,[ebx] + mov edx,[ebx+4] + + mov ebx,[Y].dword + sub eax,[ebx] + sbb edx,[ebx+4] + + mov ebx,[Z].dword + mov [ebx],eax + mov [ebx+4],edx +end; + + +(**********************************************************) +(* Multiply two Int32 to an Int64 *) + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); assembler; +{&USES ebx, edx } +asm + mov ebx,[Z].dword + mov eax,[X] + imul dword ptr [Y] + mov [ebx],eax + mov [ebx+4],edx +end; + + +(**********************************************************) +(* Divide an Int64 by an Int32 *) + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; assembler; +{&USES ebx, edx} +asm + mov ebx, [X].dword + mov eax, [ebx] + mov edx, [ebx+4] + idiv dword ptr [Y] +end; + +procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); + assembler; {&USES ebx, edx} +asm + mov ebx, [X].dword + mov eax, [ebx] + mov edx, [ebx+4] + idiv dword ptr [Y] + mov ebx, [Q].dword + mov [ebx], eax + mov ebx, [R].dword + mov [ebx], edx +end; + diff --git a/pascal/lib/ttcalc3.inc b/pascal/lib/ttcalc3.inc new file mode 100644 index 0000000..63a19a4 --- /dev/null +++ b/pascal/lib/ttcalc3.inc @@ -0,0 +1,99 @@ +(******************************************************************* + * + * TTCalc3.Inc 1.2 + * + * Arithmetic and Vectorial Computations (inline assembly) + * This version is used for Delphi 2 + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +(**********************************************************) +(* *) +(* The following routines are inline assembly, they are *) +(* thus processor and bitness specific. Replace them *) +(* with your own if you want to port the TrueType Engine *) + +(* NOTE : Delphi seems to use the eax, edx then ecx registers to pass *) +(* the first three parameters *) + +(**********************************************************) +(* 64 Bit Addition *) + +procedure Add64( var X, Y, Z : Int64 ); assembler; +asm + push ebx + push esi + mov ebx, [ eax ] + mov esi, [eax+4] + add ebx, [ edx ] + adc esi, [edx+4] + mov [ ecx ], ebx + mov [ecx+4], esi + pop esi + pop ebx +end; + + +(**********************************************************) +(* 64 Bit Substraction *) + +procedure Sub64( var X, Y, Z : Int64 ); assembler; +asm + push ebx + push esi + mov ebx, [ eax ] + mov esi, [eax+4] + sub ebx, [ edx ] + sbb esi, [edx+4] + mov [ ecx ], ebx + mov [ecx+4], esi + pop esi + pop ebx +end; + + +(**********************************************************) +(* Multiply two Int32 to an Int64 *) + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); assembler; +asm + imul edx + mov [ ecx ],eax + mov [ecx+4],edx +end; + +(**********************************************************) +(* Divide an Int64 by an Int32 *) + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; assembler; +asm + mov ecx, edx + mov edx, [eax+4].dword + mov eax, [ eax ].dword + idiv ecx +end; + +procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); + assembler; +asm + push ebx + mov ebx, edx + mov edx, [eax+4].dword + mov eax, [ eax ].dword + idiv ebx + mov [ecx], eax + mov ebx, R + mov [ebx], edx + pop ebx +end; + diff --git a/pascal/lib/ttcalc4.inc b/pascal/lib/ttcalc4.inc new file mode 100644 index 0000000..7bd0822 --- /dev/null +++ b/pascal/lib/ttcalc4.inc @@ -0,0 +1,134 @@ +(******************************************************************* + * + * TTCalc4.Inc 1.2 + * + * Arithmetic and Vectorial Computations (inline assembly) + * This version is used for i386 FreePascal + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : All vector operations were moved to the interpreter + * + ******************************************************************) + +(**********************************************************) +(* *) +(* The following routines are inline assembly, they are *) +(* thus processor and bitness specific. Replace them *) +(* with your own if you want to port the TrueType Engine *) + +(**********************************************************) +(* 64 Bit Addition *) + +procedure Add64( var X, Y, Z : Int64 ); assembler; +asm + push %ebx + push %edx + + mov X,%ebx + mov (%ebx) ,%eax + mov 4(%ebx) ,%edx + + mov Y,%ebx + add (%ebx) ,%eax + adc 4(%ebx) ,%edx + + mov Z,%ebx + mov %eax, (%ebx) + mov %edx, 4(%ebx) + + pop %edx + pop %ebx +end; + + +(**********************************************************) +(* 64 Bit Substraction *) + +procedure Sub64( var X, Y, Z : Int64 ); assembler; +asm + push %ebx + push %edx + + mov X,%ebx + mov (%ebx) ,%eax + mov 4(%ebx) ,%edx + + mov Y,%ebx + sub (%ebx) ,%eax + sbb 4(%ebx) ,%edx + + mov Z,%ebx + mov %eax, (%ebx) + mov %edx, 4(%ebx) + + pop %edx + pop %ebx +end; + + +(**********************************************************) +(* Multiply two Int32 to an Int64 *) + +procedure MulTo64( X, Y : Int32; var Z : Int64 ); assembler; +asm + push %ebx + push %edx + + mov X,%eax + imull Y + + mov Z,%ebx + mov %eax, (%ebx) + mov %edx, 4(%ebx) + + pop %edx + pop %ebx +end; + + +(**********************************************************) +(* Divide an Int64 by an Int32 *) + +function Div64by32( var X : Int64; Y : Int32 ) : Int32; assembler; +asm + push %ebx + push %edx + + mov X,%ebx + mov (%ebx) ,%eax + mov 4(%ebx) ,%edx + idivl Y + + pop %edx + pop %ebx +end; + + +procedure DivMod64by32( var X : Int64; Y : Int32; var Q, R : Int32 ); + assembler; +asm + push %ebx + push %edx + + mov X,%ebx + mov (%ebx) ,%eax + mov 4(%ebx) ,%edx + idivl Y + + mov Q, %ebx + mov %eax, (%ebx) + + mov R, %ebx + mov %edx, (%ebx) + + pop %edx + pop %ebx +end; + diff --git a/pascal/lib/ttcmap.pas b/pascal/lib/ttcmap.pas new file mode 100644 index 0000000..8794cff --- /dev/null +++ b/pascal/lib/ttcmap.pas @@ -0,0 +1,431 @@ +(******************************************************************* + * + * ttcmap.pas 1.0 + * + * Character Mappings unit. + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +unit TTCMap; + +interface + +uses FreeType, TTTypes; + +type + (********************************************************************) + (* *) + (* CHARACTER MAPPINGS SUBTABLES *) + (* *) + (********************************************************************) + + (* FORMAT 0 *) + + (* Apple standard character to glyph index mapping table *) + (* the glyphIdArray for this format has 256 entries *) + + TCMap0 = record + glyphIdArray : PUShort; + end; + + (* FORMAT 2 *) + + (* the format 2 table contains a variable-length array of subHeaders *) + (* (at most 256 entries) whose size must be determined algorithmically *) + TCMap2SubHeader = record + firstCode : UShort; (* first valid low byte *) + entryCount : UShort; (* number of valid low bytes *) + idDelta : Short; (* delta value to glyphIndex *) + idRangeOffset : UShort; (* offset fr. here to 1stCode *) + end; + + TCMap2SubHeaders = array[0..100] of TCMap2SubHeader; + PCMap2SubHeaders = ^TCMap2SubHeaders; + + (* Format 2 is used for mixed 8/16bit encodings (usually CJK fonts) *) + TCMap2 = record + subHeaderKeys : PUShort; + (* high byte mapping table *) + (* value = subHeader index * 8 *) + subHeaders : PCMap2SubHeaders; + glyphIdArray : PUShort; + numGlyphId : Int; + end; + + (* FORMAT 4 *) + + (*The format 4 table contains segCount segments *) + TCMap4Segment = record + endCount : UShort; + startCount : UShort; + idDelta : UShort; + idRangeOffset : UShort; + end; + TCMap4Segments = array[0..100] of TCMap4Segment; + PCMap4Segments = ^TCMap4Segments; + + (* Microsoft standard character to glyph index mapping table *) + TCMap4 = record + segCountX2 : UShort; (* segments number * 2 *) + searchRange : UShort; (* these parameters can be used *) + entrySelector : UShort; (* for a binary search *) + rangeShift : UShort; + segments : PCMap4Segments; + glyphIdArray : PUShort; + numGlyphId : Int; + end; + + (* FORMAT 6 *) + + (* trimmed table mapping (for representing one subrange) *) + TCMap6 = record + firstCode : UShort; (* first character code of subrange *) + entryCount : UShort; (* num. of character codes in subrange *) + + glyphIdArray : PUShort; + end; + + (* CHARMAP TABLE *) + + PCMapTable = ^TCMapTable; + TCMapTable = record + platformID : UShort; + platformEncodingID : UShort; + + Format : word; + Length : word; + Version : word; + Loaded : Boolean; + Offset : Long; + + case Byte of + 0 : ( cmap0 : TCMap0 ); + 2 : ( cmap2 : TCMap2 ); + 4 : ( cmap4 : TCMap4 ); + 6 : ( cmap6 : TCMap6 ); + end; + + TCMapTables = array[0..9] of TCMapTable; + PCMapTables = ^TCMapTables; + + + function CharMap_Load( var cmap : TCMapTable ) : TError; + + procedure CharMap_Free( var cmap : TCMapTable ); + + function CharMap_Index( var cmap : TCMapTable; charCode : Long ) : UShort; + +implementation + +uses + TTError, TTMemory, TTFile; + + function CharMap_Load( var cmap : TCMapTable ) : TError; + var + num_SH, u : UShort; + i : Int; + numGlyphId : Int; + num_segs : Int; + label + Fail; + begin + CharMap_Load := Failure; + + if cmap.loaded then + begin + CharMap_Load := Success; + exit; + end; + + if TT_Seek_File( cmap.offset ) then exit; + + case cmap.format of + + 0: with cmap.cmap0 do + if Alloc( glyphIdArray, 256 ) or + TT_Read_File( glyphIdArray^, 256 ) then goto Fail; + + 2: begin + num_SH := 0; + with cmap.cmap2 do + begin + if Alloc( subHeaderKeys, 256*sizeof(UShort) ) or + TT_Access_Frame( 512 ) then goto Fail; + + for i := 0 to 255 do + begin + u := GET_UShort shr 3; + subHeaderKeys^[i] := u; + + if num_SH < u then num_SH := u; + end; + + TT_Forget_Frame; + + (* now load sub headers *) + numGlyphId := ((cmap.length - 2*(256+3) - num_SH*8) and $FFFF) + div 2; + + if Alloc( subHeaders, (num_SH+1)*sizeof(TCMap2SubHeader) ) or + TT_Access_Frame( (num_SH+1)*8 ) then goto Fail; + + for i := 0 to num_SH do with subHeaders^[i] do + begin + firstCode := GET_UShort; + entryCount := GET_UShort; + idDelta := GET_UShort; + (* we apply the location offset immediately *) + idRangeOffset := GET_UShort - (num_SH-i)*8 - 2; + end; + + TT_Forget_Frame; + + (* load glyph ids *) + if Alloc( glyphIdArray, numGlyphId*sizeof(UShort) ) or + TT_Access_Frame( numGlyphId*2 ) then goto Fail; + + for i := 0 to numGlyphId-1 do + glyphIdArray^[i] := GET_UShort; + + TT_Forget_Frame; + end; + end; + + 4: with cmap.cmap4 do + begin + if TT_Access_Frame(8) then goto Fail; + + segCountX2 := Get_UShort; + searchRange := Get_UShort; + entrySelector := Get_UShort; + rangeShift := Get_UShort; + + num_segs := segCountX2 shr 1; + + TT_Forget_Frame; + + (* load segments *) + if Alloc( segments, num_segs*sizeof(TCMap4Segment) ) or + TT_Access_Frame( (num_segs*4+1)*2 ) then goto Fail; + + for i := 0 to num_segs-1 do + segments^[i].endCount := Get_UShort; + + Get_UShort; + + for i := 0 to num_segs-1 do + segments^[i].startCount := Get_UShort; + + for i := 0 to num_segs-1 do + segments^[i].idDelta := GET_Short; + + for i := 0 to num_segs-1 do + segments^[i].idRangeOffset := GET_UShort; + + TT_Forget_Frame; + + numGlyphId := (( cmap.length - (16+8*num_segs) ) and $FFFF) + div 2; + + (* load glyph ids *) + if Alloc( glyphIdArray, numGlyphId*sizeof(UShort) ) or + TT_Access_Frame( numGlyphId*2 ) then goto Fail; + + for i := 0 to numGlyphId-1 do + glyphIdArray^[i] := Get_UShort; + + TT_Forget_Frame; + end; + + 6: with cmap.cmap6 do + begin + if TT_Access_Frame(4) then goto Fail; + + firstCode := GET_UShort; + entryCount := GET_UShort; + + TT_Forget_Frame; + + if Alloc( glyphIdArray, entryCount*sizeof(Short) ) or + TT_Access_Frame( entryCount*2 ) then goto Fail; + + for i := 0 to entryCount-1 do + glyphIdArray^[i] := GET_UShort; + + TT_Forget_Frame; + end; + + else + error := TT_Err_Invalid_Charmap_Format; + exit; + end; + + CharMap_Load := success; + exit; + + Fail: + CharMap_Free( cmap ); + end; + + + procedure CharMap_Free( var cmap : TCMapTable ); + begin + with cmap do + case format of + + 0 : begin + Free( cmap.cmap0.glyphIdArray ); + end; + + 2 : begin + Free( cmap.cmap2.glyphIdArray ); + Free( cmap.cmap2.subHeaders ); + Free( cmap.cmap2.glyphIdArray ); + end; + + 4 : begin + Free( cmap.cmap4.segments ); + Free( cmap.cmap4.glyphIdArray ); + cmap.cmap4.segCountX2 := 0; + end; + + 6 : begin + Free( cmap.cmap6.glyphIdArray ); + cmap.cmap6.entryCount := 0; + end; + end; + + cmap.loaded := False; + cmap.format := 0; + cmap.length := 0; + cmap.version := 0; + end; + + + function code_to_index0( charCode : UShort; var cmap0 : TCMap0 ) : UShort; + begin + code_to_index0 := 0; + if charCode < 256 then + code_to_index0 := cmap0.glyphIdArray^[charCode] + end; + + + + function code_to_index2( charCode : UShort; var cmap2 : TCMap2 ) : UShort; + var + index1, idx, offset : UShort; + begin + code_to_index2 := 0; + + if charCode < 256 then idx := charCode + else idx := charCode shr 8; + + index1 := cmap2.subHeaderKeys^[idx]; + + if index1 = 0 then + begin + if charCode < 256 then + code_to_index2 := cmap2.glyphIdArray^[charCode]; (* 8Bit charcode *) + end + else + begin + if charCode < 256 then + exit; + + idx := charCode and 255; + with cmap2.subHeaders^[index1] do + begin + if ( idx < firstCode ) or + ( idx >= firstCode + entryCount ) then exit; + + offset := idRangeOffset div 2 + idx - firstCode; + + if offset >= cmap2.numGlyphId then exit; + + idx := cmap2.glyphIdArray^[offset]; + if idx <> 0 then + code_to_index2 := (idx + idDelta) and $FFFF; + end + end; + end; + + + + function code_to_index4( charCode : UShort; var cmap4 : TCMap4 ) : UShort; + var + i, index1, num_segs : Int; + label + Found; + begin + code_to_index4 := 0; + num_segs := cmap4.segCountX2 div 2; + i := 0; + + while ( i < num_segs ) do with cmap4.segments^[i] do + begin + if charCode <= endCount then goto Found; + inc(i); + end; + + exit; + + Found: + with cmap4.segments^[i] do + begin + + if charCode < startCount then + exit; + + if idRangeOffset = 0 then + code_to_index4 := (charCode + idDelta) and $FFFF + else + begin + index1 := idRangeOffset div 2 + (charCode - startCount) - + -(num_segs-i); + + if ( index1 < cmap4.numGlyphId ) and + ( cmap4.glyphIdArray^[index1] <> 0 ) then + + code_to_index4 := (cmap4.glyphIdArray^[index1] + idDelta) and $FFFF; + end; + end; + end; + + + function code_to_index6( charCode : UShort; var cmap6 : TCMap6 ) : UShort; + begin + code_to_index6 := 0; + with cmap6 do + begin + + if ( charCode < firstCode ) or + ( charCode >= firstCode + entryCount ) then exit; + + code_to_index6 := glyphIdArray^[charCode-firstCode]; + end + end; + + + function CharMap_Index( var cmap : TCMapTable; + charCode : Long ) : UShort; + begin + CharMap_Index := 0; + + case cmap.format of + 0: CharMap_Index := code_to_index0( charCode, cmap.cmap0 ); + 2: CharMap_Index := code_to_index2( charCode, cmap.cmap2 ); + 4: CharMap_Index := code_to_index4( charCode, cmap.cmap4 ); + 6: CharMap_Index := code_to_index6( charCode, cmap.cmap6 ); + end; + end; + +end. diff --git a/pascal/lib/ttconfig.inc b/pascal/lib/ttconfig.inc new file mode 100644 index 0000000..3d3677a --- /dev/null +++ b/pascal/lib/ttconfig.inc @@ -0,0 +1,75 @@ +(* *) +(* TTConfig.Inc *) +(* *) +(* This file contains several definition pragmas that are used to *) +(* build several versions of the library. Each constant is commented *) + +(* Define the DEBUG constant if you want the library dumping trace *) +(* information to the standard error output. *) +{ $DEFINE DEBUG} + + +(* Define the ASSERT constant if you want to generate runtime integrity *) +(* checks within the library. Most of the checks will panic and stop the *) +(* the program when failed.. *) +{ $DEFINE ASSERT} + + +(* Define the INLINE constant if you want to use inlining when provided *) +(* by your compiler. Currently, only Virtual Pascal does *) +{$IFDEF VIRTUALPASCAL} +{$DEFINE INLINE} +{$ENDIF} + + +(* Define the USE32 constant on 32-bit systems. Virtual Pascal *) +(* always define it by default. Now set for Delphi 2 and 3 *) +{$IFDEF WIN32} +{$DEFINE USE32} +{$ENDIF} + +(* FreeType doesn't compile on old Pascal compilers that do not allow *) +(* inline assembly like Turbo Pascal 5.5 and below *) +{$IFDEF VER50} +ERROR : FreeType cannot be compiled with something older than Turbo Pascal 6.0 +{$ENDIF} +{$IFDEF VER55} +ERROR : FreeType cannot be compiled with something older than Turbo Pascal 6.0 +{$ENDIF} + +(* Define the BORLANDPASCAL constant whenever you're using a DOS-based *) +(* version of Turbo or Borland Pascal. *) +{$IFDEF VER60} +{$DEFINE BORLANDPASCAL} +{$ENDIF} +{$IFDEF VER70} +{$DEFINE BORLANDPASCAL} +{$ENDIF} + +(* Define DELPHI16 when compiled in the 16_bit version of Delphi *) +{$IFDEF VER80} +{$DEFINE DELPHI16} +{$ENDIF} + +(* Define DELPHI32 when compiled in any 32-bit version of Delphi *) +{$IFDEF VER90} (* for Delphi 2 *) +{$DEFINE DELPHI32} +{$ENDIF} +{$IFDEF VER100} (* for Delphi 3 *) +{$DEFINE DELPHI32} +{$ENDIF} +{$IFDEF VER110} (* for Borland C++ Builder 3 *) +{$DEFINE DELPHI32} +{$ENDIF} +{$IFDEF VER120} (* for Delphi 4 *) +{$DEFINE DELPHI32} +{$ENDIF} +{$IFDEF VER125} (* for Borland C++ Builder 4 *) +{$DEFINE DELPHI32} +{$ENDIF} + +(* I don't have Delphi 5, I hope this will work *) +{$IFDEF VER130} +{$DEFINE DELPHI32} +{$ENDIF} + diff --git a/pascal/lib/ttdebug.pas b/pascal/lib/ttdebug.pas new file mode 100644 index 0000000..61e42c8 --- /dev/null +++ b/pascal/lib/ttdebug.pas @@ -0,0 +1,851 @@ +(******************************************************************* + * + * TTDebug.Pas 1.2 + * + * This unit is only used by the debugger. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +unit TTDebug; + +interface + +uses TTTypes, TTTables, TTObjs, TTInterp; + +type + + ByteHexStr = string[2]; (* hex representation of a byte *) + ShortHexStr = string[4]; (* " " " short *) + LongHexStr = string[8]; (* " " " long *) + DebugStr = string[128]; (* disassembled line output *) + + { TBreakPoint } + + { A simple record to hold breakpoint information } + { it may be completed later with pass count, etc.. } + { They must be in a sorted linked list } + + PBreakPoint = ^TBreakPoint; + TBreakPoint = record + Next : PBreakPoint; + Range : Int; + Address : Int; + end; + + { TRangeRec } + + { a record to store line number information and breakpoints list } + + PRangeRec = ^TRangeRec; + TRangeRec = record + Code : PByte; + Size : Int; + index : Int; + NLines : Int; + Disassembled : PUShort; + Breaks : PBreakPoint; + end; + + +{ Generate_Range : Generate Line Number information specific to } +{ a given range } + +procedure Generate_Range( CR : PCodeRange; + index : Int; + var RR : TRangeRec ); + +{ Throw_Range : Discard Line Number Information } + +procedure Throw_Range( var RR : TRangeRec ); + +{ Toggle_Break : Toggle a breakpoint } + +procedure Toggle_Break( var Head : PBreakPoint; Range, Adr : Int ); + +{ Set_Break : Set a breakpoint on a given address } + +procedure Set_Break ( var Head : PBreakPoint; Range, Adr : Int ); + +{ Clear_Break : Clear one specific breakpoint } + +procedure Clear_Break( var Head : PBreakPoint; Bp : PBreakPoint ); + +{ Clear_All_Breaks : Clear breakpoint list } + +procedure Clear_All_Breaks( var Head : PBreakPoint ); + +{ Find_Breakpoint : find one breakpoint at a given address } + +function Find_BreakPoint( Head : PBreakPoint; Range, IP : Int ) : PBreakPoint; + +{ Cur_U_Line : returns the current disassembled line at Code(IP) } + +function Cur_U_Line( Code : PByte; IP : Int ) : DebugStr; + +{ Get_Length : returns the length of the current opcode at Code(IP) } + +function Get_Length( Code : PByte; IP : Int ) : Int; + +function Get_Dis_Line( var cr : TRangeRec; addr : Int ) : Int; + + +{ Hex_N : returns an hexadecimal string } + +function Hex8 ( B : Byte ) : ByteHexStr; +function Hex16( W : word ) : ShortHexStr; +function Hex32( L : Long ) : LongHexStr; + + +implementation + +type + PStorageLong = ^TStorageLong; + TStorageLong = record (* do-it-all union record type *) + case Byte of + 0 : ( L : LongInt ); + 1 : ( S1, S2 : Integer ); + 2 : ( W1, W2 : Word ); + 3 : ( B1, B2, + B3, B4 : Byte ); + 4 : ( P : Pointer ); + end; + +var + OpSize : int; + +const + OpStr : array[ 0..255 ] of String[10] + = ( + 'SVTCA y', (* Set vectors to coordinate axis y *) + 'SVTCA x', (* Set vectors to coordinate axis x *) + 'SPvTCA y', (* Set Proj. vec. to coord. axis y *) + 'SPvTCA x', (* Set Proj. vec. to coord. axis x *) + 'SFvTCA y', (* Set Free. vec. to coord. axis y *) + 'SFvTCA x', (* Set Free. vec. to coord. axis x *) + 'SPvTL //', (* Set Proj. vec. parallel to segment *) + 'SPvTL +', (* Set Proj. vec. normal to segment *) + 'SFvTL //', (* Set Free. vec. parallel to segment *) + 'SFvTL +', (* Set Free. vec. normal to segment *) + 'SPvFS', (* Set Proj. vec. from stack *) + 'SFvFS', (* Set Free. vec. from stack *) + 'GPV', (* Get projection vector *) + 'GFV', (* Get freedom vector *) + 'SFvTPv', (* Set free. vec. to proj. vec. *) + 'ISECT', (* compute intersection *) + + 'SRP0', (* Set reference point 0 *) + 'SRP1', (* Set reference point 1 *) + 'SRP2', (* Set reference point 2 *) + 'SZP0', (* Set Zone Pointer 0 *) + 'SZP1', (* Set Zone Pointer 1 *) + 'SZP2', (* Set Zone Pointer 2 *) + 'SZPS', (* Set all zone pointers *) + 'SLOOP', (* Set loop counter *) + 'RTG', (* Round to Grid *) + 'RTHG', (* Round to Half-Grid *) + 'SMD', (* Set Minimum Distance *) + 'ELSE', (* Else *) + 'JMPR', (* Jump Relative *) + 'SCvTCi', (* Set CVT *) + 'SSwCi', (* *) + 'SSW', (* *) + + 'DUP', + 'POP', + 'CLEAR', + 'SWAP', + 'DEPTH', + 'CINDEX', + 'MINDEX', + 'AlignPTS', + 'INS_$28', + 'UTP', + 'LOOPCALL', + 'CALL', + 'FDEF', + 'ENDF', + 'MDAP[-]', + 'MDAP[r]', + + 'IUP[y]', + 'IUP[x]', + 'SHP[0]', + 'SHP[1]', + 'SHC[0]', + 'SHC[1]', + 'SHZ[0]', + 'SHZ[1]', + 'SHPIX', + 'IP', + 'MSIRP[0]', + 'MSIRP[1]', + 'AlignRP', + 'RTDG', + 'MIAP[-]', + 'MIAP[r]', + + 'NPushB', + 'NPushW', + 'WS', + 'RS', + 'WCvtP', + 'RCvt', + 'GC[0]', + 'GC[1]', + 'SCFS', + 'MD[0]', + 'MD[1]', + 'MPPEM', + 'MPS', + 'FlipON', + 'FlipOFF', + 'DEBUG', + + 'LT', + 'LTEQ', + 'GT', + 'GTEQ', + 'EQ', + 'NEQ', + 'ODD', + 'EVEN', + 'IF', + 'EIF', + 'AND', + 'OR', + 'NOT', + 'DeltaP1', + 'SDB', + 'SDS', + + 'ADD', + 'SUB', + 'DIV', + 'MUL', + 'ABS', + 'NEG', + 'FLOOR', + 'CEILING', + 'ROUND[G]', + 'ROUND[B]', + 'ROUND[W]', + 'ROUND[?]', + 'NROUND[G]', + 'NROUND[B]', + 'NROUND[W]', + 'NROUND[?]', + + 'WCvtF', + 'DeltaP2', + 'DeltaP3', + 'DeltaC1', + 'DeltaC2', + 'DeltaC3', + 'SROUND', + 'S45Round', + 'JROT', + 'JROF', + 'ROFF', + 'INS_$7B', + 'RUTG', + 'RDTG', + 'SANGW', + 'AA', + + 'FlipPT', + 'FlipRgON', + 'FlipRgOFF', + 'INS_$83', + 'INS_$84', + 'ScanCTRL', + 'SDPVTL[0]', + 'SDPVTL[1]', + 'GetINFO', + 'IDEF', + 'ROLL', + 'MAX', + 'MIN', + 'ScanTYPE', + 'IntCTRL', + 'INS_$8F', + + 'INS_$90', + 'INS_$91', + 'INS_$92', + 'INS_$93', + 'INS_$94', + 'INS_$95', + 'INS_$96', + 'INS_$97', + 'INS_$98', + 'INS_$99', + 'INS_$9A', + 'INS_$9B', + 'INS_$9C', + 'INS_$9D', + 'INS_$9E', + 'INS_$9F', + + 'INS_$A0', + 'INS_$A1', + 'INS_$A2', + 'INS_$A3', + 'INS_$A4', + 'INS_$A5', + 'INS_$A6', + 'INS_$A7', + 'INS_$A8', + 'INS_$A9', + 'INS_$AA', + 'INS_$AB', + 'INS_$AC', + 'INS_$AD', + 'INS_$AE', + 'INS_$AF', + + 'PushB[0]', + 'PushB[1]', + 'PushB[2]', + 'PushB[3]', + 'PushB[4]', + 'PushB[5]', + 'PushB[6]', + 'PushB[7]', + 'PushW[0]', + 'PushW[1]', + 'PushW[2]', + 'PushW[3]', + 'PushW[4]', + 'PushW[5]', + 'PushW[6]', + 'PushW[7]', + + 'MDRP[G]', + 'MDRP[B]', + 'MDRP[W]', + 'MDRP[?]', + 'MDRP[rG]', + 'MDRP[rB]', + 'MDRP[rW]', + 'MDRP[r?]', + 'MDRP[mG]', + 'MDRP[mB]', + 'MDRP[mW]', + 'MDRP[m?]', + 'MDRP[mrG]', + 'MDRP[mrB]', + 'MDRP[mrW]', + 'MDRP[mr?]', + 'MDRP[pG]', + 'MDRP[pB]', + + 'MDRP[pW]', + 'MDRP[p?]', + 'MDRP[prG]', + 'MDRP[prB]', + 'MDRP[prW]', + 'MDRP[pr?]', + 'MDRP[pmG]', + 'MDRP[pmB]', + 'MDRP[pmW]', + 'MDRP[pm?]', + 'MDRP[pmrG]', + 'MDRP[pmrB]', + 'MDRP[pmrW]', + 'MDRP[pmr?]', + + 'MIRP[G]', + 'MIRP[B]', + 'MIRP[W]', + 'MIRP[?]', + 'MIRP[rG]', + 'MIRP[rB]', + 'MIRP[rW]', + 'MIRP[r?]', + 'MIRP[mG]', + 'MIRP[mB]', + 'MIRP[mW]', + 'MIRP[m?]', + 'MIRP[mrG]', + 'MIRP[mrB]', + 'MIRP[mrW]', + 'MIRP[mr?]', + 'MIRP[pG]', + 'MIRP[pB]', + + 'MIRP[pW]', + 'MIRP[p?]', + 'MIRP[prG]', + 'MIRP[prB]', + 'MIRP[prW]', + 'MIRP[pr?]', + 'MIRP[pmG]', + 'MIRP[pmB]', + 'MIRP[pmW]', + 'MIRP[pm?]', + 'MIRP[pmrG]', + 'MIRP[pmrB]', + 'MIRP[pmrW]', + 'MIRP[pmr?]' + ); + +const + HexStr : string[16] = '0123456789abcdef'; + +(******************************************************************* + * + * Function : Hex8 + * + * Description : Returns the string hexadecimal representation + * of a Byte. + * + * Input : B byte + * + * Output : two-chars string + * + *****************************************************************) + +function Hex8( B : Byte ) : ByteHexStr; +var + S : ByteHexStr; +begin + S[0] :=#2; + S[1] := HexStr[ 1+( B shr 4 ) ]; + S[2] := HexStr[ 1+( B and 15 )]; + Hex8 := S; +end; + +(******************************************************************* + * + * Function : Hex16 + * + * Description : Returns the string hexadecimal representation + * of a Short. + * + * Input : W word + * + * Output : four-chars string + * + *****************************************************************) + +function Hex16( W : word ) : ShortHexStr; +begin + Hex16 := Hex8( Hi(w) )+Hex8( Lo(w) ); +end; + +(******************************************************************* + * + * Function : Hex32 + * + * Description : Returns the string hexadecimal representation + * of a Long. + * + * Input : L Long + * + * Output : eight-chars string + * + *****************************************************************) + +function Hex32( L : Long ) : LongHexStr; +begin + Hex32 := Hex16( TStorageLong(L).W2 )+Hex16( TStorageLong(L).W1 ); +end; + +(******************************************************************* + * + * Function : Cur_U_Line + * + * Description : Returns a string of the current unassembled + * line at Code^[IP]. + * + * Input : Code base code range + * IP current instruction pointer + * + * Output : line string + * + *****************************************************************) + +function Cur_U_Line( Code : PByte; IP : Int ) : DebugStr; +var + Op : Byte; + N, I : Int; + S : DebugStr; +begin + + Op := Code^[IP]; + S := Hex16(IP)+': '+Hex8(Op)+' '+OpStr[Op]; + + case Op of + + $40 : begin + n := Code^[IP+1]; + S := S+'('+Hex8(n)+')'; + for i := 1 to n do + S := S+' $'+Hex8( Code^[Ip+i+1] ); + end; + + $41 : begin + n := Code^[IP+1]; + S := S+'('+Hex8(n)+')'; + for i := 1 to n do + S := S+' $'+Hex8( Code^[Ip+i*2+1] )+Hex8( Code^[Ip+i*2+2] ); + end; + + $B0..$B7 : begin + n := Op-$B0; + for i := 0 to N do + S := S+' $'+Hex8( Code^[Ip+i+1] ); + end; + + $B8..$BF : begin + n := Op-$B8; + for i := 0 to N do + S := S+' $'+Hex8( Code^[IP+i*2+1] )+Hex8( Code^[Ip+i*2+2] ); + end; + + end; + + Cur_U_Line := S; +end; + +(******************************************************************* + * + * Function : Get_Length + * + * Description : Returns the length in bytes of the instruction at + * current instruction pointer. + * + * Input : Code base code range + * IP current instruction pointer + * + * Output : Length in bytes + * + *****************************************************************) + +function Get_Length( Code : PByte; IP : Int ) : Int; +var + Op : Byte; + N : Int; +begin + + Op := Code^[IP]; + + case Op of + + $40 : N := 2 + Code^[IP+1]; + $41 : N := 2 + Code^[IP+1]*2; + + $B0..$B7 : N := 2 + ( Op-$B0 ); + $B8..$BF : N := 3 + ( Op-$B8 )*2 + + else + N := 1; + end; + + Get_Length := N; + +end; + +(******************************************************************* + * + * Function : Generate_Range + * + * Description : Create a list of unassembled lines for a + * given code range + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Generate_Range( CR : PCodeRange; + index : Int; + var RR : TRangeRec ); +var + Adr, Line, N : Int; + Code : PByte; +begin + + N := CR^.Size; + + RR.Code := PByte( CR^.Base ); + RR.Size := N; + + Line := 0; + + if N > 0 then + begin + Adr := 0; + GetMem( RR.Disassembled, sizeof(Short) * N ); + + while Adr < N do + begin + RR.Disassembled^[Line] := Adr; + inc( Line ); + inc( Adr, Get_Length( RR.Code, Adr )); + end; + end; + + RR.NLines := Line; + RR.Index := index; + RR.Breaks := nil; +end; + +(******************************************************************* + * + * Function : Get_Dis_Line + * + * Description : Returns the line index of address 'addr' + * in the coderange 'cr' + * + *****************************************************************) + + function Get_Dis_Line( var cr : TRangeRec; addr : Int ) : Int; + var + l, r, m : Int; + begin + if (cr.NLines = 0) or + (addr > cr.Disassembled^[cr.Nlines-1] ) then + begin + Get_Dis_Line := -1; + exit; + end; + + l := 0; + r := cr.NLines-1; + + while ( r-l > 1 ) do + begin + if cr.Disassembled^[l] = addr then + begin + Get_Dis_Line := l; + exit; + end; + + if cr.Disassembled^[r] = addr then + begin + Get_Dis_Line := r; + exit; + end; + + m := (l+r) shr 1; + if cr.Disassembled^[m] = addr then + begin + Get_Dis_Line := m; + exit; + end + else + if cr.Disassembled^[m] < addr then + l := m + else + r := m; + end; + + if cr.Disassembled^[r] = addr then + begin + Get_Dis_Line := r; + exit; + end; + + Get_Dis_Line := l; + + end; + +(******************************************************************* + * + * Function : Throw_Range + * + * Description : Destroys a list of unassembled lines for a + * given code range + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Throw_Range( var RR : TRangeRec ); +var + B, Bnext : PBreakPoint; +begin + + if RR.Size > 0 then + FreeMem( RR.Disassembled, RR.Size * sizeof(Short) ); + + RR.Disassembled := nil; + RR.Size := 0; + RR.Code := nil; + RR.NLines := 0; + + B := RR.Breaks; + RR.Breaks := nil; + + while B<>nil do + begin + Bnext := B^.Next; + Dispose( B ); + B := Bnext; + end; +end; + +(******************************************************************* + * + * Function : Set_Break + * + * Description : Sets a Breakpoint ON + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Set_Break( var Head : PBreakPoint; + Range : Int; + Adr : Int ); +var + BP, + Old, + Cur : PBreakPoint; +begin + Old := nil; + Cur := Head; + + while (Cur <> nil) and (Cur^.Address < Adr) do + begin + Old := Cur; + Cur := Cur^.Next; + end; + + { No duplicates } + if Cur <> nil then + if (Cur^.Address = Adr) and (Cur^.Range = Range) then exit; + + New( BP ); + BP^.Address := Adr; + BP^.Range := Range; + BP^.Next := Cur; + + if Old = nil then + Head := BP + else + Old^.Next := BP; +end; + +(******************************************************************* + * + * Function : Clear_Break + * + * Description : Clears a breakpoint OFF + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Clear_Break( var Head : PBreakPoint; Bp : PBreakPoint ); +var + Old, + Cur : PBreakPoint; +begin + Old := nil; + Cur := Head; + + while (Cur <> nil) and (Cur <> Bp) do + begin + Old := Cur; + Cur := Cur^.Next; + end; + + if Cur = nil then exit; + + if Old = nil then + Head := Cur^.Next + else + Old^.Next := Cur^.Next; +end; + + + +procedure Toggle_Break( var Head : PBreakPoint; Range, Adr : Int ); +var + Bp : PBreakPoint; +begin + Bp := Find_BreakPoint( Head, Range, Adr ); + if Bp <> nil then Clear_Break( Head, Bp ) + else Set_Break( Head, Range, Adr ); +end; + +(******************************************************************* + * + * Function : Clear_All_Breaks + * + * Description : Clears all breakpoints + * + * Input : + * + * Output : + * + *****************************************************************) + +procedure Clear_All_Breaks( var Head : PBreakPoint ); +var + Old, + Cur : PBreakPoint; +begin + Cur := Head; + Head := Nil; + + while Cur <> nil do + begin + Old := Cur; + Cur := Cur^.Next; + Dispose( Old ); + end; +end; + +(******************************************************************* + * + * Function : Find_BreakPoint + * + * Description : Find a breakpoint at address IP + * + * Input : Head break points sorted linked list + * IP address of expected breakpoint + * + * Output : pointer to breakpoint if found + * nil otherwise. + * + *****************************************************************) + +function Find_BreakPoint( Head : PBreakPoint; Range, IP : Int ) : PBreakPoint; +var + Cur : PBreakPoint; + Res : PBreakPoint; +begin + Cur := Head; + Res := nil; + + while Cur <> nil do + begin + if (Cur^.Address = IP ) and + (Cur^.Range = Range) then Res := Cur; + + if (Cur^.Address >= IP) then Cur := nil + else Cur := Cur^.Next; + end; + + Find_BreakPoint := Res; +end; + +end. diff --git a/pascal/lib/tterror.pas b/pascal/lib/tterror.pas new file mode 100644 index 0000000..6d58fb2 --- /dev/null +++ b/pascal/lib/tterror.pas @@ -0,0 +1,69 @@ +(******************************************************************* + * + * tterror.pas 1.0 + * + * Simple Error management unit + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +unit TTError; + +interface + +uses FreeType; + + procedure Check_Error( error : Integer ); + + procedure Panic1( message : String ); + procedure Trace1( message : String ); + +(* The Pascal version of the library doesn't support multiple *) +(* threads. We use a global error variable, called simply "error" *) +(* to report all defects. The various functions return an error *) +(* condition, which can be either Success (false) or Failure (true) *) + +(* Note that the use of macros in the C version to automate error *) +(* reporting makes the two source trees very similar, even if they *) +(* differ from some design points like this one *) + +var + error : integer; + +implementation + + + procedure Panic1( message : String ); + begin + writeln( message ); + halt(1); + end; + + + procedure Trace1( message : String ); + begin + writeln( message ); + end; + + + procedure Check_Error( error : Integer ); + var + num : String[4]; + begin + if error <> TT_Err_Ok then + begin + str( -error:3, num ); + Panic1( 'Error code = ' + num ); + end; + end; + +end. + diff --git a/pascal/lib/ttfile.pas b/pascal/lib/ttfile.pas new file mode 100644 index 0000000..9a4478a --- /dev/null +++ b/pascal/lib/ttfile.pas @@ -0,0 +1,979 @@ +(******************************************************************* + * + * TTFile.Pas 1.2 + * + * File I/O Component (specification) + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : + * + * + * Changes from 1.1 to 1.2 : + * + * - Changes the stream operations semantics. See changes.txt + * + * - stream records are now allocated on demand in the heap + * + * - introduced the 'frame cache' to avoid Allocating/Freeing + * each frame, even tiny ones.. + * + * - support for thread-safety and re-entrancy + * + * ( re-entrancy is there for information only.. ) + * + * Changes from 1.0 to 1.1 : + * + * - defined the type TT_Stream for file handles + * - renamed ( and cleaned ) the API. + * + * - caching and memory-mapped files use the same API : + * + * TT_Access_Frame to notify + * + * - only the interface was really rewritten. This component still + * only supports one opened file at a time. + * + ******************************************************************) + +Unit TTFile; + +interface + +{$I TTCONFIG.INC} + +uses FreeType, + TTTypes, + TTError; + + function TTFile_Init : TError; + procedure TTFile_Done; + + (*********************************************************************) + (* *) + (* Stream Functions *) + (* *) + (*********************************************************************) + + function TT_Open_Stream( name : String; + var stream : TT_Stream ) : TError; + (* Open a file and return a stream handle for it *) + (* should only be used for a new typeface object's main stream *) + + procedure TT_Close_Stream( var stream : TT_Stream ); + (* closes, then discards a stream, when it becomes unuseful *) + (* should only be used for a typeface object's main stream *) + + function TT_Use_Stream( org_stream : TT_Stream; + var stream : TT_Stream ) : TError; + (* notices the component that we're going to use the file *) + (* opened in 'org_stream', and report errors to the 'error' *) + (* variable. the 'stream' variable is untouched, except in *) + (* re-entrant buids. *) + + (* in re-entrant builds, the original file handle is duplicated *) + (* to a new stream which reference is passed to the 'stream' *) + (* variable.. thus, each thread can have its own file cursor to *) + (* access the same file concurrently.. *) + + procedure TT_Flush_Stream( stream : TT_Stream ); + (* closes a stream's font handle. This is useful to save *) + (* system resources. *) + + procedure TT_Done_Stream( stream : TT_Stream ); + (* notice the file component that we don't need to perform *) + (* file ops on the stream 'stream' anymore.. *) + (* *) + (* in re-entrant builds, should also discard the stream *) + + (*********************************************************************) + (* *) + (* File Functions *) + (* *) + (* the following functions perform file operations on the *) + (* currently 'used' stream. In thread-safe builds, only one *) + (* stream can be used at a time. Synchronisation is performed *) + (* through the Use_Stream/Done_Stream functions *) + (* *) + (* Note: *) + (* re-entrant versions of these functions are only available *) + (* in the C source tree. There, a macro is used to add a 'stream' *) + (* parameter to each of these routines.. *) + (* *) + (*********************************************************************) + + function TT_Read_File( var ABuff; ACount : Int ) : TError; + (* Read a chunk of bytes directly from the file *) + + function TT_Seek_File( APos : LongInt ) : TError; + (* Seek a new file position *) + + function TT_Skip_File( ADist : LongInt ) : TError; + (* Skip to a new file position *) + + function TT_Read_At_File( APos : Long; var ABuff; ACount : Int ) : TError; + (* Seek and read a chunk of bytes *) + + function TT_File_Size : Longint; + + function TT_File_Pos : Longint; + + function TT_Stream_Size( stream : TT_Stream ) : longint; + + (*********************************************************************) + (* *) + (* Frame Functions *) + (* *) + (*********************************************************************) + + function TT_Access_Frame( aSize : Int ) : TError; + (* Access the next aSize bytes *) + + function TT_Check_And_Access_Frame( aSize : Int ) : TError; + (* Access the next min(aSize,file_size-file_pos) bytes *) + + function TT_Forget_Frame : TError; + (* Forget the previously cached frame *) + + (* The four following functions should only be used after a *) + (* TT_Access_Frame and before a TT_Forget_Frame *) + + (* They do not provide error handling, intentionnaly, and are much faster *) + (* moreover, they could be converted to MACROS in the C version *) + + function GET_Byte : Byte; + function GET_Char : ShortInt; + function GET_Short : Short; + function GET_UShort : UShort; + function GET_Long : Long; + function GET_ULong : ULong; + function GET_Tag4 : ULong; + +implementation + +uses + TTMemory; + + (* THREADS: TTMutex, *) + +const + frame_cache_size = 2048; + (* we allocate a single block where we'll place all of our frames *) + (* instead of allocating an new block on each access. Note that *) + (* frames that are bigger than this constant are effectively *) + (* allocated in the heap.. *) + +type + PString = ^string; + PFile = ^FILE; + PError = ^TT_Error; + + PStream_Rec = ^TStream_Rec; + TStream_Rec = record + name : PString; (* file pathname *) + open : Boolean; (* is the stream currently opened *) + font : PFILE; (* file handle for opened stream *) + base : Longint; (* base offset for embedding *) + size : Longint; (* size of font in resource *) + posit : Longint; (* current offset for closed streams *) + end; + +var + (* THREADS: File_Mutex : TMutex *) + + font_file : PFile; + cur_stream : PStream_Rec; + + current_frame : PByte; + frame_cursor : Longint; + frame_size : LongInt; + + dummy_error : TT_Error; + + frame_cache : PByte; + + function TT_File_Size : Longint; + begin + TT_File_Size := FileSize( font_file^ ); + end; + + function TT_File_Pos : Longint; + begin + TT_File_Pos := FilePos( font_file^ ); + end; + + function TT_Stream_Size( stream : TT_Stream ) : longint; + var + rec : PStream_Rec; + begin + rec := PStream_Rec(stream); + if rec = nil then + TT_Stream_Size := 0 + else + TT_Stream_Size := rec^.size; + end; + +(******************************************************************* + * + * Function : TTFile_Init + * + * Description : Init the file component + * + * - create a file mutex for thread-safe builds + * + ******************************************************************) + + function TTFile_Init : TError; + begin + (* empty current file *) + font_file := nil; + cur_stream := nil; + + (* empty frame *) + current_frame := nil; + frame_cursor := 0; + frame_size := 0; + + (* create frame cache *) + GetMem( frame_cache, frame_cache_size ); + + TTFile_Init := Success; + end; + +(******************************************************************* + * + * Function : TTFile_Done + * + * Description : Finalize the file component + * + * - destroys the file mutex for thread-safe builds + * + ******************************************************************) + + procedure TTFile_Done; + begin + (* empty current file *) + font_file := nil; + cur_stream := nil; + + (* empty frame *) + current_frame := nil; + frame_cursor := 0; + frame_size := 0; + end; + +(******************************************************************* + * + * Function : Stream_New + * + * Description : allocates a new stream record + * + * Input : stream : the target stream variable + * + * Output : True on sucess. + * + ******************************************************************) + + function Stream_New( pathname : string; + var stream : PStream_Rec ) : TError; + var + font : PFile; + name : PString; + len : Integer; + label + Fail_Memory; + begin + name := nil; + font := nil; + stream := nil; + len := length(pathname)+1; + + (* allocate a new stream_rec in the heap *) + if Alloc( pointer(stream), sizeof(TStream_Rec) ) or + Alloc( pointer(font), sizeof(FILE) ) or + Alloc( pointer(name), len ) then + goto Fail_Memory; + + move( pathname, name^, len ); + + stream^.font := font; + stream^.name := name; + stream^.open := false; + stream^.base := 0; + stream^.size := 0; + stream^.posit := 0; + + Stream_New := Success; + exit; + + Fail_Memory: + Free( pointer(name) ); + Free( pointer(font) ); + Free( pointer(stream) ); + Stream_New := Failure; + end; + +(******************************************************************* + * + * Function : Stream_Activate + * + * Description : activates a stream, if it needs it + * + * Input : stream : the target stream variable + * + * Output : Error condition + * + ******************************************************************) + + function Stream_Activate( stream : PStream_Rec ) : TError; + var + old_filemode : Long; + begin + Stream_Activate := Failure; + if stream = nil then exit; + + with stream^ do + begin + Stream_Activate := Success; + if open then exit; + + old_filemode := System.FileMode; + System.FileMode := 0; + (* read-only mode *) + + Assign( font^, name^ ); + {$I-} + Reset( font^, 1 ); + {$I+} + + System.FileMode := old_filemode; + + if IOResult <> 0 then + begin + error := TT_Err_Could_Not_Open_File; + Stream_Activate := Failure; + exit; + end; + + open := true; + base := 0; + if size = -1 then size := FileSize(font^); + + if posit <> 0 then + Seek( font^, posit ); + end; + end; + +(******************************************************************* + * + * Function : Stream_Deactivate + * + * Description : closes an active stream + * + * Input : stream : the target stream variable + * + * Output : Error condition + * + ******************************************************************) + + function Stream_Deactivate( stream : PStream_Rec ) : TError; + begin + Stream_Deactivate := Failure; + if stream = nil then exit; + + Stream_Deactivate := Success; + if not stream^.open then exit; + + stream^.posit := FilePos( stream^.font^ ); + close( stream^.font^ ); + stream^.open := false; + end; + +(******************************************************************* + * + * Function : Stream_Done + * + * Description : frees an active stream_rec + * + * Input : stream : the target stream variable + * + * Output : True on sucess. + * + * Notes : 'stream' is set to nil on exit.. + * + ******************************************************************) + + function Stream_Done( var stream : PStream_Rec ) : TError; + begin + Stream_Deactivate( stream ); + + Free( pointer(stream^.name) ); + Free( pointer(stream^.font) ); + Free( pointer(stream) ); + + Stream_Done := Success; + end; + +(******************************************************************* + * + * Function : TT_Open_Stream + * + * Description : opens the font file in a new stream + * + * Input : stream : target stream variable + * name : file pathname + * error : the variable that will be used to + * report stream errors + * + * Output : True on sucess. + * + ******************************************************************) + + function TT_Open_Stream( name : String; + var stream : TT_Stream ) : TError; + var + rec : PStream_Rec; + font : PFile; + + old_filemode : Long; + begin + TT_Open_Stream := Failure; + + if Stream_New( name, rec ) or + Stream_Activate( rec ) then + begin + stream.z := nil; + exit; + end; + + cur_stream := rec; + font_file := rec^.font; + stream := TT_Stream(rec); + + TT_Open_Stream := Success; + end; + +(******************************************************************* + * + * Function : TT_Close_Stream + * + * Description : Closes the font file and releases memory buffer + * + * Input : None + * + * Output : True ( always ) + * + ******************************************************************) + + procedure TT_Close_Stream( var stream : TT_Stream ); + begin + if stream.z = nil then exit; + + Stream_Done( PStream_Rec(stream) ); + font_file := nil; + cur_stream := nil; + stream.z := nil; + end; + +(******************************************************************* + * + * Function : TT_Use_Stream + * + * Description : Acquire the file mutex (blocking call) + * + * Input : org_stream : original stream to use + * stream : duplicate stream (in re-entrant builds) + * set to 'org_stream' otherwise + * error : error report variable + * + * Output : True on success. False on failure + * + ******************************************************************) + + function TT_Use_Stream( org_stream : TT_Stream; + var stream : TT_Stream ) : TError; + var + rec : PStream_Rec; + begin + TT_Use_Stream := Failure; + + stream := org_stream; + if org_stream.z = nil then exit; + + rec := PStream_Rec(stream); + Stream_Activate(rec); + cur_stream := rec; + font_file := rec^.font; + + TT_Use_Stream := Success; + end; + +(******************************************************************* + * + * Function : TT_Flush_Stream + * + * Description : closes a stream + * + * Input : stream : the stream + * + * Output : True on success. False on failure + * + ******************************************************************) + + procedure TT_Flush_Stream( stream : TT_Stream ); + begin + if stream.Z <> nil then + Stream_Deactivate( PStream_Rec(stream.z) ); + end; + +(******************************************************************* + * + * Function : TT_Done_Stream + * + * Description : Release the file mutex on a stream + * + * Input : stream : the stream + * + * Output : True on success. False on failure + * + ******************************************************************) + + procedure TT_Done_Stream( stream : TT_Stream ); + begin + if stream.z <> cur_stream then exit; + cur_stream := nil; + font_file := nil; + end; + +(******************************************************************* + * + * Function : TT_Seek_File + * + * Description : Seek the file cursor to a different position + * + * Input : APos new position on file + * + * Output : True on success. False if out of range + * + * Notes : Does not set the error variable + * + ******************************************************************) + +function TT_Seek_File( APos : LongInt ) : TError; +begin + {$I-} + Seek( Font_File^, APos ); + {$I+} + if IOResult <> 0 then + begin + error := TT_Err_Invalid_File_Offset; + TT_Seek_File := Failure; + exit; + end; + + TT_Seek_File := Success; +end; + +(******************************************************************* + * + * Function : TT_Skip_File + * + * Description : Skip forward the file cursor + * + * Input : ADist number of bytes to skip + * + * Output : see Seek_Font_File + * + ******************************************************************) + +function TT_Skip_File( ADist : LongInt ) : TError; +begin + TT_Skip_File := TT_Seek_File( FilePos(Font_File^)+ADist ); +end; + +(******************************************************************* + * + * Function : TT_Read_File + * + * Description : Reads a chunk of the file and copy it to memory + * + * Input : ABuff target buffer + * ACount length in bytes to read + * + * Output : True if success. False if out of range + * + * Notes : Current version prints an error message even if the + * debug state isn't on. + * + ******************************************************************) + +function TT_Read_File( var ABuff; ACount : Int ) : TError; +begin + TT_Read_File := Failure; + {$I-} + BlockRead( Font_File^, ABuff, ACount ); + {$I+} + + if IOResult <> 0 then + begin + error := TT_Err_Invalid_File_Read; + exit; + end; + + TT_Read_File := Success; +end; + +(******************************************************************* + * + * Function : TT_Read_At_File + * + * Description : Read file at a specified position + * + * Input : APos position to seek to before read + * ABuff target buffer + * ACount number of bytes to read + * + * Output : True on success. False if error. + * + * Notes : prints an error message if seek failed. + * + ******************************************************************) + +function TT_Read_At_File( APos : Long; var ABuff; ACount : Int ) : TError; +begin + TT_Read_At_File := Failure; + + if TT_Seek_File( APos ) or + TT_Read_File( ABuff, ACount ) then exit; + + TT_Read_At_File := Success; +end; + +(******************************************************************* + * + * Function : TT_Access_Frame + * + * Description : Notifies the component that we're going to read + * aSize bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : aSize number of bytes to access. + * + * Output : True on success. False on failure + * + * The function fails is the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly ( which usually means that aSize is + * too big in both cases ). + * + * It will also fail if you make two consecutive calls + * to TT_Access_Frame, without a TT_Forget_Frame between + * them. + * + ******************************************************************) + + function TT_Access_Frame( aSize : Int ) : TError; + var + readBytes : Longint; + begin + TT_Access_Frame := Failure; + + if current_frame <> nil then + begin + error := TT_Err_Nested_Frame_Access; + exit; + end; + (* We already are accessing one frame *) + + if aSize > frame_cache_size then + GetMem( current_frame, aSize ) + else + current_frame := frame_cache; + + if TT_Read_File( current_frame^, aSize ) then + begin + if aSize > frame_cache_size then + FreeMem( current_frame, aSize ); + + current_frame := nil; + exit; + end; + + frame_size := aSize; + frame_cursor := 0; + + TT_Access_Frame := Success; + end; + +(******************************************************************* + * + * Function : TT_Check_And_Access_Frame + * + * Description : Notifies the component that we're going to read + * aSize bytes from the current file position. + * This function should load/cache/map these bytes + * so that they will be addressed by the GET_xxx + * functions easily. + * + * Input : aSize number of bytes to access. + * + * Output : True on success. False on failure + * + * The function fails is the byte range is not within the + * the file, or if there is not enough memory to cache + * the bytes properly ( which usually means that aSize is + * too big in both cases ). + * + * It will also fail if you make two consecutive calls + * to TT_Access_Frame, without a TT_Forget_Frame between + * them. + * + * + * NOTE : The only difference with TT_Access_Frame is that we check + * that the frame is within the current file. We otherwise + * truncate it.. + * + ******************************************************************) + + function TT_Check_And_Access_Frame( aSize : Int ) : TError; + var + readBytes : Longint; + begin + TT_Check_And_Access_Frame := Failure; + + if current_frame <> nil then + begin + error := TT_Err_Nested_Frame_Access; + exit; + end; + (* We already are accessing one frame *) + + readBytes := TT_File_Size - TT_File_Pos; + if aSize > readBytes then aSize := readBytes; + + if aSize > frame_cache_size then + GetMem( current_frame, aSize ) + else + current_frame := frame_cache; + + if TT_Read_File( current_frame^, aSize ) then + begin + if aSize > frame_cache_size then + FreeMem( current_frame, aSize ); + exit; + end; + + frame_size := aSize; + frame_cursor := 0; + + TT_Check_And_Access_Frame := Success; + end; + +(******************************************************************* + * + * Function : TT_Forget_Frame + * + * Description : Releases a cached frame after reading + * + * Input : None + * + * Output : True on success. False on failure + * + ******************************************************************) + + function TT_Forget_Frame : TError; + begin + TT_Forget_Frame := Failure; + + if current_frame = nil then exit; + + if frame_size > frame_cache_size then + FreeMem( current_frame, frame_size ); + + frame_size := 0; + current_frame := nil; + frame_cursor := 0; + end; + +(******************************************************************* + * + * Function : GET_Byte + * + * Description : Extracts a byte from the current file frame + * + * Input : None + * + * Output : Extracted Byte. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Byte : Byte; + begin + GET_Byte := current_frame^[frame_cursor]; + inc( frame_cursor ); + end; + +(******************************************************************* + * + * Function : GET_Char + * + * Description : Extracts a signed byte from the current file frame + * + * Input : None + * + * Output : Extracted char. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Char : ShortInt; + begin + GET_Char := ShortInt( current_frame^[frame_cursor] ); + inc( frame_cursor ); + end; + +(******************************************************************* + * + * Function : GET_Short + * + * Description : Extracts a short from the current file frame + * + * Input : None + * + * Output : Extracted short. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Short : Short; + begin + GET_Short := (Short(current_frame^[ frame_cursor ]) shl 8) or + Short(current_frame^[frame_cursor+1]); + inc( frame_cursor, 2 ); + end; + +(******************************************************************* + * + * Function : GET_UShort + * + * Description : Extracts an unsigned short from the frame + * + * Input : None + * + * Output : Extracted ushort. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_UShort : UShort; + begin + GET_UShort := (UShort(current_frame^[ frame_cursor ]) shl 8) or + UShort(current_frame^[frame_cursor+1]); + inc( frame_cursor, 2 ); + end; + +(******************************************************************* + * + * Function : GET_Long + * + * Description : Extracts a long from the frame + * + * Input : None + * + * Output : Extracted long. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Long : Long; + begin + GET_Long := (Long(current_frame^[ frame_cursor ]) shl 24) or + (Long(current_frame^[frame_cursor+1]) shl 16) or + (Long(current_frame^[frame_cursor+2]) shl 8 ) or + (Long(current_frame^[frame_cursor+3]) ); + inc( frame_cursor, 4 ); + end; + +(******************************************************************* + * + * Function : GET_ULong + * + * Description : Extracts an unsigned long from the frame + * + * Input : None + * + * Output : Extracted ulong. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_ULong : ULong; + begin + GET_ULong := (ULong(current_frame^[ frame_cursor ]) shl 24) or + (ULong(current_frame^[frame_cursor+1]) shl 16) or + (ULong(current_frame^[frame_cursor+2]) shl 8 ) or + (ULong(current_frame^[frame_cursor+3]) ); + inc( frame_cursor, 4 ); + end; + +(******************************************************************* + * + * Function : GET_Tag4 + * + * Description : Extracts a Tag from the frame + * + * Input : None + * + * Output : Extracted 4 byte Tag. + * + * NOTES : We consider that the programmer is intelligent enough + * not to try to get a byte that is out of the frame. Hence, + * we provide no bounds check here. (A misbehaving client + * could easily page fault using this call). + * + ******************************************************************) + + function GET_Tag4 : ULong; + var + C : array[0..3] of Byte; + begin + move ( current_frame^[frame_cursor], c, 4 ); + inc( frame_cursor, 4 ); + + GET_Tag4 := ULong(C); +end; + +end. diff --git a/pascal/lib/ttgload.pas b/pascal/lib/ttgload.pas new file mode 100644 index 0000000..43c5894 --- /dev/null +++ b/pascal/lib/ttgload.pas @@ -0,0 +1,1391 @@ +(******************************************************************* + * + * ttgload.pas 1.0 + * + * TrueType glyph loader + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +Unit TTGLoad; + +interface + +{$I TTCONFIG.INC} + +uses + FreeType, TTError, TTTypes, TTObjs; + + function Load_TrueType_Glyph( instance : PInstance; + glyph : PGlyph; + glyph_index : Word; + load_flags : Int ) : TError; + (* loads a font glyph into a given glyph info. The instance and *) + (* glyph objects faces _must_ match. The load_flags indicates *) + (* what kind of values should be written to the glyph object *) + (* ( metrics, outline in EM coordinates, grid-fitted outline.. ) *) + (* *) + (* by default ( i.e. with load_flags = 0 ), this function only *) + (* returns the unscaled glyph metrics and points in EM units. *) + (* *) + (* Use the following flags to query scaling and hinting ops. *) + + (********************************************************) + (* return horizontal or vertical metrics in font units *) + (* for a given glyph. The metrics are the left side *) + (* bearing [resp. top side bearing] and advance width *) + (* [resp. advance height]. *) + (* *) + (* This function may move later to another component.. *) + (* *) + procedure TT_Get_Metrics( var header : TT_Horizontal_Header; + index : Int; + var bearing : TT_Pos; + var advance : TT_Pos ); + + function Get_Advance_Widths( face : PFace; + ppem : Int ) : PByte; + +implementation + +uses + TTTables, + TTCalc, + TTMemory, + TTFile, + TTInterp, + TTLoad; + +const + ARGS_ARE_WORDS = $01; + ARGS_ARE_XY_VALUES = $02; + ROUND_XY_TO_GRID = $04; + WE_HAVE_A_SCALE = $08; + (* reserved $10 *) + MORE_COMPONENTS = $20; + WE_HAVE_AN_XY_SCALE = $40; + WE_HAVE_A_2X2 = $80; + WE_HAVE_INSTR = $100; + USE_MY_METRICS = $200; + + + (********************************************************) + (* return horizontal or vertical metrics in font units *) + (* for a given glyph. The metrics are the left side *) + (* bearing [resp. top side bearing] and advance width *) + (* [resp. advance height]. *) + (* *) + (* This function may move later to another component.. *) + (* *) + procedure TT_Get_Metrics( var header : TT_Horizontal_Header; + index : Int; + var bearing : TT_Pos; + var advance : TT_Pos ); + var + k : Int; + longs : PTableLongMetrics; + begin + k := header.number_Of_HMetrics; + + if index < k then + begin + longs := PTableLongMetrics(header.long_metrics); + bearing := longs^[index].bearing; + advance := longs^[index].advance; + end + else + begin + bearing := PTableShortMetrics(header.short_metrics)^[index-k]; + advance := PTableLongMetrics(header.long_metrics)^[k-1].advance; + end; + end; + + + + (********************************************************) + (* return horizontal metrics in font units for a *) + (* given glyph. if "check" is true, take care of *) + (* mono-spaced fonts by returning the aw max. *) + (* *) + procedure Get_HMetrics( face : PFace; + index : Int; + check : Boolean; + var lsb : Int; + var aw : Int ); + var + left_bearing, advance : TT_Pos; + begin + TT_Get_Metrics( face^.horizontalHeader, index, left_bearing, advance ); + + lsb := Int(left_bearing); + aw := Int(advance); + + if check and (face^.postscript.isFixedPitch <> 0) then + aw := face^.horizontalHeader.advance_Width_Max; + end; + + + + (********************************************************) + (* return advance width table for a given pixel size *) + (* if it is found in the font's "hdmx" table (if any) *) + (* *) + function Get_Advance_Widths( face : PFace; + ppem : Int ) : PByte; + var + n : Integer; + begin + with face^.hdmx do + for n := 0 to num_records-1 do + if records^[n].ppem = ppem then + begin + Get_Advance_Widths := records^[n].widths; + exit; + end; + + Get_Advance_Widths := nil; + end; + + (********************************************************) + (* copy current glyph into original one *) + (* *) + procedure cur_to_org( n : int; + pts : PGlyph_Zone ); + var + k : int; + begin + for k := 0 to n-1 do with pts^ do + org^[k] := cur^[k]; + end; + + + (********************************************************) + (* copy original glyph into current one *) + (* *) + procedure org_to_cur( n : int; + pts : PGlyph_Zone ); + var + k : int; + begin + for k := 0 to n-1 do with pts^ do + cur^[k] := org^[k]; + end; + + (********************************************************) + (* translate an array of coordinates *) + (* *) + procedure translate_array( n : int; + coords : TT_Points; + dx, dy : TT_Pos ); + var + k : Int; + begin + if dx <> 0 then + for k := 0 to n-1 do inc( coords^[k].x, dx ); + if dy <> 0 then + for k := 0 to n-1 do inc( coords^[k].y, dy ); + end; + + (********************************************************) + (* mount one zone on top of another one *) + (* *) + procedure mount_zone( var source : TGlyph_Zone; + var target : TGlyph_Zone ); + var + np, nc : Int; + begin + np := source.n_points; + nc := source.n_contours; + + target.org := @source.org^[np]; + target.cur := @source.cur^[np]; + target.flags := @source.flags^[np]; + + target.conEnds := @source.conEnds^[nc]; + + target.n_points := 0; + target.n_contours := 0; + end; + +(******************************************************************* + * + * Function : Load_Simple_Glyph + * + * + ******************************************************************) + + + function Load_Simple_Glyph( exec : PExec_Context; + stream : TT_Stream; + n_contours : Int; + left_contours : Int; + left_points : Int; + load_flags : Int; + subg : PSubGlyph_Record ) : TError; + var + n_points, + n_ins, k : Int; + + c, cnt : Byte; + face : PFace; + coords : TT_Points; + flag : TT_PTouchTable; + x, y : TT_F26dot6; + pts : PGlyph_Zone; + + label + Fail, Fail_File, Fail_Exec; + begin + Load_Simple_Glyph := Failure; + + face := exec^.face; + + (* simple check *) + + if ( n_contours > left_contours ) then + begin + {$IFDEF DEBUG} + Writeln( 'ERROR: Glyph index ',i,' has ',Gl.numberOfContours ); + Writeln( ' contours > left ', left_contours ); + {$ENDIF} + error := TT_Err_Too_Many_Contours; + goto Fail; + end; + + (* preparing the execution context *) + mount_zone( subg^.zone, exec^.pts ); + + (* Reading the contours endpoints *) + + if TT_Access_Frame( (n_contours+1)*2 ) then + goto Fail_File; + + n_points := 0; + + for k := 0 to n_contours-1 do + begin + {$IFDEF DEBUG} Write( n_points,' '); {$ENDIF} + n_points := GET_Short; + exec^.pts.conEnds^[k] := n_points; + inc( n_points ); + end; + + if n_points > left_points then + begin + {$IFDEF DEBUG} Writeln( 'ERROR: Too many points' ); {$ENDIF} + error := TT_Err_Too_Many_Points; + goto Fail; + end; + + (* Loading instructions *) + + n_ins := GET_Short; + + TT_Forget_Frame; + +{ + if not subg^.is_hinted then + + if TT_Skip_File( n_ins ) then + goto Fail_File + else + (* skip the instructions *) + + else } + begin + + {$IFDEF DEBUG} Writeln('Instructions size : ', n_ins); {$ENDIF} + + if n_ins > face^.maxProfile.maxSizeOfInstructions then + begin + {$IFDEF DEBUG} Writeln('Too many instructions'); {$ENDIF} + error := TT_Err_Too_Many_Ins; + goto Fail; + end; + + with exec^ do + begin + if TT_Read_File( glyphIns^, n_ins ) then + goto Fail_File; + + glyphSize := n_ins; + + if Set_CodeRange( exec, + TT_CodeRange_Glyph, + glyphIns, + glyphSize ) then + goto Fail_Exec; + end + end; + + (* read the flags *) + + if TT_Check_And_Access_Frame( n_points*5 ) + then goto Fail; + + k := 0; + flag := exec^.pts.flags; + + while ( k < n_points ) do + begin + c := GET_Byte; + flag^[k] := c; + inc(k); + + if c and 8 <> 0 then + begin + cnt := GET_Byte; + + while ( cnt > 0 ) do + begin + flag^[k] := c; + inc( k ); + dec( cnt ); + end + end + end; + + (* Read the X *) + + x := 0; + coords := exec^.pts.org; + + for k := 0 to n_points-1 do + begin + if flag^[k] and 2 <> 0 then + + if flag^[k] and 16 <> 0 then inc( x, GET_Byte ) + else inc( x, -GET_Byte ) + else + if flag^[k] and 16 = 0 then inc( x, GET_Short ); + + coords^[k].x := x; + end; + + (* Read the Y *) + + y := 0; + + for k := 0 to n_points-1 do + begin + if flag^[k] and 4 <> 0 then + + if flag^[k] and 32 <> 0 then inc( y, GET_Byte ) + else inc( y, -GET_Byte ) + else + if flag^[k] and 32 = 0 then inc( y, GET_Short ); + + coords^[k].y := y; + end; + + TT_Forget_Frame; + + (* Now adds the two shadow points at n and n+1 *) + (* We need the left side bearing and advance width *) + + (* pp1 = xMin - lsb == glyph origin *) + coords^[n_points].x := subg^.bbox.XMin-subg^.leftBearing; + coords^[n_points].y := 0; + + (* pp2 = pp1 + aw == glyph next position *) + coords^[n_points+1].x := subg^.bbox.xMin- + subg^.leftBearing + subg^.advanceWidth; + coords^[n_points+1].y := 0; + + for k := 0 to n_points-1 do + exec^.pts.flags^[k] := exec^.pts.flags^[k] and TT_Flag_On_Curve; + + exec^.pts.flags^[n_points ] := 0; + exec^.pts.flags^[n_points+1] := 0; + + (* Note that we now return two more points, that are not *) + (* part of the glyph outline *) + inc( n_points, 2 ); + + (* now eventually scale and hint the glyph *) + + pts := @exec^.pts; + pts^.n_points := n_points; + + exec^.pts.n_contours := n_contours; + + if load_flags and TT_Load_Scale_Glyph = 0 then + begin + (* no scaling, just copy the org arrays into the cur ones *) + org_to_cur( n_points, pts ); + end + else + begin + + (* first scale the glyph points *) + for k := 0 to n_points-1 do with pts^ do + org^[k].x := Scale_X( exec^.metrics, org^[k].x ); + + for k := 0 to n_points-1 do with pts^ do + org^[k].y := Scale_Y( exec^.metrics, org^[k].y ); + + (* if hinting, round pp1, and shift the glyph accordingly *) + if subg^.is_hinted then + begin + x := pts^.org^[n_points-2].x; + x := ((x+32) and -64) - x; + translate_array( n_points, pts^.org, x, 0 ); + + org_to_cur( n_points, pts ); + + (* set the advance width *) + (* + x := (Scale_X( exec^.metrics, subg^.advanceWidth )+32) and -64; + with pts^ do + cur_x^[n_points-1] := cur_x^[n_points-2]+x; + *) + with pts^ do + cur^[n_points-1].x := (cur^[n_points-1].x+32) and -64; + + (* now consider hinting *) + if (exec^.glyphSize > 0) then + begin + exec^.is_composite := False; + + if Context_Run( exec, load_flags and TT_Load_Debug <> 0 ) then + goto Fail_Exec; + end; + end + else + org_to_cur( n_points, pts ); + end; + + (* save glyph origin and advance points *) + if not subg^.preserve_pps then + begin + subg^.pp1 := pts^.cur^[n_points-2]; + subg^.pp2 := pts^.cur^[n_points-1]; + end; + + Load_Simple_Glyph := Success; + + Fail: + exit; + + Fail_File: + error := TT_Err_File_Error; + exit; + + Fail_Exec: + error := exec^.error; + exit; + end; + +(******************************************************************* + * + * Function : Load_Composite_End + * + * + ******************************************************************) + + function Load_Composite_End( n_points : Int; + n_contours : Int; + exec : PExec_Context; + subg : PSubglyph_Record; + debug : Boolean ) : TError; + var + pts : PGlyph_Zone; + n_ins : Int; + k : Int; + phant1, + phant2, + x, y : TT_Pos; + widths : PByte; + + label + Fail, Fail_File, Fail_Exec; + begin + Load_Composite_End := Failure; + + if subg^.is_hinted and + (subg^.element_flag and WE_HAVE_INSTR <> 0) then + begin + if TT_Access_Frame(2) then goto Fail_File; + n_ins := Get_UShort; + TT_Forget_Frame; + + (* load the instructions *) + {$IFDEF DEBUG} Writeln('Instructions size : ', n_ins); {$ENDIF} + + if n_ins > exec^.face^.maxProfile.maxSizeOfInstructions then + begin + {$IFDEF DEBUG} Writeln('Too many instructions'); {$ENDIF} + error := TT_Err_Too_Many_Ins; + goto Fail; + end; + end + else + n_ins := 0; + + if n_ins > 0 then with exec^ do + begin + if TT_Read_File( glyphIns^, n_ins ) then + goto Fail_File; + + glyphSize := n_ins; + + if Set_CodeRange( exec, + TT_CodeRange_Glyph, + glyphIns, + glyphSize ) then goto Fail_File; + end; + + (* prepare the execution context *) + inc( n_points, 2 ); + + exec^.pts := subg^.zone; + pts := @exec^.pts; + pts^.n_points := n_points; + + (* add phantom points *) + with pts^ do + begin + cur^[n_points-2] := subg^.pp1; + cur^[n_points-1] := subg^.pp2; + flags^[n_points-2] := 0; + flags^[n_points-1] := 0; + end; + + (* if hinting, round the phantom points *) + if subg^.is_hinted then + begin + y := ((subg^.pp1.x+32) and -64); + pts^.cur^[n_points-2].y := y; + + x := ((subg^.pp2.x+32) and -64); + pts^.cur^[n_points-1].x := x; + end; + + for k := 0 to n_points-1 do + pts^.flags^[k] := pts^.flags^[k] and TT_Flag_On_Curve; + + cur_to_org( n_points, pts ); + + (* now consider hinting *) + if subg^.is_hinted and (n_ins > 0) then + begin + exec^.is_composite := true; + + if Context_Run( exec, debug ) then + goto Fail_Exec; + end; + + (* save glyph origin and advance points *) + subg^.pp1 := pts^.cur^[n_points-2]; + subg^.pp2 := pts^.cur^[n_points-1]; + + Load_Composite_End := Success; + error := TT_Err_Ok; + + Fail: + exit; + + Fail_File: + error := TT_Err_File_Error; + goto Fail; + + Fail_Exec: + error := exec^.error; + goto Fail; + + end; + + +(******************************************************************* + * + * Function : Init_Glyph_Component + * + * + ******************************************************************) + + + procedure Init_Glyph_Component( element : PSubGlyph_Record; + original : PSubGlyph_Record; + exec : PExec_Context ); + var + n: Int; + begin + with element^ do + begin + index := -1; + is_scaled := false; + is_hinted := false; + + if original <> nil then + mount_zone( original^.zone, zone ) + else + zone := exec^.pts; + + zone.n_contours := 0; + zone.n_points := 0; + + arg1 := 0; + arg2 := 0; + + element_flag := 0; + preserve_pps := false; + + transform.xx := 1 shl 16; + transform.xy := 0; + transform.yx := 0; + transform.yy := 1 shl 16; + + transform.ox := 0; + transform.oy := 0; + + leftBearing := 0; + advanceWidth := 0; + end; + end; + + + function Load_TrueType_Glyph( instance : PInstance; + glyph : PGlyph; + glyph_index : Word; + load_flags : Int ) : TError; + type + TPhases = ( Load_Exit, + Load_Glyph, + Load_Simple, + Load_Composite, + Load_End ); + (* the composite loader is a simple automata wich states *) + (* are defined by the TPhases enumeration *) + + var + face : PFace; + + num_points : Int; + num_contours : Int; + left_points : Int; + left_contours : Int; + + table, + num_ins, + index, + load_top : Int; + + new_flags, k, l : Int; + + glyph_offset, offset : Long; + + c : Byte; + + vec, nvec : TT_Vector; + + xmin, xmax, ymin, ymax : TT_F26Dot6; + + xx, xy, yx, yy : TT_Fixed; + + exec : PExec_Context; + stream : TT_Stream; + + subglyph, subglyph2 : PSubGlyph_Record; + + base_pts : TGlyph_Zone; + + phase : TPhases; + + debug : Boolean; + + leftSideBearing : TT_Pos; + advanceWidth : TT_Pos; + + top_bearing : TT_Pos; + advance_height : TT_Pos; + + error : TT_Error; + delta : Long; + widths : PByte; + horizontal : TT_Horizontal_Header; + label + Fin, + Fail, + Fail_File, + Fail_Handle, + Fail_Index; + + begin + + Load_TrueType_Glyph := Failure; + + (* check handle *) + + if (instance = nil) or (instance^.owner = nil) then + begin + error := TT_Err_Invalid_Face_Handle; + exit; + end; + + face := instance^.owner; + + table := LookUp_TrueType_Table( face, 'glyf'); + if table < 0 then + begin + {$IFDEF DEBUG} + Trace1( 'TTApi.load_glyph : couldn''t find glyf table' ); + {$ENDIF} + error := TT_Err_Table_Missing; + exit; + end; + + glyph_offset := face^.dirTables^[table].Offset; + + (* query new execution context *) + + if instance^.debug then + exec := instance^.context (* if debugging, use the pre-alloced context *) + else + exec := New_Context(instance); + + if exec = nil then + begin + error := TT_Err_Out_Of_Memory; + exit; + end; + + Context_Load( exec, instance ); + if instance^.GS.instruct_control and 2 <> 0 then + exec^.GS := Default_GraphicsState + else + exec^.GS := instance^.GS; + + glyph^.outline.high_precision := ( instance^.metrics.y_ppem < 24 ); + + glyph^.is_composite := false; + + (* save its critical pointers that will be modified *) + (* during load *) + + base_pts := exec^.pts; + + (* init variables *) + + left_points := face^.maxPoints; + left_contours := face^.maxContours; + + num_points := 0; + num_contours := 0; + + load_top := 0; + subglyph := @exec^.loadStack^[0]; + + Init_Glyph_Component( subglyph, nil, exec ); + + subglyph^.index := glyph_index; + subglyph^.is_hinted := load_flags and TT_Load_Hint_Glyph <> 0; + + if instance^.GS.instruct_control and 1 <> 0 then + subglyph^.is_hinted := False; + + (* now access stream *) + + if TT_Use_Stream( face^.stream, stream ) then + goto Fin; + + (* Main Loading Loop *) + + phase := Load_Glyph; + + while phase <> Load_Exit do + begin + + subglyph := @exec^.loadStack^[load_top]; + + case phase of + + (************************************************************) + (* *) + (* Load_Glyph state *) + (* *) + (* reading a glyph's generic header to determine *) + (* wether it's simple or composite *) + (* *) + (* exit states : Load_Simple and Load_Composite *) + (* *) + + Load_Glyph: + begin + (* check glyph index and table *) + + index := subglyph^.index; + if (index < 0) or (index >= face^.numGlyphs) then + begin + error := TT_Err_Invalid_Glyph_Index; + goto Fail; + end; + + (* load glyph metrics *) + Get_HMetrics( face, index, true, + subglyph^.leftBearing, + subglyph^.advanceWidth ); + + (* load glyph *) + if (index+1 < face^.numLocations) and + (face^.glyphLocations^[index] = face^.glyphLocations^[index+1]) then + begin + + (* as noticed by Frederic Loyer, these are spaces, not *) + (* the 'unknown' glyph *) + num_points := 0; + num_contours := 0; + + subglyph^.bbox.xMin := 0; + subglyph^.bbox.xMax := 0; + subglyph^.bbox.yMin := 0; + subglyph^.bbox.yMax := 0; + + subglyph^.pp1.x := 0; + subglyph^.pp2.x := subglyph^.advanceWidth; + if load_flags and TT_LOAD_Scale_Glyph <> 0 then + subglyph^.pp2.x := Scale_X( exec^.metrics, subglyph^.pp2.x ); + + exec^.glyphSize := 0; + phase := Load_End; + end + else + begin + offset := glyph_offset + face^.glyphLocations^[index]; + + (* read first glyph header *) + + if TT_Seek_File( offset ) or + TT_Access_Frame( 5*sizeof(Short) ) then + goto Fail_File; + + num_contours := GET_Short; + subglyph^.bbox.xMin := GET_Short; + subglyph^.bbox.yMin := GET_Short; + subglyph^.bbox.xMax := GET_Short; + subglyph^.bbox.yMax := GET_Short; + + TT_Forget_Frame; + + {$IFDEF DEBUG} + Writeln('Glyph ', i ); + + Writeln(' # of Contours : ',num_contours ); + Writeln(' xMin : ',subglyph^.xMin:4,' xMax : ',subglyph^.xMax); + Writeln(' yMin : ',subglyph^.yMin:4,' yMax : ',subglyph^.yMax); + Writeln('-'); + {$ENDIF} + + if num_contours > left_contours then + begin + {$IFDEF DEBUG} + Writeln( 'ERROR: Glyph index ', i, ' has ', num_contours ); + Writeln(' contours > left ', left_contours ); + {$ENDIF} + error := TT_Err_Too_Many_Contours; + goto Fail; + end; + + with subglyph^ do + begin + pp1.x := bbox.xMin - leftBearing; + pp1.y := 0; + pp2.x := pp1.x + advanceWidth; + pp2.y := 0; + + if load_flags and TT_Load_Scale_Glyph <> 0 then + begin + pp1.x := Scale_X( exec^.metrics, pp1.x ); + pp2.x := Scale_X( exec^.metrics, pp2.x ); + end; + end; + + (* is it a simple glyph ? *) + if num_contours >= 0 then + phase := Load_Simple + else + phase := Load_Composite; + + end + end; + + (************************************************************) + (* *) + (* Load_Simple state *) + (* *) + (* reading a simple glyph (num_contours must be set to *) + (* the glyph's number of contours..) *) + (* *) + (* exit states : Load_End *) + (* *) + + Load_Simple : + begin + new_flags := load_flags; + + if not subglyph^.is_hinted then + new_flags := new_flags and not TT_Load_Hint_Glyph; + (* disable hinting when scaling *) + + if new_flags and TT_Load_Debug <> 0 then + if load_top > 0 then + new_flags := new_flags and not TT_Load_Debug; + + if Load_Simple_Glyph( + exec, + stream, + num_contours, + left_contours, + left_points, + new_flags, + subglyph ) then + goto Fail; + + num_points := exec^.pts.n_points-2; + + phase := Load_End; + end; + + (************************************************************) + (* *) + (* Load_Composite state *) + (* *) + (* reading a composite glyph header a pushing a new *) + (* load element on the stack.. *) + (* *) + (* exit states : Load_Glyph *) + (* *) + + Load_Composite : + begin + + glyph^.is_composite := true; + + (* create a new element *) + + inc( load_top ); + + if load_top > face^.maxComponents then + begin + error := TT_Err_Invalid_Composite; + goto Fail; + end; + + subglyph2 := @exec^.loadStack^[load_top]; + + Init_Glyph_Component( subglyph2, subglyph, nil ); + + subglyph2^.index := -1; + subglyph2^.is_hinted := subglyph^.is_hinted; + + (* now read composite header *) + + if TT_Access_Frame( 4 ) then + goto Fail_File; + + new_flags := Get_UShort; + + subglyph^.element_flag := new_flags; + subglyph2^.index := Get_UShort; + + TT_Forget_Frame; + + k := 2; + + if new_flags and ARGS_ARE_WORDS <> 0 then + inc( k, 2 ); + + if new_flags and WE_HAVE_A_SCALE <> 0 then + inc( k, 2 ); + + if new_flags and WE_HAVE_AN_XY_SCALE <> 0 then + inc( k, 4 ); + + if new_flags and WE_HAVE_A_2X2 <> 0 then + inc( k, 8 ); + + if TT_Access_Frame( k ) then + goto Fail_File; + + if new_flags and ARGS_ARE_WORDS <> 0 then + begin + k := Get_Short; + l := Get_Short; + end + else + begin + k := Get_Byte; + l := Get_Byte; + end; + + subglyph^.arg1 := k; + subglyph^.arg2 := l; + + if new_flags and ARGS_ARE_XY_VALUES <> 0 then + begin + subglyph^.transform.ox := k; + subglyph^.transform.oy := l; + end; + + xx := 1 shl 16; + xy := 0; + yx := 0; + yy := 1 shl 16; + + if new_flags and WE_HAVE_A_SCALE <> 0 then + begin + xx := Long(Get_Short) shl 2; + yy := xx; + + subglyph2^.is_scaled := true; + end + else if new_flags and WE_HAVE_AN_XY_SCALE <> 0 then + begin + xx := Long(Get_Short) shl 2; + yy := Long(Get_Short) shl 2; + + subglyph2^.is_scaled := true; + end + else if new_flags and WE_HAVE_A_2X2 <> 0 then + begin + xx := Long(Get_Short) shl 2; + xy := Long(Get_Short) shl 2; + yx := Long(Get_Short) shl 2; + yy := Long(Get_Short) shl 2; + + subglyph2^.is_scaled := true; + end; + + subglyph^.transform.xx := xx; + subglyph^.transform.xy := xy; + subglyph^.transform.yx := yx; + subglyph^.transform.yy := yy; + + delta := MulDiv_Round( xx, yy, 1 shl 16 ) - + MulDiv_Round( xy, yx, 1 shl 16 ); + + if abs(delta) <> 1 shl 16 then + subglyph2^.is_hinted := false; + + TT_Forget_Frame; + + subglyph^.file_offset := TT_File_Pos; + + phase := Load_Glyph; + end; + + (************************************************************) + (* *) + (* Load_End state *) + (* *) + (* after loading a glyph, apply transform and offset *) + (* where necessary, pops element and continue or *) + (* stop process.. *) + (* *) + (* exit states : Load_Composite and Load_Exit *) + (* *) + + Load_End : + if load_top > 0 then + begin + + subglyph2 := subglyph; + + dec( load_top ); + subglyph := @exec^.loadStack^[load_top]; + + (* check advance width and left side bearing *) + + if not subglyph^.preserve_pps and + (subglyph^.element_flag and USE_MY_METRICS <> 0) then + begin + + subglyph^.leftBearing := subglyph2^.leftBearing; + subglyph^.advanceWidth := subglyph2^.advanceWidth; + + subglyph^.pp1 := subglyph2^.pp1; + subglyph^.pp2 := subglyph2^.pp2; + + subglyph^.preserve_pps := true; + end; + + (* apply scale/symmetry/rotation/wathever *) + + for k := 0 to num_points-1 do with subglyph^ do + begin + vec := subglyph2^.zone.cur^[k]; + + nvec.x := MulDiv_Round( vec.x, transform.xx, 1 shl 16 ) + + MulDiv_Round( vec.y, transform.yx, 1 shl 16 ); + + nvec.y := MulDiv_Round( vec.x, transform.xy, 1 shl 16 ) + + MulDiv_Round( vec.y, transform.yy, 1 shl 16 ); + + subglyph2^.zone.cur^[k] := nvec; + + vec := subglyph2^.zone.org^[k]; + + nvec.x := MulDiv_Round( vec.x, transform.xx, 1 shl 16 ) + + MulDiv_Round( vec.y, transform.yx, 1 shl 16 ); + + nvec.y := MulDiv_Round( vec.x, transform.xy, 1 shl 16 ) + + MulDiv_Round( vec.y, transform.yy, 1 shl 16 ); + + subglyph2^.zone.org^[k] := nvec; + end; + + (* adjust counts *) + for k := 0 to num_contours-1 do + inc( subglyph2^.zone.conEnds^[k], subglyph^.zone.n_points ); + + inc( subglyph^.zone.n_points, num_points ); + inc( subglyph^.zone.n_contours, num_contours ); + + dec( left_points, num_points ); + dec( left_contours, num_contours ); + + (* apply offset *) + + if subglyph^.element_flag and ARGS_ARE_XY_VALUES = 0 then + begin + k := subglyph^.arg1; + l := subglyph^.arg2; + + if (k < 0) or (k >= subglyph^.zone.n_points ) or + (l < 0) or (l >= num_points) then + begin + error := TT_Err_Invalid_Composite; + goto Fail; + end; + + inc( l, subglyph^.zone.n_points ); + + vec.x := subglyph^.zone.cur^[k].x - + subglyph^.zone.cur^[l].x; + + vec.y := subglyph^.zone.cur^[k].y - + subglyph^.zone.cur^[l].y; + end + else + begin + vec.x := subglyph^.transform.ox; + vec.y := subglyph^.transform.oy; + + if load_flags and TT_Load_Scale_Glyph <> 0 then + begin + vec.x := Scale_X( exec^.metrics, vec.x ); + vec.y := Scale_Y( exec^.metrics, vec.y ); + + if subglyph^.element_flag and ROUND_XY_TO_GRID <> 0 then + begin + vec.x := (vec.x+32) and -64; + vec.y := (vec.y+32) and -64; + end; + end + end; + + translate_array( num_points, subglyph2^.zone.cur, vec.x, vec.y ); + + cur_to_org( num_points, @subglyph2^.zone ); + + num_points := subglyph^.zone.n_points; + num_contours := subglyph^.zone.n_contours; + + (* check for last component *) + + if TT_Seek_File( subglyph^.file_offset ) then + goto Fail_File; + + if subglyph^.element_flag and MORE_COMPONENTS <> 0 then + phase := Load_Composite + else + begin + debug := ( load_top = 0 ) and + ( load_flags and TT_Load_Debug <> 0 ); + + if Load_Composite_End( num_points, + num_contours, + exec, + subglyph, + debug ) then goto Fail; + phase := Load_End; + end; + + end + else + phase := Load_Exit; + + end; + end; + + (* finally, copy the points arrays to the glyph object *) + + exec^.pts := base_pts; + + (* copy also the phantom points, the debugger needs them *) + inc( num_points, 2 ); + + for k := 0 to num_points-1 do with glyph^.outline do + begin + points^[k] := exec^.pts.cur^[k]; + flags ^[k] := exec^.pts.flags^[k]; + end; + + for k := 0 to num_contours-1 do with glyph^.outline do + conEnds^[k] := exec^.pts.conEnds^[k]; + + glyph^.outline.n_points := num_points; + glyph^.outline.n_contours := num_contours; + glyph^.outline.second_pass := true; + + TT_Get_Outline_BBox( glyph^.outline, glyph^.metrics.bbox ); + + glyph^.metrics.horiBearingX := glyph^.metrics.bbox.xMin - subglyph^.pp1.x; + glyph^.metrics.horiBearingY := glyph^.metrics.bbox.yMax; + glyph^.metrics.horiAdvance := subglyph^.pp2.x - subglyph^.pp1.x; + + glyph^.computed_width := glyph^.metrics.horiAdvance; + glyph^.precalc_width := -1; + + (* Now take care of vertical metrics. In the case where there is *) + (* no vertical information within the font (which is relatively *) + (* common), make up some metrics "by hand".. *) + (* *) + + begin + (* get the unscaled "tsb" and "ah" *) + (* don't assume that both the vertical header and metrics are *) + (* present in a font file... *) + if face^.verticalInfo and + ( face^.verticalHeader.number_Of_VMetrics > 0 ) then + begin + (* apparently, the following line isn't accepted by the FreePascal *) + (* compiler. It complains because the typecast occurs on a 'var' *) + (* parameter. Don't know if this is compiler bug or not, but I *) + (* changed the code with some stupid copy trick.. *) + (* *) + (* TT_Get_Metrics( TT_Horizontal_Header(face^.verticalHeader), *) + (* glyph_index, *) + (* top_bearing, *) + (* advance_height ); *) + (* *) + horizontal := TT_Horizontal_Header(face^.verticalHeader); + TT_Get_Metrics( horizontal, + glyph_index, + top_bearing, + advance_height ); + end + else + begin + (* Make up the distances from the horizontal header.. *) + (* *) + (* The typographic values are the only portable ones, which *) + (* is why we use them.. *) + (* *) + (* The sTypoDescender field is always negative, unlike the *) + (* Windows Descender.. *) + (* *) + with face^.os2 do + begin + top_bearing := sTypoLineGap div 2; + advance_height := sTypoAscender - sTypoDescender + sTypoLineGap; + end; + + end; + + (* now scale the metrics *) + if load_flags and TT_Load_Scale_Glyph <> 0 then + begin + top_bearing := Scale_Y( exec^.metrics, top_bearing ); + advance_height := Scale_Y( exec^.metrics, advance_height ); + end; + + with glyph^.metrics do + begin + vertBearingX := ( bbox.xMin - bbox.xMax ) div 2; + vertBearingY := top_bearing; + vertAdvance := advance_height; + + if load_flags and TT_Load_Hint_Glyph <> 0 then + begin + vertBearingX := vertBearingX and -64; + vertBearingY := (vertBearingY + 63) and -64; + vertAdvance := (vertAdvance+32) and -64; + end; + end; + + end; + + (* use hdmx table to adjust advance width as necessary *) + if load_flags and TT_Load_Default = TT_Load_Default then + begin + widths := Get_Advance_Widths( exec^.face, + exec^.instance^.metrics.x_ppem ); + if widths <> nil then + begin + glyph^.metrics.horiAdvance := widths^[glyph_index]*64; + glyph^.precalc_width := glyph^.metrics.horiAdvance; + end; + end; + + (* in case of hinting, shift the glyph so that (0,0) corresponds *) + (* to the glyph origin. *) + if subglyph^.is_hinted then + begin + glyph^.metrics.horiBearingX := (glyph^.metrics.bbox.xMin and -64) - + subglyph^.pp1.x; + + glyph^.metrics.horiAdvance := (glyph^.metrics.horiAdvance+32) and -64; + glyph^.computed_width := (glyph^.computed_width+32) and -64; + + translate_array( num_points, + glyph^.outline.points, + -subglyph^.pp1.x, + 0 ); + end; + + glyph^.outline.dropout_mode := exec^.GS.scan_type; + + Load_TrueType_Glyph := Success; + + Fail: + TT_Done_Stream( stream ); + + Fin: + + (* reset the execution context *) + exec^.pts := base_pts; + + if instance^.debug then + begin + exec^.pts.n_points := num_points; + exec^.pts.n_contours := num_contours; + end + else + Done_Context( exec); + + exit; + + Fail_File: + error := TT_Err_File_Error; + goto Fail; + + Fail_Handle: + error := TT_Err_Invalid_Instance_Handle; + exit; + + Fail_Index: + error := TT_Err_Invalid_Glyph_Index; + exit; + + end; + + +end. diff --git a/pascal/lib/ttinterp.pas b/pascal/lib/ttinterp.pas new file mode 100644 index 0000000..4d82e99 --- /dev/null +++ b/pascal/lib/ttinterp.pas @@ -0,0 +1,4797 @@ +(******************************************************************* + * + * TTInterp.pas 2.0 + * + * TrueType bytecode intepreter. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Changes between 2.0 and 1.2 : + * + * - Lots, lots, of changes : This version is not re-entrant, + * but much faster. + * + * + ******************************************************************) + +unit TTInterp; + +interface + +uses FreeType, + TTTypes, + TTObjs; + + function Run_Ins( exec : PExec_Context ) : Boolean; + (* Run the interpreter with the current code range and IP *) + +implementation +uses + TTError, + TTMemory, + TTCalc; + +type + TInstruction_Function = procedure( args : PStorage ); + +const + Null_Vector : TT_Vector = (x:0;y:0); + +var + exc : TExec_Context; (* static variable *) + +const + + (*********************************************************************) + (* *) + (* Before an opcode is executed, the interpreter verifies that *) + (* there are enough arguments on the stack, with the help of *) + (* the Pop_Push_Count table. *) + (* *) + (* Note that for opcodes with a varying numbre of parameters, *) + (* either 0 or 1 arg is verified before execution, depending *) + (* on the nature of the instruction : *) + (* *) + (* - if the number of arguments is given by the bytecode *) + (* stream or the loop variable, 0 is chosen. *) + (* *) + (* - if the first argument is a count n that is followed *) + (* by arguments a1..an, then 1 is chosen. *) + (* *) + (*********************************************************************) + + Pop_Push_Count : array[0..511] of byte + = ( + (* SVTCA y *) 0, 0, + (* SVTCA x *) 0, 0, + (* SPvTCA y *) 0, 0, + (* SPvTCA x *) 0, 0, + (* SFvTCA y *) 0, 0, + (* SFvTCA x *) 0, 0, + (* SPvTL // *) 2, 0, + (* SPvTL + *) 2, 0, + (* SFvTL // *) 2, 0, + (* SFvTL + *) 2, 0, + (* SPvFS *) 2, 0, + (* SFvFS *) 2, 0, + (* GPV *) 0, 2, + (* GFV *) 0, 2, + (* SFvTPv *) 0, 0, + (* ISECT *) 5, 0, + + (* SRP0 *) 1, 0, + (* SRP1 *) 1, 0, + (* SRP2 *) 1, 0, + (* SZP0 *) 1, 0, + (* SZP1 *) 1, 0, + (* SZP2 *) 1, 0, + (* SZPS *) 1, 0, + (* SLOOP *) 1, 0, + (* RTG *) 0, 0, + (* RTHG *) 0, 0, + (* SMD *) 1, 0, + (* ELSE *) 0, 0, + (* JMPR *) 1, 0, + (* SCvTCi *) 1, 0, + (* SSwCi *) 1, 0, + (* SSW *) 1, 0, + + (* DUP *) 1, 2, + (* POP *) 1, 0, + (* CLEAR *) 0, 0, + (* SWAP *) 2, 2, + (* DEPTH *) 0, 1, + (* CINDEX *) 1, 1, + (* MINDEX *) 1, 0, (* first arg *) + (* AlignPTS *) 2, 0, + (* INS_$28 *) 0, 0, + (* UTP *) 1, 0, + (* LOOPCALL *) 2, 0, + (* CALL *) 1, 0, + (* FDEF *) 1, 0, + (* ENDF *) 0, 0, + (* MDAP[0] *) 1, 0, + (* MDAP[1] *) 1, 0, + + (* IUP[0] *) 0, 0, + (* IUP[1] *) 0, 0, + (* SHP[0] *) 0, 0, (* no args *) + (* SHP[1] *) 0, 0, (* no args *) + (* SHC[0] *) 1, 0, + (* SHC[1] *) 1, 0, + (* SHZ[0] *) 1, 0, + (* SHZ[1] *) 1, 0, + (* SHPIX *) 1, 0, (* first arg *) + (* IP *) 0, 0, (* no args *) + (* MSIRP[0] *) 2, 0, + (* MSIRP[1] *) 2, 0, + (* AlignRP *) 0, 0, (* no args *) + (* RTDG *) 0, 0, + (* MIAP[0] *) 2, 0, + (* MIAP[1] *) 2, 0, + + (* NPushB *) 0, 0, + (* NPushW *) 0, 0, + (* WS *) 2, 0, + (* RS *) 1, 1, + (* WCvtP *) 2, 0, + (* RCvt *) 1, 1, + (* GC[0] *) 1, 1, + (* GC[1] *) 1, 1, + (* SCFS *) 2, 0, + (* MD[0] *) 2, 1, + (* MD[1] *) 2, 1, + (* MPPEM *) 0, 1, + (* MPS *) 0, 1, + (* FlipON *) 0, 0, + (* FlipOFF *) 0, 0, + (* DEBUG *) 1, 0, + + (* LT *) 2, 1, + (* LTEQ *) 2, 1, + (* GT *) 2, 1, + (* GTEQ *) 2, 1, + (* EQ *) 2, 1, + (* NEQ *) 2, 1, + (* ODD *) 1, 1, + (* EVEN *) 1, 1, + (* IF *) 1, 0, + (* EIF *) 0, 0, + (* AND *) 2, 1, + (* OR *) 2, 1, + (* NOT *) 1, 1, + (* DeltaP1 *) 1, 0, (* first arg *) + (* SDB *) 1, 0, + (* SDS *) 1, 0, + + (* ADD *) 2, 1, + (* SUB *) 2, 1, + (* DIV *) 2, 1, + (* MUL *) 2, 1, + (* ABS *) 1, 1, + (* NEG *) 1, 1, + (* FLOOR *) 1, 1, + (* CEILING *) 1, 1, + (* ROUND[0] *) 1, 1, + (* ROUND[1] *) 1, 1, + (* ROUND[2] *) 1, 1, + (* ROUND[3] *) 1, 1, + (* NROUND[0]*) 1, 1, + (* NROUND[1]*) 1, 1, + (* NROUND[2]*) 1, 1, + (* NROUND[3]*) 1, 1, + + (* WCvtF *) 2, 0, + (* DeltaP2 *) 1, 0, (* first arg *) + (* DeltaP3 *) 1, 0, (* first arg *) + (* DeltaCn[0]*) 1, 0, (* first arg *) + (* DeltaCn[1]*) 1, 0, (* first arg *) + (* DeltaCn[2]*) 1, 0, (* first arg *) + (* SROUND *) 1, 0, + (* S45Round *) 1, 0, + (* JROT *) 2, 0, + (* JROF *) 2, 0, + (* ROFF *) 0, 0, + (* INS_$7B *) 0, 0, + (* RUTG *) 0, 0, + (* RDTG *) 0, 0, + (* SANGW *) 1, 0, + (* AA *) 1, 0, + + (* FlipPT *) 0, 0, (* no args *) + (* FlipRgON *) 2, 0, + (* FlipRgOFF*) 2, 0, + (* INS_$83 *) 0, 0, + (* INS_$84 *) 0, 0, + (* ScanCTRL *) 1, 0, + (* SDVPTL[0]*) 2, 0, + (* SDVPTL[1]*) 2, 0, + (* GetINFO *) 1, 1, + (* IDEF *) 1, 0, + (* ROLL *) 3, 3, (* pops 3 args/push 3 args *) + (* MAX *) 2, 1, + (* MIN *) 2, 1, + (* ScanTYPE *) 1, 0, + (* InstCTRL *) 2, 0, + (* INS_$8F *) 0, 0, + + (* INS_$90 *) 0, 0, + (* INS_$91 *) 0, 0, + (* INS_$92 *) 0, 0, + (* INS_$93 *) 0, 0, + (* INS_$94 *) 0, 0, + (* INS_$95 *) 0, 0, + (* INS_$96 *) 0, 0, + (* INS_$97 *) 0, 0, + (* INS_$98 *) 0, 0, + (* INS_$99 *) 0, 0, + (* INS_$9A *) 0, 0, + (* INS_$9B *) 0, 0, + (* INS_$9C *) 0, 0, + (* INS_$9D *) 0, 0, + (* INS_$9E *) 0, 0, + (* INS_$9F *) 0, 0, + + (* INS_$A0 *) 0, 0, + (* INS_$A1 *) 0, 0, + (* INS_$A2 *) 0, 0, + (* INS_$A3 *) 0, 0, + (* INS_$A4 *) 0, 0, + (* INS_$A5 *) 0, 0, + (* INS_$A6 *) 0, 0, + (* INS_$A7 *) 0, 0, + (* INS_$A8 *) 0, 0, + (* INS_$A9 *) 0, 0, + (* INS_$AA *) 0, 0, + (* INS_$AB *) 0, 0, + (* INS_$AC *) 0, 0, + (* INS_$AD *) 0, 0, + (* INS_$AE *) 0, 0, + (* INS_$AF *) 0, 0, + + (* PushB[0] *) 0, 1, + (* PushB[1] *) 0, 2, + (* PushB[2] *) 0, 3, + (* PushB[3] *) 0, 4, + (* PushB[4] *) 0, 5, + (* PushB[5] *) 0, 6, + (* PushB[6] *) 0, 7, + (* PushB[7] *) 0, 8, + (* PushW[0] *) 0, 1, + (* PushW[1] *) 0, 2, + (* PushW[2] *) 0, 3, + (* PushW[3] *) 0, 4, + (* PushW[4] *) 0, 5, + (* PushW[5] *) 0, 6, + (* PushW[6] *) 0, 7, + (* PushW[7] *) 0, 8, + + (* MDRP[00] *) 1, 0, + (* MDRP[01] *) 1, 0, + (* MDRP[02] *) 1, 0, + (* MDRP[03] *) 1, 0, + (* MDRP[04] *) 1, 0, + (* MDRP[05] *) 1, 0, + (* MDRP[06] *) 1, 0, + (* MDRP[07] *) 1, 0, + (* MDRP[08] *) 1, 0, + (* MDRP[09] *) 1, 0, + (* MDRP[10] *) 1, 0, + (* MDRP[11] *) 1, 0, + (* MDRP[12] *) 1, 0, + (* MDRP[13] *) 1, 0, + (* MDRP[14] *) 1, 0, + (* MDRP[15] *) 1, 0, + (* MDRP[16] *) 1, 0, + (* MDRP[17] *) 1, 0, + + (* MDRP[18] *) 1, 0, + (* MDRP[19] *) 1, 0, + (* MDRP[20] *) 1, 0, + (* MDRP[21] *) 1, 0, + (* MDRP[22] *) 1, 0, + (* MDRP[23] *) 1, 0, + (* MDRP[24] *) 1, 0, + (* MDRP[25] *) 1, 0, + (* MDRP[26] *) 1, 0, + (* MDRP[27] *) 1, 0, + (* MDRP[28] *) 1, 0, + (* MDRP[29] *) 1, 0, + (* MDRP[30] *) 1, 0, + (* MDRP[31] *) 1, 0, + + (* MIRP[00] *) 2, 0, + (* MIRP[01] *) 2, 0, + (* MIRP[02] *) 2, 0, + (* MIRP[03] *) 2, 0, + (* MIRP[04] *) 2, 0, + (* MIRP[05] *) 2, 0, + (* MIRP[06] *) 2, 0, + (* MIRP[07] *) 2, 0, + (* MIRP[08] *) 2, 0, + (* MIRP[09] *) 2, 0, + (* MIRP[10] *) 2, 0, + (* MIRP[11] *) 2, 0, + (* MIRP[12] *) 2, 0, + (* MIRP[13] *) 2, 0, + (* MIRP[14] *) 2, 0, + (* MIRP[15] *) 2, 0, + (* MIRP[16] *) 2, 0, + (* MIRP[17] *) 2, 0, + + (* MIRP[18] *) 2, 0, + (* MIRP[19] *) 2, 0, + (* MIRP[20] *) 2, 0, + (* MIRP[21] *) 2, 0, + (* MIRP[22] *) 2, 0, + (* MIRP[23] *) 2, 0, + (* MIRP[24] *) 2, 0, + (* MIRP[25] *) 2, 0, + (* MIRP[26] *) 2, 0, + (* MIRP[27] *) 2, 0, + (* MIRP[28] *) 2, 0, + (* MIRP[29] *) 2, 0, + (* MIRP[30] *) 2, 0, + (* MIRP[31] *) 2, 0 + ); + + +(******************************************************************* + * + * Function : Norm + * + * Description : returns the norm (length) of a vector + * + * Input : X, Y vector + * + * Output : returns length in F26dot6 + * + *****************************************************************) + + function Norm( X, Y : TT_F26dot6 ): TT_F26dot6; + var + T1, T2 : Int64; + begin + MulTo64( X, X, T1 ); + MulTo64( Y, Y, T2 ); + + Add64( T1, T2, T1 ); + + if ( (T1.lo or T1.Hi) = 0 ) then Norm := 0 + else Norm := Sqrt64( T1 ); + end; + +(******************************************************************* + * + * Function : Scale_Pixels + * + * Description : Converts from FUnits to Fractional pixels + * coordinates. + * + *****************************************************************) + + function Scale_Pixels( value : long ) : TT_F26Dot6; + {$IFDEF INLINE} inline; {$ENDIF} + begin + Scale_Pixels := MulDiv_Round( value, + exc.metrics.scale1, + exc.metrics.scale2 ); + end; + + function Get_Current_Ratio : Long; + var + x, y : Long; + begin + if exc.metrics.ratio <> 0 then + Get_Current_Ratio := exc.metrics.ratio + else + begin + if exc.GS.projVector.y = 0 then + exc.metrics.ratio := exc.metrics.x_ratio + + else if exc.GS.projVector.x = 0 then + exc.metrics.ratio := exc.metrics.y_ratio + + else + begin + x := MulDiv_Round( exc.GS.projVector.x, + exc.metrics.x_ratio, + $4000 ); + + y := MulDiv_Round( exc.GS.projVector.y, + exc.metrics.y_ratio, + $4000 ); + + exc.metrics.ratio := Norm( x, y ); + end; + + Get_Current_Ratio := exc.metrics.ratio; + end + end; + + function Get_Ppem : Long; + {$IFDEF INLINE} inline; {$ENDIF} + begin + Get_Ppem := MulDiv_Round( exc.metrics.ppem, Get_Current_Ratio, $10000 ); + end; + + + function Read_CVT( index : Int ) : TT_F26Dot6; + {$IFNDEF FPK} far; {$ENDIF} + begin + Read_CVT := exc.cvt^[index]; + end; + + function Read_CVT_Stretched( index : Int ) : TT_F26Dot6; far; + begin + Read_CVT_Stretched := MulDiv_Round( exc.cvt^[index], + Get_Current_Ratio, + $10000 ); + end; + + + procedure Write_CVT( index : Int; value : TT_F26Dot6 ); far; + begin + exc.cvt^[index] := value; + end; + + procedure Write_CVT_Stretched( index : Int; value : TT_F26Dot6 ); far; + begin + exc.cvt^[index] := MulDiv_Round( value, + $10000, + Get_Current_Ratio ); + end; + + + procedure Move_CVT( index : Int; value : TT_F26Dot6 ); far; + begin + inc( exc.cvt^[index], value ); + end; + + procedure Move_CVT_Stretched( index : Int; value : TT_F26dot6 ); far; + begin + inc( exc.cvt^[index], MulDiv_Round( value, + $10000, + Get_Current_Ratio )); + end; + +(******************************************************************* + * + * Function : Calc_Length + * + * Description : Computes the length in bytes of current opcode + * + *****************************************************************) + + function Calc_Length : boolean; + begin + Calc_Length := false; + + exc.opcode := exc.Code^[exc.IP]; + + case exc.opcode of + + $40 : if exc.IP+1 >= exc.codeSize + then exit + else + exc.length := exc.code^[exc.IP+1] + 2; + + $41 : if exc.IP+1 >= exc.codeSize + then exit + else + exc.length := exc.code^[exc.IP+1]*2 + 2; + + $B0..$B7 : exc.length := exc.opcode-$B0 + 2; + $B8..$BF : exc.length := (exc.opcode-$B8)*2 + 3; + else + exc.length := 1; + end; + + Calc_Length := exc.IP+exc.length <= exc.codeSize; + end; + +(******************************************************************* + * + * Function : Get_Short + * + * Description : Return a short integer taken from the instruction + * stream at address IP. + * + * Input : None + * + * Output : Short read at Code^[IP..IP+1] + * + * Notes : This one could become a Macro in the C version + * + *****************************************************************) + + function GetShort : Short; + var + L : Array[0..1] of Byte; + resultat : Short absolute L; (* XXX : un-portable *) + begin + (* This is little-endian code *) + + L[1] := exc.code^[exc.IP]; inc(exc.IP); + L[0] := exc.code^[exc.IP]; inc(exc.IP); + GetShort := resultat; + end; + + + function Goto_CodeRange( aRange, + aIP : Int ): boolean; + begin + + Goto_CodeRange := False; + + with exc do + begin + if (aRange<1) or (aRange>3) then + begin + exc.error := TT_Err_Bad_Argument; + exit; + end; + + with CodeRangeTable[ARange] do + begin + + if Base = nil then (* invalid coderange *) + begin + error := TT_Err_Invalid_Coderange; + exit; + end; + + (* NOTE : Because the last instruction of a program may be a CALL *) + (* which will return to the first byte *after* the code *) + (* range, we test for AIP <= Size, instead of AIP < Size *) + + if AIP > Size then + begin + error := TT_Err_Code_Overflow; + Goto_CodeRange := False; + exit; + end; + + Code := PByte(Base); + CodeSize := Size; + IP := AIP; + end; + + curRange := ARange; + end; + + Goto_CodeRange := True; + end; + + +(******************************************************************* + * + * Function : Direct_Move + * + * Description : Moves a point by a given distance along the + * freedom vector. + * + * Input : Vx, Vy point coordinates to move + * touch touch flag to modify + * distance + * + * Output : None + * + *****************************************************************) + + {$F+} + procedure Direct_Move( zone : PGlyph_Zone; + point : Int; + distance : TT_F26dot6 ); + var + v : TT_F26dot6; + begin + v := exc.GS.freeVector.x; + if v <> 0 then + begin + inc( zone^.cur^[point].x, MulDiv_Round( distance, + Long(v)*$10000, + exc.F_dot_P )); + + zone^.flags^[point] := zone^.flags^[point] or TT_Flag_Touched_X; + end; + + v := exc.GS.freeVector.y; + if v <> 0 then + begin + inc( zone^.cur^[point].y, MulDiv_Round( distance, + Long(v)*$10000, + exc.F_dot_P )); + + zone^.flags^[point] := zone^.flags^[point] or TT_Flag_Touched_Y; + end; + end; + + (* The following versions are used whenever both vectors are both *) + (* along one of the coordinate unit vectors, i.e. in 90% cases *) + + procedure Direct_Move_X( zone : PGlyph_Zone; + point : Int; + distance : TT_F26dot6 ); + begin + inc( zone^.cur^[point].x, distance ); + zone^.flags^[point] := zone^.flags^[point] or TT_Flag_Touched_X; + end; + + procedure Direct_Move_Y( zone : PGlyph_Zone; + point : Int; + distance : TT_F26dot6 ); + begin + inc( zone^.cur^[point].y, distance ); + zone^.flags^[point] := zone^.flags^[point] or TT_Flag_Touched_Y; + end; + +(******************************************************************* + * + * Function : Round_None + * + * Description : Do not round, but add engine compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + * NOTE : The spec says very few about the relationship between + * rounding and engine compensation. However, it seems + * from the description of super round that we should + * should add the compensation before rounding + * + *****************************************************************) + + function Round_None( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := distance + compensation; + if val < 0 then val := 0; + end + else + begin + val := distance - compensation; + if val > 0 then val := 0; + end; + + Round_None := val; + end; + +(******************************************************************* + * + * Function : Round_To_Grid + * + * Description : round value to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_To_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + 32 + compensation) and -64; + if val < 0 then val := 0; + end + else + begin + val := - ((compensation - distance + 32) and -64); + if val > 0 then val := 0; + end; + + Round_To_Grid := val; + end; + +(******************************************************************* + * + * Function : Round_To_Half_Grid + * + * Description : round value to half grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_To_Half_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + compensation) and -64 + 32; + if val < 0 then val := 0; + end + else + begin + val := - ((-distance + compensation) and -64 + 32); + if val > 0 then val := 0; + end; + + Round_To_Half_Grid := val; + end; + + +(******************************************************************* + * + * Function : Round_Down_To_Grid + * + * Description : round value down to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_Down_To_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + compensation) and -64; + if val < 0 then val := 0; + end + else + begin + val := - ((-distance + compensation) and -64); + if val > 0 then val := 0; + end; + + Round_Down_To_Grid := val; + end; + +(******************************************************************* + * + * Function : Round_Up_To_Grid + * + * Description : round value up to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_Up_To_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + 63 + compensation) and -64; + if val < 0 then val := 0; + end + else + begin + val := - ((-distance + 63 + compensation) and -64); + if val > 0 then val := 0; + end; + + Round_Up_To_Grid := val; + end; + +(******************************************************************* + * + * Function : Round_To_Double_Grid + * + * Description : round value to double grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + *****************************************************************) + + function Round_To_Double_Grid( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + if distance >= 0 then + begin + val := (distance + 16 + compensation) and -32; + if val < 0 then val := 0; + end + else + begin + val := - ((-distance + 16 + compensation) and -32); + if val > 0 then val := 0; + end; + + Round_To_Double_Grid := val; + end; + +(******************************************************************* + * + * Function : Round_Super + * + * Description : super round value to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + * NOTE : The spec says very few about the relationship between + * rounding and engine compensation. However, it seems + * from the description of super round that we should + * should add the compensation before rounding + * + *****************************************************************) + + function Round_Super( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + with exc do + + if distance >= 0 then + begin + val := (distance - phase + threshold + compensation) and -period; + if val < 0 then val := 0; + val := val + phase; + end + else + begin + val := -((-distance - phase + threshold + compensation) and -period); + if val > 0 then val := 0; + val := val - phase; + end; + + Round_Super := val; + end; + +(******************************************************************* + * + * Function : Round_Super_45 + * + * Description : super round value to grid after adding engine + * compensation + * + * Input : distance : distance to round + * compensation : engine compensation + * + * Output : rounded distance + * + * NOTE : There is a separate function for Round_Super_45 as we + * may need a greater precision. + * + *****************************************************************) + + function Round_Super_45( distance : TT_F26dot6; + compensation : TT_F26dot6 ) : TT_F26dot6; + var + val : TT_F26dot6; + begin + with exc do + + if distance >= 0 then + begin + val := ((distance - phase + threshold + compensation) div period) + * period; + if val < 0 then val := 0; + val := val + phase; + end + else + begin + val := -((-distance - phase + threshold + compensation) div period + * period ); + if val > 0 then val := 0; + val := val - phase; + end; + + Round_Super_45 := val; + end; + {$F-} + + procedure Compute_Round( round_mode : Byte ); + begin + case Round_Mode of + +{$IFDEF FPK} + TT_Round_Off : exc.func_round := @Round_None; + TT_Round_To_Grid : exc.func_round := @Round_To_Grid; + TT_Round_Up_To_Grid : exc.func_round := @Round_Up_To_Grid; + TT_Round_Down_To_Grid : exc.func_round := @Round_Down_To_Grid; + TT_Round_To_Half_Grid : exc.func_round := @Round_To_Half_Grid; + TT_Round_To_Double_Grid : exc.func_round := @Round_To_Double_Grid; + TT_Round_Super : exc.func_round := @Round_Super; + TT_Round_Super_45 : exc.func_round := @Round_Super_45; +{$ELSE} + TT_Round_Off : exc.func_round := Round_None; + TT_Round_To_Grid : exc.func_round := Round_To_Grid; + TT_Round_Up_To_Grid : exc.func_round := Round_Up_To_Grid; + TT_Round_Down_To_Grid : exc.func_round := Round_Down_To_Grid; + TT_Round_To_Half_Grid : exc.func_round := Round_To_Half_Grid; + TT_Round_To_Double_Grid : exc.func_round := Round_To_Double_Grid; + TT_Round_Super : exc.func_round := Round_Super; + TT_Round_Super_45 : exc.func_round := Round_Super_45; +{$ENDIF} + end; + end; + + +(******************************************************************* + * + * Function : SetSuperRound + * + * Description : Set Super Round parameters + * + * Input : GridPeriod Grid period + * OpCode SROUND opcode + * + * Output : None + * + * Notes : + * + *****************************************************************) + + procedure SetSuperRound( GridPeriod : TT_F26dot6; selector : Long ); + + begin + with exc do + begin + + Case selector and $C0 of + + $00 : period := GridPeriod div 2; + $40 : period := GridPeriod; + $80 : period := GridPeriod * 2; + + (* This opcode is reserved, but ... *) + + $C0 : period := GridPeriod; + end; + + Case selector and $30 of + + $00 : phase := 0; + $10 : phase := period div 4; + $20 : phase := period div 2; + $30 : phase := gridPeriod*3 div 4; + end; + + if selector and $F = 0 then + + Threshold := Period-1 + else + Threshold := (Integer( selector and $F )-4)*period div 8; + + period := period div 256; + phase := phase div 256; + threshold := threshold div 256; + + end + end; + +(******************************************************************* + * + * Function : Project + * + * Description : Computes the projection of (Vx,Vy) along the + * current projection vector + * + * Input : Vx, Vy input vector + * + * Output : return distance in F26dot6 + * + *****************************************************************) + + {$F+} + function Project( var P1, P2 : TT_Vector ) : TT_F26dot6; + var + T1, T2 : Int64; + begin + with exc.GS.projVector do + begin + MulTo64( P1.x - P2.x, x, T1 ); + MulTo64( P1.y - P2.y, y, T2 ); + end; + + Add64( T1, T2, T1 ); + + Project := Div64by32( T1, $4000 ); + end; + + + function Dual_Project( var P1, P2 : TT_Vector ) : TT_F26dot6; + var + T1, T2 : Int64; + begin + with exc.GS.dualVector do + begin + MulTo64( P1.x - P2.x, x, T1 ); + MulTo64( P1.y - P2.y, y, T2 ); + end; + + Add64( T1, T2, T1 ); + + Dual_Project := Div64by32( T1, $4000 ); + end; + + + function Free_Project( var P1, P2 : TT_Vector ) : TT_F26dot6; + var + T1, T2 : Int64; + begin + with exc.GS.freeVector do + begin + MulTo64( P1.x - P2.x, x, T1 ); + MulTo64( P1.y - P2.y, y, T2 ); + end; + + Add64( T1, T2, T1 ); + + Free_Project := Div64by32( T1, $4000 ); + end; + + + function Project_x( var P1, P2 : TT_Vector ) : TT_F26dot6; + begin + Project_x := P1.x - P2.x; + end; + + function Project_y( var P1, P2 : TT_Vector ) : TT_F26dot6; + begin + Project_y := P1.y - P2.y; + end; + {$F-} + +(******************************************************************* + * + * Function : Compute_Funcs + * + * Description : Computes the projections and movement function + * pointers according to the current graphics state + * + * Input : None + * + *****************************************************************) + + procedure Compute_Funcs; + begin + with exc, GS do + begin + + if (freeVector.x = $4000) then + begin +{$IFDEF FPK} + func_freeProj := @Project_x; +{$ELSE} + func_freeProj := Project_x; +{$ENDIF} + F_dot_P := Long(projVector.x) * $10000; + end + else + if (freeVector.y = $4000) then + begin +{$IFDEF FPK} + func_freeProj := @Project_y; +{$ELSE} + func_freeProj := Project_y; +{$ENDIF} + F_dot_P := Long(projVector.y) * $10000; + end + else + begin +{$IFDEF FPK} + func_move := @Direct_Move; + func_freeProj := @Free_Project; +{$ELSE} + func_move := Direct_Move; + func_freeProj := Free_Project; +{$ENDIF} + F_dot_P := Long(projVector.x) * freeVector.x * 4 + + Long(projVector.y) * freeVector.y * 4; + end; + +{$IFDEF FPK} + if (projVector.x = $4000) then func_Project := @Project_x + else + if (projVector.y = $4000) then func_Project := @Project_y + else + func_Project := @Project; + + if (dualVector.x = $4000) then func_dualproj := @Project_x + else + if (dualVector.y = $4000) then func_dualproj := @Project_y + else + func_dualproj := @Dual_Project; + + func_move := @Direct_Move; + + if F_dot_P = $40000000 then + + if freeVector.x = $4000 then func_move := @Direct_Move_x + else + if freeVector.y = $4000 then func_move := @Direct_Move_y; +{$ELSE} + if (projVector.x = $4000) then func_Project := Project_x + else + if (projVector.y = $4000) then func_Project := Project_y + else + func_Project := Project; + + if (dualVector.x = $4000) then func_dualproj := Project_x + else + if (dualVector.y = $4000) then func_dualproj := Project_y + else + func_dualproj := Dual_Project; + + func_move := Direct_Move; + + if F_dot_P = $40000000 then + + if freeVector.x = $4000 then func_move := Direct_Move_x + else + if freeVector.y = $4000 then func_move := Direct_Move_y; +{$ENDIF} + + (* at small sizes, F_dot_P can become too small, resulting *) + (* in overflows and 'spikes' in a number of glyfs like 'w' *) + + if abs( F_dot_P ) < $4000000 then F_dot_P := $40000000; + + (* set aspect ratio to 0 to force recomputation by Get_Current_Ratio *) + metrics.ratio := 0; + end; + end; + + +(**************************************************) +(* *) +(* Normalize : Normer un vecteur ( U, V ) *) +(* r‚sultat dans ( X, Y ) *) +(* False si vecteur paramŠtre nul *) +(* *) +(**************************************************) + +function Normalize( U, V : TT_F26dot6; var R : TT_UnitVector ): boolean; +var + Vec : TT_Vector; + W : TT_F26dot6; + S1, S2 : Boolean; + T : Int64; +begin + + if (Abs(U) < $10000) and (Abs(V) < $10000) then + begin + U := U*$100; + V := V*$100; + + W := Norm( U, V ); + if W = 0 then + begin + (* XXX : Undocumented. Apparently, it is possible to try *) + (* to normalize the vector (0,0). Return success *) + (* in this case *) + Normalize := SUCCESS; + exit; + end; + + R.x := MulDiv( U, $4000, W ); + R.y := MulDiv( V, $4000, W ); + + end + else + begin + + W := Norm( U, V ); + + if W > 0 then + begin + U := MulDiv( U, $4000, W ); + V := MulDiv( V, $4000, W ); + + W := U*U + V*V; + + (* Now, we want that Sqrt( W ) = $4000 *) + (* Or $1000000 <= W < $1004000 *) + + if U < 0 then begin U := -U; S1 := True; end else S1 := False; + if V < 0 then begin V := -V; S2 := True; end else S2 := False; + + while W < $1000000 do + begin + (* We need to increase W, by a minimal amount *) + if U < V then inc( U ) + else inc( V ); + W := U*U + V*V; + end; + + while W >= $1004000 do + begin + (* We need to decrease W, by a minimal amount *) + if U < V then dec( U ) + else dec( V ); + W := U*U + V*V; + end; + + (* Note that in various cases, we can only *) + (* compute a Sqrt(W) of $3FFF, eg. U=V *) + + if S1 then U := -U; + if S2 then V := -V; + + R.x := U; (* Type conversion *) + R.y := V; (* Type conversion *) + + end + else + begin + Normalize := False; + exc.error := TT_Err_Divide_By_Zero; + end; + end; + + Normalize := True; +end; + +{$F+} + +(****************************************************************) +(* *) +(* MANAGING THE STACK *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* DUP[] : Duplicate top stack element *) +(* CodeRange : $20 *) + + procedure Ins_DUP( args : PStorage ); + begin + args^[1] := args^[0]; + end; + +(*******************************************) +(* POP[] : POPs the stack's top elt. *) +(* CodeRange : $21 *) + + procedure Ins_POP( args : PStorage ); + begin + (* nothing to do *) + end; + +(*******************************************) +(* CLEAR[] : Clear the entire stack *) +(* CodeRange : $22 *) + + procedure Ins_CLEAR( args : PStorage ); + begin + exc.new_top := 0; + end; + +(*******************************************) +(* SWAP[] : Swap the top two elements *) +(* CodeRange : $23 *) + + procedure Ins_SWAP( args : PStorage ); + var L : Long; + begin + L := args^[0]; + args^[0] := args^[1]; + args^[1] := L; + end; + +(*******************************************) +(* DEPTH[] : return the stack depth *) +(* CodeRange : $24 *) + + procedure Ins_DEPTH( args : PStorage ); + begin + args^[0] := exc.top; + end; + +(*******************************************) +(* CINDEX[] : copy indexed element *) +(* CodeRange : $25 *) + + procedure Ins_CINDEX( args : PStorage ); + var + L : Long; + begin + L := args^[0]; + if (L <= 0) or (L > exc.args) then + exc.error := TT_Err_Invalid_Reference + else + args^[0] := exc.stack^[exc.args-l]; + end; + +(*******************************************) +(* MINDEX[] : move indexed element *) +(* CodeRange : $26 *) + + procedure Ins_MINDEX( args : PStorage ); + var + L, K : Long; + begin + L := args^[0]; + if (L <= 0) or (L > exc.args) then + exc.Error := TT_Err_Invalid_Reference + else + begin + K := exc.stack^[exc.args-L]; + + move( exc.stack^[exc.args-L+1], + exc.stack^[exc.args-L], + (L-1)*sizeof(Long) ); + + exc.stack^[exc.args-1] := K; + end; + end; + +(*******************************************) +(* ROLL[] : roll top three elements *) +(* CodeRange : $8A *) + + procedure Ins_ROLL( args : PStorage ); + var + A, B, C : Long; + begin + A := args^[2]; + B := args^[1]; + C := args^[0]; + + args^[2] := C; + args^[1] := A; + args^[0] := B; + end; + +(****************************************************************) +(* *) +(* MANAGING THE FLOW OF CONTROL *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + + function SkipCode : boolean; + var + b : Boolean; + begin + b := False; + + inc( exc.IP, exc.length ); + + b := exc.IP < exc.codeSize; + + if b then b := Calc_Length; + + if not b then + exc.error := TT_Err_Code_Overflow; + + SkipCode := b; + end; + + +(*******************************************) +(* IF[] : IF test *) +(* CodeRange : $58 *) + + procedure Ins_IF( args : PStorage ); + var + nIfs : Int; + Out : Boolean; + begin + if args^[0] <> 0 then exit; + + nIfs := 1; + Out := False; + + Repeat + + if not SkipCode then exit; + + Case exc.opcode of + + (* IF *) + $58 : inc( nIfs ); + + (* ELSE *) + $1B : out:= nIfs=1; + + (* EIF *) + $59 : begin + dec( nIfs ); + out:= nIfs=0; + end; + end; + + until Out; + end; + + +(*******************************************) +(* ELSE[] : ELSE *) +(* CodeRange : $1B *) + + procedure Ins_ELSE( args : PStorage ); + var + nIfs : Int; + begin + nIfs := 1; + + Repeat + + if not SkipCode then exit; + + case exc.opcode of + + (* IF *) + $58 : inc( nIfs ); + + (* EIF *) + $59 : dec( nIfs ); + end; + + until nIfs=0; + end; + +(*******************************************) +(* EIF[] : End IF *) +(* CodeRange : $59 *) + + procedure Ins_EIF( args : PStorage ); + begin + (* nothing to do *) + end; + +(*******************************************) +(* JROT[] : Jump Relative On True *) +(* CodeRange : $78 *) + + procedure Ins_JROT( args : PStorage ); + begin + if args^[1] <> 0 then + begin + inc( exc.IP, args^[0] ); + exc.step_ins := false; + end; + end; + +(*******************************************) +(* JMPR[] : JuMP Relative *) +(* CodeRange : $1C *) + + procedure Ins_JMPR( args : PStorage ); + begin + inc( exc.IP, args^[0] ); + exc.step_ins := false; + end; + +(*******************************************) +(* JROF[] : Jump Relative On False *) +(* CodeRange : $79 *) + + procedure Ins_JROF( args : PStorage ); + begin + if args^[1] = 0 then + begin + inc( exc.IP, args^[0] ); + exc.step_ins := false; + end; + end; + +(****************************************************************) +(* *) +(* LOGICAL FUNCTIONS *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* LT[] : Less Than *) +(* CodeRange : $50 *) + + procedure Ins_LT( args : PStorage ); + begin + if args^[0] < args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* LTEQ[] : Less Than or EQual *) +(* CodeRange : $51 *) + + procedure Ins_LTEQ( args : PStorage ); + begin + if args^[0] <= args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* GT[] : Greater Than *) +(* CodeRange : $52 *) + + procedure Ins_GT( args : PStorage ); + begin + if args^[0] > args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* GTEQ[] : Greater Than or EQual *) +(* CodeRange : $53 *) + + procedure Ins_GTEQ( args : PStorage ); + begin + if args^[0] >= args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* EQ[] : EQual *) +(* CodeRange : $54 *) + + procedure Ins_EQ( args : PStorage ); + begin + if args^[0] = args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* NEQ[] : Not EQual *) +(* CodeRange : $55 *) + + procedure Ins_NEQ( args : PStorage ); + begin + if args^[0] <> args^[1] then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* ODD[] : Odd *) +(* CodeRange : $56 *) + + procedure Ins_ODD( args : PStorage ); + begin + if exc.func_round( args^[0], 0 ) and 127 = 64 then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* EVEN[] : Even *) +(* CodeRange : $57 *) + + procedure Ins_EVEN( args : PStorage ); + begin + if exc.func_round( args^[0], 0 ) and 127 = 0 then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* AND[] : logical AND *) +(* CodeRange : $5A *) + + procedure Ins_AND( args : PStorage ); + begin + if ( args^[0] <> 0 ) and + ( args^[1] <> 0 ) then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* OR[] : logical OR *) +(* CodeRange : $5B *) + + procedure Ins_OR( args : PStorage ); + begin + if ( args^[0] <> 0 ) or + ( args^[1] <> 0 ) then args^[0] := 1 + else args^[0] := 0; + end; + +(*******************************************) +(* NOT[] : logical NOT *) +(* CodeRange : $5C *) + + procedure Ins_NOT( args : PStorage ); + begin + if args^[0] <> 0 then args^[0] := 0 + else args^[0] := 1; + end; + +(****************************************************************) +(* *) +(* ARITHMETIC AND MATH INSTRUCTIONS *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* ADD[] : ADD *) +(* CodeRange : $60 *) + + procedure Ins_ADD( args : PStorage ); + begin + inc( args^[0], args^[1] ); + end; + +(*******************************************) +(* SUB[] : SUBstract *) +(* CodeRange : $61 *) + + procedure Ins_SUB( args : PStorage ); + begin + dec( args^[0], args^[1] ); + end; + +(*******************************************) +(* DIV[] : DIVide *) +(* CodeRange : $62 *) + + procedure Ins_DIV( args : PStorage ); + begin + if args^[1] = 0 then + begin + exc.error := TT_Err_Divide_By_Zero; + exit; + end; + + args^[0] := MulDiv_Round( args^[0], 64, args^[1] ); + end; + +(*******************************************) +(* MUL[] : MULtiply *) +(* CodeRange : $63 *) + + procedure Ins_MUL( args : PStorage ); + begin + args^[0] := MulDiv_Round( args^[0], args^[1], 64 ); + end; + +(*******************************************) +(* ABS[] : ABSolute value *) +(* CodeRange : $64 *) + + procedure Ins_ABS( args : PStorage ); + begin + args^[0] := abs( args^[0] ); + end; + +(*******************************************) +(* NEG[] : NEGate *) +(* CodeRange : $65 *) + + procedure Ins_NEG( args : PStorage ); + begin + args^[0] := -args^[0]; + end; + +(*******************************************) +(* FLOOR[] : FLOOR *) +(* CodeRange : $66 *) + + procedure Ins_FLOOR( args : PStorage ); + begin + args^[0] := args^[0] and -64; + end; + +(*******************************************) +(* CEILING[] : CEILING *) +(* CodeRange : $67 *) + + procedure Ins_CEILING( args : PStorage ); + begin + args^[0] := ( args^[0]+63 ) and -64; + end; + +(*******************************************) +(* MAX[] : MAXimum *) +(* CodeRange : $68 *) + + procedure Ins_MAX( args : PStorage ); + begin + if args^[1] > args^[0] then args^[0] := args^[1]; + end; + +(*******************************************) +(* MIN[] : MINimum *) +(* CodeRange : $69 *) + + procedure Ins_MIN( args : PStorage ); + begin + if args^[1] < args^[0] then args^[0] := args^[1]; + end; + +(****************************************************************) +(* *) +(* COMPENSATING FOR THE ENGINE CHARACTERISTICS *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* ROUND[ab] : ROUND value *) +(* CodeRange : $68-$6B *) + + procedure Ins_ROUND( args : PStorage ); + begin + args^[0] := exc.func_round( args^[0], + exc.metrics.compensations[ exc.opcode-$68 ] ); + end; + +(*******************************************) +(* NROUND[ab]: No ROUNDing of value *) +(* CodeRange : $6C-$6F *) + + procedure Ins_NROUND( args : PStorage ); + begin + args^[0] := Round_None( args^[0], + exc.metrics.compensations[ exc.opcode-$6C ] ); + end; + +(****************************************************************) +(* *) +(* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* FDEF[] : Function DEFinition *) +(* CodeRange : $2C *) + + procedure Ins_FDEF( args : PStorage ); + var + func : int; + label + Suite; + begin + + (* check space *) + if exc.numFDefs >= exc.maxFDefs then begin + exc.error := TT_Err_Too_Many_FuncDefs; + exit; + end; + + func := Int(args^[0]); + with exc.FDefs^[exc.numFDefs] do + begin + Range := exc.curRange; + Opc := func; + Start := exc.IP+1; + Active := True; + end; + + if func > exc.maxFunc then + exc.maxFunc := func; + + inc(exc.numFDefs); + + (* now skip the whole function definition *) + (* we don't allow nested IDEFS & FDEFs *) + + while SkipCode do + + case exc.opcode of + + $89, (* IDEF *) + $2C : (* FDEF *) + begin + exc.error := TT_Err_Nested_Defs; + exit; + end; + + $2D : (* ENDF *) + exit; + end; + end; + +(*******************************************) +(* ENDF[] : END Function definition *) +(* CodeRange : $2D *) + + procedure Ins_ENDF( args : PStorage ); + begin + + if exc.callTop <= 0 then (* We encountered an ENDF without a call *) + begin + exc.error := TT_Err_ENDF_in_Exec_Stream; + exit; + end; + + dec( exc.CallTop ); + + with exc.Callstack^[exc.CallTop] do + begin + dec( Cur_Count ); + + exc.step_ins := false; + + if Cur_Count > 0 then + + begin + (* Loop the current function *) + inc( exc.callTop ); + exc.IP := Cur_Restart; + end + + else + (* exit the current call frame *) + (* NOTE : When the last intruction of a program *) + (* is a CALL or LOOPCALL, the return address *) + (* is always out of the code range. This is *) + (* valid address, and is why we do not test *) + (* the result of Goto_CodeRange here !! *) + + Goto_CodeRange( Caller_Range, Caller_IP ) + end; + + end; + +(*******************************************) +(* CALL[] : CALL function *) +(* CodeRange : $2B *) + + procedure Ins_CALL( args : PStorage ); + var + ii, nn : Int; + def : PDefRecord; + label + Fail; + begin + + (* First of all, check index *) + if (args^[0] < 0) or (args^[0] > exc.maxFunc) then + goto Fail; + + (* Except for some old Apple fonts, all functions in a TrueType *) + (* fonts are defined in increasing order, starting from 0. *) + (* *) + (* This mean that, normally, we have : *) + (* *) + (* exc.maxFunc+1 = exc.numFDefs *) + (* exc.FDefs[n].opc = n for n in 0..exc.maxFunc *) + (* *) + + nn := Int(args^[0]); + def := @exc.FDefs^[nn]; + + if ( exc.maxFunc+1 <> exc.numFDefs ) or ( def^.opc <> nn ) then begin + (* lookup the FDefs table *) + ii := 0; + def := @exc.FDefs^[0]; + while (ii < exc.numFDefs) and (def^.opc <> nn) do begin + inc(ii); + inc(def); + end; + + (* Fail if the function isn't listed *) + if ii >= exc.numFDefs then + goto Fail; + end; + + (* check that the function is active *) + if not def^.active then + goto Fail; + + (* check call stack *) + if exc.callTop >= exc.callSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + with exc.callstack^[exc.callTop] do + begin + Caller_Range := exc.curRange; + Caller_IP := exc.IP+1; + Cur_Count := 1; + Cur_Restart := def^.Start; + end; + + inc( exc.CallTop ); + + with def^ do Goto_CodeRange( Range, Start ); + + exc.step_ins := false; + exit; + + Fail: + exc.error := TT_Err_Invalid_Reference; + exit; + end; + +(*******************************************) +(* LOOPCALL[]: LOOP and CALL function *) +(* CodeRange : $2A *) + + procedure Ins_LOOPCALL( args : PStorage ); + begin + + if ( args^[1] < 0 ) or ( args^[1] >= exc.numFDefs ) or + ( not exc.FDefs^[args^[1]].Active ) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if exc.callTop >= exc.callSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + if args^[0] > 0 then + begin + with exc.callstack^[exc.callTop] do + begin + Caller_Range := exc.curRange; + Caller_IP := exc.IP+1; + Cur_Count := args^[0]; + Cur_Restart := exc.FDefs^[args^[1]].Start; + end; + + inc( exc.CallTop ); + + with exc.FDefs^[args^[1]] do Goto_CodeRange( Range, Start ); + + exc.step_ins := false; + end; + + end; + +(*******************************************) +(* IDEF[] : Instruction DEFinition *) +(* CodeRange : $89 *) + + procedure Ins_IDEF( args : PStorage ); + var + i, A : Int; + begin + + A := 0; + + while ( A < exc.numIDefs ) do + with exc.IDefs^[A] do + begin + + if not Active then + begin + Opc := args^[0]; + Start := exc.IP+1; + Range := exc.curRange; + Active := True; + + A := exc.numIDefs; + + (* now skip the whole function definition *) + (* we don't allow nested IDEFS & FDEFs *) + + while SkipCode do + case exc.opcode of + + $89, (* IDEF *) + $2C : (* FDEF *) + begin + exc.error := TT_Err_Nested_Defs; + exit; + end; + + $2D : (* ENDF *) + exit; + end; + end + else + inc( A ); + end; + end; + +(****************************************************************) +(* *) +(* PUSHING DATA ONTO THE INTERPRETER STACK *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* NPUSHB[] : PUSH N Bytes *) +(* CodeRange : $40 *) + + procedure Ins_NPUSHB( args : PStorage ); + var + L, K : Long; + begin + L := exc.code^[exc.IP+1]; + + if exc.top + L > exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + for K := 1 to L do + args^[k-1] := exc.code^[exc.IP+1+k]; + + inc( exc.new_top, L ); + end; + +(*******************************************) +(* NPUSHW[] : PUSH N Words *) +(* CodeRange : $41 *) + + procedure Ins_NPUSHW( args : PStorage ); + var + L, K : Long; + begin + L := exc.code^[exc.IP+1]; + + if exc.top + L > exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + inc( exc.IP, 2 ); + + for K := 1 to L do + args^[k-1] := GetShort; + + exc.step_ins := false; + + inc( exc.new_top, L ); + end; + +(*******************************************) +(* PUSHB[abc]: PUSH Bytes *) +(* CodeRange : $B0-$B7 *) + + procedure Ins_PUSHB( args : PStorage ); + var + L, K : Long; + begin + L := exc.opcode - $B0+1; + + if exc.top + L >= exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + for k := 1 to L do + args^[k-1] := exc.code^[exc.ip+k]; + + end; + +(*******************************************) +(* PUSHW[abc]: PUSH Words *) +(* CodeRange : $B8-$BF *) + + procedure Ins_PUSHW( args : PStorage ); + var + L, K : Long; + begin + L := exc.opcode - $B8+1; + + if exc.top + L >= exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + exit; + end; + + inc( exc.IP ); + + for k := 1 to L do + args^[k-1] := GetShort; + + exc.step_ins := false; + + end; + +(****************************************************************) +(* *) +(* MANAGING THE STORAGE AREA *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* RS[] : Read Store *) +(* CodeRange : $43 *) + + procedure Ins_RS( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.storeSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + args^[0] := exc.storage^[args^[0]]; + end; + +(*******************************************) +(* WS[] : Write Store *) +(* CodeRange : $42 *) + + procedure Ins_WS( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.storeSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.storage^[args^[0]] := args^[1]; + end; + +(*******************************************) +(* WCVTP[] : Write CVT in Pixel units *) +(* CodeRange : $44 *) + + procedure Ins_WCVTP( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.func_write_cvt( args^[0], args^[1] ); + end; + +(*******************************************) +(* WCVTF[] : Write CVT in FUnits *) +(* CodeRange : $70 *) + + procedure Ins_WCVTF( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.cvt^[args^[0]] := Scale_Pixels(args^[1]); + end; + +(*******************************************) +(* RCVT[] : Read CVT *) +(* CodeRange : $45 *) + + procedure Ins_RCVT( args : PStorage ); + begin + if (args^[0] < 0) or (args^[0] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + args^[0] := exc.func_read_cvt(args^[0]); + end; + +(****************************************************************) +(* *) +(* MANAGING THE GRAPHICS STATE *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + +(*******************************************) +(* SVTCA[a] : Set F and P vectors to axis *) +(* CodeRange : $00-$01 *) + + procedure Ins_SVTCA( args : PStorage ); + var A, B : Short; + begin + case (exc.opcode and 1) of + 0 : A := $0000; + 1 : A := $4000; + end; + B := A xor $4000; + + exc.GS.freeVector.x := A; + exc.GS.projVector.x := A; + exc.GS.dualVector.x := A; + + exc.GS.freeVector.y := B; + exc.GS.projVector.y := B; + exc.GS.dualVector.y := B; + + Compute_Funcs; + end; + +(*******************************************) +(* SPVTCA[a] : Set PVector to Axis *) +(* CodeRange : $02-$03 *) + + procedure Ins_SPVTCA( args : PStorage ); + var A, B : Short; + begin + case (exc.opcode and 1) of + 0 : A := $0000; + 1 : A := $4000; + end; + B := A xor $4000; + + exc.GS.projVector.x := A; + exc.GS.dualVector.x := A; + + exc.GS.projVector.y := B; + exc.GS.dualVector.y := B; + + Compute_Funcs; + end; + +(*******************************************) +(* SFVTCA[a] : Set FVector to Axis *) +(* CodeRange : $04-$05 *) + + procedure Ins_SFVTCA( args : PStorage ); + var A, B : Short; + begin + case (exc.opcode and 1) of + 0 : A := $0000; + 1 : A := $4000; + end; + B := A xor $4000; + + exc.GS.freeVector.x := A; + exc.GS.freeVector.y := B; + + Compute_Funcs; + end; + + + + function Ins_SxVTL( aIdx1 : Int; + aIdx2 : Int; + aOpc : Int; + var Vec : TT_UnitVector ) : boolean; + var + A, B, C : Long; + begin + Ins_SxVTL := False; + + with exc do + begin + + if (aIdx2 >= zp1.n_points) or (aIdx1 >= zp2.n_points) then + begin + Error := TT_Err_Invalid_Reference; + exit; + end; + + with zp1.Cur^[aIdx2] do + begin + A := x; + B := y; + end; + + with zp2.Cur^[aIdx1] do + begin + dec( A, x ); + dec( B, y ); + end; + + if aOpc and 1 <> 0 then + begin + C := B; (* CounterClockwise rotation *) + B := A; + A := -C; + end; + + if not Normalize( A, B, Vec ) then + begin + exc.error := TT_Err_Ok; + Vec.x := $4000; + Vec.y := $0000; + end; + + Ins_SxVTL := True; + end; + end; + + +(*******************************************) +(* SPVTL[a] : Set PVector to Line *) +(* CodeRange : $06-$07 *) + + procedure Ins_SPVTL( args : PStorage ); + begin + if not INS_SxVTL( args^[1], + args^[0], + exc.opcode, + exc.GS.projVector ) then exit; + + exc.GS.dualVector := exc.GS.projVector; + Compute_Funcs; + end; + +(*******************************************) +(* SFVTL[a] : Set FVector to Line *) +(* CodeRange : $08-$09 *) + + procedure Ins_SFVTL( args : PStorage ); + begin + if not INS_SxVTL( args^[1], + args^[0], + exc.opcode, + exc.GS.freeVector ) then exit; + + Compute_Funcs; + end; + +(*******************************************) +(* SFVTPV[] : Set FVector to PVector *) +(* CodeRange : $0E *) + + procedure Ins_SFVTPV( args : PStorage ); + begin + exc.GS.freeVector := exc.GS.projVector; + Compute_Funcs; + end; + +(*******************************************) +(* SDPVTL[a] : Set Dual PVector to Line *) +(* CodeRange : $86-$87 *) + + procedure Ins_SDPVTL( args : PStorage ); + var + A, B, C : Long; + p1, p2 : Int; + begin + + p1 := args^[1]; + p2 := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp1.n_points) or + (args^[1] < 0) or (args^[1] >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + A := exc.zp1.org^[p2].x - exc.zp2.org^[p1].x; + B := exc.zp1.org^[p2].y - exc.zp2.org^[p1].y; + + if exc.opcode and 1 <> 0 then + begin + C := B; (* CounterClockwise rotation *) + B := A; + A := -C; + end; + + Normalize( A, B, exc.GS.dualVector ); + + A := exc.zp1.cur^[p2].x - exc.zp2.cur^[p1].x; + B := exc.zp1.cur^[p2].y - exc.zp2.cur^[p1].y; + + if exc.opcode and 1 <> 0 then + begin + C := B; (* CounterClockwise rotation *) + B := A; + A := -C; + end; + + Normalize( A, B, exc.GS.projVector ); + + Compute_Funcs; + exc.error := TT_Err_Ok; + end; + +(*******************************************) +(* SPVFS[] : Set PVector From Stack *) +(* CodeRange : $0A *) + + procedure Ins_SPVFS( args : PStorage ); + var + S : Short; + X, Y : Long; + begin + S := args^[1]; Y := S; (* type conversion; extends sign *) + S := args^[0]; X := S; (* type conversion; extends sign *) + + if not Normalize( X, Y, exc.GS.projVector ) then exit; + + exc.GS.dualVector := exc.GS.projVector; + + Compute_Funcs; + end; + +(*******************************************) +(* SFVFS[] : Set FVector From Stack *) +(* CodeRange : $0B *) + + procedure Ins_SFVFS( args : PStorage ); + var + S : Short; + X, Y : Long; + begin + S := args^[1]; Y := S; (* type conversion; extends sign *) + S := args^[0]; X := S; (* type conversion; extends sign *) + + if not Normalize( X, Y, exc.GS.freeVector ) then exit; + + Compute_Funcs; + end; + +(*******************************************) +(* GPV[] : Get Projection Vector *) +(* CodeRange : $0C *) + + procedure Ins_GPV( args : PStorage ); + begin + args^[0] := exc.GS.projVector.x; + args^[1] := exc.GS.projVector.y; + end; + +(*******************************************) +(* GFV[] : Get Freedom Vector *) +(* CodeRange : $0D *) + + procedure Ins_GFV( args : PStorage ); + begin + args^[0] := exc.GS.freeVector.x; + args^[1] := exc.GS.freeVector.y; + end; + +(*******************************************) +(* SRP0[] : Set Reference Point 0 *) +(* CodeRange : $10 *) + + procedure Ins_SRP0( args : PStorage ); + begin + exc.GS.rp0 := args^[0]; + end; + +(*******************************************) +(* SRP1[] : Set Reference Point 1 *) +(* CodeRange : $11 *) + + procedure Ins_SRP1( args : PStorage ); + begin + exc.GS.rp1 := args^[0]; + end; + +(*******************************************) +(* SRP2[] : Set Reference Point 2 *) +(* CodeRange : $12 *) + + procedure Ins_SRP2( args : PStorage ); + begin + exc.GS.rp2 := args^[0]; + end; + +(*******************************************) +(* SZP0[] : Set Zone Pointer 0 *) +(* CodeRange : $13 *) + + procedure Ins_SZP0( args : PStorage ); + begin + case args^[0] of + + 0 : exc.zp0 := exc.Twilight; + 1 : exc.zp0 := exc.Pts; + else + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.GS.gep0 := args^[0]; + end; + +(*******************************************) +(* SZP1[] : Set Zone Pointer 1 *) +(* CodeRange : $14 *) + + procedure Ins_SZP1( args : PStorage ); + begin + case args^[0] of + + 0 : exc.zp1 := exc.Twilight; + 1 : exc.zp1 := exc.Pts; + else + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.GS.gep1 := args^[0]; + end; + +(*******************************************) +(* SZP2[] : Set Zone Pointer 2 *) +(* CodeRange : $15 *) + + procedure Ins_SZP2( args : PStorage ); + begin + case args^[0] of + + 0 : exc.zp2 := exc.Twilight; + 1 : exc.zp2 := exc.Pts; + else + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.GS.gep2 := args^[0]; + end; + +(*******************************************) +(* SZPS[] : Set Zone Pointers *) +(* CodeRange : $16 *) + + procedure Ins_SZPS( args : PStorage ); + begin + case args^[0] of + + 0 : exc.zp0 := exc.Twilight; + 1 : exc.zp0 := exc.Pts; + else + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.zp1 := exc.zp0; + exc.zp2 := exc.zp0; + + exc.GS.gep0 := args^[0]; + exc.GS.gep1 := args^[0]; + exc.GS.gep2 := args^[0]; + end; + +(*******************************************) +(* RTHG[] : Round To Half Grid *) +(* CodeRange : $19 *) + + procedure Ins_RTHG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_To_Half_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_To_Half_Grid; +{$ELSE} + exc.func_round := Round_To_Half_Grid; +{$ENDIF} + end; + +(*******************************************) +(* RTG[] : Round To Grid *) +(* CodeRange : $18 *) + + procedure Ins_RTG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_To_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_To_Grid; +{$ELSE} + exc.func_round := Round_To_Grid; +{$ENDIF} + end; + +(*******************************************) +(* RTDG[] : Round To Double Grid *) +(* CodeRange : $3D *) + + procedure Ins_RTDG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_To_Double_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_To_Double_Grid; +{$ELSE} + exc.func_round := Round_To_Double_Grid; +{$ENDIF} + end; + +(*******************************************) +(* RUTG[] : Round Up To Grid *) +(* CodeRange : $7C *) + + procedure Ins_RUTG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_Up_To_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_Up_To_Grid; +{$ELSE} + exc.func_round := Round_Up_To_Grid; +{$ENDIF} + end; + +(*******************************************) +(* RDTG[] : Round Down To Grid *) +(* CodeRange : $7D *) + + procedure Ins_RDTG( args : PStorage ); + begin + exc.GS.round_state := TT_Round_Down_To_Grid; + +{$IFDEF FPK} + exc.func_round := @Round_Down_To_Grid; +{$ELSE} + exc.func_round := Round_Down_To_Grid; +{$ENDIF} + end; + +(*******************************************) +(* ROFF[] : Round OFF *) +(* CodeRange : $7A *) + + procedure Ins_ROFF( args : PStorage ); + begin + exc.GS.round_state := TT_Round_Off; + +{$IFDEF FPK} + exc.func_round := @Round_None; +{$ELSE} + exc.func_round := Round_None; +{$ENDIF} + end; + +(*******************************************) +(* SROUND[] : Super ROUND *) +(* CodeRange : $76 *) + + procedure Ins_SROUND( args : PStorage ); + begin + SetSuperRound( $4000, args^[0] ); + exc.GS.round_state := TT_Round_Super; + +{$IFDEF FPK} + exc.func_round := @Round_Super; +{$ELSE} + exc.func_round := Round_Super; +{$ENDIF} + end; + +(*******************************************) +(* S45ROUND[]: Super ROUND 45 degrees *) +(* CodeRange : $77 *) + + procedure Ins_S45ROUND( args : PStorage ); + begin + SetSuperRound( $2D41, args^[0] ); + exc.GS.round_state := TT_Round_Super_45; + +{$IFDEF FPK} + exc.func_round := @Round_Super_45; +{$ELSE} + exc.func_round := Round_Super_45; +{$ENDIF} + end; + + +(*******************************************) +(* SLOOP[] : Set LOOP variable *) +(* CodeRange : $17 *) + + procedure Ins_SLOOP( args : PStorage ); + begin + exc.GS.Loop := args^[0]; + end; + +(*******************************************) +(* SMD[] : Set Minimum Distance *) +(* CodeRange : $1A *) + + procedure Ins_SMD( args : PStorage ); + begin + exc.GS.minimum_distance := args^[0]; + end; + +(*******************************************) +(* INSTCTRL[]: INSTruction ConTRol *) +(* CodeRange : $8e *) + + procedure Ins_INSTCTRL( args : PStorage ); + var + K, L : Int; + begin + K := args^[1]; + L := args^[0]; + + if ( K < 1 ) or ( K > 2 ) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if L <> 0 then L := K; + + exc.GS.instruct_control := ( exc.GS.instruct_control and not K ) or L; + end; + +(*******************************************) +(* SCANCTRL[]: SCAN ConTRol *) +(* CodeRange : $85 *) + + procedure Ins_SCANCTRL( args : PStorage ); + var + A : Int; + begin + + (* Get Threshold *) + A := args^[0] and $FF; + + if A = $FF then + exc.GS.scan_Control := True + else + if A = 0 then + exc.GS.scan_Control := False + else + begin + + A := A * 64; + + (* XXX TODO : Add rotation and stretch cases *) + + if ( args^[0] and $100 <> 0 ) and + ( exc.metrics.pointSize <= A ) then exc.GS.scan_Control := True; + + if ( args^[0] and $200 <> 0 ) and + ( false ) then exc.GS.scan_Control := True; + + if ( args^[0] and $400 <> 0 ) and + ( false ) then exc.GS.scan_Control := True; + + if ( args^[0] and $800 <> 0 ) and + ( exc.metrics.pointSize > A ) then exc.GS.scan_Control := False; + + if ( args^[0] and $1000 <> 0 ) and + ( not False ) then exc.GS.scan_Control := False; + + if ( args^[0] and $2000 <> 0 ) and + ( not False ) then exc.GS.scan_Control := False; + end; + end; + +(*******************************************) +(* SCANTYPE[]: SCAN TYPE *) +(* CodeRange : $8D *) + + procedure Ins_SCANTYPE( args : PStorage ); + begin + (* For compatibility with future enhancements, *) + (* we must ignore new modes *) + + if (args^[0] >= 0 ) and (args^[0] <= 5) then + begin + if args^[0] = 3 then args^[0] := 2; + + exc.GS.scan_type := args^[0]; + end; + end; + +(**********************************************) +(* SCVTCI[] : Set Control Value Table Cut In *) +(* CodeRange : $1D *) + + procedure Ins_SCVTCI( args : PStorage ); + begin + exc.GS.control_value_cutin := args^[0]; + end; + +(**********************************************) +(* SSWCI[] : Set Single Width Cut In *) +(* CodeRange : $1E *) + + procedure Ins_SSWCI( args : PStorage ); + begin + exc.GS.single_width_cutin := args^[0]; + end; + +(**********************************************) +(* SSW[] : Set Single Width *) +(* CodeRange : $1F *) + + procedure Ins_SSW( args : PStorage ); + begin + exc.GS.single_width_value := args^[0] div $400; + end; + +(**********************************************) +(* FLIPON[] : Set Auto_flip to On *) +(* CodeRange : $4D *) + + procedure Ins_FLIPON( args : PStorage ); + begin + exc.GS.auto_flip := True; + end; + +(**********************************************) +(* FLIPOFF[] : Set Auto_flip to Off *) +(* CodeRange : $4E *) + + procedure Ins_FLIPOFF( args : PStorage ); + begin + exc.GS.auto_flip := False; + end; + +(**********************************************) +(* SANGW[] : Set Angle Weigth *) +(* CodeRange : $7E *) + + procedure Ins_SANGW( args : PStorage ); + begin + (* instruction not supported anymore *) + end; + +(**********************************************) +(* SDB[] : Set Delta Base *) +(* CodeRange : $5E *) + + procedure Ins_SDB( args : PStorage ); + begin + exc.GS.delta_base := args^[0] + end; + +(**********************************************) +(* SDS[] : Set Delta Shift *) +(* CodeRange : $5F *) + + procedure Ins_SDS( args : PStorage ); + begin + exc.GS.delta_shift := args^[0] + end; + +(**********************************************) +(* GC[a] : Get Coordinate projected onto *) +(* CodeRange : $46-$47 *) + +(* BULLSHIT : Measures from the original glyph must to be taken *) +(* along the dual projection vector !! *) + + procedure Ins_GC( args : PStorage ); + var + L : Int; + begin + L := args^[0]; + + if (L < 0) or (L >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + case exc.opcode and 1 of + + 0 : L := exc.func_project ( exc.zp2.cur^[L], Null_Vector ); + 1 : L := exc.func_dualProj( exc.zp2.org^[L], Null_Vector ); + end; + + args^[0] := L; + end; + +(**********************************************) +(* SCFS[] : Set Coordinate From Stack *) +(* CodeRange : $48 *) +(* *) +(* Formule : *) +(* *) +(* OA := OA + ( value - OA.p )/( f.p ) x f *) +(* *) + + procedure Ins_SCFS( args : PStorage ); + var + K, L : Int; + begin + L := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + K := exc.func_project( exc.zp2.cur^[L], Null_Vector ); + + exc.func_move( @exc.zp2, L, args^[1] - K ); + + (* not part of the specs, but here for safety *) + + if exc.GS.gep2 = 0 then + exc.zp2.org^[L] := exc.zp2.cur^[L]; + + end; + +(**********************************************) +(* MD[a] : Measure Distance *) +(* CodeRange : $49-$4A *) + +(* BULLSHIT : Measure taken in the original glyph must be along *) +(* the dual projection vector *) + +(* Second BULLSHIT : Flag attributions are inverted !! *) +(* 0 => measure distance in original outline *) +(* 1 => measure distance in grid-fitted outline *) + + procedure Ins_MD( args : PStorage ); + var + K, L : Int; + D : TT_F26dot6; + vec1 : TT_Vector; + vec2 : TT_Vector; + begin + K := args^[1]; + L := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp0.n_points) or + (args^[1] < 0) or (args^[1] >= exc.zp1.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + case exc.opcode and 1 of + + 0 : D := exc.func_dualProj( exc.zp0.org^[L], exc.zp1.org^[K] ); + 1 : D := exc.func_project ( exc.zp0.cur^[L], exc.zp1.cur^[K] ); + end; + + args^[0] := D; + end; + +(**********************************************) +(* MPPEM[] : Measure Pixel Per EM *) +(* CodeRange : $4B *) + + procedure Ins_MPPEM( args : PStorage ); + begin + args^[0] := Get_Ppem; + end; + +(**********************************************) +(* MPS[] : Measure PointSize *) +(* CodeRange : $4C *) + + procedure Ins_MPS( args : PStorage ); + begin + args^[0] := exc.metrics.pointSize; + end; + +(****************************************************************) +(* *) +(* MANAGING OUTLINES *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + + +(**********************************************) +(* FLIPPT[] : FLIP PoinT *) +(* CodeRange : $80 *) + + procedure Ins_FLIPPT( args : PStorage ); + var + point : Int; + begin + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Too_Few_Arguments; + exit; + end; + + while exc.GS.loop > 0 do + begin + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + if (point < 0) or (point >= exc.pts.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + exc.pts.flags^[point] := exc.pts.flags^[point] xor TT_Flag_On_Curve; + + dec( exc.GS.loop ); + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* FLIPRGON[]: FLIP RanGe ON *) +(* CodeRange : $81 *) + + procedure Ins_FLIPRGON( args : PStorage ); + var + I, K, L : Int; + begin + K := args^[1]; + L := args^[0]; + + if (K < 0) or (K >= exc.pts.n_points) or + (L < 0) or (L >= exc.pts.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + for I := L to K do + exc.pts.flags^[I] := exc.pts.flags^[I] or TT_Flag_On_Curve; + end; + +(**********************************************) +(* FLIPRGOFF : FLIP RanGe OFF *) +(* CodeRange : $82 *) + + procedure Ins_FLIPRGOFF( args : PStorage ); + var + I, K, L : Int; + begin + K := args^[1]; + L := args^[0]; + + if (K < 0) or (K >= exc.pts.n_points) or + (L < 0) or (L >= exc.pts.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + for I := L to K do + exc.pts.flags^[I] := exc.pts.flags^[I] and not TT_Flag_On_Curve; + end; + + + + function Compute_Point_Displacement( var x : TT_F26dot6; + var y : TT_F26dot6; + var zone : PGlyph_Zone; + var refp : Int ) : TError; + var + zp : PGlyph_Zone; + p : Int; + d : TT_F26dot6; + vec1 : TT_Vector; + vec2 : TT_Vector; + begin + + Compute_Point_Displacement := Success; + + case exc.opcode and 1 of + 0 : begin zp := @exc.zp1; p := exc.GS.rp2; end; + 1 : begin zp := @exc.zp0; p := exc.GS.rp1; end; + end; + + if (p < 0) or (p >= zp^.n_points) then + begin + exc.error := TT_Err_Invalid_Displacement; + Compute_Point_Displacement := Failure; + exit; + end; + + zone := zp; + refp := p; + + d := exc.func_project( zp^.cur^[p], zp^.org^[p] ); + + x := MulDiv_Round( d, Long(exc.GS.freeVector.x)*$10000, exc.F_dot_P ); + y := MulDiv_Round( d, Long(exc.GS.freeVector.y)*$10000, exc.F_dot_P ); + + end; + + + procedure Move_Zp2_Point( point : Int; + dx : TT_F26dot6; + dy : TT_F26dot6 ); + begin + if exc.GS.freeVector.x <> 0 then + begin + inc( exc.zp2.cur^[point].x, dx ); + exc.zp2.flags^[point] := exc.zp2.flags^[point] or TT_Flag_Touched_X; + end; + + if exc.GS.freeVector.y <> 0 then + begin + inc( exc.zp2.cur^[point].y, dy ); + exc.zp2.flags^[point] := exc.zp2.flags^[point] or TT_Flag_Touched_Y; + end; + end; + +(**********************************************) +(* SHP[a] : SHift Point by the last point *) +(* CodeRange : $32-33 *) + + procedure Ins_SHP( args : PStorage ); + var + zp : PGlyph_Zone; + refp : Int; + + dx : TT_F26dot6; + dy : TT_F26dot6; + point: Int; + begin + + if Compute_Point_Displacement( dx, dy, zp, refp ) then + exit; + + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + while exc.GS.loop > 0 do + begin + + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + if (point < 0) or (point >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + Move_Zp2_Point( point, dx, dy ); + + dec( exc.GS.loop ); + + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* SHC[a] : SHift Contour *) +(* CodeRange : $34-35 *) + + procedure Ins_SHC( args : PStorage ); + var + zp : PGlyph_Zone; + refp : Int; + dx : TT_F26dot6; + dy : TT_F26dot6; + + contour, i : Int; + + first_point, last_point : Int; + begin + + contour := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.pts.n_contours ) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if Compute_Point_Displacement( dx, dy, zp, refp ) then + exit; + + if contour = 0 then first_point := 0 else + first_point := exc.pts.conEnds^[contour-1]+1; + + last_point := exc.pts.conEnds^[contour]; + + for i := first_point to last_point do + begin + if (zp^.cur <> exc.zp2.cur) or + (refp <> i ) then + + Move_Zp2_Point( i, dx, dy ); + end; + + end; + +(**********************************************) +(* SHZ[a] : SHift Zone *) +(* CodeRange : $36-37 *) + + procedure Ins_SHZ( args : PStorage ); + var + zp : PGlyph_Zone; + refp : Int; + dx : TT_F26dot6; + dy : TT_F26dot6; + + zone, i : Int; + + last_point : Int; + begin + + zone := args^[0]; + + if (args^[0] < 0) or (args^[0] > 1) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if Compute_Point_Displacement( dx, dy, zp, refp ) then + exit; + + last_point := zp^.n_points-1; + + for i := 0 to last_point do + begin + if (zp^.cur <> exc.zp2.cur) or + (refp <> i ) then + + Move_Zp2_Point( i, dx, dy ); + end; + + end; + +(**********************************************) +(* SHPIX[] : SHift points by a PIXel amount *) +(* CodeRange : $38 *) + + procedure Ins_SHPIX( args : PStorage ); + var + dx : TT_F26dot6; + dy : TT_F26dot6; + point: Int; + begin + + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + dx := MulDiv_Round( args^[0], + exc.GS.freeVector.x, + $4000 ); + + dy := MulDiv_Round( args^[0], + exc.GS.freeVector.y, + $4000 ); + + while exc.GS.loop > 0 do + begin + + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + if (point < 0) or (point >= exc.zp2.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + Move_Zp2_Point( point, dx, dy ); + + dec( exc.GS.loop ); + + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* MSIRP[a] : Move Stack Indirect Relative *) +(* CodeRange : $3A-$3B *) + + procedure Ins_MSIRP( args : PStorage ); + var + point : Int; + distance : TT_F26dot6; + vec1 : TT_Vector; + vec2 : TT_Vector; + begin + + point := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp1.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + (* XXX : UNDOCUMENTED - Twilight Zone *) + + (* Again, one stupid undocumented feature found in the *) + (* twilight zone. What did these guys had in mind when *) + (* they wrote the spec ? There _must_ be another *) + (* specification than the published one !! #@%$& !! *) + + if exc.GS.gep0 = 0 then (* if in twilight zone *) + begin + exc.zp1.org^[point] := exc.zp0.org^[exc.GS.rp0]; + exc.zp1.cur^[point] := exc.zp1.org^[point]; + end; + + distance := exc.func_project( exc.zp1.cur^[point], + exc.zp0.cur^[exc.GS.rp0] ); + + exc.func_move( @exc.zp1, point, args^[1] - distance ); + + exc.GS.rp1 := exc.GS.rp0; + exc.GS.rp2 := point; + + if exc.opcode and 1 <> 0 then exc.GS.rp0 := point; + end; + +(**********************************************) +(* MDAP[a] : Move Direct Absolute Point *) +(* CodeRange : $2E-$2F *) + + procedure Ins_MDAP( args : PStorage ); + var + point : Int; + cur_dist : TT_F26dot6; + distance : TT_F26dot6; + begin + point := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp0.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + (* XXXX Is there some undocumented feature while in the *) + (* twilight zone ?? *) + + if exc.opcode and 1 <> 0 then + begin + + cur_dist := exc.func_project( exc.zp0.cur^[point], Null_Vector ); + + distance := exc.func_round( cur_dist, + exc.metrics.compensations[0] ) - + cur_dist; + end + else + distance := 0; + + exc.func_move( @exc.zp0, point, distance ); + + exc.GS.rp0 := point; + exc.GS.rp1 := point; + end; + +(**********************************************) +(* MIAP[a] : Move Indirect Absolute Point *) +(* CodeRange : $3E-$3F *) + + procedure Ins_MIAP( args : PStorage ); + var + cvtEntry : Int; + point : Int; + distance : TT_F26dot6; + org_dist : TT_F26dot6; + begin + cvtEntry := args^[1]; + point := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp0.n_points ) or + (args^[1] < 0) or (args^[1] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + (* Undocumented : *) + (* *) + (* The behaviour of an MIAP instruction is quite *) + (* different when used in the twilight zone^. *) + (* *) + (* First, no control value cutin test is performed *) + (* as it would fail anyway. Second, the original *) + (* point, i.e. (org_x,org_y) of zp0.point, is set *) + (* to the absolute, unrounded, distance found in *) + (* the CVT. *) + (* *) + (* This is used in the CVT programs of the Microsoft *) + (* fonts Arial, Times, etc.., in order to re-adjust *) + (* some key font heights. It allows the use of the *) + (* IP instruction in the twilight zone, which *) + (* otherwise would be "illegal" per se the specs :) *) + (* *) + (* We implement it with a special sequence for the *) + (* twilight zone. This is a bad hack, but it seems *) + (* to work.. *) + (* - David *) + + distance := exc.func_read_cvt(cvtEntry); + + if exc.GS.gep0 = 0 then (* If in twilight zone *) + begin + exc.zp0.org^[point].y := MulDiv_Round( exc.GS.freeVector.x, + distance, + $4000 ); + + exc.zp0.org^[point].y := MulDiv_Round( exc.GS.freeVector.y, + distance, + $4000 ); + + exc.zp0.cur^[point] := exc.zp0.org^[point]; + end; + + org_dist := exc.func_project( exc.zp0.cur^[point], Null_Vector ); + + if exc.opcode and 1 <> 0 then (* rounding and control cutin flag *) + begin + + if abs( distance-org_dist ) > exc.GS.control_value_cutin then + distance := org_dist; + + distance := exc.func_round( distance, + exc.metrics.compensations[0] ); + end; + + exc.func_move( @exc.zp0, point, distance - org_dist ); + + exc.GS.rp0 := point; + exc.GS.rp1 := point; + + end; + +(**********************************************) +(* MDRP[abcde] : Move Direct Relative Point *) +(* CodeRange : $C0-$DF *) + + procedure Ins_MDRP( args : PStorage ); + var + point : Int; + distance : TT_F26dot6; + org_dist : TT_F26dot6; + begin + point := args^[0]; + + if (args^[0] < 0) or (args^[0] >= exc.zp1.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + (* XXXX Is there some undocumented feature while in the *) + (* twilight zone ?? *) + + org_dist := exc.func_dualProj( exc.zp1.org^[point], + exc.zp0.org^[exc.GS.rp0] ); + (* single width cutin test *) + + if abs(org_dist) < exc.GS.single_width_cutin then + + if org_dist >= 0 then org_dist := exc.GS.single_width_value + else org_dist := -exc.GS.single_width_value; + + (* round flag *) + + if exc.opcode and 4 <> 0 then + + distance := exc.func_round( org_dist, + exc.metrics.compensations[ exc.opcode and 3 ] ) + else + distance := Round_None( org_dist, + exc.metrics.compensations[ exc.opcode and 3 ] ); + + (* minimum distance flag *) + + if exc.opcode and 8 <> 0 then + begin + + if org_dist >= 0 then + + if distance < exc.GS.minimum_distance then + distance := exc.GS.minimum_distance + else + else + if distance > -exc.GS.minimum_distance then + distance := -exc.GS.minimum_distance; + end; + + (* now move the point *) + + org_dist := exc.func_project( exc.zp1.cur^[point], + exc.zp0.cur^[exc.GS.rp0] ); + + exc.func_move( @exc.zp1, point, distance - org_dist ); + + exc.GS.rp1 := exc.GS.rp0; + exc.GS.rp2 := point; + + if exc.opcode and 16 <> 0 then exc.GS.rp0 := point; + end; + +(**********************************************) +(* MIRP[abcde] : Move Indirect Relative Point *) +(* CodeRange : $E0-$FF *) + + procedure Ins_MIRP( args : PStorage ); + var + point : Int; + cvtEntry : Int; + cvt_dist : TT_F26dot6; + distance : TT_F26dot6; + cur_dist : TT_F26dot6; + org_dist : TT_F26dot6; + begin + + point := args^[0]; + cvtEntry := args^[1]; + + (* XXX : UNDOCUMENTED => cvt[-1] = 0 ???? *) + + if (args^[0] < 0 ) or (args^[0] >= exc.zp1.n_points) or + (args^[1] < -1) or (args^[1] >= exc.cvtSize) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + if cvtEntry < 0 then + cvt_dist := 0 + else + cvt_dist := exc.func_read_cvt(cvtEntry); + + (* single width test *) + + if abs(cvt_dist) < exc.GS.single_width_cutin then + + if cvt_dist >= 0 then cvt_dist := exc.GS.single_width_value + else cvt_dist := -exc.GS.single_width_value; + + (* XXX : Undocumented - twilight zone *) + + if exc.GS.gep1 = 0 then (* if in twilight zone *) + begin + exc.zp1.org^[point].x := exc.zp0.org^[exc.GS.rp0].x + + MulDiv_Round( cvt_dist, + exc.GS.freeVector.x, + $4000 ); + + exc.zp1.org^[point].x := exc.zp0.org^[exc.GS.rp0].y + + MulDiv_Round( cvt_dist, + exc.GS.freeVector.y, + $4000 ); + + exc.zp1.cur^[point] := exc.zp1.org^[point]; + end; + + + org_dist := exc.func_dualProj( exc.zp1.org^[point], + exc.zp0.org^[exc.GS.rp0] ); + + cur_dist := exc.func_Project( exc.zp1.cur^[point], + exc.zp0.cur^[exc.GS.rp0] ); + + (* auto-flip test *) + + if exc.GS.auto_flip then + if (org_dist xor cvt_dist < 0) then + cvt_dist := -cvt_dist; + + (* control value cutin and round *) + + if exc.opcode and 4 <> 0 then + begin + (* XXX : UNDOCUMENTED : only perform cut-in test when both *) + (* zone pointers refer to the points zone *) + + if exc.GS.gep0 = exc.GS.gep1 then + if abs( cvt_dist - org_dist ) >= exc.GS.control_value_cutin then + cvt_dist := org_dist; + + distance := exc.func_round( cvt_dist, + exc.metrics.compensations[ exc.opcode and 3 ] ); + end + else + distance := Round_None( cvt_dist, + exc.metrics.compensations[ exc.opcode and 3 ] ); + + (* minimum distance test *) + + if exc.opcode and 8 <> 0 then + begin + if org_dist >= 0 then + + if distance < exc.GS.minimum_distance then + distance := exc.GS.minimum_distance + else + else + if distance > -exc.GS.minimum_distance then + distance := -exc.GS.minimum_distance; + end; + + exc.func_move( @exc.zp1, point, distance - cur_dist ); + + exc.GS.rp1 := exc.GS.rp0; + + if exc.opcode and 16 <> 0 then exc.GS.rp0 := point; + + (* UNDOCUMENTED !! *) + + exc.GS.rp2 := point; + end; + +(**********************************************) +(* ALIGNRP[] : ALIGN Relative Point *) +(* CodeRange : $3C *) + + procedure Ins_ALIGNRP( args : PStorage ); + var + point : Int; + distance : TT_F26dot6; + begin + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + while exc.GS.loop > 0 do + begin + + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + if (point < 0) or (point >= exc.zp1.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + distance := exc.func_project( exc.zp1.cur^[point], + exc.zp0.cur^[exc.GS.rp0] ); + + exc.func_move( @exc.zp1, point, -distance ); + + dec( exc.GS.loop ); + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* AA[] : Adjust Angle *) +(* CodeRange : $7F *) + + procedure Ins_AA( args : PStorage ); + begin + (* Intentional - no longer supported *) + end; + +(**********************************************) +(* ISECT[] : moves point to InterSECTion *) +(* CodeRange : $0F *) + + procedure Ins_ISECT( args : PStorage ); + var + point : Int; + a0, a1 : Int; + b0, b1 : Int; + + discriminant : TT_F26dot6; + dx, dy, + dax, day, + dbx, dby : TT_F26dot6; + + val : TT_F26dot6; + + R : TT_Vector; + + U, V : TT_UnitVector; + T1, T2 : Int64; + begin + + point := args^[0]; + a0 := args^[1]; + a1 := args^[2]; + b0 := args^[3]; + b1 := args^[4]; + + if (b0 >= exc.zp0.n_points) or (b1 >= exc.zp0.n_points) or + (a0 >= exc.zp1.n_points) or (a1 >= exc.zp1.n_points) or + (point >= exc.zp0.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; +(* + if Normalize( exc.zp1.cur_x^[a1] - exc.zp1.cur_x^[a0], + exc.zp1.cur_y^[a1] - exc.zp1.cur_y^[a0], + U ) + and + Normalize( - exc.zp0.cur_x^[b1] - exc.zp0.cur_x^[b0], + exc.zp0.cur_y^[b1] - exc.zp0.cur_y^[b0], + V ) + then + begin + + dx := MulDiv_Round( exc.zp0.cur_x^[b0] - + exc.zp1.cur_x^[a0], + V.x, + $4000 ) + + + MulDiv_Round( exc.zp0.cur_y^[b0] - + exc.zp1.cur_y^[a0], + V.y, + $4000 ); + + dy := MulDiv_Round( U.x, V.x, $4000 ) + + MulDiv_Round( U.y, V.y, $4000 ); + + if dy <> 0 then + begin + dx := MulDiv_Round( dx, $4000, dy ); + + exc.zp2.flags^[point] := exc.zp2.flags^[point] or + TT_Flag_Touched_Both; + + exc.zp2.cur_x^[point] := exc.zp1.cur_x^[a0] + + + MulDiv_Round( dx, U.x, $4000 ); + + exc.zp2.cur_y^[point] := exc.zp1.cur_y^[a0] + + + MulDiv_Round( dx, U.y, $4000 ); + + exit; + end; + end; + *) + dbx := exc.zp0.cur^[b1].x - exc.zp0.cur^[b0].x; + dby := exc.zp0.cur^[b1].y - exc.zp0.cur^[b0].y; + + dax := exc.zp1.cur^[a1].x - exc.zp1.cur^[a0].x; + day := exc.zp1.cur^[a1].y - exc.zp1.cur^[a0].y; + + dx := exc.zp0.cur^[b0].x - exc.zp1.cur^[a0].x; + dy := exc.zp0.cur^[b0].y - exc.zp1.cur^[a0].y; + + exc.zp2.flags^[point] := exc.zp2.flags^[point] or + TT_Flag_Touched_Both; + + discriminant := MulDiv( dax, -dby, $40 ) + + MulDiv( day, dbx, $40 ); + + if abs(discriminant) >= $40 then + begin + + val := MulDiv( dx, -dby, $40 ) + + MulDiv( dy, dbx, $40 ); + + R.x := MulDiv( val, dax, discriminant ); + R.y := MulDiv( val, day, discriminant ); + + exc.zp2.cur^[point].x := exc.zp1.cur^[a0].x + R.x; + exc.zp2.cur^[point].y := exc.zp1.cur^[a0].y + R.y; + end + else + begin + + (* else, take the middle of the middles of A and B *) + + exc.zp2.cur^[point].x := ( exc.zp1.cur^[a0].x + + exc.zp1.cur^[a1].x + + exc.zp0.cur^[b0].x + + exc.zp0.cur^[b1].x ) div 4; + + exc.zp2.cur^[point].y := ( exc.zp1.cur^[a0].y + + exc.zp1.cur^[a1].y + + exc.zp0.cur^[b0].y + + exc.zp0.cur^[b1].y ) div 4; + end; + end; + +(**********************************************) +(* ALIGNPTS[] : ALIGN PoinTS *) +(* CodeRange : $27 *) + + procedure Ins_ALIGNPTS( args : PStorage ); + var + p1, p2 : Int; + distance : TT_F26dot6; + begin + p1 := args^[0]; + p2 := args^[1]; + + if (args^[0] < 0) or (args^[0] >= exc.zp1.n_points) or + (args^[1] < 0) or (args^[1] >= exc.zp0.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + distance := exc.func_project( exc.zp0.cur^[p2], + exc.zp1.cur^[p1] ) div 2; + + exc.func_move( @exc.zp1, p1, distance ); + exc.func_move( @exc.zp0, p2, -distance ); + end; + +(**********************************************) +(* IP[] : Interpolate Point *) +(* CodeRange : $39 *) + + procedure Ins_IP( args : PStorage ); + var + org_a : TT_F26dot6; + org_b : TT_F26dot6; + org_x : TT_F26dot6; + cur_a : TT_F26dot6; + cur_b : TT_F26dot6; + cur_x : TT_F26dot6; + + distance : TT_F26dot6; + + point : Int; + begin + + if exc.top < exc.GS.loop then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + org_a := exc.func_dualProj( exc.zp0.org^[exc.GS.rp1], Null_Vector ); + + org_b := exc.func_dualProj( exc.zp1.org^[exc.GS.rp2], Null_Vector ); + + cur_a := exc.func_project( exc.zp0.cur^[exc.GS.rp1], Null_Vector ); + + cur_b := exc.func_project( exc.zp1.cur^[exc.GS.rp2], Null_Vector ); + + while exc.GS.loop > 0 do + begin + + dec( exc.args ); + + point := exc.stack^[ exc.args ]; + + org_x := exc.func_dualProj( exc.zp2.org^[point], Null_Vector ); + + cur_x := exc.func_project( exc.zp2.cur^[point], Null_Vector ); + + if (( org_a <= org_b ) and ( org_x <= org_a )) or + (( org_a > org_b ) and ( org_x >= org_a )) then + begin + distance := ( cur_a - org_a ) + ( org_x - cur_x ); + end + else + if (( org_a <= org_b ) and ( org_x >= org_b )) or + (( org_a > org_b ) and ( org_x < org_b )) then + begin + distance := ( cur_b - org_b ) + ( org_x - cur_x ); + end + else + begin + (* note : it seems that rounding this value isn't a good *) + (* idea ( width of capital 'S' in Times *) + + distance := MulDiv( cur_b - cur_a, + org_x - org_a, + org_b - org_a ) + ( cur_a - cur_x ); + end; + + exc.func_move( @exc.zp2, point, distance ); + + dec( exc.GS.loop ); + end; + + exc.GS.loop := 1; + exc.new_top := exc.args; + end; + +(**********************************************) +(* UTP[a] : UnTouch Point *) +(* CodeRange : $29 *) + + procedure Ins_UTP( args : PStorage ); + var + mask : Byte; + begin + if (args^[0] < 0) or (args^[0] >= exc.zp0.n_points) then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + mask := $FF; + + if exc.GS.freeVector.x <> 0 then mask := mask and not TT_Flag_Touched_X; + if exc.GS.freeVector.y <> 0 then mask := mask and not TT_Flag_Touched_Y; + + exc.zp0.flags^[args^[0]] := exc.zp0.flags^[args^[0]] and mask; + end; + +(**********************************************) +(* IUP[a] : Interpolate Untouched Points *) +(* CodeRange : $30-$31 *) + + procedure Ins_IUP( args : PStorage ); + var + mask : byte; + + first_point, (* first point of contour *) + end_point, (* end point (last+1) of contour *) + + first_touched, (* first touched point in contour *) + cur_touched, (* current touched point in contour *) + + point, (* current point *) + contour : Int; (* current contour *) + + orgs, (* original and current coordinate *) + curs : TT_Points; (* arrays *) + + procedure Shift_X( p1, p2, p : Int ); + var + i : Int; + x : TT_F26dot6; + begin + x := curs^[p].x - orgs^[p].x; + + for i := p1 to p-1 do inc( curs^[i].x, x ); + for i := p+1 to p2 do inc( curs^[i].x, x ); + end; + + procedure Shift_Y( p1, p2, p : Int ); + var + i : Int; + y : TT_F26dot6; + begin + y := curs^[p].y - orgs^[p].y; + + for i := p1 to p-1 do inc( curs^[i].y, y ); + for i := p+1 to p2 do inc( curs^[i].y, y ); + end; + + + procedure Interp_X( p1, p2, ref1, ref2 : Int ); + var + i : Int; + x, x1, x2, d1, d2 : TT_F26dot6; + begin + + if p1 > p2 then exit; + + x1 := orgs^[ref1].x; d1 := curs^[ref1].x - orgs^[ref1].x; + x2 := orgs^[ref2].x; d2 := curs^[ref2].x - orgs^[ref2].x; + + if x1 = x2 then + for i := p1 to p2 do + begin + x := orgs^[i].x; + if x <= x1 then x := x + d1 + else x := x + d2; + + curs^[i].x := x; + end + + else + if x1 < x2 then + + for i := p1 to p2 do + begin + x := orgs^[i].x; + + if (x <= x1) then x := x + d1 + else + if (x >= x2) then x := x + d2 + else + x := curs^[ref1].x + + MulDiv( x-x1, curs^[ref2].x-curs^[ref1].x, x2-x1 ); + + curs^[i].x := x; + end + else + + (* x2 < x1 *) + + for i := p1 to p2 do + begin + x := orgs^[i].x; + + if ( x <= x2 ) then x := x + d2 + else + if ( x >= x1 ) then x := x + d1 + else + x := curs^[ref1].x + + MulDiv( x-x1, curs^[ref2].x-curs^[ref1].x, x2-x1 ); + + curs^[i].x := x; + end; + end; + + procedure Interp_Y( p1, p2, ref1, ref2 : Int ); + var + i : Int; + y, y1, y2, d1, d2 : TT_F26dot6; + begin + + if p1 > p2 then exit; + + y1 := orgs^[ref1].y; d1 := curs^[ref1].y - orgs^[ref1].y; + y2 := orgs^[ref2].y; d2 := curs^[ref2].y - orgs^[ref2].y; + + if y1 = y2 then + for i := p1 to p2 do + begin + y := orgs^[i].y; + if y <= y1 then y := y + d1 + else y := y + d2; + + curs^[i].y := y; + end + + else + if y1 < y2 then + + for i := p1 to p2 do + begin + y := orgs^[i].y; + + if (y <= y1) then y := y + d1 + else + if (y >= y2) then y := y + d2 + else + y := curs^[ref1].y + + MulDiv( y-y1, curs^[ref2].y-curs^[ref1].y, y2-y1 ); + + curs^[i].y := y; + end + else + + (* y2 < y1 *) + + for i := p1 to p2 do + begin + y := orgs^[i].y; + + if ( y <= y2 ) then y := y + d2 + else + if ( y >= y1 ) then y := y + d1 + else + y := curs^[ref1].y + + MulDiv( y-y1, curs^[ref2].y-curs^[ref1].y, y2-y1 ); + + curs^[i].y := y; + end; + end; + + begin + orgs := exc.pts.org; + curs := exc.pts.cur; + + case exc.opcode and 1 of + 0 : mask := TT_Flag_Touched_Y; + 1 : mask := TT_Flag_Touched_X; + end; + + with exc do + begin + + contour := 0; + point := 0; + + repeat + + end_point := pts.conEnds^[contour]; + first_point := point; + + while ( point <= end_point ) and + ( pts.flags^[point] and mask = 0 ) do inc(point); + + if point <= end_point then + begin + + first_touched := point; + cur_touched := point; + + inc( point ); + + while ( point <= end_point ) do + begin + if pts.flags^[point] and mask <> 0 then + begin + if opcode and 1 <> 0 then + Interp_X( cur_touched+1, point-1, cur_touched, point ) + else + Interp_Y( cur_touched+1, point-1, cur_touched, point ); + + cur_touched := point; + end; + + inc( point ); + end; + + if cur_touched = first_touched then + if opcode and 1 <> 0 then + Shift_X( first_point, end_point, cur_touched ) + else + Shift_Y( first_point, end_point, cur_touched ) + else + begin + if opcode and 1 <> 0 then + begin + interp_x( cur_touched+1, end_point, cur_touched, first_touched ); + interp_x( first_point, first_touched-1, cur_touched, first_touched ); + end + else + begin + interp_y( cur_touched+1, end_point, cur_touched, first_touched ); + interp_y( first_point, first_touched-1, cur_touched, first_touched ); + end; + end; + + end; + + inc( contour ); + + until contour >= pts.n_contours; + + end; + + end; + +(**********************************************) +(* DELTAPn[] : DELTA Exceptions P1, P2, P3 *) +(* CodeRange : $5D,$71,$72 *) + + procedure Ins_DELTAP( args : PStorage ); + var + nump : Int; + k : Int; + A, B, C :Int; + begin + + nump := args^[0]; + + for K := 1 to nump do + begin + if exc.args < 2 then + begin + exc.error := TT_Err_Too_Few_Arguments; + exit; + end; + + dec( exc.args, 2 ); + + A := exc.stack^[exc.args+1]; + B := exc.stack^[ exc.args ]; + + (* XXX : *) + (* some commonly fonts have broke programs where the *) + (* the point reference has an invalid value. Here, we *) + (* simply ignore them, because a DeltaP won't change *) + (* a glyph shape dramatically.. *) + (* *) + + if A < exc.zp0.n_points then + begin + C := ( B and $F0 ) shr 4; + + Case exc.opcode of + $5D : ; + $71 : C := C+16; + $72 : C := C+32; + end; + + C := C + exc.GS.delta_Base; + + if GET_Ppem = C then + begin + B := (B and $F) - 8; + if B >= 0 then B := B+1; + B := ( B*64 ) div ( 1 shl exc.GS.delta_Shift ); + + exc.func_move( @exc.zp0, A, B ); + end; + end; + + end; + + exc.new_top := exc.args; + end; + + +(**********************************************) +(* DELTACn[] : DELTA Exceptions C1, C2, C3 *) +(* CodeRange : $73,$74,$75 *) + + procedure Ins_DELTAC( args : PStorage ); + var + nump : Int; + k : Int; + A, B, C :Int; + begin + + nump := args^[0]; + + for K := 1 to nump do + begin + if exc.args < 2 then + begin + exc.error := TT_Err_Too_Few_Arguments; + exit; + end; + + dec( exc.args, 2 ); + + A := exc.stack^[exc.args+1]; + B := exc.stack^[ exc.args ]; + + if A >= exc.cvtSize then + begin + exc.error := TT_Err_Invalid_Reference; + exit; + end; + + C := ( B and $F0 ) shr 4; + + Case exc.opcode of + $73 : ; + $74 : C := C+16; + $75 : C := C+32; + end; + + C := C + exc.GS.delta_Base; + + if GET_Ppem = C then + begin + B := (B and $F) - 8; + if B >= 0 then B := B+1; + B := ( B*64 ) div ( 1 shl exc.GS.delta_Shift ); + + exc.func_move_cvt( A, B ); + end; + end; + + exc.new_top := exc.args; + end; + +(****************************************************************) +(* *) +(* MISC. INSTRUCTIONS *) +(* *) +(****************************************************************) + +(***********************************************************) +(* DEBUG[] : DEBUG. Unsupported *) +(* CodeRange : $4F *) + +(* NOTE : The original instruction pops a value from the stack *) + + procedure Ins_DEBUG( args : PStorage ); + begin + exc.error := TT_Err_Debug_Opcode; + end; + +(**********************************************) +(* GETINFO[] : GET INFOrmation *) +(* CodeRange : $88 *) + + procedure Ins_GETINFO( args : PStorage ); + var + K : Int; + begin + K := 0; + + if args^[0] and 1 <> 0 then K := 3; + (* We return then Windows 3.1 version number *) + (* for the font scaler *) + + if false then K := K or $80; + (* Has the glyph been rotated ? *) + (* XXXX TO DO *) + + if false then K := K or $100; + (* Has the glyph been stretched ? *) + (* XXXX TO DO *) + + args^[0] := K; + end; + + + procedure Ins_UNKNOWN( args : PStorage ); + begin + exc.error := TT_Err_Invalid_Opcode; + end; + {$F-} + + + +const + Instruct_Dispatch : array[0..255] of TInstruction_Function + = ( + (* SVTCA y *) Ins_SVTCA, + (* SVTCA x *) Ins_SVTCA, + (* SPvTCA y *) Ins_SPVTCA, + (* SPvTCA x *) Ins_SPVTCA, + (* SFvTCA y *) Ins_SFVTCA, + (* SFvTCA x *) Ins_SFVTCA, + (* SPvTL // *) Ins_SPVTL, + (* SPvTL + *) Ins_SPVTL, + (* SFvTL // *) Ins_SFVTL, + (* SFvTL + *) Ins_SFVTL, + (* SPvFS *) Ins_SPVFS, + (* SFvFS *) Ins_SFVFS, + (* GPV *) Ins_GPV, + (* GFV *) Ins_GFV, + (* SFvTPv *) Ins_SFVTPV, + (* ISECT *) Ins_ISECT, + + (* SRP0 *) Ins_SRP0, + (* SRP1 *) Ins_SRP1, + (* SRP2 *) Ins_SRP2, + (* SZP0 *) Ins_SZP0, + (* SZP1 *) Ins_SZP1, + (* SZP2 *) Ins_SZP2, + (* SZPS *) Ins_SZPS, + (* SLOOP *) Ins_SLOOP, + (* RTG *) Ins_RTG, + (* RTHG *) Ins_RTHG, + (* SMD *) Ins_SMD, + (* ELSE *) Ins_ELSE, + (* JMPR *) Ins_JMPR, + (* SCvTCi *) Ins_SCVTCI, + (* SSwCi *) Ins_SSWCI, + (* SSW *) Ins_SSW, + + (* DUP *) Ins_DUP, + (* POP *) Ins_POP, + (* CLEAR *) Ins_CLEAR, + (* SWAP *) Ins_SWAP, + (* DEPTH *) Ins_DEPTH, + (* CINDEX *) Ins_CINDEX, + (* MINDEX *) Ins_MINDEX, + (* AlignPTS *) Ins_ALIGNPTS, + (* INS_$28 *) Ins_UNKNOWN, + (* UTP *) Ins_UTP, + (* LOOPCALL *) Ins_LOOPCALL, + (* CALL *) Ins_CALL, + (* FDEF *) Ins_FDEF, + (* ENDF *) Ins_ENDF, + (* MDAP[0] *) Ins_MDAP, + (* MDAP[1] *) Ins_MDAP, + + (* IUP[0] *) Ins_IUP, + (* IUP[1] *) Ins_IUP, + (* SHP[0] *) Ins_SHP, + (* SHP[1] *) Ins_SHP, + (* SHC[0] *) Ins_SHC, + (* SHC[1] *) Ins_SHC, + (* SHZ[0] *) Ins_SHZ, + (* SHZ[1] *) Ins_SHZ, + (* SHPIX *) Ins_SHPIX, + (* IP *) Ins_IP, + (* MSIRP[0] *) Ins_MSIRP, + (* MSIRP[1] *) Ins_MSIRP, + (* AlignRP *) Ins_ALIGNRP, + (* RTDG *) Ins_RTDG, + (* MIAP[0] *) Ins_MIAP, + (* MIAP[1] *) Ins_MIAP, + + (* NPushB *) Ins_NPUSHB, + (* NPushW *) Ins_NPUSHW, + (* WS *) Ins_WS, + (* RS *) Ins_RS, + (* WCvtP *) Ins_WCVTP, + (* RCvt *) Ins_RCVT, + (* GC[0] *) Ins_GC, + (* GC[1] *) Ins_GC, + (* SCFS *) Ins_SCFS, + (* MD[0] *) Ins_MD, + (* MD[1] *) Ins_MD, + (* MPPEM *) Ins_MPPEM, + (* MPS *) Ins_MPS, + (* FlipON *) Ins_FLIPON, + (* FlipOFF *) Ins_FLIPOFF, + (* DEBUG *) Ins_DEBUG, + + (* LT *) Ins_LT, + (* LTEQ *) Ins_LTEQ, + (* GT *) Ins_GT, + (* GTEQ *) Ins_GTEQ, + (* EQ *) Ins_EQ, + (* NEQ *) Ins_NEQ, + (* ODD *) Ins_ODD, + (* EVEN *) Ins_EVEN, + (* IF *) Ins_IF, + (* EIF *) Ins_EIF, + (* AND *) Ins_AND, + (* OR *) Ins_OR, + (* NOT *) Ins_NOT, + (* DeltaP1 *) Ins_DELTAP, + (* SDB *) Ins_SDB, + (* SDS *) Ins_SDS, + + (* ADD *) Ins_ADD, + (* SUB *) Ins_SUB, + (* DIV *) Ins_DIV, + (* MUL *) Ins_MUL, + (* ABS *) Ins_ABS, + (* NEG *) Ins_NEG, + (* FLOOR *) Ins_FLOOR, + (* CEILING *) Ins_CEILING, + (* ROUND[0] *) Ins_ROUND, + (* ROUND[1] *) Ins_ROUND, + (* ROUND[2] *) Ins_ROUND, + (* ROUND[3] *) Ins_ROUND, + (* NROUND[0]*) Ins_ROUND, + (* NROUND[1]*) Ins_ROUND, + (* NROUND[2]*) Ins_ROUND, + (* NROUND[3]*) Ins_ROUND, + + (* WCvtF *) Ins_WCVTF, + (* DeltaP2 *) Ins_DELTAP, + (* DeltaP3 *) Ins_DELTAP, + (* DeltaCn[0]*) Ins_DELTAC, + (* DeltaCn[1]*) Ins_DELTAC, + (* DeltaCn[2]*) Ins_DELTAC, + (* SROUND *) Ins_SROUND, + (* S45Round *) Ins_S45ROUND, + (* JROT *) Ins_JROT, + (* JROF *) Ins_JROF, + (* ROFF *) Ins_ROFF, + (* INS_$7B *) Ins_UNKNOWN, + (* RUTG *) Ins_RUTG, + (* RDTG *) Ins_RDTG, + (* SANGW *) Ins_SANGW, + (* AA *) Ins_AA, + + (* FlipPT *) Ins_FLIPPT, + (* FlipRgON *) Ins_FLIPRGON, + (* FlipRgOFF*) Ins_FLIPRGOFF, + (* INS_$83 *) Ins_UNKNOWN, + (* INS_$84 *) Ins_UNKNOWN, + (* ScanCTRL *) Ins_SCANCTRL, + (* SDPVTL[0]*) Ins_SDPVTL, + (* SDPVTL[1]*) Ins_SDPVTL, + (* GetINFO *) Ins_GETINFO, + (* IDEF *) Ins_IDEF, + (* ROLL *) Ins_ROLL, + (* MAX *) Ins_MAX, + (* MIN *) Ins_MIN, + (* ScanTYPE *) Ins_SCANTYPE, + (* InstCTRL *) Ins_INSTCTRL, + (* INS_$8F *) Ins_UNKNOWN, + + (* INS_$90 *) Ins_UNKNOWN, + (* INS_$91 *) Ins_UNKNOWN, + (* INS_$92 *) Ins_UNKNOWN, + (* INS_$93 *) Ins_UNKNOWN, + (* INS_$94 *) Ins_UNKNOWN, + (* INS_$95 *) Ins_UNKNOWN, + (* INS_$96 *) Ins_UNKNOWN, + (* INS_$97 *) Ins_UNKNOWN, + (* INS_$98 *) Ins_UNKNOWN, + (* INS_$99 *) Ins_UNKNOWN, + (* INS_$9A *) Ins_UNKNOWN, + (* INS_$9B *) Ins_UNKNOWN, + (* INS_$9C *) Ins_UNKNOWN, + (* INS_$9D *) Ins_UNKNOWN, + (* INS_$9E *) Ins_UNKNOWN, + (* INS_$9F *) Ins_UNKNOWN, + + (* INS_$A0 *) Ins_UNKNOWN, + (* INS_$A1 *) Ins_UNKNOWN, + (* INS_$A2 *) Ins_UNKNOWN, + (* INS_$A3 *) Ins_UNKNOWN, + (* INS_$A4 *) Ins_UNKNOWN, + (* INS_$A5 *) Ins_UNKNOWN, + (* INS_$A6 *) Ins_UNKNOWN, + (* INS_$A7 *) Ins_UNKNOWN, + (* INS_$A8 *) Ins_UNKNOWN, + (* INS_$A9 *) Ins_UNKNOWN, + (* INS_$AA *) Ins_UNKNOWN, + (* INS_$AB *) Ins_UNKNOWN, + (* INS_$AC *) Ins_UNKNOWN, + (* INS_$AD *) Ins_UNKNOWN, + (* INS_$AE *) Ins_UNKNOWN, + (* INS_$AF *) Ins_UNKNOWN, + + (* PushB[0] *) Ins_PUSHB, + (* PushB[1] *) Ins_PUSHB, + (* PushB[2] *) Ins_PUSHB, + (* PushB[3] *) Ins_PUSHB, + (* PushB[4] *) Ins_PUSHB, + (* PushB[5] *) Ins_PUSHB, + (* PushB[6] *) Ins_PUSHB, + (* PushB[7] *) Ins_PUSHB, + (* PushW[0] *) Ins_PUSHW, + (* PushW[1] *) Ins_PUSHW, + (* PushW[2] *) Ins_PUSHW, + (* PushW[3] *) Ins_PUSHW, + (* PushW[4] *) Ins_PUSHW, + (* PushW[5] *) Ins_PUSHW, + (* PushW[6] *) Ins_PUSHW, + (* PushW[7] *) Ins_PUSHW, + + (* MDRP[00] *) Ins_MDRP, + (* MDRP[01] *) Ins_MDRP, + (* MDRP[02] *) Ins_MDRP, + (* MDRP[03] *) Ins_MDRP, + (* MDRP[04] *) Ins_MDRP, + (* MDRP[05] *) Ins_MDRP, + (* MDRP[06] *) Ins_MDRP, + (* MDRP[07] *) Ins_MDRP, + (* MDRP[08] *) Ins_MDRP, + (* MDRP[09] *) Ins_MDRP, + (* MDRP[10] *) Ins_MDRP, + (* MDRP[11] *) Ins_MDRP, + (* MDRP[12] *) Ins_MDRP, + (* MDRP[13] *) Ins_MDRP, + (* MDRP[14] *) Ins_MDRP, + (* MDRP[15] *) Ins_MDRP, + (* MDRP[16] *) Ins_MDRP, + (* MDRP[17] *) Ins_MDRP, + + (* MDRP[18] *) Ins_MDRP, + (* MDRP[19] *) Ins_MDRP, + (* MDRP[20] *) Ins_MDRP, + (* MDRP[21] *) Ins_MDRP, + (* MDRP[22] *) Ins_MDRP, + (* MDRP[23] *) Ins_MDRP, + (* MDRP[24] *) Ins_MDRP, + (* MDRP[25] *) Ins_MDRP, + (* MDRP[26] *) Ins_MDRP, + (* MDRP[27] *) Ins_MDRP, + (* MDRP[28] *) Ins_MDRP, + (* MDRP[29] *) Ins_MDRP, + (* MDRP[30] *) Ins_MDRP, + (* MDRP[31] *) Ins_MDRP, + + (* MIRP[00] *) Ins_MIRP, + (* MIRP[01] *) Ins_MIRP, + (* MIRP[02] *) Ins_MIRP, + (* MIRP[03] *) Ins_MIRP, + (* MIRP[04] *) Ins_MIRP, + (* MIRP[05] *) Ins_MIRP, + (* MIRP[06] *) Ins_MIRP, + (* MIRP[07] *) Ins_MIRP, + (* MIRP[08] *) Ins_MIRP, + (* MIRP[09] *) Ins_MIRP, + (* MIRP[10] *) Ins_MIRP, + (* MIRP[11] *) Ins_MIRP, + (* MIRP[12] *) Ins_MIRP, + (* MIRP[13] *) Ins_MIRP, + (* MIRP[14] *) Ins_MIRP, + (* MIRP[15] *) Ins_MIRP, + + (* MIRP[16] *) Ins_MIRP, + (* MIRP[17] *) Ins_MIRP, + (* MIRP[18] *) Ins_MIRP, + (* MIRP[19] *) Ins_MIRP, + (* MIRP[20] *) Ins_MIRP, + (* MIRP[21] *) Ins_MIRP, + (* MIRP[22] *) Ins_MIRP, + (* MIRP[23] *) Ins_MIRP, + (* MIRP[24] *) Ins_MIRP, + (* MIRP[25] *) Ins_MIRP, + (* MIRP[26] *) Ins_MIRP, + (* MIRP[27] *) Ins_MIRP, + (* MIRP[28] *) Ins_MIRP, + (* MIRP[29] *) Ins_MIRP, + (* MIRP[30] *) Ins_MIRP, + (* MIRP[31] *) Ins_MIRP + + ); + +(****************************************************************) +(* *) +(* RUN *) +(* *) +(* This function executes a run of opcodes. It will exit *) +(* in the following cases : *) +(* *) +(* - Errors ( in which case it returns FALSE ) *) +(* *) +(* - Reaching the end of the main code range (returns TRUE) *) +(* reaching the end of a code range within a function *) +(* call is an error. *) +(* *) +(* - After executing one single opcode, if the flag *) +(* 'Instruction_Trap' is set to TRUE. (returns TRUE) *) +(* *) +(* On exit whith TRUE, test IP < CodeSize to know wether it *) +(* comes from a instruction trap or a normal termination *) +(* *) +(* *) +(* Note : The documented DEBUG opcode pops a value from *) +(* the stack. This behaviour is unsupported, here *) +(* a DEBUG opcode is always an error. *) +(* *) +(* *) +(* THIS IS THE INTERPRETER'S MAIN LOOP *) +(* *) +(* Instructions appear in the specs' order *) +(* *) +(****************************************************************) + + function Run_Ins( exec : PExec_Context ) : Boolean; + label + SuiteLabel, ErrorLabel, No_Error; + var + A : Int; + begin + + exc := exec^; + + (* set cvt functions *) + + exc.metrics.ratio := 0; + if exc.instance^.metrics.x_ppem <> exc.instance^.metrics.y_ppem then +{$IFDEF FPK} + begin + exc.func_read_cvt := @Read_CVT_Stretched; + exc.func_write_cvt := @Write_CVT_Stretched; + exc.func_move_cvt := @Move_CVT_Stretched; + end + else + begin + exc.func_read_cvt := @Read_CVT; + exc.func_write_cvt := @Write_CVT; + exc.func_move_cvt := @Move_CVT; + end; +{$ELSE} + begin + exc.func_read_cvt := Read_CVT_Stretched; + exc.func_write_cvt := Write_CVT_Stretched; + exc.func_move_cvt := Move_CVT_Stretched; + end + else + begin + exc.func_read_cvt := Read_CVT; + exc.func_write_cvt := Write_CVT; + exc.func_move_cvt := Move_CVT; + end; +{$ENDIF} + Compute_Funcs; + Compute_Round( exc.GS.round_state ); + + repeat + Calc_Length; + + (* First, let's check for empty stack and overflow *) + + exc.args := exc.top - Pop_Push_Count[ exc.opcode*2 ]; + + (* args is the top of the stack once arguments have been popped *) + (* one can also see it as the index of the last argument *) + + if exc.args < 0 then + begin + exc.error := TT_Err_Too_Few_Arguments; + goto ErrorLabel; + end; + + exc.new_top := exc.args + Pop_Push_Count[ exc.opcode*2+1 ]; + + (* new_top is the new top of the stack, after the instruction's *) + (* execution. top will be set to new_top after the 'case' *) + + if exc.new_top > exc.stackSize then + begin + exc.error := TT_Err_Stack_Overflow; + goto ErrorLabel; + end; + + exc.step_ins := true; + exc.error := TT_Err_Ok; + + Instruct_Dispatch[ exc.opcode ]( PStorage(@exc.stack^[exc.args]) ); + + if exc.error <> TT_Err_Ok then + begin + + case exc.error of + + TT_Err_Invalid_Opcode: (* looking for redefined instructions *) + + begin + A := 0; + while ( A < exc.numIDefs ) do + with exc.IDefs^[A] do + + if Active and ( exc.opcode = Opc ) then + begin + if exc.callTop >= exc.callSize then + begin + exc.error := TT_Err_Invalid_Reference; + goto ErrorLabel; + end; + + with exc.callstack^[exc.callTop] do + begin + Caller_Range := exc.curRange; + Caller_IP := exc.IP+1; + Cur_Count := 1; + Cur_Restart := Start; + end; + + if not Goto_CodeRange( Range, Start ) then + goto ErrorLabel; + + goto SuiteLabel; + end + else + inc(A); + + exc.error := TT_Err_Invalid_Opcode; + goto ErrorLabel; + + end; + else + exc.error := exc.error; + goto ErrorLabel; + end; + + end; + + exc.top := exc.new_top; + + if exc.step_ins then inc( exc.IP, exc.length ); + + SuiteLabel: + + if (exc.IP >= exc.codeSize) then + + if exc.callTop > 0 then + begin + exc.error := TT_Err_Code_Overflow; + goto ErrorLabel; + end + else + goto No_Error; + + until exc.instruction_trap; + + No_Error: + Run_Ins := Success; + exec^ := exc; + exit; + + ErrorLabel: + Run_Ins := Failure; + exec^ := exc; + + end; + +end. diff --git a/pascal/lib/ttload.pas b/pascal/lib/ttload.pas new file mode 100644 index 0000000..a7f234a --- /dev/null +++ b/pascal/lib/ttload.pas @@ -0,0 +1,1496 @@ +(******************************************************************* + * + * TTLoad.Pas 1.0 + * + * TrueType Tables loaders + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Difference between 1.0 and 1.1 : HUGE !! + * + * - Changed the load model to get in touch with TTFile 1.1 + * - Now loads one whole resident table in one call + * - defined resident and instance records/data + * + ******************************************************************) + +Unit TTLoad; + +interface + +uses FreeType, TTTypes, TTTables, TTCMap, TTObjs; + + function LookUp_TrueType_Table( face : PFace; + aTag : string ) : int; + + function Load_TrueType_Directory( face : PFace; + faceIndex : Int ) : TError; + + function Load_TrueType_MaxProfile( face : PFace ) : TError; + function Load_TrueType_Header ( face : PFace ) : TError; + function Load_TrueType_Locations ( face : PFace ) : TError; + function Load_TrueType_CVT ( face : PFace ) : TError; + function Load_TrueType_CMap ( face : PFace ) : TError; + function Load_TrueType_Gasp ( face : PFace ) : TError; + function Load_TrueType_Names ( face : PFace ) : TError; + function Load_TrueType_Programs ( face : PFace ) : TError; + function Load_trueType_Postscript( face : PFace ) : TError; + function Load_TrueType_OS2 ( face : PFace ) : TError; + function Load_TrueType_HDMX ( face : PFace ) : TError; + + function Load_TrueType_Metrics_Header( face : PFace; + vertical : Boolean ) : TError; + + function Load_TrueType_Any( face : PFace; + tag : longint; + offset : longint; + var buffer; + var length : longint ) : TError; + +implementation + +uses TTError, TTMemory, TTFile, TTCalc; + + (* Composite glyph decoding flags *) + +(******************************************************************* + * + * Function : LookUp_TrueType_Table + * + * Description : Looks for a TrueType table by name + * + * Input : face resident table to look for + * aTag searched tag + * + * Output : index of table if found, -1 otherwise. + * + ******************************************************************) + + function LookUp_TrueType_Table( face : PFace; + aTag : string ) : int; + var + ltag : Long; + i : int; + begin + ltag := (Long(ord(aTag[1])) shl 24) + (Long(ord(aTag[2])) shl 16) + + (Long(ord(aTag[3])) shl 8 ) + Long(ord(aTag[4])); + + for i := 0 to face^.numTables-1 do + begin + + if face^.dirTables^[i].Tag = lTag then + begin + LookUp_TrueType_Table := i; + exit; + end + end; + + (* couldn't find the table *) + LookUp_TrueType_Table := -1; + end; + + + function LookUp_Mandatory_Table( face : PFace; + aTag : string ) : int; + var + table : int; + begin + table := LookUp_TrueType_Table( face, aTag ); + if table < 0 then + error := TT_Err_Table_Missing; + + LookUp_Mandatory_Table := table; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Collection + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : A table directory doesn't own subttables. There is no + * constructor or destructor for it. + * + ******************************************************************) + + function Load_TrueType_Collection( face : PFace ) : TError; + var + n : Int; + const + TTC_Tag = ( ord('t') shl 24 ) + + ( ord('t') shl 16 ) + + ( ord('c') shl 8 ) + + ( ord(' ') ); + begin + Load_TrueType_Collection := Failure; + + with face^.ttcHeader do + begin + + if TT_Seek_File( 0 ) or + TT_Access_Frame( 12 ) then exit; + + Tag := Get_ULong; + version := Get_Long; + dirCount := Get_Long; + + TT_Forget_Frame; + + if Tag <> TTC_Tag then + begin + Tag := 0; + version := 0; + dirCount := 0; + tableDirectory := nil; + + error := TT_Err_File_Is_Not_Collection; + exit; + end; + + if Alloc( tableDirectory, dirCount * sizeof(ULong) ) or + TT_Access_Frame( dirCount*4 ) then exit; + + for n := 0 to dirCount-1 do + tableDirectory^[n] := Get_ULong; + + TT_Forget_Frame; + end; + + Load_TrueType_Collection := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Directory + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : A table directory doesn't own subttables. There is no + * constructor or destructor for it. + * + ******************************************************************) + + function Load_TrueType_Directory( face : PFace; + faceIndex : Int ) : TError; + var + n : Int; + tableDir : TTableDir; + begin + Load_TrueType_Directory := Failure; + + {$IFDEF DEBUG} Write('Directory '); {$ENDIF} + + if Load_TrueType_Collection(face) then + begin + if error <> TT_Err_File_Is_Not_Collection then + exit; + + (* The file isn't a collection, exit if index isn't 0 *) + if faceIndex <> 0 then + exit; + + error := TT_Err_Ok; + + (* Now skip to the beginning of the file *) + if TT_Seek_File(0) then + exit; + end + else + begin + (* file is a collection. Check the index *) + if ( faceIndex < 0 ) or + ( faceIndex >= face^.ttcHeader.dirCount ) then + begin + error := TT_Err_Bad_Argument; + exit; + end; + + (* select a TT Font within the ttc file *) + if TT_Seek_File( face^.ttcHeader.tableDirectory^[faceIndex] ) then + exit; + end; + + if TT_Access_Frame( 12 ) then + exit; + + tableDir.version := GET_Long; + tableDir.numTables := GET_UShort; + + tableDir.searchRange := GET_UShort; + tableDir.entrySelector := GET_UShort; + tableDir.rangeShift := GET_UShort; + + {$IFDEF DEBUG} Writeln('Tables number : ', tableDir.numTables ); {$ENDIF} + + TT_Forget_Frame; + + (* Check that we have a 'sfnt' format there *) + if (tableDir.version <> $10000 ) and (* MS fonts *) + (tableDir.version <> $74727565) then (* Mac fonts *) + begin + {$IFDEF DEBUG} Writeln('Invalid font format'); {$ENDIF} + error := TT_Err_Invalid_File_Format; + exit; + end; + + with face^ do + begin + + numTables := tableDir.numTables; + + if Alloc( dirTables, numTables * sizeof( TTableDirEntry ) ) or + TT_Access_Frame( 16 * numTables ) then exit; + + for n := 0 to numTables-1 do with dirTables^[n] do + begin + Tag := GET_ULong; + Checksum := GET_ULong; + Offset := GET_Long; + Length := Get_Long; + end; + + TT_Forget_Frame; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Directory := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_MaxProfile + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : A maximum profile is a static table that owns no + * subttable. It has then no constructor nor destructor + * + ******************************************************************) + + function Load_TrueType_MaxProfile( face : PFace ) : TError; + var + table : int; + begin + + Load_TrueType_MaxProfile := Failure; + + {$IFDEF DEBUG} Write('MaxProfile '); {$ENDIF} + + table := LookUp_Mandatory_Table( face, 'maxp'); + if table < 0 then exit; + + with face^ do + begin + + if TT_Seek_File( dirTables^[table].Offset ) or + TT_Access_Frame( 32 ) then exit; + + with MaxProfile do + begin + + ULong(Version) := GET_ULong; + + numGlyphs := GET_UShort; + maxPoints := GET_UShort; + maxContours := GET_UShort; + + maxCompositePoints := GET_UShort; + maxCompositeContours := GET_UShort; + maxZones := GET_UShort; + maxTwilightPoints := GET_UShort; + maxStorage := GET_UShort; + maxFunctionDefs := GET_UShort; + maxINstructionDefs := GET_UShort; + maxStackElements := GET_UShort; + + maxSizeOfInstructions := GET_UShort; + maxComponentElements := GET_UShort; + maxComponentDepth := GET_UShort; + end; + + TT_Forget_Frame; + + (* XXX : an adjustement that is necessary to load certain */ + /* broken fonts like "Keystrokes MT" :-( */ + /* */ + /* We allocate 64 function entries by default when */ + /* the maxFunctionDefs field is null. *) + + (* otherwise, we increment this field by one, in order *) + (* to load some old Apple fonts.. *) + + if maxProfile.maxFunctionDefs = 0 then + maxProfile.maxFunctionDefs := 64; + + numGlyphs := MaxProfile.numGlyphs; + (* compute number of glyphs *) + + maxPoints := MaxProfile.maxCompositePoints; + if (maxPoints < MaxProfile.maxPoints) then + maxPoints := MaxProfile.maxPoints; + (* compute max number of points *) + + maxContours := MaxProfile.maxCompositeContours; + if maxContours < MaxProfile.maxContours then + maxContours := MaxProfile.maxContours; + (* compute max number of contours *) + + maxComponents := MaxProfile.maxComponentElements + + MaxProfile.maxComponentDepth; + (* compute max number of components for glyph loading *) + + (* XXX: some fonts have maxComponents set to 0; we will *) + (* then use 16 of them by default *) + if maxComponents = 0 then maxComponents := 16; + + (* We also increase maxPoints and maxContours in order to support *) + (* some broken fonts *) + inc( maxPoints, 8 ); + inc( maxContours, 4 ); + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_MaxProfile := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Gasp + * + * Description : + * + * Input : face + * + ******************************************************************) + + function Load_TrueType_Gasp( face : PFace ) : TError; + var + gRanges : PGaspRanges; + table, i : Int; + label + Fail; + begin + Load_TrueType_Gasp := Failure; + + with face^.gasp do + begin + version := 0; + numRanges := 0; + gaspRanges := nil; + end; + + table := Lookup_TrueType_Table( face, 'gasp' ); + if ( table < 0 ) then + begin + Load_TrueType_Gasp := Success; + exit; + end; + + if TT_Seek_File( face^.dirTables^[table].Offset ) or + TT_Access_Frame( 4 ) then exit; + + with face^.gasp do + begin + version := Get_UShort; + numRanges := Get_UShort; + gaspRanges := nil; + end; + + TT_Forget_Frame; + + if Alloc( gRanges, face^.gasp.numRanges * sizeof(TGaspRange) ) or + TT_Access_Frame( face^.gasp.numRanges * 4 ) then + goto Fail; + + face^.gasp.gaspRanges := gRanges; + + for i := 0 to face^.gasp.numRanges-1 do + with gRanges^[i] do + begin + maxPPEM := Get_UShort; + gaspFlag := Get_UShort; + end; + + TT_Forget_Frame; + + Load_TrueType_Gasp := Success; + exit; + + Fail: + Free( gRanges ); + face^.gasp.numRanges := 0; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_Header + * + * Description : Load the TrueType header table in the resident + * table + * + * Input : face current leading segment. + * + * Output : True on success. False on failure + * + * Notes : A font header is a static table that owns no + * subttable. It has then no constructor nor destructor + * + ******************************************************************) + + function Load_TrueType_Header( face : PFace ) : TError; + var + i : int; + begin + Load_TrueType_Header := Failure; + + {$IFDEF DEBUG} Write('Header '); {$ENDIF} + + i := LookUp_Mandatory_Table(face, 'head'); + if i <= 0 then exit; + + with face^ do + begin + + if TT_Seek_File( dirTables^[i].offset ) or + TT_Access_Frame( 54 ) then exit; + + with FontHeader do + begin + + ULong(Table_Version) := GET_ULong; + ULong(Font_Revision) := GET_ULong; + + Checksum_Adjust := GET_Long; + Magic_Number := GET_Long; + + Flags := GET_UShort; + Units_Per_EM := GET_UShort; + + Created [0] := GET_Long; Created [1] := GET_Long; + Modified[0] := GET_Long; Modified[1] := GET_Long; + + xMin := GET_Short; + yMin := GET_SHort; + xMax := GET_SHort; + yMax := GET_Short; + + Mac_Style := GET_UShort; + Lowest_Rec_PPEM := GET_UShort; + + Font_Direction := GET_Short; + Index_To_Loc_Format := GET_Short; + Glyph_Data_Format := GET_Short; + + {$IFDEF DEBUG} Writeln('Units per EM : ',Units_Per_EM ); {$ENDIF} + + end; + + TT_Forget_Frame; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Header := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Metrics + * + * Description : Load TrueType metrics either from the "hmtx" or + * "vmtx" table. + * + * Input : face current resident leading segment + * vertical boolean. When set, try to load the vertical + * header. + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Metrics( face : PFace; + vertical : Boolean ) : TError; + var + table, n : int; + num_longs : int; + num_shorts : int; + num_shorts_checked : int; + temp : Short; + + header : ^TT_Horizontal_Header; + + shorts : ^PTableShortMetrics; + longs : ^PTableLongMetrics; + + begin + Load_TrueType_Metrics := Failure; + + {$IFDEF DEBUG} + if vertical then + Write('vmtx ') + else + Write('hmtx '); + {$ENDIF} + + if vertical then + begin + + table := LookUp_TrueType_Table( face, 'vmtx' ); + if table < 0 then + begin + (* This is an optional table. Return silently if it *) + (* wasn't found. Note : some fonts have a vertical *) + (* header, but no 'vmtx'. E.g. : mingliu.ttf *) + + face^.verticalHeader.number_Of_VMetrics := 0; + Load_TrueType_Metrics := Success; + exit; + end; + + header := @TT_Horizontal_Header(face^.verticalHeader); + end + else + begin + table := LookUp_Mandatory_Table( face, 'hmtx' ); + if table < 0 then + exit; + + header := @face^.horizontalHeader; + end; + + + shorts := @PTableShortMetrics(header^.short_metrics); + longs := @PTableLongMetrics (header^.long_metrics ); + + num_longs := header^.number_Of_HMetrics; + num_shorts := face^.numGlyphs - num_longs; + + num_shorts_checked := (face^.dirTables^[table].Length - num_longs*4) div 2; + + if num_shorts < 0 then + begin + {$IFDEF DEBUG} Writeln('!! More metrics than glyphs !\n'); {$ENDIF} + if vertical then error := TT_Err_Invalid_Vert_Metrics + else error := TT_Err_Invalid_Horiz_Metrics; + exit; + end; + + if Alloc( longs^, sizeof(TLongMetrics) * num_longs ) or + Alloc( shorts^, sizeof(TShortMetrics)* num_shorts ) or + + TT_Seek_File( face^.dirTables^[table].Offset ) or + TT_Access_Frame( face^.dirTables^[table].Length ) then exit; + + for n := 0 to num_longs-1 do with longs^^[n] do + begin + advance := GET_UShort; + bearing := GET_Short; + end; + + (* do we have an inconsistent number of metric values ? *) + if num_shorts > num_shorts_checked then + begin + for n := 0 to num_shorts_checked-1 do + shorts^^[n] := GET_Short; + + (* we fill up the missing left side bearings with the *) + (* last valid value. Since this will occur for buggy CJK *) + (* fonts usually, nothing serious will happen. *) + + temp := shorts^^[num_shorts_checked-1]; + + for n := num_shorts_checked to num_shorts-1 do + shorts^^[n] := temp; + end + else + for n := 0 to num_shorts-1 do + shorts^^[n] := GET_Short; + + TT_Forget_Frame; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Metrics := Success; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_Metrics_Header + * + * Description : + * + * Input : face current resident leading segment + * vertical boolean. When set, try to load the vertical + * header. + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Metrics_Header( face : PFace; + vertical : Boolean ) : TError; + var + table : int; + header : ^TT_Horizontal_Header; + begin + Load_TrueType_Metrics_Header := Failure; + + {$IFDEF DEBUG} + if vertical then + Write('Vertical Header ') + else + Write('Horizontal Header '); + {$ENDIF} + + if vertical then + begin + face^.verticalInfo := False; + + (* the vertical header is an optional table.. so return *) + (* silently if we don't find it *) + table := LookUp_TrueType_Table( face, 'vhea' ); + if (table < 0) then + begin + Load_TrueType_Metrics_Header := Success; + exit; + end; + + face^.verticalInfo := True; + header := @TT_Horizontal_Header(face^.verticalHeader); + end + else + begin + table := LookUp_Mandatory_Table( face, 'hhea'); + if ( table < 0 ) then + exit; + header := @face^.horizontalHeader; + end; + + with face^ do + begin + + if TT_Seek_File( dirTables^[table].Offset ) or + TT_Access_Frame( 36 ) then + exit; + + with header^ do + begin + + Long(Version) := GET_ULong; + Ascender := GET_Short; + Descender := GET_Short; + Line_Gap := GET_Short; + + advance_Width_Max := GET_UShort; + + min_Left_Side_Bearing := GET_Short; + min_Right_Side_Bearing := GET_Short; + xMax_Extent := GET_Short; + caret_Slope_Rise := GET_Short; + caret_Slope_Run := GET_Short; + + Reserved[0] := GET_Short; (* this is cared offset for vertical *) + + Reserved[1] := GET_Short; + Reserved[2] := GET_Short; + Reserved[3] := GET_Short; + Reserved[4] := GET_Short; + + metric_Data_Format := GET_Short; + number_Of_HMetrics := GET_UShort; + + short_metrics := nil; + long_metrics := nil; + + end; + + TT_Forget_Frame; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Metrics_Header := Load_TrueType_Metrics( face, vertical ); + end; + +(******************************************************************* + * + * Function : Load_TrueType_Locations + * + * Description : Loads the location table in resident table + * + * Input : face Current Resident Leading Segment + * + * Output : True on success. False on failure + * + * NOTES : + * + * The Font Header *must* be loaded in the leading segment + * before calling this function. + * + * This table is destroyed directly by the resident destructor. + * + ******************************************************************) + + function Load_TrueType_Locations( face : PFace ): TError; + var + t, n : int; + LongOffsets : int; + begin + + Load_TrueType_Locations := Failure; + + {$IFDEF DEBUG} Write('Locations '); {$ENDIF} + + with face^ do + begin + + LongOffsets := fontHeader.Index_To_Loc_Format; + + t := LookUp_Mandatory_Table( face, 'loca' ); + if t < 0 then exit; + + if TT_Seek_File( dirTables^[T].Offset ) then exit; + + if LongOffsets <> 0 then + begin + + numLocations := dirTables^[T].Length shr 2; + + {$IFDEF DEBUG} + Writeln('Glyph locations # ( 32 bits offsets ) : ', numLocations ); + {$ENDIF} + + if Alloc( glyphLocations, sizeof(Long)*numLocations ) or + TT_Access_Frame( numLocations*4 ) then exit; + + for n := 0 to numLocations-1 do + glyphLocations^[n] := GET_Long; + + TT_Forget_Frame; + + end + else + begin + numLocations := dirTables^[T].Length shr 1; + + {$IFDEF DEBUG} + Writeln('Glyph locations # ( 16 bits offsets ) : ', numLocations ); + {$ENDIF} + + if Alloc( glyphLocations, sizeof(Long)*numLocations ) or + TT_Access_Frame( numLocations*2 ) then exit; + + for n := 0 to numLocations-1 do + glyphLocations^[n] := Long(GET_UShort) * 2; + + TT_Forget_Frame; + end; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_Locations := Success; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_Names + * + * Description : Loads the name table into the face table + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : This attribute table is destroyed by the resident + * destructor. + * + ******************************************************************) + + function Load_TrueType_Names( face : PFace ) : TError; + var + table, i : Int; + bytes : Long; + begin + Load_TrueType_Names := Failure; + + table := Lookup_Mandatory_Table( face, 'name' ); + if table < 0 then exit; + + with face^.nameTable do + begin + (* Seek to the beginning of the table and check the frame access. *) + if TT_Seek_File( face^.dirTables^[table].Offset ) or + TT_Access_Frame( 6 ) then exit; + + format := GET_UShort; + numNameRecords := GET_UShort; + storageOffset := GET_UShort; + + TT_Forget_Frame; + + if Alloc( names, numNameRecords*sizeof(TName_Record) ) or + TT_Access_Frame( numNameRecords*12 ) then + begin + numNameRecords := 0; + exit; + end; + + (* Load the name records and determine how much storage is needed *) + (* to hold the strings themselves *) + + bytes := 0; + for i := 0 to numNameRecords-1 do with names^[i] do + begin + platformID := GET_UShort; + encodingID := GET_UShort; + languageID := GET_UShort; + nameID := GET_UShort; + length := GET_UShort; + offset := GET_UShort; + + (* this test takes care of 'holes' in the names tabls, as *) + (* reported by Erwin *) + if Offset + Length > bytes then + bytes := Offset + Length; + end; + + TT_Forget_Frame; + + storage := nil; + if bytes > 0 then + begin + if Alloc( storage, bytes ) then exit; + + if TT_Read_At_File( face^.dirTables^[table].Offset + storageOffset, + storage^, bytes ) then + begin + Free(storage); + exit; + end; + end; + + end; + + Load_TrueType_Names := Success; + exit; + end; + +(******************************************************************* + * + * Function : Load_TrueType_CVT + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : This attribute table is destroyed by the resident + * destructor. + * + ******************************************************************) + + function Load_TrueType_CVT( face : PFace ): TError; + var + t, n : Int; + begin + Load_TrueType_CVT := Failure; + + {$IFDEF DEBUG} Write('CVT '); {$ENDIF} + + (* the CVT table is optional *) + + t := LookUp_TrueType_Table( face, 'cvt '); + if t < 0 then + begin + face^.cvt := nil; + face^.cvtSize := 0; + Load_TrueType_CVT := Success; + {$IFDEF DEBUG} writeln('none'); {$ENDIF} + exit; + end; + + with face^ do + begin + + cvtSize := dirTables^[t].Length div 2; + + if Alloc( cvt, sizeof(Short)*cvtSize ) or + + TT_Seek_File( dirTables^[t].Offset ) or + + TT_Access_Frame( 2*cvtSize ) then exit; + + for n := 0 to cvtSize-1 do + cvt^[n] := GET_Short; + + TT_Forget_Frame; + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + Load_TrueType_CVT := Success; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_CMap + * + * Description : + * + * Input : face + * + * Output : True on success. False on failure + * + * Notes : The Cmap table directory is destroyed by the resident + * destructor. The Cmap subtables must be destroyed by + * Free_CMap_Table. + * + ******************************************************************) + + function Load_TrueType_CMap( face : PFace ) : TError; + var + off, table_start : Longint; + n, limit, t : Int; + + cmap_dir : TCMapDir; + entry : TCMapDirEntry; + cmap : PCMapTable; + label + Fail; + begin + + Load_TrueType_CMap := Failure; + + {$IFDEF DEBUG} Write('CMaps '); {$ENDIF} + + t := LookUp_Mandatory_Table( face,'cmap' ); + if t < 0 then exit; + + with face^ do + begin + + table_start := dirTables^[t].offset; + + if TT_Seek_File( dirTables^[t].Offset ) or + TT_Access_Frame( 4 ) then exit; + + cmap_dir.tableVersionNumber := GET_UShort; + cmap_dir.numCMaps := GET_UShort; + + TT_Forget_Frame; + + off := TT_File_Pos; + + (* save space in face data for cmap tables *) + numCMaps := cmap_dir.numCMaps; + if Alloc( cMaps, numCMaps * sizeof(TCMapTable) ) then exit; + + for n := 0 to numCMaps-1 do + begin + + if TT_Seek_File ( off ) or + TT_Access_Frame( 8 ) then exit; + + cmap := @cMaps^[n]; + + entry.platformID := GET_UShort; + entry.platformEncodingID := GET_UShort; + entry.offset := GET_Long; + + cmap^.loaded := False; + cmap^.platformID := entry.platformID; + cmap^.platformEncodingID := entry.platformEncodingID; + + TT_Forget_Frame; + + off := TT_File_Pos; + + if TT_Seek_File ( table_start + entry.offset ) or + TT_Access_Frame( 6 ) then exit; + + cmap^.format := Get_UShort; + cmap^.length := Get_UShort; + cmap^.version := Get_UShort; + + TT_Forget_Frame; + + cmap^.offset := TT_File_Pos; + + end; (* for n *) + + end; (* with face^ *) + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_CMap := Success; + exit; + + Fail: + Free( face^.cMaps ); + Load_TrueType_CMap := Failure; + end; + + +(* + procedure Free_CMap_Table( var cmap : TCMapTable ); + begin + if cmap.cmap0 <> nil then + with cmap do + case format of + + 0 : begin + Free( cmap0^.glyphIdArray ); + Free( cmap0 ); + end; + + 2 : begin + Free( cmap2^.glyphIdArray ); + Free( cmap2^.subHeaders ); + Free( cmap2 ); + end; + + 4 : begin + Free( cmap4^.glyphIdArray ); + Free( cmap4^.segments ); + Free( cmap4 ); + end; + + 6 : begin + Free( cmap6^.glyphIdArray ); + Free( cmap6 ); + end; + end; + + cmap.format := 0; + cmap.length := 0; + cmap.version := 0; + end; +*) + +(******************************************************************* + * + * Function : Load_TrueType_Programs + * + * Description : Load the Font and CVT programs in the resident + * table + * + * Input : face + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Programs( face : PFace ) : TError; + var + t : Int; + begin + + Load_TrueType_Programs := Failure; + + {$IFDEF DEBUG} Write('Font program '); {$ENDIF} + + (* The font program is optional *) + + t := Lookup_TrueType_Table( face, 'fpgm' ); + + if t < 0 then + + with face^ do + begin + fontProgram := nil; + fontPgmSize := 0; + + {$IFDEF DEBUG} Writeln('none in file'); {$ENDIF} + end + + else + + with face^ do + begin + + fontPgmSize := dirTables^[t].Length; + + if Alloc( fontProgram, fontPgmSize ) or + TT_Read_At_File( dirTables^[t].offset, + fontProgram^, + fontPgmSize ) then exit; + + {$IFDEF DEBUG} Writeln('loaded, ',fontPgmSize,' bytes'); {$ENDIF} + end; + + {$IFDEF DEBUG} Write('CVT program '); {$ENDIF} + + t := LookUp_trueType_Table( face, 'prep' ); + + (* The CVT table is optional *) + + if t < 0 then + + with face^ do + begin + cvtProgram := nil; + cvtPgmSize := 0; + + {$IFDEF DEBUG} Writeln('none in file'); {$ENDIF} + end + + else + + with face^ do + begin + + cvtPgmSize := dirTables^[t].Length; + + if Alloc( cvtProgram, cvtPgmSize ) or + TT_Read_At_File( dirTables^[t].offset, + cvtProgram^, + cvtPgmSize ) then exit; + + {$IFDEF DEBUG} Writeln('loaded, ',cvtPgmSize,' bytes'); {$ENDIF} + end; + + Load_TrueType_Programs := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_OS2 + * + * Description : Load the OS2 Table + * + * Input : face + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_OS2( face : PFace ) : TError; + var + table : Int; + i : Int; + begin + Load_TrueType_OS2 := Failure; + + {$IFDEF DEBUG} Write('OS/2 table '); {$ENDIF} + + (* We now support Apple fonts who do not have an OS/2 table *) + table := LookUp_Mandatory_Table( face, 'OS/2' ); + if table < 0 then begin + face^.os2.version := $FFFF; + Load_TrueType_OS2 := Success; + error := TT_Err_Ok; (* clear error *) + exit; + end; + + if TT_Seek_File( face^.dirTables^[table].offset ) or + TT_Access_Frame( 78 ) then exit; + + with face^.os2 do + begin + version := Get_UShort; + xAvgCharWidth := Get_Short; + usWeightClass := Get_UShort; + usWidthClass := Get_UShort; + fsType := Get_Short; + ySubscriptXSize := Get_Short; + ySubscriptYSize := Get_Short; + ySubscriptXOffset := Get_Short; + ySubscriptYOffset := Get_Short; + ySuperscriptXSize := Get_Short; + ySuperscriptYSize := Get_Short; + ySuperscriptXOffset := Get_Short; + ySuperscriptYOffset := Get_Short; + yStrikeoutSize := Get_Short; + yStrikeoutPosition := Get_Short; + sFamilyClass := Get_Short; + + for i := 0 to 9 do panose[i] := Get_Byte; + + ulUnicodeRange1 := Get_ULong; + ulUnicodeRange2 := Get_ULong; + ulUnicodeRange3 := Get_ULong; + ulUnicodeRange4 := Get_ULong; + + for i := 0 to 3 do achVendID[i] := Get_Byte; + + fsSelection := Get_UShort; + usFirstCharIndex := Get_UShort; + usLastCharIndex := Get_UShort; + sTypoAscender := Get_UShort; + sTypoDescender := Get_UShort; + sTypoLineGap := Get_UShort; + usWinAscent := Get_UShort; + usWinDescent := Get_UShort; + + TT_Forget_Frame; + + if version >= $0001 then + begin + if TT_Access_Frame(8) then exit; + + ulCodePageRange1 := Get_ULong; + ulCodePageRange2 := Get_ULong; + + TT_Forget_Frame; + end + else + begin + ulCodePageRange1 := 0; + ulCodePageRange2 := 0; + end; + + end; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_TrueType_OS2 := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_Postscript + * + * Description : Load the 'post' table + * + * Input : face + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Postscript( face : PFace ) : TError; + var + table : Int; + i : Int; + begin + Load_TrueType_Postscript := Failure; + + {$IFDEF DEBUG} Write('post table '); {$ENDIF} + + table := LookUp_TrueType_Table( face, 'post' ); + if table < 0 then exit; + + if TT_Seek_File( face^.dirTables^[table].offset ) or + TT_Access_Frame(32) then exit; + + with face^.postscript do + begin + formatType := Get_ULong; + italicAngle := Get_ULong; + underlinePosition := Get_Short; + underlineThickness := Get_Short; + isFixedPitch := Get_ULong; + minMemType42 := Get_ULong; + maxMemType42 := Get_ULong; + minMemType1 := Get_ULong; + maxMemType1 := Get_ULong; + end; + + TT_Forget_Frame; + + {$IFDEF DEBUG} Writeln('loaded'); {$ENDIF} + + Load_trueType_Postscript := Success; + end; + +(******************************************************************* + * + * Function : Load_TrueType_HDMX + * + * Description : Load the 'hdmx' tables + * + * Input : face + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Hdmx( face : PFace ) : TError; + var + table, n : Int; + num_glyphs : Int; + + version : UShort; + num_rec : Short; + recs : PHdmx_Records; + rec_size : Long; + rec : PHdmx_Record; + label + Fail; + begin + Load_TrueType_Hdmx := Failure; + + with face^.hdmx do + begin + version := 0; + num_records := 0; + records := nil; + end; + + (* This table is optional *) + + table := LookUp_TrueType_Table( face, 'hdmx' ); + if table < 0 then + begin + Load_TrueType_Hdmx := Success; + exit; + end; + + if TT_Seek_File( face^.dirTables^[table].offset ) or + TT_Access_Frame( 8 ) then exit; + + version := Get_UShort; + num_rec := Get_Short; + rec_size := Get_Long; + + TT_Forget_Frame; + + (* right now, we only recognize format 0 *) + + if version <> 0 then + exit; + + if Alloc( face^.hdmx.records, sizeof(THdmx_Record)*num_rec ) then + exit; + + face^.hdmx.num_records := num_rec; + num_glyphs := face^.NumGlyphs; + + rec_size := rec_size - num_glyphs - 2; + + for n := 0 to num_rec-1 do + begin + rec := @face^.hdmx.records^[n]; + + (* read record *) + + if TT_Access_Frame(2) then + goto Fail; + + rec^.ppem := Get_Byte; + rec^.max_width := Get_Byte; + + TT_Forget_Frame; + + if Alloc( rec^.widths, num_glyphs ) or + TT_Read_File( rec^.widths^, num_glyphs ) then + goto Fail; + + (* skip padding bytes *) + + if rec_size > 0 then + if TT_Skip_File( rec_size ) then + goto Fail; + end; + + Load_TrueType_HDMX := Success; + exit; + + Fail: + for n := 0 to num_rec-1 do + Free( face^.hdmx.records^[n].widths ); + + Free( face^.hdmx.records ); + face^.hdmx.num_records := 0; + end; + + +(******************************************************************* + * + * Function : Load_TrueType_Any + * + * Description : Load any TrueType table in user memory + * + * Input : face the font file's face object + * tag the table + * + * Output : True on success. False on failure + * + ******************************************************************) + + function Load_TrueType_Any( face : PFace; + tag : longint; + offset : longint; + var buffer; + var length : longint ) : TError; + var + stream : TT_Stream; + found, i : integer; + begin + if tag <> 0 then + begin + found := -1; + i := 0; + while i < face^.numTables do + if Longint(face^.dirTables^[i].tag) = tag then + begin + found := i; + i := face^.numTables; + end + else + inc(i); + + if found < 0 then + begin + error := TT_Err_Table_Missing; + Load_TrueType_Any := Failure; + exit; + end; + + inc( offset, face^.dirTables^[found].offset ); + + (* if length = 0, the user requested the table's size *) + if length = 0 then + begin + length := face^.dirTables^[found].length; + Load_TrueType_Any := Success; + exit; + end; + end + else + (* if length = 0 and tag = 0, the user requested the font file's size *) + if length = 0 then + begin + (* return length of font file *) + length := TT_Stream_Size( face^.stream ); + Load_TrueType_Any := Success; + exit; + end; + + TT_Use_Stream( face^.stream, stream ); + Load_TrueType_Any := TT_Read_At_File( offset, buffer, length ); + TT_Done_Stream( face^.stream ); + end; + +end. + diff --git a/pascal/lib/ttmemory.pas b/pascal/lib/ttmemory.pas new file mode 100644 index 0000000..e721f56 --- /dev/null +++ b/pascal/lib/ttmemory.pas @@ -0,0 +1,282 @@ +(******************************************************************* + * + * TTMemory.Pas 2.1 + * + * Memory management component (specification) + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * Differences between 2.1 and 2.0 : + * + * - Added a memory mutex to make the component thread-safe + * + * Differences between 2.0 and 1.1 : + * + * - The growing heap was completely removed in version 2.0 + * + * - The support for small mini-heaps may be re-introduced later + * to allow the storage of several consecutive arrays in one + * single block. + * + * IMPORTANT NOTICE : + * + * The Alloc and Free functions mimic their C equivalent, + * however, some points must be noticed : + * + * - both functions return a boolean. As usual, True indicates + * success, while False indicates failure. + * + * - the Alloc function puts a small header on front of each + * allocated block. The header contains a magic cookie and + * the size of the allocated block. This allows calls to + * Free without passing a block size as an argument, and thus + * reduces the risks of memory leaks. + * + * - it is possible to call Free with a nil pointer, in which + * case nothing happens, and the result is set to True (success) + * + * The pointer is set to nil after a call to Free in all cases. + * + * This is done to clear the destructors code, allowing + * + * if (pointer) then + * begin + * Free(pointer); + * pointer := nil; + * end; + * + * to be replaced by a single line : + * + * Free(pointer); + * + * + ******************************************************************) + +unit TTMemory; + +interface + +uses TTTypes; + +{$I TTCONFIG.INC} + +type + TMarkRecord = record + Magic : longint; + Top : integer; + end; + +const + Font_Pool_Allocated : boolean = False; + + function Alloc( var P; size : Longint ) : TError; + (* Allocates a new memory block in the current heap of 'size' bytes *) + (* - returns failure if no memory is left in the heap *) + + procedure Free ( var P ); + (* Releases a block previously allocated through 'Alloc' *) + (* - returns True (success) of P is nil before the call *) + (* - sets P to nil before exit *) + + function TTMemory_Init : TError; + procedure TTMemory_Done; + +implementation + +uses TTError; + +type + TByte = array[0..0] of Byte; + PByte = ^TByte; + + PBlock_Header = ^TBlock_Header; + TBlock_Header = record + magic : Longint; (* magic cookie *) + size : Longint; (* allocated size, including header *) + end; + + TBlock_Headers = array[0..1] of TBlock_Header; + PBlock_Headers = ^TBlock_Headers; + + (* Note that the Turbo-Pascal GetMem/FreeMem functions use no block *) + (* headers. That's why a byte size is needed for FreeMem. Thus, we *) + (* do not waste space here compared to a C malloc implementation *) + +const + Mark_Magic = $BABE0007; + (* This is the magic cookie used to recognize valide allocated blocks *) + + Header_Size = sizeof(TBlock_Header); + + (************************************************************************) + (* *) + (* MyHeapErr : *) + (* *) + (* By default, a call to GetMem with insufficient memory left will *) + (* generate a runtime error. We define here a function that is used *) + (* to allow GetMem to return nil in such cases. *) + (* *) + (************************************************************************) + + function MyHeapErr( Size: Integer ): Integer; far; + begin + MyHeapErr := 1; + end; + +(******************************************************************* + * + * Function : Alloc + * + * Description : allocate a new block in the current heap + * + * Notes : If you want to replace this function with + * your own, please be sure to respect these + * simple rules : + * + * - P must be set to nil in case of failure + * + * - The allocated block must be zeroed ! + * + *****************************************************************) + + function Alloc( var P; size : Longint ) : TError; + var + OldHeapError : Pointer; + + L : Longint; + P2 : Pointer; + begin + {$IFNDEF DELPHI32} + OldHeapError := HeapError; + HeapError := @MyHeapErr; + {$ENDIF} + + L := ( size + Header_Size + 3 ) and -4; + + {$IFDEF MSDOS} + if L shr 16 <> 0 then + begin + Writeln('Sorry, but this font is too large to be handled by a 16-bit program' ); + Alloc := Failure; + end; + {$ENDIF} + + GetMem( Pointer(P), L ); + + {$IFNDEF DELPHI32} + HeapError := OldHeapError; + {$ENDIF} + + if Pointer(P) <> nil then + begin + PBlock_Headers(P)^[0].magic := Mark_Magic; + PBlock_Headers(P)^[0].size := L; + + P2 := Pointer( @(PBlock_Headers(P)^[1]) ); + + {$IFDEF MSDOS} + if (ofs(P2^) <> ofs(Pointer(P)^)+Header_Size) or + (seg(P2^) <> seg(Pointer(P)^)) then + begin + Writeln('AAARGH !!: Sorry, but I have problems with 64 Kb segments'); + halt(1); + end; + {$ENDIF} + + Pointer(P) := P2; + fillchar( P2^, size, 0 ); + (* zero block *) + + Alloc := Success; + end + else + Alloc := Failure; + + end; + + +(******************************************************************* + * + * Function : Free + * + * Description : frees a block that was previsouly allocated + * by the Alloc function + * + * Notes : Doesn't need any size parameter. + * + * If you want to replace this function with your own, please + * be sure to respect these two rules : + * + * - the argument pointer can be nil, in which case the function + * should return immediately, with a success report. + * + * - the pointer P should be set to nil when exiting the + * function, except in case of failure. + * + *****************************************************************) + + procedure Free( var P ); + var + head : PBlock_Header; + i : Integer; + size : Longint; + begin + if Pointer(P) = nil then exit; + + i := -1; + head := @(PBlock_Headers(P)^[i]); + (* A hack to get the header in PB, as the line *) + (* @(PBlock_Headers(P)^[-1] would give a 'constant error' *) + (* at compile time. I'm unsure this works correctly in BP *) + + if head^.magic <> Mark_Magic then + begin + (* PANIC : An invalid Free call *) + Writeln('Invalid Free call'); + halt(1); + end; + + size := head^.size; + + head^.magic := 0; (* cleans the header *) + head^.size := 0; + + FreeMem( head, size ); + + Pointer(P) := nil; + end; + +(******************************************************************* + * + * Function : TTMemory_Init + * + * Description : Initializes the Memory component + * + *****************************************************************) + + function TTMemory_Init : TError; + begin + (* nothing to be done *) + TTMemory_Init := Success; + end; + +(******************************************************************* + * + * Function : TTMemory_Done + * + * Description : Finalize the memory component + * + *****************************************************************) + + procedure TTMemory_Done; + begin + (* nothing to be done *) + end; + +end. diff --git a/pascal/lib/ttobjs.pas b/pascal/lib/ttobjs.pas new file mode 100644 index 0000000..4f32967 --- /dev/null +++ b/pascal/lib/ttobjs.pas @@ -0,0 +1,1945 @@ +(******************************************************************* + * + * ttobjs.pas 2.0 + * + * Objects definition unit. + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +(* *) +(* The four important objects managed by the library are : *) +(* *) +(* Face : the object for a given typeface *) +(* Instance : the object for a face's given pointsize/transform *) +(* Context : the object for a given glyph loading/hinting execution *) +(* Glyph : the object for a given glyph ( outline and metrics ) *) +(* *) +(* A Face object is described by a TFace record, and its *) +(* associated sub-tables. It is created through a call to the *) +(* 'TT_Open_Face' API. *) +(* *) +(* An Instance object is described by a TInstance record, and *) +(* sub-tables. It is created for a given face through a call to the *) +(* 'TT_Open_Instance' API. Several instances can share the same face *) +(* *) +(* The pointsize and/or transform of a given instance object can be *) +(* changed on the fly through a call to the 'TT_Reset_Instance' API. *) +(* *) +(* A Glyph object is used to describe a glyph to the client application *) +(* It is made of a TGlyph_Record header, with several sub-tables used *) +(* to store, for example, point coordinates or outline info.. *) +(* It can hold metrics information and other attributes, as well as *) +(* the glyph's outline. A client application can request any kind of *) +(* info to the library on a given glyph through the 'TT_Get_Glyph' *) +(* call. *) +(* *) +(* *) +(* A Context is described by a TExec_Context record, and sub-tables *) +(* Execution contexts are created on demand during the following *) +(* operations : *) +(* *) +(* - creating a new instance ( to read and execute the font program ) *) +(* - setting/resetting the pointsize ( to execute the CVT program ) *) +(* - during glyph loading ( when hinting is on ) *) +(* *) +(* They are used to run TrueType instructions and load/store *) +(* glyph data that are not part of the Glyph object ( as they're of *) +(* no meaning to a client application ). *) +(* *) +(* The library keeps track of all objects related to a given face : *) +(* *) +(* A face's instances are kept in two linked lists : one is the 'active' *) +(* list, which tracks the face's current opened instances, while the *) +(* other is the 'idle' list used to collect/recycle instance objects *) +(* when they become unuseful after a 'TT_Close_Instance' call. *) +(* *) +(* In the same way, a face's execution contexts are kept in two *) +(* similar lists. Note that, as contexts are created on demand, *) +(* the active and idle contexts lists should always contain few *) +(* elements. *) +(* *) +(* Look also for the following files : *) +(* *) +(* Face manager : TTFace.pas *) +(* Instance manager : TTInst.pas *) +(* Context manager : TTExec.pas *) +(* Glyph manager : TTGlyph.pas *) +(* *) + +unit TTObjs; + +interface + +{$I TTCONFIG.INC} + +uses FreeType, + TTTypes, + TTError, + TTCache, + TTTables, + TTCMap; + +type + (* Graphics State *) + (* *) + (* The Graphics State (GS) is managed by the *) + (* instruction field, but does not come from *) + (* the font file. Thus, we can use 'int's *) + (* where needed. *) + (* *) + + PGraphicsState = ^TGraphicsState; + TGraphicsState = record + rp0, + rp1, + rp2 : int; + + dualVector, + projVector, + freeVector : TT_UnitVector; + + loop : longint; + minimum_distance : TT_F26dot6; + round_state : int; + + auto_flip : boolean; + control_value_cutin : TT_F26dot6; + single_width_cutin : TT_F26dot6; + single_width_value : TT_F26dot6; + delta_base : int; + delta_shift : int; + + instruct_control : byte; + scan_control : Boolean; + scan_type : Int; + + gep0, + gep1, + gep2 : int; + end; + + +const + Default_GraphicsState : TGraphicsState + = ( + rp0 : 0; + rp1 : 0; + rp2 : 0; + dualVector : ( x:$4000; y:0 ); + projVector : ( x:$4000; y:0 ); + freeVector : ( x:$4000; y:0 ); + loop : 1; + minimum_distance : 64; + round_state : 1; + auto_flip : True; + control_value_cutin : 4*17; + single_width_cutin : 0; + single_width_value : 0; + delta_Base : 9; + delta_Shift : 3; + instruct_control : 0; + scan_control : True; + scan_type : 0; + gep0 : 1; + gep1 : 1; + gep2 : 1 + ); + + (**********************************************************************) + (* *) + (* Execution Subtables : *) + (* *) + (**********************************************************************) + +const + MaxCodeRanges = 3; + (* There can only be 3 active code ranges at once : *) + (* - the Font Program *) + (* - the CVT Program *) + (* - a glyph's instructions set *) + + TT_CodeRange_Font = 1; + TT_CodeRange_Cvt = 2; + TT_CodeRange_Glyph = 3; + + CvtFlag_None = 0; + CvtFlag_X = 1; + CvtFlag_Y = 2; + CvtFlag_Both = 3; + +type + TCodeRange = record + Base : PByte; + Size : Int; + end; + PCodeRange = ^TCodeRange; + + (* defines a code range *) + (* *) + (* code ranges can be resident to a glyph ( i.e. the Font Program) *) + (* while some others are volatile ( Glyph instructions ) *) + (* tracking the state and presence of code ranges allows function *) + (* and instruction definitions within a code range to be forgotten *) + (* when the range is discarded *) + + TCodeRangeTable = array[1..MaxCodeRanges] of TCodeRange; + + (* defines a function/instruction definition record *) + PDefRecord = ^TDefRecord; + TDefRecord = record + Range : Int; (* in which code range is it located ? *) + Start : Int; (* where does it start ? *) + Opc : Byte; (* function #, or instruction code *) + Active : boolean; (* is the entry active ? *) + end; + + PDefArray = ^TDefArray; + TDefArray = array[0..99] of TDefRecord; + + (* defines a call record, used to manage function calls *) + TCallRecord = record + Caller_Range : Int; + Caller_IP : Int; + Cur_Count : Int; + Cur_Restart : Int; + end; + + (* defines a simple call stack *) + TCallStack = array[0..99] of TCallRecord; + PCallStack = ^TCallStack; + + PGlyph_Zone = ^TGlyph_Zone; + TGlyph_Zone = record + n_points : Int; + n_contours : Int; + + org : TT_Points; (* original (scaled) coords *) + cur : TT_Points; (* current coordinates *) + flags : TT_PTouchTable; + + conEnds : PUShort; + end; + + TRound_Function = function( distance, compensation : TT_F26dot6 ) + : TT_F26dot6; + (* Rounding function, as used by the interpreter *) + + TMove_Function = procedure( zone : PGlyph_Zone; + point : Int; + distance : TT_F26dot6 ); + (* Point displacement along the freedom vector routine, as *) + (* used by the interpreter *) + + TProject_Function = function( var P1, P2 : TT_Vector ) : TT_F26dot6; + (* Distance projection along one of the proj. vectors, as used *) + (* by the interpreter *) + + TFunc_Get_CVT = function ( index : Int ) : TT_F26Dot6; + (* Reading a cvt value. Take care of non-square pixels when *) + (* needed *) + + TFunc_Set_CVT = procedure( index : Int; value : TT_F26Dot6 ); + (* Setting or Moving a cvt value. Take care of non-square *) + (* pixels when needed *) + + + (********************************************************************) + (* *) + (* Glyph Sub-Tables *) + (* *) + (********************************************************************) + + PGlyph_Transform = ^TGlyph_Transform; + TGlyph_Transform = record + xx, xy : TT_Fixed; + yx, yy : TT_Fixed; + ox, oy : TT_F26Dot6; + end; + + PSubglyph_Record = ^TSubglyph_Record; + TSubglyph_Record = record + index : Int; + is_scaled : boolean; + is_hinted : boolean; + preserve_pps : boolean; + + bbox : TT_BBox; + zone : TGlyph_Zone; + + arg1, arg2 : Int; + element_flag : Int; + transform : TGlyph_Transform; + file_offset : Long; + + pp1, pp2 : TT_Vector; + + advanceWidth : Int; + leftBearing : Int; + end; + + TSubglyph_Stack = array[0..10] of TSubglyph_Record; + PSubglyph_Stack = ^TSubglyph_Stack; + + (* A note regarding non-squared pixels : *) + (* *) + (* ( This text will probably go into some docs at some time, for *) + (* now, it is kept there to explain some definitions in the *) + (* TIns_Metrics record ). *) + (* *) + (* The CVT is a one-dimensional array containing values that *) + (* control certain important characteristics in a font, like *) + (* the height of all capitals, all lowercase letter, default *) + (* spacing or stem width/height. *) + (* *) + (* These values are found in FUnits in the font file, and must be *) + (* scaled to pixel coordinates before being used by the CVT and *) + (* glyph programs. Unfortunately, when using distinct x and y *) + (* resolutions ( or distinct x and y pointsizes ), there are two *) + (* possible scalings. *) + (* *) + (* A first try was to implement a 'lazy' scheme were all values *) + (* were scaled when first used. However, some values are always *) + (* used in the same direction, and some other are used in many *) + (* different circumstances and orientations. *) + (* *) + (* I have found a simpler way to do the same, and it even seems to *) + (* work in most of the cases : *) + (* *) + (* - all CVT values are scaled to the maximum ppem size *) + (* *) + (* - when performing a read or write in the CVT, a ratio factor *) + (* is used to perform adequate scaling. Example : *) + (* *) + (* x_ppem = 14 *) + (* y_ppem = 10 *) + (* *) + (* we chose ppem = x_ppem = 14 as the CVT scaling size. All cvt *) + (* entries are scaled to it. *) + (* *) + (* x_ratio = 1.0 *) + (* y_ratio = y_ppem/ppem ( < 1.0 ) *) + (* *) + (* we compute the current ratio like : *) + (* *) + (* - if projVector is horizontal, ratio = x_ratio = 1.0 *) + (* - if projVector is vertical, ratop = y_ratio *) + (* - else, ratio = sqrt( (proj.x*x_ratio)ý+(proj.y*y_ratio)ý ) *) + (* *) + (* reading a cvt value returns ratio*cvt[index] *) + (* writing a cvt value in pixels cvt[index]/ratio *) + (* *) + (* the current ppem is simple ratio*ppem *) + (* *) + + TIns_Metrics = record + pointsize : TT_F26Dot6; + x_resolution : Int; + y_resolution : Int; + x_ppem : Int; + y_ppem : Int; + + x_scale1 : Long; + x_scale2 : Long; + y_scale1 : Long; + y_scale2 : Long; + + (* for non-square pixels *) + x_ratio : Long; + y_ratio : Long; + + scale1 : Long; + scale2 : Long; + ppem : Int; + ratio : Long; + + (* compensations *) + compensations : array[0..3] of TT_F26Dot6; + + (* flags *) + rotated : Boolean; + stretched : Boolean; + end; + + (********************************************************************) + (* *) + (* FreeType Face Object *) + (* *) + (********************************************************************) + + PFace = ^TFace; + PInstance = ^TInstance; + PExec_Context = ^TExec_Context; + + TFace = record + + stream : TT_Stream; + (* i/o stream *) + + ttcHeader : TTTCHeader; + (* TrueType collection header, if any was found *) + + maxProfile : TMaxProfile; + (* maximum profile table, as defined by the TT Spec *) + + (* Note : *) + (* it seems that some maximum values cannot be *) + (* taken directly from this table, but rather by *) + (* combining some of its fields ( e.g. the max. *) + (* number of points seems to be given by *) + (* MAX( maxPoints, maxCompositePoints ) *) + (* *) + (* For this reason, we define later our own *) + (* max values that are used to load and allocate *) + (* further tables.. *) + + fontHeader : TT_Header; + (* the font header as defined by the TT Spec *) + + horizontalHeader : TT_Horizontal_Header; + (* the horizontal header, as defined in the spec *) + + verticalInfo : Boolean; + (* set to true when vertical data is in the font *) + + verticalHeader : TT_Vertical_Header; + (* vertical header table *) + + os2 : TT_OS2; + (* 'OS/2' table *) + + postscript : TT_Postscript; + (* 'Post' table *) + + hdmx : THdmx; + (* 'hdmx' = horizontal device metrics table *) + + nameTable : TName_Table; + (* 'name' = name table *) + + numTables : Int; + dirTables : PTableDirEntries; + (* The directory of the TrueType tables found in *) + (* this face's stream *) + + numCMaps : Int; + cMaps : PCMapTables; + (* the directory of character mappings tables found *) + (* for this face.. *) + + numLocations : Int; + glyphLocations : PStorage; + (* the glyph locations table *) + + (* the hmtx table is now within the horizontal header *) + + fontPgmSize : Int; + fontProgram : PByte; + (* the font program, if any.. *) + + cvtPgmSize : Int; + cvtProgram : PByte; + (* the cvt (or 'prep') program, if any.. *) + + cvtSize : Int; + cvt : PShort; + (* the original, unscaled, control value table *) + + gasp : TGasp; + + (* the following values must be set by the *) + (* maximum profile loader.. *) + + numGlyphs : Int; + (* the face's total number of glyphs *) + + maxPoints : Int; + (* max glyph points number, simple and composite *) + + maxContours : Int; + (* max glyph contours number, simple and composite *) + + maxComponents : Int; + (* max components in a composite glyph *) + + (* the following lists are used to track active *) + (* instance and context objects, as well as *) + (* to recycle them.. *) + + (* see 'TTLists'.. *) + + instances : TCache; + glyphs : TCache; + (* various caches for this face's child objects *) + + extension : Pointer; + (* a typeless pointer to the face object's extensions *) + + generic : Pointer; + (* generic pointer - see TT_Set/Get_Face_Pointer *) + end; + + (********************************************************************) + (* *) + (* FreeType Instance Object *) + (* *) + (********************************************************************) + + TInstance = record + + owner : PFace; + + valid : Boolean; + metrics : TIns_Metrics; + + numFDefs : Int; (* number of function defs *) + maxFDefs : Int; + FDefs : PDefArray; (* table of FDefs entries *) + + numIDefs : Int; (* number of instruction defs *) + maxIDefs : Int; + IDefs : PDefArray; (* table of IDefs entries *) + + maxFunc : Int; (* maximum function number *) + maxIns : Int; (* maximum instruction number *) + + codeRangeTable : TCodeRangeTable; + + GS : TGraphicsState; + + storeSize : Int; + storage : PStorage; + (* the storage area *) + + cvtSize : Int; + cvt : PLong; + (* the scaled control value table *) + + twilight : TGlyph_Zone; + (* the instance's twilight zone *) + + (* debugging variables *) + + debug : Boolean; + context : PExec_Context; + (* when using the debugger, we must keep the *) + (* execution context with the instance object *) + (* rather than asking it on demand *) + + generic : Pointer; + (* generic pointer - see TT_Set/Get_Instance_Pointer *) + end; + + (********************************************************************) + (* *) + (* FreeType Execution Context Object *) + (* *) + (********************************************************************) + + TExec_Context = record + + face : PFace; + instance : PInstance; + error : Int; + + stackSize : Int; (* size of instance stack *) + top : Int; (* top of instance stack *) + stack : PStorage; (* current instance stack *) + + args : Int; (* number of arguments in opcode *) + new_top : Int; (* new stack top after opc. exec *) + + zp0, + zp1, + zp2, + twilight, + pts : TGlyph_Zone; + + GS : TGraphicsState; + + curRange : Int; (* current code range number *) + code : PByte; (* current code range *) + IP : Int; (* current instruction pointer *) + codeSize : Int; (* size of current range *) + + opcode : Byte; (* current opcode *) + length : Int; (* length of current opcode *) + + step_ins : boolean; (* used by the interpreter *) + (* if true, go to the next *) + (* instruction.. *) + + loadSize : Int; + loadStack : PSubglyph_Stack; + (* the load stack used to load composite glyphs *) + + glyphIns : PByte; (* glyph instructions *) + glyphSize : Int; (* glyph ins. size *) + + callTop : Int; + callSize : Int; + callStack : PCallStack; (* interpreter call stack *) + + period, (* values used for the *) + phase, (* 'SuperRounding' *) + threshold : TT_F26dot6; + + maxPoints : Int; + maxContours : Int; + + (* the following are copies of the variables found *) + (* in an instance object *) + + numFDefs : Int; (* number of function defs *) + maxFDefs : Int; + FDefs : PDefArray; (* table of FDefs entries *) + + numIDefs : Int; (* number of instruction defs *) + maxIDefs : Int; + IDefs : PDefArray; (* table of IDefs entries *) + + maxFunc : Int; (* maximum function number *) + maxIns : Int; (* maximum instruction number *) + + codeRangeTable : TCodeRangeTable; + + storeSize : Int; (* size of current storage *) + storage : PStorage; (* storage area *) + + metrics : TIns_Metrics; + + cur_ppem : Int; + scale1 : Long; + scale2 : Long; + cached_metrics : Boolean; + +(* + numContours : Int; + endContours : PUShort; +*) + Instruction_Trap : Boolean; + (* used by the full-screen debugger. If set, the *) + (* interpreter will exit after executing one *) + (* opcode. Used to perform single-stepping.. *) + + is_composite : Boolean; + (* this flag is true when the glyph is a composite *) + (* one. In this case, we measure original distances *) + (* in the loaded coordinates (font units), then *) + (* scale them appropriately. This get rids of *) + (* transformation artifacts (like symetries..) *) + + cvtSize : Int; + cvt : PLong; + + (* these variables are proper to the context *) + + F_dot_P : Long; + (* the dot product of the free and projection *) + (* vector is used in frequent operations.. *) + + func_round : TRound_Function; + func_project : TProject_Function; + func_dualproj : TProject_Function; + func_freeProj : TProject_Function; + func_move : TMove_Function; + + func_read_cvt : TFunc_Get_CVT; + func_write_cvt : TFunc_Set_CVT; + func_move_cvt : TFunc_Set_CVT; + (* single width ? *) + + end; + + (********************************************************************) + (* *) + (* FreeType Glyph Object *) + (* *) + (********************************************************************) + + PGlyph = ^TGlyph; + TGlyph = record + face : PFace; + metrics : TT_Big_Glyph_Metrics; + outline : TT_Outline; + + (* temporary - debugging purposes *) + computed_width : Int; + precalc_width : Int; + is_composite : Boolean; + end; + + PFont_Input = ^TFont_Input; + TFont_Input = record + stream : TT_Stream; (* inpute stream *) + fontIndex : Int; (* index of font in collection *) + end; + + (****************************************************************) + (* *) + (* Code Range Functions *) + (* *) + (****************************************************************) + + function Goto_CodeRange( exec : PExec_Context; + range : Int; + IP : Int ) : TError; + (* Go to a specified coderange *) + + function Get_CodeRange( exec : PExec_Context; + range : Int ) : PCodeRange; + (* return a pointer to a given coderange record *) + (* used only by the debugger *) + + function Set_CodeRange( exec : PExec_Context; + range : Int; + base : Pointer; + length : Int ) : TError; + (* Set a given code range properties *) + + function Clear_CodeRange( exec : PExec_Context; + range : Int ) : TError; + (* Clear a given code range *) + + (****************************************************************) + (* *) + (* Management Functions *) + (* *) + (****************************************************************) + + function New_Context( instance : PInstance ) : PExec_Context; + (* Get a new execution context, either fresh or recycled, for *) + (* an instance of the face 'res' *) + (* *) + (* Notes : - called by 'New_Face_Context' *) + (* - assumes that the face mutex is acquired *) + + procedure Done_Context( exec : PExec_Context ); + (* Releases an execution context. The context can be destroyed *) + (* or recycled, depending on implementation *) + (* *) + (* Notes : - called by 'Done_Face_Context' *) + (* - assumes that the face mutex is acquired *) + + (****************************************************************) + (* *) + (* Instance Update Functions *) + (* *) + (****************************************************************) + + procedure Context_Load( exec : PExec_Context; + ins : PInstance ); + (* update exec's data with the one found in 'ins' *) + (* typically before an execution *) + + procedure Context_Save( exec : PExec_Context; + ins : PInstance ); + (* update ins's data with the one found in 'exec' *) + (* typically after an execution *) + + function Context_Run( exec : PExec_Context; + debug : Boolean ) : TError; + + function Instance_Init( ins : PInstance ) : TError; + + function Instance_Reset( ins : PInstance; + debug : boolean ) : TError; + + + function Scale_X( var metrics : TIns_Metrics; x : TT_Pos ) : TT_Pos; + + function Scale_Y( var metrics : TIns_Metrics; y : TT_Pos ) : TT_Pos; + + function TTObjs_Init : TError; + (* Initialize object manager *) + + procedure TTObjs_Done; + (* Finalize object manager *) + +var + face_cache : TCache; + exec_cache : TCache; + +implementation + +uses TTMemory, TTFile, TTCalc, TTLoad, TTInterp; + + function Face_Create( _face : Pointer; + _input : Pointer ) : TError; far; forward; + + function Face_Destroy( _face : Pointer ) : TError; far; forward; + + function Context_Create( _context : Pointer; + _face : Pointer ) : TError; far; forward; + + function Context_Destroy( exec : Pointer ) : TError; far; forward; + + function Instance_Create( _ins : Pointer; + _face : Pointer ) : TError; far; forward; + + function Instance_Destroy( instance : Pointer ) : TError; far; forward; + + function Glyph_Create( _glyph : Pointer; + _face : Pointer ) : TError; far; forward; + + function Glyph_Destroy( _glyph : Pointer ) : TError; far; forward; + + + +const + objs_face_class : TCache_Class + = (object_size: sizeof(TFace); + idle_limit : -1; + init : Face_Create; + done : Face_Destroy ); + + objs_exec_class : TCache_Class + = (object_size: sizeof(TExec_Context); + idle_limit : 1; + init : Context_Create; + done : Context_Destroy ); + + objs_instance_class : TCache_Class + = (object_size: sizeof(TInstance); + idle_limit : -1; + init : Instance_Create; + done : Instance_Destroy ); + + objs_glyph_class : TCache_Class + = (object_size: sizeof(TGlyph); + idle_limit : -1; + init : Glyph_Create; + done : Glyph_Destroy ); + +(******************************************************************* + * + * Function : New_Context + * + * Description : gets a new active execution context for a given + * resident/face object. + * + * Input : aResident + * + * Output : Returns new exec. context. Nil in case of failure + * + * Notes : Don't forget to modify 'Free_Context' if you change + * the fields of a TExec_Context + * + ******************************************************************) + + function New_Context( instance : PInstance ) : PExec_Context; + var + exec : PExec_Context; + begin + if instance = nil then + exec := nil + else + Cache_New( exec_cache, Pointer(exec), instance^.owner ); + + New_Context := exec; + end; + +(******************************************************************* + * + * Function : Done_Context + * + * Description : + * + * Input : aResident + * + * Output : Discards an active execution context when it + * becomes unuseful. It is putin its face's recycle + * list + * + ******************************************************************) + + procedure Done_Context( exec : PExec_Context ); + begin + if exec <> nil then + Cache_Done( exec_cache, Pointer(exec) ); + end; + +(******************************************************************* + * + * Function : New_Instance + * + * Description : gets a new active instance for a given + * face object. + * + * Input : face + * + * Output : Returns new instance. Nil in case of failure + * + ******************************************************************) + + function New_Instance( face : PFace ) : PInstance; + var + ins : PInstance; + begin + if face = nil then + ins := nil + else + Cache_New( face^.instances, Pointer(ins), face ); + + New_Instance := ins; + end; + +(******************************************************************* + * + * Function : Done_Instance + * + * Description : + * + * Input : instance + * + * Output : Discards an active instance when it + * becomes unuseful. It is put in its face's recycle + * list + * + ******************************************************************) + + procedure Done_Instance( instance : PInstance ); + begin + if instance <> nil then + Cache_Done( instance^.owner^.instances, Pointer(instance) ); + end; + + (****************************************************************) + (* *) + (* Code Range Functions *) + (* *) + (****************************************************************) + +(******************************************************************* + * + * Function : Goto_CodeRange + * + * Description : Switch to a new code range (updates Code and IP). + * + * Input : exec target execution context + * range new execution code range + * IP new IP in new code range + * + * Output : SUCCESS on success. FAILURE on error (no code range). + * + *****************************************************************) + + function Goto_CodeRange( exec : PExec_Context; + range : Int; + IP : Int ) : TError; + begin + Goto_CodeRange := Failure; + + if (range < 1) or (range > 3) then + begin + error := TT_Err_Bad_Argument; + exit; + end; + + with exec^.codeRangeTable[range] do + begin + + if base = nil then + begin + error := TT_Err_Invalid_CodeRange; + exit; + end; + + (* NOTE : Because the last instruction of a program may be a CALL *) + (* which will return to the first byte *after* the code *) + (* range, we test for IP <= Size, instead of IP < Size. *) + + if IP > size then + begin + error := TT_Err_Code_Overflow; + exit; + end; + + exec^.code := base; + exec^.codeSize := size; + exec^.IP := IP; + exec^.currange := range; + end; + + Goto_CodeRange := Success; + end; + +(******************************************************************* + * + * Function : Get_CodeRange + * + * Description : Returns a pointer to a given code range. Should + * be used only by the debugger. Returns NULL if + * 'range' is out of current bounds. + * + * Input : exec target execution context + * range new execution code range + * + * Output : Pointer to the code range record. NULL on failure. + * + *****************************************************************) + + function Get_CodeRange( exec : PExec_Context; + range : Int ) : PCodeRange; + begin + if (range < 1) or (range > 3) then + Get_CodeRange := nil + else + Get_CodeRange := @exec^.codeRangeTable[range]; + end; + +(******************************************************************* + * + * Function : Set_CodeRange + * + * Description : Sets a code range. + * + * Input : exec target execution context + * range code range index + * base new code base + * length sange size in bytes + * + * Output : SUCCESS on success. FAILURE on error. + * + *****************************************************************) + + function Set_CodeRange( exec : PExec_Context; + range : Int; + base : Pointer; + length : Int ) : TError; + begin + Set_CodeRange := Failure; + + if (range < 1) or (range > 3) then + begin + error := TT_Err_Invalid_CodeRange; + exit; + end; + + exec^.codeRangeTable[range].base := base; + exec^.codeRangeTable[range].size := length; + + Set_CodeRange := Success; + end; + +(******************************************************************* + * + * Function : Clear_CodeRange + * + * Description : clears a code range. + * + * Input : exec target execution context + * range code range index + * + * Output : SUCCESS on success. FAILURE on error. + * + * Notes : Does not set the Error variable. + * + *****************************************************************) + + function Clear_CodeRange( exec : PExec_Context; + range : Int ) : TError; + begin + Clear_CodeRange := Failure; + + if (range < 1) or (range > 3) then + begin + error := TT_Err_Invalid_CodeRange; + exit; + end; + + exec^.codeRangeTable[range].base := nil; + exec^.codeRangeTable[range].size := 0; + + Clear_CodeRange := Success; + end; + + + (****************************************************************) + (* *) + (* Management Functions *) + (* *) + (****************************************************************) + +(******************************************************************* + * + * Function : Context_Destroy + * + * Description : Frees an execution context + * + * Input : context : execution context + * + * Notes : Allocation is found in the 'New_Context' function + * + ******************************************************************) + + function Context_Destroy( exec : Pointer ) : TError; + begin + Context_Destroy := Success; + + if exec = nil then exit; + + with PExec_Context(exec)^ do + begin + (* Free contours array *) + Free( pts.conEnds ); + pts.n_contours := 0; + + Free( pts.cur ); + Free( pts.org ); + + Free( pts.flags ); + pts.n_points := 0; + + (* Free stack *) + Free( stack ); + stackSize := 0; + + (* Free call stack *) + Free( callStack ); + callSize := 0; + callTop := 0; + + (* Free composite load stack *) + Free( loadStack ); + + (* free glyph code range *) + Free( glyphIns ); + glyphSize := 0; + + instance := nil; + face := nil; + end; + end; + + +(******************************************************************* + * + * Function : Context_Create + * + * Description : Creates a new execution context + * + * Input : _context context record + * _face face record + * + ******************************************************************) + + function Context_Create( _context : Pointer; + _face : Pointer ) : TError; + var + n_points : Int; + n_twilight : Int; + + exec : PExec_Context; + label + Fail_Memory; + begin + Context_Create := Failure; + + exec := PExec_Context(_context); + exec^.face := PFace(_face); + + with exec^ do + begin + + callSize := 32; + loadSize := face^.maxComponents + 1; + storeSize := face^.MaxProfile.maxStorage; + stackSize := face^.MaxProfile.maxStackElements + 32; + (* Allocate a little extra for broken fonts like Courbs.ttf *) + (* and Timesbs.ttf *) + + n_points := face^.maxPoints + 2; + + (* Reserve glyph code range *) + if Alloc( glyphIns, face^.MaxProfile.maxSizeOfInstructions ) or + + (* Reserve call stack *) + Alloc( callStack, callSize*sizeof(TCallRecord) ) or + + (* Reserve stack *) + Alloc( stack, stackSize*sizeof(Long) ) then + + (* we don't reserve the points and contours arrays anymore *) + (* as this will be performed automatically by a Context_Load *) + + (* the same is true for the load stack *) + + goto Fail_Memory; + + maxPoints := 0; + maxContours := 0; + + loadSize := 0; + loadStack := nil; + + pts.n_points := 0; + pts.n_contours := 0; + + instance := nil; + end; + + Context_Create := Success; + exit; + + Fail_Memory: + Context_Destroy(_context); + error := TT_Err_Out_Of_Memory; + exit; + end; + +(******************************************************************* + * + * Function : Context_Run + * + * Description : Run a glyph's bytecode stream + * + * Input : exec context record + * + ******************************************************************) + + function Context_Run( exec : PExec_Context; + debug : Boolean ) : TError; + begin + Context_Run := Failure; + + if Goto_CodeRange( exec, TT_CodeRange_Glyph, 0 ) then + exit; + + with exec^ do + begin + top := 0; + callTop := 0; + zp0 := pts; + zp1 := pts; + zp2 := pts; + GS.gep0 := 1; + GS.gep1 := 1; + GS.gep2 := 1; + + GS.projVector.x := $4000; + GS.projVector.y := $0000; + GS.freeVector := GS.projVector; + GS.dualVector := GS.projVector; + GS.round_state := 1; + GS.loop := 1; + end; + + if not debug and Run_Ins( @exec^ ) then + begin + error := exec^.error; + exit; + end; + + Context_Run := Success; + end; + +(****************************************************************) +(* *) +(* Instance Update Functions *) +(* *) +(****************************************************************) + +(******************************************************************* + * + * Function : Context_Load + * + * Description : loads instance data into a new execution context + * + *******************************************************************) + + procedure Context_Load( exec : PExec_Context; + ins : PInstance ); + + procedure Update_Max( var size : Int; + mult : Int; + var buff; + new_max : Int ); + begin + if size*mult < new_max then + begin + Free(buff); + Alloc( buff, new_max*mult ); + size := new_max; + end; + end; + + + procedure Update_Points( max_points : Int; + max_contours : Int; + exec : PExec_Context ); + begin + if exec^.maxPoints < max_points then + begin + Free( exec^.pts.org ); + Free( exec^.pts.cur ); + Free( exec^.pts.flags ); + + Alloc( exec^.pts.org, 2*sizeof(TT_F26dot6)*max_points ); + Alloc( exec^.pts.cur, 2*sizeof(TT_F26dot6)*max_points ); + Alloc( exec^.pts.flags, sizeof(Byte) *max_points ); + + exec^.maxPoints := max_points; + end; + + if exec^.maxContours < max_contours then + begin + Free( exec^.pts.conEnds ); + Alloc( exec^.pts.conEnds, sizeof(Short)*max_contours ); + exec^.maxContours := max_contours; + end; + end; + + + begin + with exec^ do + begin + + instance := ins; + face := ins^.owner; + + numFDefs := ins^.numFDefs; + numIDefs := ins^.numIDefs; + maxFDefs := ins^.maxFDefs; + maxIDefs := ins^.maxIDefs; + FDefs := ins^.FDefs; + IDefs := ins^.IDefs; + maxFunc := ins^.maxFunc; + maxIns := ins^.maxIns; + + metrics := ins^.metrics; + + codeRangeTable := ins^.codeRangeTable; + + storeSize := ins^.storeSize; + storage := ins^.storage; + + twilight := ins^.twilight; + + (* We reserve some extra space to deal with broken fonts *) + (* like Arial BS, Courier BS, etc.. *) + Update_Max( stackSize, + sizeof(Long), + stack, + face^.maxProfile.maxStackElements+32 ); + + Update_Max( loadSize, + sizeof(TSubglyph_Record), + loadStack, + face^.maxComponents+1 ); + + Update_Max( glyphSize, + sizeof(Byte), + glyphIns, + face^.maxProfile.maxSizeOfInstructions ); + + (* XXXX : Don't forget the phantom points !! *) + Update_Points( face^.maxPoints+2, face^.maxContours, exec ); + + pts.n_points := 0; + pts.n_contours := 0; + + instruction_trap := false; + + (* Set default graphics state *) + GS := ins^.GS; + + cvtSize := ins^.cvtSize; + cvt := ins^.cvt; + end; + end; + + + procedure Context_Save( exec : PExec_Context; + ins : PInstance ); + begin + with ins^ do + begin + error := exec^.error; + + numFDefs := exec^.numFDefs; + numIDefs := exec^.numIDefs; + maxFunc := exec^.maxFunc; + maxIns := exec^.maxIns; + + codeRangeTable := exec^.codeRangeTable; + + (* Set default graphics state *) + + GS := exec^.GS; + end; + end; + +(******************************************************************* + * + * Function : Instance_Destroy + * + * Description : The Instance Record destructor. + * + *****************************************************************) + + function Instance_Destroy( instance : Pointer ) : TError; + var + ins : PInstance; + begin + + Instance_Destroy := Success; + + ins := PInstance(instance); + if ins = nil then + exit; + + with ins^ do + begin + + if debug then + begin + context := nil; + debug := false; + end; + + (* Free twilight zone *) + Free( twilight.org ); + Free( twilight.cur ); + Free( twilight.flags ); + twilight.n_points := 0; + + Free( cvt ); + cvtSize := 0; + + Free( storage ); + storeSize := 0; + + Free( FDefs ); + Free( IDefs ); + numFDefs := 0; + numIDefs := 0; + maxFDefs := 0; + maxIDefs := 0; + + owner := nil; + valid := false; + + end; + end; + +(******************************************************************* + * + * Function : Instance_Create + * + * Description : The Instance constructor. + * + * This functions creates a new instance object for a given face + * + *****************************************************************) + + function Instance_Create( _ins : Pointer; + _face : Pointer ) : TError; + label + Fail_Memory; + var + l : Longint; + ins : PInstance; + face : PFace; + + n_twilight : Int; + begin + Instance_Create := Failure; + + {$IFDEF ASSERT} + if (_face = nil) then + Panic1('TTInst.Init_Instance : void argument' ); + {$ENDIF} + + face := PFace(_face); + ins := PInstance(_ins); + + ins^.owner := face; + + with face^, ins^ do + begin + + (* Reserve function and instruction defs arrays *) + maxFDefs := maxProfile.maxFunctionDefs; + maxIDefs := maxProfile.maxInstructionDefs; + storeSize := maxProfile.maxStorage; + n_twilight := maxProfile.maxTwilightPoints; + + if Alloc( FDefs, maxFDefs * sizeof(TDefRecord) ) or + Alloc( IDefs, maxIDefs * sizeof(TDefRecord) ) or + Alloc( storage, storeSize * sizeof(Long) ) or + + Alloc( twilight.org, 2* n_twilight * sizeof(TT_F26Dot6) ) or + Alloc( twilight.cur, 2* n_twilight * sizeof(TT_F26Dot6) ) or + Alloc( twilight.flags, n_twilight ) + + then goto Fail_Memory; + + twilight.n_points := n_twilight; + + metrics.x_resolution := 96; + metrics.y_resolution := 96; + metrics.pointSize := 10; + metrics.x_scale2 := 1; + metrics.y_scale2 := 1; + metrics.scale2 := 1; + + { Reserve Control Value Table } + cvtSize := face^.cvtSize; + + if Alloc( cvt, cvtSize * sizeof(Long) ) then + goto Fail_Memory; + + end; + + Instance_Create := Success; + exit; + + Fail_Memory: + Instance_Destroy(ins); + (* free all partially allocated tables, including the instance record *) + + error := TT_Err_Out_Of_Memory; + exit; + end; + + +(******************************************************************* + * + * Function : Instance_Init + * + * Description : Initializes a fresh new instance + * Executes the font program if any is found + * + * Input : ins the instance object to initialise + * + *****************************************************************) + + function Instance_Init( ins : PInstance ) : TError; + var + exec : PExec_Context; + face : PFace; + label + Fin; + begin + Instance_Init := Failure; + + face := ins^.owner; + + if ins^.debug then + exec := ins^.context + else + exec := New_Context( ins ); + (* debugging instances have their own context *) + + if exec = nil then + begin + error := TT_Err_Could_Not_Find_Context; + exit; + end; + + with ins^ do begin + GS := Default_GraphicsState; + numFDefs := 0; + numIDefs := 0; + maxFunc := -1; + maxIns := -1; + end; + + Context_Load( exec, ins ); + + with exec^ do + begin + callTop := 0; + top := 0; + period := 64; + phase := 0; + threshold := 0; + + with metrics do + begin + x_ppem := 10; + y_ppem := 10; + pointSize := 10; + x_scale1 := 0; + x_scale2 := 1; + y_scale1 := 0; + y_scale2 := 1; + + scale1 := 0; + scale2 := 1; + ratio := 1 shl 16; + end; + + instruction_trap := false; + + cvtSize := ins^.cvtSize; + cvt := ins^.cvt; + + F_dot_P := $10000; + end; + + Set_CodeRange( exec, + TT_CodeRange_Font, + face^.fontProgram, + face^.fontPgmSize ); + (* Allow font program execution *) + + Clear_CodeRange( exec, TT_CodeRange_Cvt ); + Clear_CodeRange( exec, TT_CodeRange_Glyph ); + (* disable CVT and glyph programs coderanges *) + + if face^.fontPgmSize > 0 then + begin + if Goto_CodeRange( exec, TT_CodeRange_Font, 0 ) then + goto Fin; + + if Run_Ins( @exec^ ) then + begin + error := exec^.error; + goto Fin; + end; + end; + + Instance_Init := Success; + + Fin: + Context_Save( exec, ins ); + + if not ins^.debug then + Done_Context( exec ); + + ins^.valid := False; + end; + +(******************************************************************* + * + * Function : Instance_Reset + * + * Description : Reset an instance to a new pointsize + * Executes the prep/cvt program if any is found + * + * Input : ins the instance object to initialise + * + *****************************************************************) + + function Instance_Reset( ins : PInstance; + debug : boolean ) : TError; + var + exec : PExec_Context; + face : PFace; + i : Int; + label + Fin; + begin + Instance_Reset := Failure; + + if ins^.valid then + begin + Instance_Reset := Success; + exit; + end; + + face := ins^.owner; + + (* compute new transform *) + + with ins^.metrics do + begin + + if x_ppem < 1 then x_ppem := 1; + if y_ppem < 1 then y_ppem := 1; + + if x_ppem >= y_ppem then + begin + scale1 := x_scale1; + scale2 := x_scale2; + ppem := x_ppem; + x_ratio := 1 shl 16; + y_ratio := MulDiv_Round( y_ppem, $10000, x_ppem ); + end + else + begin + scale1 := y_scale1; + scale2 := y_scale2; + ppem := y_ppem; + x_ratio := MulDiv_Round( x_ppem, $10000, y_ppem ); + y_ratio := 1 shl 16 + end; + end; + + (* scale the cvt values to the new ppem *) + + for i := 0 to ins^.cvtSize-1 do + ins^.cvt^[i] := MulDiv_Round( ins^.owner^.cvt^[i], + ins^.metrics.scale1, + ins^.metrics.scale2 ); + + (* Note that we use the y resolution by default to scale the cvt *) + + ins^.GS := Default_GraphicsState; + + if ins^.debug then + exec := ins^.context + else + exec := New_Context(ins); + + if exec = nil then + begin + error := TT_Err_Could_Not_Find_Context; + exit; + end; + + Context_Load( exec, ins ); + + Set_CodeRange( exec, + TT_CodeRange_CVT, + face^.cvtProgram, + face^.cvtPgmSize ); + + Clear_CodeRange( exec, TT_CodeRange_Glyph ); + + with exec^ do + begin + + for i := 0 to storeSize-1 do + storage^[i] := 0; + + instruction_trap := False; + + top := 0; + callTop := 0; + + (* all twilight points are originally zero *) + for i := 0 to twilight.n_points-1 do + begin + twilight.org^[i].x := 0; + twilight.org^[i].y := 0; + twilight.cur^[i].x := 0; + twilight.cur^[i].y := 0; + end; + end; + + if face^.cvtPgmSize > 0 then + if Goto_CodeRange( exec, TT_CodeRange_CVT, 0 ) or + ( (not debug) and Run_Ins( @exec^ ) ) then + goto Fin; + + ins^.GS := exec^.GS; + Instance_Reset := Success; + + Fin: + Context_Save( exec, ins ); + + if not ins^.debug then + Done_Context(exec); + + if error = 0 then + ins^.valid := True; + end; + + +(******************************************************************* + * + * Function : Face_Destroy + * + * Description : The face object destructor + * + *****************************************************************) + + function Face_Destroy( _face : Pointer ) : TError; + var + face : PFace; + n : Int; + begin + Face_Destroy := Success; + + face := PFace(_face); + if face = nil then exit; + + Cache_Destroy( face^.instances ); + Cache_Destroy( face^.glyphs ); + + (* freeing the tables directory *) + Free( face^.dirTables ); + face^.numTables := 0; + + (* freeing the locations table *) + Free( face^.glyphLocations ); + face^.numLocations := 0; + + (* freeing the character mapping tables *) + for n := 0 to face^.numCMaps-1 do + CharMap_Free( face^.cMaps^[n] ); + + Free( face^.cMaps ); + face^.numCMaps := 0; + + (* freeing the CVT *) + Free( face^.cvt ); + face^.cvtSize := 0; + + (* freeing the horizontal header *) + Free( face^.horizontalHeader.short_metrics ); + Free( face^.horizontalHeader.long_metrics ); + if face^.verticalInfo then + begin + Free( face^.verticalHeader.short_metrics ); + Free( face^.verticalHeader.long_metrics ); + face^.verticalInfo := False; + end; + + (* freeing the programs *) + Free( face^.fontProgram ); + Free( face^.cvtProgram ); + face^.fontPgmSize := 0; + face^.cvtPgmSize := 0; + + (* freeing the gasp table - none yet *) + Free( face^.gasp.gaspRanges ); + + (* freeing the names table *) + Free( face^.nameTable.names ); + Free( face^.nameTable.storage ); + face^.nameTable.numNameRecords := 0; + face^.nameTable.format := 0; + + (* freeing the hdmx table *) + for n := 0 to face^.hdmx.num_records-1 do + Free( face^.hdmx.records^[n].widths ); + + Free( face^.hdmx.records ); + face^.hdmx.num_records := 0; + + TT_Close_Stream( face^.stream ); + end; + +(******************************************************************* + * + * Function : Face_Create + * + * Description : The face object constructor + * + *****************************************************************) + + function Face_Create( _face : Pointer; + _input : Pointer ) : TError; + var + input : PFont_Input; + face : PFace; + label + Fail; + begin + Face_Create := Failure; + + face := PFace(_face); + input := PFont_Input(_input); + + face^.stream := input^.stream; + + if Cache_Create( objs_instance_class, face^.instances ) or + Cache_Create( objs_glyph_class, face^.glyphs ) then exit; + + (* Load collection directory if present *) + if Load_TrueType_Directory( face, input^.fontIndex ) then + exit; + + if Load_TrueType_Header ( face ) or + Load_TrueType_MaxProfile ( face ) or + Load_TrueType_Locations ( face ) or + Load_TrueType_CMap ( face ) or + Load_TrueType_CVT ( face ) or + Load_TrueType_Metrics_Header ( face, false ) or + Load_TrueType_Programs ( face ) or + Load_TrueType_Gasp ( face ) or + Load_TrueType_Names ( face ) or + Load_TrueType_OS2 ( face ) or + Load_TrueType_Hdmx ( face ) or + Load_TrueType_Postscript ( face ) or + Load_TrueType_Metrics_Header ( face, true ) then + goto Fail; + + Face_Create := Success; + exit; + + Fail: + Face_Destroy( face ); + end; + + + function Glyph_Destroy( _glyph : Pointer ) : TError; + var + glyph : PGlyph; + begin + Glyph_Destroy := Success; + + glyph := PGlyph(_glyph); + if glyph = nil then + exit; + + glyph^.outline.owner := true; + TT_Done_Outline( glyph^.outline ); + end; + + + function Glyph_Create( _glyph : Pointer; + _face : Pointer ) : TError; + var + glyph : PGlyph; + begin + glyph := PGlyph(_glyph); + + glyph^.face := PFace(_face); + error := TT_New_Outline( glyph^.face^.maxPoints+2, + glyph^.face^.maxContours, + glyph^.outline ); + if error <> TT_Err_Ok then + Glyph_Create := Failure + else + Glyph_Create := Success; + end; + + + + function Scale_X( var metrics : TIns_Metrics; x : TT_Pos ) : TT_Pos; + begin + Scale_X := MulDiv_Round( x, metrics.x_scale1, metrics.x_scale2 ); + end; + + + + function Scale_Y( var metrics : TIns_Metrics; y : TT_Pos ) : TT_Pos; + begin + Scale_Y := MulDiv_Round( y, metrics.y_scale1, metrics.y_scale2 ); + end; + + + + function TTObjs_Init : TError; + begin + TTObjs_Init := Failure; + + Cache_Create( objs_face_class, face_cache ); + Cache_Create( objs_exec_class, exec_cache ); + + TTObjs_Init := success; + end; + + + + procedure TTObjs_Done; + begin + Cache_Destroy( face_cache ); + Cache_Destroy( exec_cache ); + end; + +end. + diff --git a/pascal/lib/ttraster.pas b/pascal/lib/ttraster.pas new file mode 100644 index 0000000..9f17ca2 --- /dev/null +++ b/pascal/lib/ttraster.pas @@ -0,0 +1,3445 @@ +(******************************************************************* + * + * TTRaster.Pas v 1.2 + * + * The FreeType glyph rasterizer. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * NOTES : This version supports the following : + * + * - direct grayscaling + * - sub-banding + * - drop-out modes 4 and 5 + * - second pass for complete drop-out control ( bitmap only ) + * - variable precision + * + * Re-entrancy is _not_ planned. + * + * Changes between 1.1 and 1.2 : + * + * - no more trace tables, now uses linked list to sort + * coordinates. + * + * - reduced code size using function dispatch within a generic + * draw_sweep function. + * + * - added variable precision for finer rendering at small ppems + * + * + * Note that its interface may change in the future. + * + ******************************************************************) + +Unit TTRASTER; + +interface + +{$I TTCONFIG.INC} + +{ $DEFINE TURNS} + +uses +{$IFDEF VIRTUALPASCAL} + Use32, +{$ENDIF} + FreeType, + TTTypes; + +const + + Err_Ras_None = 0; + Err_Ras_NotIni = -2; (* Rasterizer not Initialized *) + Err_Ras_Overflow = -3; (* Profile Table Overflow *) + Err_Ras_Neg_H = -4; (* Negative Height encountered ! *) + Err_Ras_Invalid = -5; (* Invalid value encountered ! *) + Err_Ras_Invalid_Contours = -6; + + function Render_Glyph( var glyph : TT_Outline; + var target : TT_Raster_Map ) : TError; + + (* Render one glyph in the target bitmap, using drop-out control *) + (* mode 'scan' *) + + function Render_Gray_Glyph( var glyph : TT_Outline; + var target : TT_Raster_Map ) : TError; + + (* Render one gray-level glyph in the target pixmap *) + (* palette points to an array of 5 colors used for the rendering *) + (* use nil to reuse the last palette. Default is VGA graylevels *) + +{$IFDEF SMOOTH} + function Render_Smooth_Glyph( var glyph : TGlyphRecord; + target : PRasterBlock; + scan : Byte; + palette : pointer ) : boolean; +{$ENDIF} + + procedure Set_High_Precision( High : boolean ); + (* Set rendering precision. Should be set to TRUE for small sizes only *) + (* ( typically < 20 ppem ) *) + + procedure Set_Second_Pass( Pass : boolean ); + (* Set second pass flag *) + + function TTRaster_Init : TError; + procedure TTRaster_Done; + +implementation + +uses + TTCalc, { used for MulDiv } + TTError +{$IFDEF DEBUG} + ,GMain { Used to access VRAM pointer VIO during DEBUG } +{$ENDIF} + ; + + +{$DEFINE NO_ASM} + +const + Render_Pool_Size = 64000; + Gray_Lines_Size = 2048; + + MaxBezier = 32; (* Maximum number of stacked B‚ziers. *) + (* Setting this constant to more than 32 *) + (* is a pure waste of space *) + + Pixel_Bits = 6; (* fractional bits of input coordinates *) + + Cell_Bits = 8; + +type + + TEtats = ( Indetermine, Ascendant, Descendant, Plat ); + + PProfile = ^TProfile; + TProfile = record + Flow : Int; (* ascending or descending Profile *) + Height : Int; (* Profile's height in scanlines *) + Start : Int; (* Profile's starting scanline *) + Offset : ULong; (* offset of first coordinate in *) + (* render pool *) + + Link : PProfile; (* link used in several cases *) + + X : Longint; (* current coordinate during sweep *) + CountL : Int; (* number of lines to step before *) + (* this Profile becomes drawable *) + + next : PProfile; (* next Profile of the same contour *) + end; + + TBand = record + Y_Min : Int; + Y_Max : Int; + end; + + (* Simple record used to implement a stack of bands, required *) + (* by the sub-banding mechanism *) + +const + AlignProfileSize = ( sizeOf(TProfile) + 3 ) div 4; + (* You may need to compute this according to your prefered alignement *) + + LMask : array[0..7] of Byte + = ($FF,$7F,$3F,$1F,$0F,$07,$03,$01); + + RMask : array[0..7] of Byte + = ($80,$C0,$E0,$F0,$F8,$FC,$FE,$FF); + + (* left and right fill bitmasks *) + +type + Function_Sweep_Init = procedure( var min, max : Int ); + + Function_Sweep_Span = procedure( y : Int; + x1 : TT_F26dot6; + x2 : TT_F26dot6; + Left : PProfile; + Right : PProfile ); + + Function_Sweep_Step = procedure; + + (* prototypes used for sweep function dispatch *) + + TPoint = record x, y : long; end; + + TBezierStack = array[0..32*2] of TPoint; + PBezierStack = ^TBezierStack; + +{$IFNDEF CONST_PREC} + +var + Precision_Bits : Int; (* Fractional bits of Raster coordinates *) + Precision : Int; + Precision_Half : Int; + Precision_Step : Int; (* Bezier subdivision minimal step *) + Precision_Shift : Int; (* Shift used to convert coordinates *) + Precision_Mask : Longint; (* integer truncatoin mask *) + Precision_Jitter : Int; + +{$ELSE} + +const + Precision_Bits = 6; + Precision = 1 shl Precision_Bits; + Precision_Half = Precision div 2; + Precision_Step = Precision_Half; + Precision_Shift = 0; + Precision_Mask = -Precision; + Precision_Jitter = 2; + +{$ENDIF} + +var + Scale_Shift : Int; + + cProfile : PProfile; (* current Profile *) + fProfile : PProfile; (* head of Profiles linked list *) + oProfile : PProfile; (* old Profile *) + gProfile : PProfile; (* last Profile in case of impact *) + + nProfs : Int; (* current number of Profiles *) + + Etat : TEtats; (* State of current trace *) + + Fresh : Boolean; (* Indicates a new Profile which 'Start' field *) + (* must be set *) + + Joint : Boolean; (* Indicates that the last arc stopped sharp *) + (* on a scan-line. Important to get rid of *) + (* doublets *) + + Buff : PStorage; (* Profiles buffer a.k.a. Render Pool *) + SizeBuff : ULong; (* current render pool's size *) + MaxBuff : ULong; (* current render pool's top *) + profCur : ULong; (* current render pool cursor *) + + Cible : TT_Raster_Map; (* Description of target map *) + + BWidth : integer; + BCible : PByte; (* target bitmap buffer *) + GCible : PByte; (* target pixmap buffer *) + + TraceOfs : Int; (* current offset in target bitmap *) + TraceIncr : Int; (* increment to next line in target map *) + TraceG : Int; (* current offset in targer pixmap *) + + gray_min_x : Int; (* current min x during gray rendering *) + gray_max_x : Int; (* current max x during gray rendering *) + + (* Dispatch variables : *) + + Proc_Sweep_Init : Function_Sweep_Init; (* Sweep initialisation *) + Proc_Sweep_Span : Function_Sweep_Span; (* Span drawing *) + Proc_Sweep_Drop : Function_Sweep_Span; (* Drop out control *) + Proc_Sweep_Step : Function_Sweep_Step; (* Sweep line step *) + + Arcs : TBezierStack; + CurArc : Int; (* stack's top *) + + Points : TT_Points; + + Flags : PByte; (* current flags array *) + Outs : TT_PConStarts; (* current endpoints array *) + + nPoints, (* current number of points *) + nContours : Int; (* current number of contours *) + + LastX, (* Last and extrema coordinates during *) + LastY, (* rendering *) + MinY, + MaxY : LongInt; + +{$IFDEF TURNS} + numTurns : Int; +{$ENDIF} + + DropOutControl : Byte; (* current drop-out control mode *) + + Count_Table : array[0..255] of Word; + (* Look-up table used to quickly count set bits in a gray 2x2 cell *) + + Count_Table2 : array[0..255] of Word; + (* Look-up table used to quickly count set bits in a gray 2x2 cell *) + + Grays : array[0..4] of Byte; + (* gray palette used during gray-levels rendering *) + (* 0 : background .. 4 : foreground *) + + Gray_Lines : PByte; { 2 intermediate bitmap lines } + Gray_Width : integer; { width of the 'gray' lines in pixels } + +{$IFDEF SMOOTH} + Smooth_Cols : integer; + Smooths : array[0..16] of Byte; + (* smooth palette used during smooth-levels rendering *) + (* 0 : background...16 : foreground *) + + smooth_pass : integer; +{$ENDIF} + + Second_Pass : boolean; + (* indicates wether an horizontal pass should be performed *) + (* to control drop-out accurately when calling Render_Glyph *) + (* Note that there is no horizontal pass during gray render *) + + (* better set it off at ppem >= 18 *) + + Band_Stack : array[1..16] of TBand; + Band_Top : Int; + + + +{$IFDEF DEBUG3} +(****************************************************************************) +(* *) +(* Function: Pset *) +(* *) +(* Description: Used only in the "DEBUG3" state. *) +(* *) +(* This procedure simply plots a point on the video screen *) +(* Note that it relies on the value of cProfile->start, *) +(* which may sometimes not be set yet when Pset is called. *) +(* This will usually result in a dot plotted on the first *) +(* screen scanline ( far away its original position ). *) +(* *) +(* This "bug" means not that the current implementation is *) +(* buggy, as the bitmap will be rendered correctly, so don't *) +(* panic if you see 'flying' dots in debugging mode *) +(* *) +(* *) +(* Input: None *) +(* *) +(* Returns: Nada *) +(* *) +(****************************************************************************) + +procedure PSet; +var c : byte; + o : Int; + xz : LongInt; +begin + xz := Buff^[profCur] div Precision; + + with cProfile^ do + begin + + case Flow of + TT_Flow_Up : o := 80 * (profCur-Offset+Start) + xz div 8; + TT_Flow_Down : o := 80 * (Start-profCur+offset) + xz div 8; + end; + + if o > 0 then + begin + c := Vio^[o] or ( $80 shr ( xz and 7 )); + Vio^[o] := c; + end + end; +end; + +(****************************************************************************) +(* *) +(* Function: Clear_Band *) +(* *) +(* Description: Clears a Band on screen during DEBUG3 rendering *) +(* *) +(* Input: y1, y2 top and bottom of screen-wide band *) +(* *) +(* Returns: Nada. *) +(* *) +(****************************************************************************) + +procedure ClearBand( y1, y2 : Int ); +var + Y : Int; + K : Word; +begin + K := y1*80; + FillChar( Vio^[k], (y2-y1+1)*80, 0 ); +end; +{$ENDIF} + +{$IFNDEF CONST_PREC} + +(****************************************************************************) +(* *) +(* Function: Set_High_Precision *) +(* *) +(* Description: Sets precision variables according to param flag *) +(* *) +(* Input: High set to True for high precision ( typically for *) +(* ppem < 18 ), false otherwise. *) +(* *) +(****************************************************************************) + +procedure Set_High_Precision( High : boolean ); +begin + if High then + begin + Precision_Bits := 10; + Precision_Step := 128; + Precision_Jitter := 24; + end + else + begin + Precision_Bits := 6; + Precision_Step := 32; + Precision_Jitter := 2; + end; + + Precision := 1 shl Precision_Bits; + Precision_Half := Precision shr 1; + Precision_Shift := Precision_Bits - Pixel_Bits; + Precision_Mask := -Precision; +end; + +{$ENDIF} + +procedure Set_Second_Pass( Pass : boolean ); +begin + second_pass := pass; +end; + + +function TRUNC( x : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + Trunc := (x and -Precision) div Precision; +end; + +function FRAC( x : Long ) : Int; {$IFDEF INLINE} inline; {$ENDIF} +begin + Frac := x and (Precision-1); +end; + +function FLOOR( x : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + Floor := x and -Precision; +end; + +function CEILING( x : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + Ceiling := (x + Precision-1) and -Precision; +end; + +function SCALED( x : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + SCALED := (x shl scale_shift) - precision_half; +end; + +{$IFDEF USE32} (* speed things a bit on 32-bit systems *) +function MulDiv( a, b, c : Long ) : Long; {$IFDEF INLINE} inline; {$ENDIF} +begin + MulDiv := a*b div c; +end; +{$ENDIF} + +(****************************************************************************) +(* *) +(* Function: New_Profile *) +(* *) +(* Description: Creates a new Profile in the render pool *) +(* *) +(* Input: AEtat state/orientation of the new Profile *) +(* *) +(* Returns: True on sucess *) +(* False in case of overflow or of incoherent Profile *) +(* *) +(****************************************************************************) + +function New_Profile( AEtat : TEtats ) : boolean; +begin + + if fProfile = NIL then + begin + cProfile := PProfile( @Buff^[profCur] ); + fProfile := cProfile; + inc( profCur, AlignProfileSize ); + end; + + if profCur >= MaxBuff then + begin + Error := Err_Ras_Overflow; + New_Profile := False; + exit; + end; + + with cProfile^ do + begin + + Case AEtat of + + Ascendant : Flow := TT_Flow_Up; + Descendant : Flow := TT_Flow_Down; + else +{$IFDEF DEBUG} + Writeln('ERROR : Incoherent Profile' ); + Halt(30); +{$ELSE} + New_Profile := False; + Error := Err_Ras_Invalid; + exit; +{$ENDIF} + end; + + Start := 0; + Height := 0; + Offset := profCur; + Link := nil; + next := nil; + end; + + if gProfile = nil then gProfile := cProfile; + + Etat := AEtat; + Fresh := True; + Joint := False; + + New_Profile := True; +end; + +{$IFDEF TURNS} +(****************************************************************************) +(* *) +(* Function: Insert_Y_Turn *) +(* *) +(* Description: Insert a slaient into the sorted list *) +(* *) +(* Input: new y turn *) +(* *) +(****************************************************************************) + +procedure Insert_Y_Turn( y : Int ); +var + y_turns : PStorage; + y2, n : Int; +begin + n := numTurns-1; + y_turns := @Buff^[SizeBuff-numTurns]; + + (* look for first y value that is <= *) + while (n >= 0) and (y < y_turns^[n]) do dec(n); + + (* if it is <, simply insert it, ignor if we found one == *) + + if (n >= 0) and (y > y_turns^[n]) then + while (n >= 0) do + begin + y2 := y_turns^[n]; + y_turns^[n] := y; + y := y2; + dec( n ); + end; + + if (n < 0) then + begin + dec( MaxBuff ); + inc( numTurns ); + Buff^[SizeBuff-numTurns] := y; + end +end; +{$ENDIF} + + +(****************************************************************************) +(* *) +(* Function: End_Profile *) +(* *) +(* Description: Finalizes the current Profile. *) +(* *) +(* Input: None *) +(* *) +(* Returns: True on success *) +(* False on overflow or incoherency. *) +(* *) +(****************************************************************************) + +function End_Profile : boolean; +var + H : Int; + oldProfile : PProfile; +begin + H := profCur - cProfile^.Offset; + + if H < 0 then + begin + End_Profile := False; + Error := Err_Ras_Neg_H; + exit; + end; + + if H > 0 then + begin + oldProfile := cProfile; + cProfile^.Height := H; + cProfile := PProfile( @Buff^[profCur] ); + + inc( profCur, AlignProfileSize ); + + cProfile^.Height := 0; + cProfile^.Offset := profCur; + oldProfile^.next := cProfile; + inc( nProfs ); + end; + + if profCur >= MaxBuff then + begin + End_Profile := False; + Error := Err_Ras_Overflow; + exit; + end; + + Joint := False; + + End_Profile := True; +end; + +(****************************************************************************) +(* *) +(* Function: Finalize_Profile_Table *) +(* *) +(* Description: Adjusts all links in the Profiles list *) +(* *) +(* Input: None *) +(* *) +(* Returns: Nada *) +(* *) +(****************************************************************************) + +procedure Finalize_Profile_Table; +var + n : int; + p : PProfile; + + Bottom, Top : Int; +begin + + n := nProfs; + + if n > 1 then + begin + + P := fProfile; + + while n > 0 do with P^ do + begin + if n > 1 then + Link := PProfile( @Buff^[ Offset + Height ] ) + else + Link := nil; + + with P^ do + Case Flow of + + TT_Flow_Up : begin + Bottom := Start; + Top := Start+Height-1; + end; + + TT_Flow_Down : begin + Bottom := Start-Height+1; + Top := Start; + + Start := Bottom; + Offset := Offset+Height-1; + end; + end; +{$IFDEF TURNS} + Insert_Y_Turn( Bottom ); + Insert_Y_Turn( Top+1 ); +{$ENDIF} + P := Link; + + dec( n ); + end; + end + else + fProfile := nil; + +end; + +(****************************************************************************) +(* *) +(* Function: Split_Bezier *) +(* *) +(* Description: Subdivises one Bezier arc into two joint *) +(* sub-arcs in the Bezier stack. *) +(* *) +(* Input: None ( subdivised bezier is taken from the top of the *) +(* stack ) *) +(* *) +(* Returns: Nada *) +(* *) +(****************************************************************************) + +procedure Split_Bezier( base : PBezierStack ); +var + arc : PBezierStack; + a, b : Long; +begin +{$IFNDEF NO_ASM} + asm + push esi + push ebx + push ecx + + mov esi, base + + mov eax, [esi+2*8] (* arc^[4].x := arc^[2].x *) + mov ebx, [esi+1*8] (* b := arc^[1].x *) + mov ecx, [esi+0*8] (* b := (arc^[0].x+b) div 2 *) + + mov [esi+4*8], eax + + add eax, ebx (* a := (arc^[2].x+b) div 2 *) + add ebx, ecx + mov edx, eax + mov ecx, ebx + sar edx, 31 + sar ecx, 31 + sub eax, edx + sub ebx, ecx + sar eax, 1 + sar ebx, 1 + + mov [esi+3*8], eax (* arc^[3].x := a *) + mov [esi+1*8], ebx + + add eax, ebx (* arc[2].x := (a+b) div 2 *) + mov edx, eax + sar edx, 31 + sub eax, edx + sar eax, 1 + mov [esi+2*8], eax + + add esi, 4 + + mov eax, [esi+2*8] (* arc^[4].x := arc^[2].x *) + mov ebx, [esi+1*8] (* b := arc^[1].x *) + mov ecx, [esi+0*8] (* b := (arc^[0].x+b) div 2 *) + + mov [esi+4*8], eax + + add eax, ebx (* a := (arc^[2].x+b) div 2 *) + add ebx, ecx + mov edx, eax + mov ecx, ebx + sar edx, 31 + sar ecx, 31 + sub eax, edx + sub ebx, ecx + sar eax, 1 + sar ebx, 1 + + mov [esi+3*8], eax (* arc^[3].x := a *) + mov [esi+1*8], ebx + + add eax, ebx (* arc[2].x := (a+b) div 2 *) + mov edx, eax + sar edx, 31 + sub eax, edx + sar eax, 1 + mov [esi+2*8], eax + + pop ecx + pop ebx + pop esi + end; +{$ELSE} + arc := base; + + arc^[4].x := arc^[2].x; + b := arc^[1].x; + a := (arc^[2].x + b) div 2; arc^[3].x := a; + b := (arc^[0].x + b) div 2; arc^[1].x := b; + arc^[2].x := (a+b) div 2; + + arc^[4].y := arc^[2].y; + b := arc^[1].y; + a := (arc^[2].y + b) div 2; arc^[3].y := a; + b := (arc^[0].y + b) div 2; arc^[1].y := b; + arc^[2].y := (a+b) div 2; +{$ENDIF} +end; + +(****************************************************************************) +(* *) +(* Function: Push_Bezier *) +(* *) +(* Description: Clears the Bezier stack and pushes a new Arc on top of it. *) +(* *) +(* Input: x1,y1 x2,y2 x3,y3 new Bezier arc *) +(* *) +(* Returns: nada *) +(* *) +(****************************************************************************) + +procedure PushBezier( x1, y1, x2, y2, x3, y3 : LongInt ); +begin + curArc:=0; + + with Arcs[CurArc+2] do begin x:=x1; y:=y1; end; + with Arcs[CurArc+1] do begin x:=x2; y:=y2; end; + with Arcs[ CurArc ] do begin x:=x3; y:=y3; end; +end; + +(****************************************************************************) +(* *) +(* Function: Line_Up *) +(* *) +(* Description: Compute the x-coordinates of an ascending line segment *) +(* and stores them in the render pool. *) +(* *) +(* Input: x1,y1 x2,y2 Segment start (x1,y1) and end (x2,y2) points *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow. *) +(* *) +(****************************************************************************) + +function Line_Up( x1, y1, x2, y2, miny, maxy : LongInt ) : boolean; +var + Dx, Dy : LongInt; + e1, e2, f1, f2, size : Int; + Ix, Rx, Ax : LongInt; + top : PStorage; +begin + Line_Up := True; + + Dx := x2-x1; Dy := y2-y1; + + if (Dy <= 0) or (y2 < MinY) or (y1 > MaxY) then exit; + + if y1 < MinY then + begin + x1 := x1 + MulDiv( Dx, MinY-y1, Dy ); + e1 := Trunc(MinY); + f1 := 0; + end + else + begin + e1 := Trunc(y1); + f1 := Frac(y1); + end; + + if y2 > MaxY then + begin + (* x2 := x2 + MulDiv( Dx, MaxY-y2, Dy ); *) + e2 := Trunc(MaxY); + f2 := 0; + end + else + begin + e2 := Trunc(y2); + f2 := Frac(y2); + end; + + if f1 > 0 then + if e1 = e2 then exit + else + begin + inc( x1, MulDiv( Dx, precision-f1, Dy ) ); + inc( e1 ); + end + else + if Joint then + dec( profCur ); + + Joint := (f2 = 0); + + (* Indicates that the segment stopped sharp on a ScanLine *) + + if Fresh then + begin + cProfile^.Start := e1; + Fresh := False; + end; + + size := ( e2-e1 )+1; + if ( profCur + size >= MaxBuff ) then + begin + Line_Up := False; + Error := Err_Ras_Overflow; + exit; + end; + + if Dx > 0 then + begin + Ix := (Precision*Dx) div Dy; + Rx := (Precision*Dx) mod Dy; + Dx := 1; + end + else + begin + Ix := -((Precision*-Dx) div Dy); + Rx := (Precision*-Dx) mod Dy; + Dx := -1; + end; + + Ax := -Dy; + {top := @Buff^[profCur];} + + while size > 0 do + begin + Buff^[profCur] := x1; + {$IFDEF DEBUG3} Pset; {$ENDIF} + inc( profCur ); + {top := @top^[1];} + + inc( x1, Ix ); + inc( ax, rx ); + + if ax >= 0 then + begin + dec( ax, dy ); + inc( x1, dx ); + end; + + dec( size ); + end; + +end; + +(****************************************************************************) +(* *) +(* Function: Line_Down *) +(* *) +(* Description: Compute the x-coordinates of a descending line segment *) +(* and stores them in the render pool. *) +(* *) +(* Input: x1,y1 x2,y2 Segment start (x1,y1) and end (x2,y2) points *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow. *) +(* *) +(****************************************************************************) + +function Line_Down( x1, y1, x2, y2, miny, maxy : LongInt ): boolean; +var + _fresh : Boolean; +begin + _fresh := fresh; + + Line_Down := Line_Up( x1, -y1, x2, -y2, -maxy, -miny ); + + if _fresh and not fresh then + cProfile^.start := -cProfile^.start; +end; + +(****************************************************************************) +(* *) +(* Function: Bezier_Up *) +(* *) +(* Description: Compute the x-coordinates of an ascending bezier arc *) +(* and stores them in the render pool. *) +(* *) +(* Input: None.The arc is taken from the top of the Bezier stack. *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow. *) +(* *) +(****************************************************************************) + +function Bezier_Up( miny, maxy : Long ) : boolean; +var + x1, y1, x2, y2, e, e2, e0 : LongInt; + carc, debArc, f1 : Int; + base : PBezierStack; +label + Fin; +begin + Bezier_Up := True; + + carc := curArc; + base := @Arcs[cArc]; + y1 := base^[2].y; + y2 := base^[0].y; + + if ( y2 < MinY ) or ( y1 > MaxY ) then + goto Fin; + + e2 := FLOOR(y2); + + if e2 > MaxY then e2 := MaxY; + + e0 := MinY; + + if y1 < MinY then + e := MinY + else + begin + e := CEILING(y1); + f1 := FRAC(y1); + e0 := e; + + if f1 = 0 then + begin + + if Joint then begin dec(profCur); Joint:=False; end; + (* ^ Ce test permet d'‚viter les doublons *) + + Buff^[profCur] := base^[2].x; + {$IFDEF DEBUG3} Pset; {$ENDIF} + inc( profCur ); + inc( e, Precision ); + end + end; + + if Fresh then + begin + cProfile^.Start := TRUNC(e0); + Fresh := False; + end; + + if e2 < e then + goto Fin; + + (* overflow ? *) + if ( profCur + TRUNC(e2-e)+ 1 >= MaxBuff ) then + begin + Bezier_Up := False; + Error := Err_Ras_Overflow; + exit; + end; + + debArc := cArc; + + while ( cArc >= debArc ) and ( e <= e2 ) do + begin + Joint := False; + y2 := base^[0].y; + + if y2 > e then + begin + y1 := base^[2].y; + if ( y2-y1 >= precision_step ) then + begin + Split_Bezier( base ); + inc( cArc, 2 ); + base := @base^[2]; + end + else + begin + Buff^[profCur] := base^[2].x + + MulDiv( base^[0].x - base^[2].x, + e - y1, + y2 - y1 ); + + {$IFDEF DEBUG3} Pset; {$ENDIF} + + inc( profCur ); + dec( cArc, 2 ); + base := @Arcs[cArc]; + inc( e, Precision ); + end; + end + else + begin + if y2 = e then + begin + joint := True; + Buff^[profCur] := Arcs[cArc].x; + {$IFDEF DEBUG3} Pset; {$ENDIF} + inc( profCur ); + inc( e, Precision ); + end; + dec( cArc, 2 ); + base := @Arcs[cArc]; + end + end; + +Fin: + dec( curArc, 2); + exit; +end; + + +(****************************************************************************) +(* *) +(* Function: Bezier_Down *) +(* *) +(* Description: Compute the x-coordinates of a descending bezier arc *) +(* and stores them in the render pool. *) +(* *) +(* Input: None. Arc is taken from the top of the Bezier stack. *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow. *) +(* *) +(****************************************************************************) + +function Bezier_Down( miny, maxy : Long ) : boolean; +var + base : PBezierStack; + _fresh : Boolean; +begin + _fresh := fresh; + base := @Arcs[curArc]; + + base^[0].y := -base^[0].y; + base^[1].y := -base^[1].y; + base^[2].y := -base^[2].y; + + Bezier_Down := Bezier_Up( -maxy, -miny ); + + if _fresh and not fresh then + cProfile^.start := -cProfile^.start; + + base^[0].y := -base^[0].y; +end; + +(****************************************************************************) +(* *) +(* Function: Line_To *) +(* *) +(* Description: Injects a new line segment and adjust Profiles list. *) +(* *) +(* Input: x, y : segment endpoint ( start point in LastX,LastY ) *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow or Incorrect Profile *) +(* *) +(****************************************************************************) + +function Line_To( x, y : LongInt ) : boolean; +begin + Line_To := False; + + case Etat of + + Indetermine : if y > lastY then + if not New_Profile( Ascendant ) then exit else + else + if y < lastY then + if not New_Profile( Descendant ) then exit; + + Ascendant : if y < lastY then + if not End_Profile or + not New_Profile( Descendant ) then exit; + + Descendant : if y > LastY then + if not End_Profile or + not New_Profile( Ascendant ) then exit; + end; + + Case Etat of + Ascendant : if not Line_Up ( LastX, LastY, X, Y, miny, maxy ) then exit; + Descendant : if not Line_Down( LastX, LastY, X, Y, miny, maxy ) then exit; + end; + + LastX := x; + LastY := y; + + Line_To := True; +end; + +(****************************************************************************) +(* *) +(* Function: Bezier_State *) +(* *) +(* Description: Determines the state (ascending/descending/flat/undet) *) +(* of a Bezier arc, along one given axis. *) +(* *) +(* Input: y1, y2, y3 : coordinates of the Bezier arc. *) +(* along the concerned axis. *) +(* *) +(* Returns: State, i.e. Ascending, Descending, Flat or Undetermined *) +(* *) +(****************************************************************************) + + +function Bezier_State( y1, y2, y3 : TT_F26Dot6 ) : TEtats; +begin + (* determine orientation of a Bezier arc *) + if y1 = y2 then + + if y2 = y3 then Bezier_State := Plat + else + if y2 > y3 then Bezier_State := Descendant + else + Bezier_State := Ascendant + else + if y1 > y2 then + + if y2 >= y3 then Bezier_State := Descendant + else + Bezier_State := Indetermine + else + + if y2 <= y3 then Bezier_State := Ascendant + else + Bezier_State := Indetermine; +end; + + +(****************************************************************************) +(* *) +(* Function: Bezier_To *) +(* *) +(* Description: Injects a new bezier arc and adjust Profiles list. *) +(* *) +(* Input: x, y : arc endpoint ( start point in LastX, LastY ) *) +(* Cx, Cy : control point *) +(* *) +(* Returns: True on success *) +(* False if Render Pool overflow or Incorrect Profile *) +(* *) +(****************************************************************************) + + +function Bezier_To( x, y, Cx, Cy : LongInt ) : boolean; +var + y3, x3 : LongInt; + Etat_Bez : TEtats; +begin + Bezier_To := False; + + PushBezier( LastX, LastY, Cx, Cy, X, Y ); + + while ( curArc >= 0 ) do + begin + y3 := Arcs[curArc].y; + x3 := Arcs[curArc].x; + + Etat_Bez := Bezier_State( Arcs[curArc+2].y, Arcs[curArc+1].y, y3 ); + + case Etat_Bez of + + Plat : dec( curArc, 2 ); + + Indetermine : begin + Split_Bezier( @Arcs[curArc] ); + inc( curArc, 2 ); + end; + else + if Etat <> Etat_Bez then + begin + if Etat <> Indetermine then + if not End_Profile then exit; + + if not New_Profile( Etat_Bez ) then exit; + end; + + case Etat of + Ascendant : if not Bezier_Up( miny, maxy ) then exit; + Descendant : if not Bezier_Down( miny, maxy ) then exit; + end; + + end; + end; + + LastX := x3; + LastY := y3; + + Bezier_To := True; +end; + +(****************************************************************************) +(* *) +(* Function: DecomposeCurve *) +(* *) +(* Description: This functions scans the outline arrays in order to *) +(* emit individual segments and beziers by calling the *) +(* functions Line_To and Bezier_To. It handles all weird *) +(* cases, like when the first point is off the curve, or *) +(* when there are simply no "on" points in the contour ! *) +(* *) +(* Input: xCoord, yCoord : array coordinates to use. *) +(* first, last : indexes of first and last point in *) +(* contour. *) +(* *) +(* Returns: True on success *) +(* False if case of error. *) +(* *) +(* Notes: The function assumes that 'first' < 'last' *) +(* *) +(****************************************************************************) + +procedure swap( var x, y : Long ); {$IFDEF INLINE} inline; {$ENDIF} +var + s : Long; +begin + s := x; x := y; y := s; +end; + +function DecomposeCurve( first, last : Int; + flipped : Boolean ) : boolean; +var + index : Int; + + x, y : Long; (* current point *) + cx, cy : Long; (* current Bezier control point *) + mx, my : Long; (* middle point *) + + x_first, y_first : Long; (* first point coordinates *) + x_last, y_last : Long; (* last point coordinates *) + + on_curve : Boolean; +begin + + DecomposeCurve := False; + +(* the following code is miscompiled by Virtual Pascal 1.1 *) +(* although it works OK with 2.0, strange... *) +(* + with points^[first] do + begin + x_first := SCALED( x ); + y_first := SCALED( y ); + end; +*) + x_first := SCALED( points^[first].x ); + y_first := SCALED( points^[first].y ); + + if flipped then swap( x_first, y_first ); + + with points^[last] do + begin + x_last := SCALED( x ); + y_last := SCALED( y ); + end; + + if flipped then swap( x_last, y_last ); + + LastX := x_first; cx := x_first; + LastY := y_first; cy := y_first; + + index := first; + on_curve := Flags^[first] and 1 <> 0; + + (* check first point, and set origin *) + if not on_curve then + begin + (* first point is off the curve - yes, this happens !! *) + + if Flags^[last] and 1 <> 0 then + begin + LastX := x_last; (* start at last point if it is *) + LastY := y_last; (* on the curve *) + end + else + begin + LastX := (LastX + x_last) div 2; (* if both first and last point *) + LastY := (LastY + y_last) div 2; (* are off the curve, start midway *) + + (* record midpoint in x_last,y_last *) + x_last := LastX; + y_last := LastY; + end; + end; + + (* now process each contour point *) + while ( index < last ) do + begin + inc( index ); + + x := SCALED( points^[index].x ); + y := SCALED( points^[index].y ); + + if flipped then swap( x, y ); + + if on_curve then + begin + (* the previous point was on the curve *) + + on_curve := Flags^[index] and 1 <> 0; + if on_curve then + begin + (* two successive on points -> emit segment *) + if not Line_To( x, y ) then exit; + end + else + begin + (* else, keep current point as control for next bezier *) + cx := x; + cy := y; + end; + end + else + begin + (* the previous point was off the curve *) + + on_curve := Flags^[index] and 1 <> 0; + if on_curve then + begin + (* reaching on point -> emit Bezier *) + if not Bezier_To( x, y, cx, cy ) then exit; + end + else + begin + (* two successive off points -> create middle point *) + (* then emit Bezier *) + mx := (cx + x) div 2; + my := (cy + y) div 2; + + if not Bezier_To( mx, my, cx, cy ) then exit; + + cx := x; + cy := y; + end; + end; + end; + + (* end of contour, close curve cleanly *) + if ( Flags^[first] and 1 <> 0 ) then + + if on_curve then + if not Line_To( x_first, y_first ) then exit else + else + if not Bezier_To( x_first, y_first, cx, cy ) then exit else + + else + if not on_curve then + if not Bezier_To( x_last, y_last, cx, cy ) then exit; + + DecomposeCurve := True; +end; + +(****************************************************************************) +(* *) +(* Function: Convert_Glyph *) +(* *) +(* Description: Converts a glyph into a series of segments and arcs *) +(* and make a Profiles list with them. *) +(* *) +(* Input: _xCoord, _yCoord : coordinates tables. *) +(* *) +(* Uses the 'Flag' table too. *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + +Function Convert_Glyph( flipped : Boolean ) : boolean; +var + i, j, First, Last, Start : Int; + + y1, y2, y3 : LongInt; + + lastProfile : PProfile; + +begin + Convert_Glyph := False; + + j := 0; + fProfile := NIL; + Joint := False; + Fresh := False; + + MaxBuff := SizeBuff - AlignProfileSize; + +{$IFDEF TURNS} + numTurns := 0; +{$ENDIF} + + cProfile := PProfile( @Buff^[profCur] ); + cProfile^.Offset := profCur; + nProfs := 0; + + for i := 0 to nContours-1 do + begin + + Etat := Indetermine; + gProfile := nil; + + (* decompose a single contour into individual segments and *) + (* beziers *) + + if not DecomposeCurve( j, outs^[i], flipped ) then exit; + j := outs^[i] + 1; + + (* We _must_ take care of the case when the first and last arcs join *) + (* while having the same orientation *) + + if ( Frac(lastY) = 0 ) and + ( lastY >= MinY ) and + ( lastY <= MaxY ) then + + if ( gProfile <> nil ) and (* gProfile can be nil *) + ( gProfile^.Flow = cProfile^.Flow ) then (* if the contour was *) + (* too small to be drawn *) + dec( profCur ); + + lastProfile := cProfile; + + if not End_Profile then exit; + + if gProfile <> nil then lastProfile^.next := gProfile; + + end; + + Finalize_Profile_Table; + + Convert_Glyph := (profCur < MaxBuff); +end; + + + (************************************************) + (* *) + (* Init_Linked *) + (* *) + (* Init an empty linked list. *) + (* *) + (************************************************) + + procedure Init_Linked( var L : PProfile ); + begin + L := nil; + end; + + (************************************************) + (* *) + (* InsNew : *) + (* *) + (* Inserts a new Profile in a linked list. *) + (* *) + (************************************************) + + procedure InsNew( var List : PProfile; + Profile : PProfile ); + var + current : PProfile; + old : ^PProfile; + x : Long; + label + Place; + begin + + old := @list; + current := old^; + x := profile^.x; + + while current <> nil do + begin + if x < current^.x then + goto Place; + + old := @current^.link; + current := old^; + end; + + Place: + profile^.link := current; + old^ := profile; + end; + + (************************************************) + (* *) + (* DelOld : *) + (* *) + (* Removes an old Profile from a linked list *) + (* *) + (************************************************) + + + procedure DelOld( var List : PProfile; + Profile : PProfile ); + var + current : PProfile; + old : ^PProfile; + + begin + + old := @list; + current := old^; + + while current <> nil do + begin + if current = profile then + begin + old^ := current^.link; + exit; + end; + + old := @current^.link; + current := old^; + end; + + {$IFDEF ASSERT} + Writeln('(Raster:DelOld) Incoherent deletion'); + halt(9); + {$ENDIF} + end; + + +{$IFDEF TURNS} + (************************************************) + (* *) + (* Update: *) + (* *) + (* Update all X offsets in a drawing list *) + (* *) + (************************************************) + + procedure Update( var List : PProfile ); + var + current : PProfile; + begin + (* recompute coordinates *) + current := list; + + while current <> nil do with current^ do + begin + X := Buff^[offset]; + inc( offset, flow ); + dec( height ); + current := link; + end; + end; +{$ENDIF} + + (************************************************) + (* *) + (* Sort : *) + (* *) + (* Sorts 'quickly' (??) a trace list. *) + (* *) + (************************************************) + + procedure Sort( var List : PProfile ); + var + current, next : PProfile; + old : ^PProfile; + begin + + (* First, recompute coordinates *) + + current := list; + + while current <> nil do with current^ do + begin + X := Buff^[offset]; + inc( offset, flow ); + dec( height ); + current := link; + end; + + (* Then, do the sort *) + + old := @list; + current := old^; + + if current = nil then + exit; + + next := current^.link; + + while next <> nil do + begin + if current^.x <= next^.x then + begin + old := @current^.link; + current := old^; + + if current = nil then + exit; + end + else + begin + old^ := next; + current^.link := next^.link; + next^.link := current; + + old := @list; + current := old^; + end; + + next := current^.link; + end; + + end; + +{$IFDEF TURNS} + +(********************************************************************) +(* *) +(* Generic Sweep Drawing routine *) +(* *) +(* *) +(* *) +(********************************************************************) + +function Draw_Sweep : boolean; + +label + Scan_DropOuts, + Next_Line, + Skip_To_Next; + +var + y, k, + I, J : Int; + P, Q : PProfile; + + Top, + Bottom, + y_height, + y_change, + min_Y, + max_Y : Int; + + x1, x2, xs, e1, e2 : LongInt; + + Wait : PProfile; + + Draw_Left : PProfile; + Draw_Right : PProfile; + + Drop_Left : PProfile; + Drop_Right : PProfile; + + P_Left, Q_Left : PProfile; + P_Right, Q_Right : PProfile; + + Phase : Int; + dropouts : Int; + +begin + + Draw_Sweep := False; + + (* Init the empty linked lists *) + + Init_Linked( Wait ); + + Init_Linked( Draw_Left ); + Init_Linked( Draw_Right ); + + Init_Linked( Drop_Left ); + Init_Linked( Drop_Right ); + + (* First, compute min Y and max Y *) + + P := fProfile; + max_Y := TRUNC(MinY); + min_Y := TRUNC(MaxY); + + while P <> nil do + with P^ do + begin + Q := P^.Link; + + Bottom := P^.Start; + Top := Bottom + P^.Height-1; + + if min_Y > Bottom then min_Y := Bottom; + if max_Y < Top then max_Y := Top; + + X := 0; + InsNew( Wait, P ); + + P := Q; + end; + + (* Check the y-turns *) + if (numTurns = 0) then + begin + Error := Err_Ras_Invalid; + exit; + end; + + (* Now inits the sweeps *) + + Proc_Sweep_Init( min_Y, max_Y ); + + (* Then compute the distance of each Profile to min Y *) + + P := Wait; + while P <> nil do + begin + with P^ do CountL := (Start-min_Y); + P := P^.link;; + end; + + (* Let's go *) + + y := min_y; + y_height := 0; + + if ( numTurns > 0 ) and + ( Buff^[sizeBuff-numTurns] = min_y ) then + dec( numTurns ); + + while numTurns > 0 do + begin + (* Look in the wait list for new activations *) + + P := Wait; + while P <> nil do with P^ do + begin + Q := link; + + dec( CountL, y_height ); + if CountL = 0 then + begin + DelOld( Wait, P ); + case Flow of + TT_Flow_Up : InsNew( Draw_Left, P ); + TT_Flow_Down : InsNew( Draw_Right, P ); + end + end; + + P := Q; + end; + + (* Sort the drawing lists *) + + Sort( Draw_Left ); + Sort( Draw_Right ); + + y_change := Buff^[sizebuff-numTurns]; + dec( numTurns ); + + y_height := y_change - y; + + while y < y_change do + begin + + (* Let's trace *) + + dropouts := 0; + + P_Left := Draw_Left; + P_Right := Draw_Right; + + while ( P_Left <> nil ) do + begin + + {$IFDEF ASSERT} + if P_Right = nil then + Halt(13); + {$ENDIF} + + x1 := P_Left^ .X; + x2 := P_Right^.X; + + if x1 > x2 then + begin + xs := x1; + x1 := x2; + x2 := xs; + end; + + if ( x2-x1 <= Precision ) then + begin + e1 := ( x1+Precision-1 ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + if (dropOutControl <> 0) and + ((e1 > e2) or (e2 = e1 + Precision)) then + begin + P_Left ^.x := x1; + P_Right^.x := x2; + + inc( dropouts ); + + (* mark profile for drop-out control *) + P_Left^.CountL := 1; + + goto Skip_To_Next; + end + end; + + Proc_Sweep_Span( y, x1, x2, P_Left, P_Right ); + + Skip_To_Next: + + P_Left := P_Left ^.Link; + P_Right := P_Right^.Link; + end; + + {$IFDEF ASSERT} + if P_Right <> nil then + Halt(10); + {$ENDIF} + + (* Now perform the dropouts only _after_ the span drawing *) + if (dropouts > 0) then + goto Scan_DropOuts; + +Next_Line: + + (* Step to next line *) + Proc_Sweep_Step; + + inc(y); + + if y < y_change then + begin + Update( Draw_Left ); + Update( Draw_Right ); + end + + end; + + (* We finalize the Profiles that need it *) + + P := Draw_Left; + while P <> nil do + begin + Q := P^.Link; + if P^.height = 0 then + DelOld( Draw_Left, P ); + P := Q; + end; + + P := Draw_Right; + while P <> nil do + begin + Q := P^.Link; + if P^.height = 0 then + DelOld( Draw_Right, P ); + P := Q; + end; + + end; + + while y <= max_y do + begin + Proc_Sweep_Step; + inc( y ); + end; + + Draw_Sweep := True; + exit; + +Scan_DropOuts : + P_Left := Draw_Left; + P_Right := Draw_Right; + + while (P_Left <> nil) do + begin + if P_Left^.countL <> 0 then + begin + P_Left^.countL := 0; + Proc_Sweep_Drop( y, P_Left^.x, P_Right^.x, P_Left, P_Right ); + end; + + P_Left := P_Left^.link; + P_Right := P_Right^.Link; + end; + + goto Next_Line; +end; + + +{$ELSE} + +(********************************************************************) +(* *) +(* Generic Sweep Drawing routine *) +(* *) +(* *) +(* *) +(********************************************************************) + +function Draw_Sweep : boolean; + +label + Skip_To_Next; + +var + y, k, + I, J : Int; + P, Q : PProfile; + + Top, + Bottom, + min_Y, + max_Y : Int; + + x1, x2, xs, e1, e2 : LongInt; + + Wait : PProfile; + + Draw_Left : PProfile; + Draw_Right : PProfile; + + Drop_Left : PProfile; + Drop_Right : PProfile; + + P_Left, Q_Left : PProfile; + P_Right, Q_Right : PProfile; + + Phase : Int; + dropouts : Int; + +begin + + Draw_Sweep := False; + + (* Init the empty linked lists *) + + Init_Linked( Wait ); + + Init_Linked( Draw_Left ); + Init_Linked( Draw_Right ); + + Init_Linked( Drop_Left ); + Init_Linked( Drop_Right ); + + (* First, compute min Y and max Y *) + + P := fProfile; + max_Y := TRUNC(MinY); + min_Y := TRUNC(MaxY); + + while P <> nil do + with P^ do + begin + Q := P^.Link; + + Bottom := P^.Start; + Top := Bottom + P^.Height-1; + + if min_Y > Bottom then min_Y := Bottom; + if max_Y < Top then max_Y := Top; + + X := 0; + InsNew( Wait, P ); + + P := Q; + end; + + (* Now inits the sweeps *) + + Proc_Sweep_Init( min_Y, max_Y ); + + (* Then compute the distance of each Profile to min Y *) + + P := Wait; + while P <> nil do + begin + with P^ do CountL := (Start-min_Y); + P := P^.link;; + end; + + (* Let's go *) + + for y := min_Y to max_Y do + begin + + (* Look in the wait list for new activations *) + + P := Wait; + while P <> nil do with P^ do + begin + Q := link; + + if CountL = 0 then + begin + DelOld( Wait, P ); + case Flow of + TT_Flow_Up : InsNew( Draw_Left, P ); + TT_Flow_Down : InsNew( Draw_Right, P ); + end + end + else + dec( CountL ); + + P := Q; + end; + + (* Sort the drawing lists *) + + Sort( Draw_Left ); + Sort( Draw_Right ); + + (* Let's trace *) + + dropouts := 0; + + P_Left := Draw_Left; + P_Right := Draw_Right; + + while ( P_Left <> nil ) do + begin + + {$IFDEF ASSERT} + if P_Right = nil then + Halt(13); + {$ENDIF} + + Q_Left := P_Left^ .Link; + Q_Right := P_Right^.Link; + + {$IFDEF ASSERT} + if Q_Right = nil then + Halt(11); + {$ENDIF} + + x1 := P_Left^ .X; + x2 := P_Right^.X; + + if x1 > x2 then + begin + xs := x1; + x1 := x2; + x2 := xs; + end; + + if ( x2-x1 <= Precision ) then + begin + e1 := ( x1+Precision-1 ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + if (dropOutControl <> 0) and + ((e1 > e2) or (e2 = e1 + Precision)) then + begin + P_Left^.x := x1; + P_Right^.x := x2; + + inc( dropouts ); + + DelOld( Draw_Left, P_Left ); + DelOld( Draw_Right, P_Right ); + + InsNew( Drop_Left, P_Left ); + InsNew( Drop_Right, P_Right ); + + goto Skip_To_Next; + end + end; + + Proc_Sweep_Span( y, x1, x2, P_Left, P_Right ); + + (* We finalize the Profile if needed *) + + if P_Left ^.height = 0 then + DelOld( Draw_Left, P_Left ); + + if P_Right^.height = 0 then + DelOld( Draw_Right, P_Right ); + + Skip_To_Next: + + P_Left := Q_Left; + P_Right := Q_Right; + end; + + {$IFDEF ASSERT} + if P_Right <> nil then + Halt(10); + {$ENDIF} + + (* Now perform the dropouts only _after_ the span drawing *) + + P_Left := Drop_Left; + P_Right := Drop_Right; + + while ( dropouts > 0 ) do + begin + + Q_Left := P_Left^. Link; + Q_Right := P_Right^.Link; + + DelOld( Drop_Left, P_Left ); + DelOld( Drop_Right, P_Right ); + + Proc_Sweep_Drop( y, P_Left^.x, P_Right^.x, P_Left, P_Right ); + + if P_Left^.height > 0 then + InsNew( Draw_Left, P_Left ); + + if P_Right^.height > 0 then + InsNew( Draw_Right, P_Right ); + + P_Left := Q_Left; + P_Right := Q_Right; + + dec( dropouts ); + end; + + (* Step to next line *) + + Proc_Sweep_Step; + + end; + + Draw_Sweep := True; + +end; + +{$ENDIF} + +{$F+ Far calls are necessary for function pointers under BP7} +{ This flag is currently ignored by the Virtual Compiler } + +(***********************************************************************) +(* *) +(* Vertical Sweep Procedure Set : *) +(* *) +(* These three routines are used during the vertical black/white *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(***********************************************************************) + +procedure Vertical_Sweep_Init( var min, max : Int ); +begin + case Cible.flow of + + TT_Flow_Up : begin + traceOfs := min * Cible.cols; + traceIncr := Cible.cols; + end; + else + traceOfs := (Cible.rows - 1 - min)*Cible.cols; + traceIncr := -Cible.cols; + end; + + gray_min_x := 0; + gray_max_x := 0; +end; + + + +procedure Vertical_Sweep_Span( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + c1, c2 : Int; + f1, f2 : Int; + base : PByte; +begin +{$IFNDEF NO_ASM} + asm + push esi + push ebx + push ecx + + mov eax, X1 + mov ebx, X2 + mov ecx, [Precision_Bits] + + sub ebx, eax + add eax, [Precision] + dec eax + + sub ebx, [Precision] + cmp ebx, [Precision_Jitter] + jg @No_Jitter + + @Do_Jitter: + mov ebx, eax + jmp @0 + + @No_Jitter: + mov ebx, X2 + + @0: + sar ebx, cl + js @Sortie + + sar eax, cl + mov ecx, [BWidth] + + cmp eax, ebx + jg @Sortie + + cmp eax, ecx + jge @Sortie + + test eax, eax + jns @1 + xor eax, eax + @1: + cmp ebx, ecx + jl @2 + lea ebx, [ecx-1] + @2: + + mov edx, eax + mov ecx, ebx + and edx, 7 + sar eax, 3 + and ecx, 7 + sar ebx, 3 + + cmp eax, [gray_min_X] + jge @3 + mov [gray_min_X], eax + + @3: + cmp ebx, [gray_max_X] + jl @4 + mov [gray_max_X], ebx + + @4: + mov esi, ebx + + mov ebx, [BCible] + add ebx, [TraceOfs] + add ebx, eax + + sub esi, eax + jz @5 + + mov al, [LMask + edx].byte + or [ebx], al + inc ebx + dec esi + jz @6 + mov eax, -1 + @7: + mov [ebx].byte, al + dec esi + lea ebx, [ebx+1] + jnz @7 + + @6: + mov al, [RMask + ecx].byte + or [ebx], al + jmp @8 + + @5: + mov al, [LMask + edx].byte + and al, [RMask + ecx].byte + or [ebx], al + + @8: + @Sortie: + pop ecx + pop ebx + pop esi + end; +{$ELSE} + + e1 := (( x1+Precision-1 ) and Precision_Mask) div Precision; + + if ( x2-x1-Precision <= Precision_Jitter ) then + e2 := e1 + else + e2 := ( x2 and Precision_Mask ) div Precision; + + if (e2 >= 0) and (e1 < BWidth) then + + begin + if e1 < 0 then e1 := 0; + if e2 >= BWidth then e2 := BWidth-1; + + c1 := e1 shr 3; + c2 := e2 shr 3; + + f1 := e1 and 7; + f2 := e2 and 7; + + if gray_min_X > c1 then gray_min_X := c1; + if gray_max_X < c2 then gray_max_X := c2; + + base := @BCible^[TraceOfs + c1]; + + if c1 = c2 then + base^[0] := base^[0] or ( LMask[f1] and Rmask[f2] ) + else + begin + base^[0] := base^[0] or LMask[f1]; + + if c2>c1+1 then + FillChar( base^[1], c2-c1-1, $FF ); + + base := @base^[c2-c1]; + base^[0] := base^[0] or RMask[f2]; + end + end; +{$ENDIF} +end; + + +procedure Vertical_Sweep_Drop( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + c1, c2 : Int; + f1, f2 : Int; + + j : Int; +begin + + (* Drop-out control *) + + e1 := ( x1+Precision-1 ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + (* We are guaranteed that x2-x1 <= Precision here *) + + if e1 > e2 then + if e1 = e2 + Precision then + + case DropOutControl of + + (* Drop-out Control Rule #3 *) + 1 : e1 := e2; + + 4 : begin + e1 := ((x1+x2+1) div 2 + Precision-1) and Precision_Mask; + e2 := e1; + end; + + (* Drop-out Control Rule #4 *) + + (* The spec is not very clear regarding rule #4. It *) + (* presents a method that is way too costly to implement *) + (* while the general idea seems to get rid of 'stubs'. *) + (* *) + (* Here, we only get rid of stubs recognized when : *) + (* *) + (* upper stub : *) + (* *) + (* - P_Left and P_Right are in the same contour *) + (* - P_Right is the successor of P_Left in that contour *) + (* - y is the top of P_Left and P_Right *) + (* *) + (* lower stub : *) + (* *) + (* - P_Left and P_Right are in the same contour *) + (* - P_Left is the successor of P_Right in that contour *) + (* - y is the bottom of P_Left *) + (* *) + + 2,5 : begin + + if ( x2-x1 < Precision_Half ) then + begin + (* upper stub test *) + + if ( Left^.next = Right ) and + ( Left^.Height <= 0 ) then exit; + + (* lower stub test *) + + if ( Right^.next = Left ) and + ( Left^.Start = y ) then exit; + end; + + (* Check that the rightmost pixel is not already set *) + e1 := e1 div Precision; + + c1 := e1 shr 3; + f1 := e1 and 7; + + if ( e1 >= 0 ) and ( e1 < BWidth ) and + ( BCible^[TraceOfs+c1] and ($80 shr f1) <> 0 ) then + exit; + + case DropOutControl of + 2 : e1 := e2; + 5 : e1 := ((x1+x2+1) div 2 + Precision-1) and Precision_Mask; + end; + + e2 := e1; + + end; + else + exit; (* unsupported mode *) + end + + else + else + e2 := e1; (* when x1 = e1, x2 = e2, e2 = e1 + 64 *) + + e1 := e1 div Precision; + + if (e1 >= 0) and (e1 < BWidth ) then + begin + c1 := e1 shr 3; + f1 := e1 and 7; + + if gray_min_X > c1 then gray_min_X := c1; + if gray_max_X < c1 then gray_max_X := c1; + + j := TraceOfs + c1; + + BCible^[j] := BCible^[j] or ($80 shr f1); + end; +end; + + + +procedure Vertical_Sweep_Step; +begin + inc( TraceOfs, traceIncr ); +end; + + +(***********************************************************************) +(* *) +(* Horizontal Sweep Procedure Set : *) +(* *) +(* These three routines are used during the horizontal black/white *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(***********************************************************************) + +procedure Horizontal_Sweep_Init( var min, max : Int ); +begin + (* Nothing, really *) +end; + + +procedure Horizontal_Sweep_Span( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + c1, c2 : Int; + f1, f2 : Int; + + j : Int; +begin + + if ( x2-x1 < Precision ) then + begin + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + if e1 = e2 then + begin + c1 := y shr 3; + f1 := y and 7; + + if (e1 >= 0) then + begin + e1 := e1 shr Precision_Bits; + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e1)*Cible.cols; + if e1 < Cible.Rows then + BCible^[j] := BCible^[j] or ($80 shr f1); + end; + end; + end; + +{$IFDEF RIEN} + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + (* We are here guaranteed that x2-x1 > Precision *) + + c1 := y shr 3; + f1 := y and 7; + + if (e1 >= 0) then + begin + e1 := e1 shr Precision_Bits; + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e1)*Cible.cols; + if e1 < Cible.Rows then + BCible^[j] := BCible^[j] or ($80 shr f1); + end; + + if (e2 >= 0) then + begin + e2 := e2 shr Precision_Bits; + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e2)*Cible.cols; + if (e2 <> e1) and (e2 < Cible.Rows) then + BCible^[j] := BCible^[j] or ($80 shr f1); + end; +{$ENDIF} + +end; + + + +procedure Horizontal_Sweep_Drop( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + c1, c2 : Int; + f1, f2 : Int; + + j : Int; +begin + + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + (* During the horizontal sweep, we only take care of drop-outs *) + + if e1 > e2 then + if e1 = e2 + Precision then + + case DropOutControl of + + 0 : exit; + + (* Drop-out Control Rule #3 *) + 1 : e1 := e2; + + 4 : begin + e1 := ( (x1+x2) div 2 +Precision div 2 ) and Precision_Mask; + e2 := e1; + end; + + (* Drop-out Control Rule #4 *) + + (* The spec is not very clear regarding rule #4. It *) + (* presents a method that is way too costly to implement *) + (* while the general idea seems to get rid of 'stubs'. *) + (* *) + + 2,5 : begin + + (* rightmost stub test *) + + if ( Left^.next = Right ) and + ( Left^.Height <= 0 ) then exit; + + (* leftmost stub test *) + + if ( Right^.next = Left ) and + ( Left^.Start = y ) then exit; + + (* Check that the upmost pixel is not already set *) + + e1 := e1 div Precision; + + c1 := y shr 3; + f1 := y and 7; + + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e1)*Cible.cols; + + if ( e1 >= 0 ) and ( e1 < Cible.Rows ) and + ( BCible^[j] and ($80 shr f1) <> 0 ) then exit; + + case DropOutControl of + 2 : e1 := e2; + 5 : e1 := ((x1+x2) div 2 + Precision_Half) and Precision_Mask; + end; + + e2 := e1; + end; + else + exit; (* Unsupported mode *) + end; + + c1 := y shr 3; + f1 := y and 7; + + if (e1 >= 0) then + begin + e1 := e1 shr Precision_Bits; + if Cible.flow = TT_Flow_Up then + j := c1 + e1*Cible.cols + else + j := c1 + (Cible.rows-1-e1)*Cible.cols; + if e1 < Cible.Rows then BCible^[j] := BCible^[j] or ($80 shr f1); + end; + +end; + + + +procedure Horizontal_Sweep_Step; +begin + (* Nothing, really *) +end; + +(***********************************************************************) +(* *) +(* Vertical Gray Sweep Procedure Set : *) +(* *) +(* These two routines are used during the vertical gray-levels *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(* *) +(* NOTES : *) +(* *) +(* - The target pixmap's width *must* be a multiple of 4 *) +(* *) +(* - you have to use the function Vertical_Sweep_Span for *) +(* the gray span call. *) +(* *) +(***********************************************************************) + +procedure Vertical_Gray_Sweep_Init( var min, max : Int ); +begin + min := min and -2; + max := (max+3) and -2; + + case Cible.flow of + + TT_Flow_Up : begin + traceG := (min div 2)*Cible.cols; + traceIncr := Cible.cols; + end; + else + traceG := (Cible.rows-1- (min div 2))*Cible.cols; + traceIncr := -Cible.cols; + end; + + TraceOfs := 0; + gray_min_x := Cible.Cols; + gray_max_x := -Cible.Cols; +end; + + +procedure Vertical_Gray_Sweep_Step; +var + j, c1, c2 : Int; +begin + inc( TraceOfs, Gray_Width ); + + if TraceOfs > Gray_Width then + begin + + if gray_max_X >= 0 then + begin + + if gray_max_x > cible.cols-1 then gray_max_x := cible.cols-1; + if gray_min_x < 0 then gray_min_x := 0; + + j := TraceG + gray_min_x*4; + + for c1 := gray_min_x to gray_max_x do + begin + + c2 := Count_Table[ BCible^[c1 ] ] + + Count_Table[ BCible^[c1+Gray_Width] ]; + + if c2 <> 0 then + begin + BCible^[c1 ] := 0; + BCible^[c1+Gray_Width] := 0; + + GCible^[j] := GCible^[j] or Grays[ (c2 and $F000) shr 12 ]; inc(j); + GCible^[j] := GCible^[j] or Grays[ (c2 and $0F00) shr 8 ]; inc(j); + GCible^[j] := GCible^[j] or Grays[ (c2 and $00F0) shr 4 ]; inc(j); + GCible^[j] := GCible^[j] or Grays[ (c2 and $000F) ]; inc(j); + end + else + inc( j, 4 ); + + end; + end; + + TraceOfs := 0; + inc( TraceG, traceIncr ); + + gray_min_x := Cible.Cols; + gray_max_x := -Cible.Cols; + end; +end; + +(***********************************************************************) +(* *) +(* Horizontal Gray Sweep Procedure Set : *) +(* *) +(* These three routines are used during the horizontal gray-levels *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(***********************************************************************) + +procedure Horizontal_Gray_Sweep_Span( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : TT_F26Dot6; + c1, f1, j : Int; +begin + exit; + y := y div 2; + + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + if (e1 >= 0) then + begin + e1 := e1 shr (Precision_Bits+1); +(* if Cible.flow = TT_Flow_Up then *) + j := y + e1*Cible.cols; +(* else +// j := c1 + (Cible.rows-1-e1)*Cible.cols; *) + if e1 < Cible.Rows then + if GCible^[j] = Grays[0] then + GCible^[j] := Grays[1]; + end; + + if (e2 >= 0) then + begin + e2 := e2 shr (Precision_Bits+1); +(* if Cible.flow = TT_Flow_Up then *) + j := y + e2*Cible.cols; +(* else +// j := c1 + (Cible.rows-1-e2)*Cible.cols; *) + if (e2 <> e1) and (e2 < Cible.Rows) then + if GCible^[j] = Grays[0] then + GCible^[j] := Grays[1]; + end; + +end; + + +procedure Horizontal_Gray_Sweep_Drop( y : Int; + x1, + x2 : TT_F26dot6; + Left, + Right : PProfile ); +var + e1, e2 : Longint; + f1, f2 : Int; + color : Byte; + j : Int; +begin + + e1 := ( x1+(Precision-1) ) and Precision_Mask; + e2 := x2 and Precision_Mask; + + (* During the horizontal sweep, we only take care of drop-outs *) + + if e1 > e2 then + if e1 = e2 + Precision then + + case DropOutControl of + + 0 : exit; + + (* Drop-out Control Rule #3 *) + 1 : e1 := e2; + + 4 : begin + e1 := ( (x1+x2) div 2 +Precision div 2 ) and Precision_Mask; + e2 := e1; + end; + + (* Drop-out Control Rule #4 *) + + (* The spec is not very clear regarding rule #4. It *) + (* presents a method that is way too costly to implement *) + (* while the general idea seems to get rid of 'stubs'. *) + (* *) + + 2,5 : begin + + (* lowest stub test *) + + if ( Left^.next = Right ) and + ( Left^.Height <= 0 ) then exit; + + (* upper stub test *) + + if ( Right^.next = Left ) and + ( Left^.Start = y ) then exit; + + case DropOutControl of + 2 : e1 := e2; + 5 : e1 := ((x1+x2) div 2 + Precision_Half) and Precision_Mask; + end; + + e2 := e1; + end; + else + exit; (* Unsupported mode *) + end; + + if (e1 >= 0) then + begin + (* A small trick to make 'average' thin line appear in *) + (* medium gray.. *) + + if ( x2-x1 >= Precision_Half ) then + color := Grays[2] + else color := Grays[1]; + + e1 := e1 shr (Precision_Bits+1); + if Cible.flow = TT_Flow_Up then + j := (y div 2) + e1*Cible.cols + else + j := (y div 2) + (Cible.rows-1-e1)*Cible.cols; + if e1 < Cible.Rows then + if GCible^[j] = Grays[0] then + GCible^[j] := color; + end; +end; + +{$IFDEF SMOOTH} + +(***********************************************************************) +(* *) +(* Vertical Smooth Sweep Procedure Set : *) +(* *) +(* These two routines are used during the vertical smooth-levels *) +(* sweep phase by the generic Draw_Sweep function. *) +(* *) +(* *) +(* NOTES : *) +(* *) +(* - The target pixmap's width *must* be a multiple of 2 *) +(* *) +(* - you have to use the function Vertical_Sweep_Span for *) +(* the smooth span call. *) +(* *) +(***********************************************************************) + +procedure Smooth_Sweep_Init( var min, max : Int ); +var + i : integer; +begin + min := min and -4; + max := (max + 7) and -4; + TraceOfs := 0; + TraceG := Cible.Cols * ( min div 4 ); + gray_min_x := Cible.Cols; + gray_max_x := -Cible.Cols; + + smooth_pass := 0; +(* + for i := 0 to Smooth_Cols-1 do + GCible^[i] := 0; +*) +end; + + + +procedure Smooth_Sweep_Step; +var + j, c1, c2 : Int; +begin + + if gray_max_X >= 0 then + begin + + if gray_max_x > cible.cols-1 then gray_max_x := cible.cols-1; + + if gray_min_x < 0 then gray_min_x := 0; + + j := TraceG + gray_min_x*2; + + for c1 := gray_min_x to gray_max_x do + begin + + c2 := Count_Table2[ BCible^[c1] ]; + + if c2 <> 0 then + begin + inc( GCible^[j], c2 shr 4 ); inc(j); + inc( GCible^[j], c2 and 15 ); inc(j); + + BCible^[c1] := 0; + end + else + inc( j, 2 ); + end; + + end; + + traceOfs := 0; + inc( smooth_pass ); + + if smooth_pass >= 4 then + begin + + j := TraceG + gray_min_x*2; + + for c1 := gray_min_x to gray_max_x do + begin + c2 := GCible^[j]; GCible^[j] := Smooths[c2]; inc(j); + c2 := GCible^[j]; GCible^[j] := Smooths[c2]; inc(j); + end; + + smooth_pass := 0; + inc( TraceG, Cible.Cols ); + + gray_min_x := Cible.Cols; + gray_max_x := -Cible.Cols; + end; + +end; + +{$ENDIF} + +{$F- End of dispatching functions definitions } + +(****************************************************************************) +(* *) +(* Function: Render_Single_Pass *) +(* *) +(* Description: Performs one sweep with sub-banding. *) +(* *) +(* Input: _XCoord, _YCoord : x and y coordinates arrays *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + +function Render_Single_Pass( vertical : Boolean ) : boolean; +var + i, j, k : Int; +begin + Render_Single_Pass := False; + + while Band_Top > 0 do + + begin + + with Band_Stack[ Band_Top ] do + begin + MaxY := longint(Y_Max) * Precision; + MinY := longint(Y_Min) * Precision; + end; + + profCur := 0; + Error := Err_Ras_None; + + if not Convert_Glyph( vertical ) then + begin + + if Error <> Err_Ras_Overflow then exit; + Error := Err_Ras_None; + + (* sub-banding *) + + {$IFDEF DEBUG3} + ClearBand( MinY shr Precision_Bits, MaxY shr Precision_Bits ); + {$ENDIF} + + with Band_Stack[Band_Top] do + begin + I := Y_Min; + J := Y_Max; + end; + + K := ( I + J ) div 2; + + if ( Band_Top >= 8 ) or ( K <= I ) then + begin + Band_Top := 0; + Error := Err_Ras_Invalid; + exit; + end + else + begin + + with Band_Stack[Band_Top+1] do + begin + Y_Min := K; + Y_Max := J; + end; + + Band_Stack[Band_Top].Y_Max := K-1; + + inc( Band_Top ); + end + end + else + begin + + if ( fProfile <> nil ) then + if not Draw_Sweep then exit; + + dec( Band_Top ); + end; + + end; + + Render_Single_Pass := true; +end; + +(****************************************************************************) +(* *) +(* Function: Render_Glyph *) +(* *) +(* Description: Renders a glyph in a bitmap. Sub-banding if needed *) +(* *) +(* Input: AGlyph Glyph record *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + +function Render_Glyph( var glyph : TT_Outline; + var target : TT_Raster_Map ) : TError; +begin + + Render_Glyph := Failure; + + if Buff = nil then + begin + Error := Err_Ras_NotIni; + exit; + end; + + if glyph.conEnds^[glyph.n_contours-1] > glyph.n_points then + begin + Error := Err_Ras_Invalid_Contours; + exit; + end; + + Cible := target; + + Outs := glyph.conEnds; + Flags := PByte(glyph.flags); + nPoints := Glyph.n_points; + nContours := Glyph.n_contours; + + points := Glyph.points; + + Set_High_Precision( glyph.high_precision ); + scale_shift := precision_shift; + DropOutControl := glyph.dropout_mode; + second_pass := glyph.second_pass; + + Error := Err_Ras_None; + + (* Vertical Sweep *) + +{$IFDEF FPK} + Proc_Sweep_Init := @Vertical_Sweep_Init; + Proc_Sweep_Span := @Vertical_Sweep_Span; + Proc_Sweep_Drop := @Vertical_Sweep_Drop; + Proc_Sweep_Step := @Vertical_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Vertical_Sweep_Init; + Proc_Sweep_Span := Vertical_Sweep_Span; + Proc_Sweep_Drop := Vertical_Sweep_Drop; + Proc_Sweep_Step := Vertical_Sweep_Step; +{$ENDIF} + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := Cible.Rows-1; + + BWidth := Cible.width; + BCible := PByte( Cible.Buffer ); + + if not Render_Single_Pass( False ) then exit; + + (* Horizontal Sweep *) + + if Second_Pass then + begin + +{$IFDEF FPK} + Proc_Sweep_Init := @Horizontal_Sweep_Init; + Proc_Sweep_Span := @Horizontal_Sweep_Span; + Proc_Sweep_Drop := @Horizontal_Sweep_Drop; + Proc_Sweep_Step := @Horizontal_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Horizontal_Sweep_Init; + Proc_Sweep_Span := Horizontal_Sweep_Span; + Proc_Sweep_Drop := Horizontal_Sweep_Drop; + Proc_Sweep_Step := Horizontal_Sweep_Step; +{$ENDIF} + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := Cible.Width-1; + + BWidth := Cible.rows; + BCible := PByte( Cible.Buffer ); + + if not Render_Single_Pass( True ) then exit; + + end; + + Render_Glyph := Success; +end; + +(****************************************************************************) +(* *) +(* Function: Render_Gray_Glyph *) +(* *) +(* Description: Renders a glyph with grayscaling. Sub-banding if needed *) +(* *) +(* Input: AGlyph Glyph record *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + + function Render_Gray_Glyph( var glyph : TT_Outline; + var target : TT_Raster_Map ) : TError; +begin + + Render_Gray_Glyph := Failure; + + cible := target; + + Outs := Glyph.conEnds; + Flags := PByte(glyph.flags); + nPoints := Glyph.n_points; + nContours := Glyph.n_contours; + + points := Glyph.points; + + Set_High_Precision( glyph.high_precision ); + scale_shift := precision_shift+1; + DropOutControl := glyph.dropout_mode; + second_pass := glyph.high_precision; + + Error := Err_Ras_None; + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := 2*Cible.Rows - 1; + + BWidth := Gray_Width; + + if BWidth > Cible.cols div 4 then BWidth := Cible.cols div 4; + + BWidth := BWidth*8; + BCible := PByte( Gray_Lines ); + GCible := PByte( Cible.Buffer ); + +{$IFDEF FPK} + Proc_Sweep_Init := @Vertical_Gray_Sweep_Init; + Proc_Sweep_Span := @Vertical_Sweep_Span; + Proc_Sweep_Drop := @Vertical_Sweep_Drop; + Proc_Sweep_Step := @Vertical_Gray_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Vertical_Gray_Sweep_Init; + Proc_Sweep_Span := Vertical_Sweep_Span; + Proc_Sweep_Drop := Vertical_Sweep_Drop; + Proc_Sweep_Step := Vertical_Gray_Sweep_Step; +{$ENDIF} + + if not Render_Single_Pass( False ) then exit; + + (* Horizontal Sweep *) + + if Second_Pass then + begin + +{$IFDEF FPK} + Proc_Sweep_Init := @Horizontal_Sweep_Init; + Proc_Sweep_Span := @Horizontal_Gray_Sweep_Span; + Proc_Sweep_Drop := @Horizontal_Gray_Sweep_Drop; + Proc_Sweep_Step := @Horizontal_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Horizontal_Sweep_Init; + Proc_Sweep_Span := Horizontal_Gray_Sweep_Span; + Proc_Sweep_Drop := Horizontal_Gray_Sweep_Drop; + Proc_Sweep_Step := Horizontal_Sweep_Step; +{$ENDIF} + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := Cible.Width*2-1; + + BWidth := Cible.rows; + GCible := PByte( Cible.Buffer ); + + if not Render_Single_Pass( True ) then exit; + + end; + + Render_Gray_Glyph := Success; + exit; + +end; + +{$IFDEF SMOOTH} +(****************************************************************************) +(* *) +(* Function: Render_Smooth_Glyph *) +(* *) +(* Description: Renders a glyph with grayscaling. Sub-banding if needed *) +(* *) +(* Input: AGlyph Glyph record *) +(* *) +(* Returns: True on success *) +(* False if any error was encountered during render. *) +(* *) +(****************************************************************************) + +function Render_Smooth_Glyph( var glyph : TGlyphRecord; + target : PRasterBlock; + scan : Byte; + palette : pointer ) : boolean; +begin + + Render_Smooth_Glyph := Failure; + + if target <> nil then + cible := target^; +(* + if palette <> nil then + move( palette^, Grays, 5 ); +*) + Outs := Glyph.endPoints; + Flags := PByte(glyph.Flag); + nPoints := Glyph.Points; + nContours := Glyph.numConts; + + scale_shift := precision_shift+2; + DropOutControl := scan; + + Raster_Error := Err_Ras_None; + + Band_Top := 1; + Band_Stack[1].Y_Min := 0; + Band_Stack[1].Y_Max := 4*Cible.Rows - 1; + + BWidth := Smooth_Cols; + + if BWidth > Cible.cols then BWidth := Cible.cols; + + BWidth := BWidth*8; + BCible := PByte( Gray_Lines ); + GCible := PByte( Cible.Buffer ); + +{$IFDEF FPK} + Proc_Sweep_Init := @Smooth_Sweep_Init; + Proc_Sweep_Span := @Vertical_Sweep_Span; + Proc_Sweep_Drop := @Vertical_Sweep_Drop; + Proc_Sweep_Step := @Smooth_Sweep_Step; +{$ELSE} + Proc_Sweep_Init := Smooth_Sweep_Init; + Proc_Sweep_Span := Vertical_Sweep_Span; + Proc_Sweep_Drop := Vertical_Sweep_Drop; + Proc_Sweep_Step := Smooth_Sweep_Step; +{$ENDIF} + + if not Render_Single_Pass( Glyph.XCoord, Glyph.YCoord ) then exit; + + Render_Smooth_Glyph := Success; + +end; + +{$ENDIF} + +(****************************************************************************) +(* *) +(* Function: Init_Rasterizer *) +(* *) +(* Description: Initializes the rasterizer. *) +(* *) +(* Input: rasterBlock target bitmap/pixmap description *) +(* profBuffer pointer to the render pool *) +(* profSize size in bytes of the render pool *) +(* *) +(* Returns: 1 ( always, but we should check parameters ) *) +(* *) +(****************************************************************************) + +function TTRaster_Init : TError; +var + i, j, c, l : integer; +const + Default_Grays : array[0..4] of Byte + = ( 0, 23, 27, 29, 31 ); + + Default_Smooths : array[0..16] of Byte + = ( 0, 20, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 31, 31, 31 ); +begin + GetMem( Buff, Render_Pool_Size ); + SizeBuff := (Render_Pool_Size div 4); + + GetMem( Gray_Lines, Gray_Lines_Size ); + Gray_Width := Gray_Lines_Size div 2; + +{$IFDEF SMOOTH} + Smooth_Cols := Gray_Lines_Size div 4; +{$ENDIF} + + { Initialisation of Count_Table } + + for i := 0 to 255 do + begin + l := 0; + j := i; + for c := 0 to 3 do + begin + l := l shl 4; + if ( j and $80 <> 0 ) then inc(l); + if ( j and $40 <> 0 ) then inc(l); + j := (j shl 2) and $FF; + end; + Count_table[i] := l; + end; + + (* default Grays takes the gray levels of the standard VGA *) + (* 256 colors mode *) + + Grays[0] := 0; + Grays[1] := 23; + Grays[2] := 27; + Grays[3] := 29; + Grays[4] := 31; + + +{$IFDEF SMOOTH} + + { Initialisation of Count_Table2 } + for i := 0 to 255 do + begin + l := 0; + j := i; + for c := 0 to 1 do + begin + l := l shl 4; + if ( j and $80 <> 0 ) then inc(l); + if ( j and $40 <> 0 ) then inc(l); + if ( j and $20 <> 0 ) then inc(l); + if ( j and $10 <> 0 ) then inc(l); + j := (j shl 4) and $FF; + end; + Count_table2[i] := l; + end; + move( Default_Smooths, Smooths, 17 ); +{$ENDIF} + + Set_High_Precision(False); + Set_Second_Pass(False); + + DropOutControl := 2; + Error := Err_Ras_None; + + TTRaster_Init := Success; +end; + +procedure Cycle_DropOut; +begin + case DropOutControl of + + 0 : DropOutControl := 1; + 1 : DropOutControl := 2; + 2 : DropOutControl := 4; + 4 : DropOutControl := 5; + else + DropOutControl := 0; + end; +end; + +procedure TTRaster_Done; +begin + FreeMem( Buff, Render_Pool_Size ); + FreeMem( Gray_Lines, Gray_Lines_Size ); +end; + + +end. diff --git a/pascal/lib/tttables.pas b/pascal/lib/tttables.pas new file mode 100644 index 0000000..d098558 --- /dev/null +++ b/pascal/lib/tttables.pas @@ -0,0 +1,247 @@ +(******************************************************************* + * + * TTTables.Pas 1.2 + * + * TrueType Tables declarations + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + * + * Difference between 1.1 and 1.2 : + * + * - TTTables now only contains the declarations of the + * TrueType tables. + * + * - Instance, Resident and Execution context declarations + * were moved to TTObjs + * + * - Tables loaders were moved to the new TTLoad component + * + ******************************************************************) + +Unit TTTables; + +interface + +uses FreeType, TTTypes; + +(***************************************************************************) +(* *) +(* TrueType Table Types *) +(* *) +(***************************************************************************) + +type + (* TrueType collection header *) + PTTCHeader = ^TTTCHeader; + TTTCHeader = record + Tag : Long; + version : TT_Fixed; + DirCount : ULong; + TableDirectory : PStorage; + end; + + (* TrueType Table Directory type *) + PTableDir = ^TTableDir; + TTableDir = Record + version : TT_Fixed; (* should be $10000 *) + numTables : UShort; (* Tables number *) + + searchRange, (* These parameters are only used *) + entrySelector, (* for a dichotomy search in the *) + rangeShift : UShort; (* directory. We ignore them *) + end; + + (* The 'TableDir' is followed by 'numTables' TableDirEntries *) + + TTableDirEntry = Record + Tag : Long; (* table type *) + CheckSum : Long; (* table Checksum *) + Offset : Long; (* Table file offset *) + Length : Long; (* Table length *) + end; + + TTableDirEntries = array[0..100] of TTableDirEntry; + PTableDirEntries = ^TTableDirEntries; + + (* 'cmap' tables *) + + TCMapDir = record + tableVersionNumber : UShort; + numCMaps : UShort; + end; + + TCMapDirEntry = record + platformID : UShort; + platformEncodingID : UShort; + offset : Long; + end; + + TCMapDirEntries = array[0..10] of TCMapDirEntry; + PCMapDirEntries = ^TCMapDirEntries; + + (* table "maxp" of Maximum Profiles' *) + + TMaxProfile = Record + Version : TT_Fixed; + numGlyphs, + maxPoints, + maxContours, + maxCompositePoints, + maxCompositeContours, + maxZones, + maxTwilightPoints, + maxStorage, + maxFunctionDefs, + maxInstructionDefs, + maxStackElements, + + maxSizeOfInstructions, + maxComponentElements, + maxComponentDepth : UShort; + end; + + (* table "gasp" *) + +const + Gasp_GridFit = 1; + Gasp_DoGray = 2; + +type + TGaspRange = record + maxPPEM : UShort; + gaspFlag : UShort; + end; + + TGaspRanges = array[0..9] of TGaspRange; + PGaspRanges = ^TGaspRanges; + + TGasp = record + version : UShort; + numRanges : UShort; + gaspRanges : PGaspRanges; + end; + + (* table "HMTX" *) + + TLongMetrics = record + advance : UShort; + bearing : Short; + end; + + TTableLongMetrics = array[0..255] of TLongMetrics; + PTableLongMetrics = ^TTableLongMetrics; + + TShortMetrics = Short; + TTableShortMetrics = array[0..255] of TShortMetrics; + PTableShortMetrics = ^TTableShortMetrics; + +{ + (* table "OS/2" *) + + TOS2_Table = record + version : UShort; (* $0001 *) + xAvgCharWidth : Short; + usWeightClass : UShort; + usWidthClass : UShort; + fsType : Short; + ySubscriptXSize : Short; + ySubscriptYSize : Short; + ySubScriptXOffset : Short; + ySubscriptYOffset : Short; + ySuperscriptXSize : Short; + ySuperscriptYSize : Short; + ySuperscriptXOffset : Short; + ySuperscriptYOffset : Short; + yStrikeoutSize : Short; + yStrikeoutPosition : Short; + sFamilyClass : Short; + panose : array[0..9] of Byte; + ulUnicodeRange1 : ULong; (* bits 0-31 *) + ulUnicodeRange2 : ULong; (* bits 32-63 *) + ulUnicodeRange3 : ULong; (* bits 64-95 *) + ulUnicodeRange4 : ULong; (* bits 96-127 *) + achVendID : array[0..3] of Byte; + fsSelection : UShort; + usFirstCharIndex : UShort; + usLastCharIndex : UShort; + sTypoAscender : UShort; + sTypoDescender : UShort; + sTypoLineGap : UShort; + usWinAscent : UShort; + usWinDescent : UShort; + + (* only version 1 tables *) + ulCodePageRange1 : ULong; + ulCodePageRange2 : ULong; + end; + + (* table "post" *) + + TPostscript = record + FormatType : TT_Fixed; + italicAngle : TT_Fixed; + underlinePosition : Short; + underlineThickness : Short; + isFixedPitch : ULong; + minMemType42 : ULong; + maxMemType42 : ULong; + minMemType1 : ULong; + maxMemType1 : ULong; + end; +} + (* table "name" *) + + (* table "name" *) + + TName_Record = record + + platformID : UShort; + encodingID : UShort; + languageID : UShort; + nameID : UShort; + length : UShort; + offset : UShort; + end; + PName_Record = ^TName_Record; + TName_Records = array[0..0] of TName_Record; + PName_Records = ^TName_Records; + + + PName_Table = ^TName_Table; + TName_Table = record + + format : UShort; + numNameRecords : UShort; + storageOffset : UShort; + names : PName_Records; + storage : PByte; + end; + + + PHdmx_Record = ^THdmx_Record; + THdmx_Record = record + ppem : Byte; + max_width : Byte; + widths : PByte; + end; + + THdmx_Records = array[0..19] of THdmx_Record; + PHdmx_Records = ^THdmx_Records; + + THdmx = record + version : UShort; + num_records : Short; + records : PHdmx_Records; + end; + +implementation + +end. + diff --git a/pascal/lib/tttypes.pas b/pascal/lib/tttypes.pas new file mode 100644 index 0000000..7450b4d --- /dev/null +++ b/pascal/lib/tttypes.pas @@ -0,0 +1,102 @@ +(******************************************************************* + * + * TTTypes.pas 1.0 + * + * Global internal types definitions + * + * Copyright 1996, 1997 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +unit TTTypes; + +interface + +uses FreeType; + +type + + (*********************** SIMPLE PRIMITIVE TYPES *******************) + + (* BYTE is already defined in Pascal *) + (* They are equivalent to C unsigned chars *) + + UShort = Word; (* unsigned short integer, must be on 16 bits *) + Short = Integer; (* signed short integer, must be on 16 bits *) + + Long = Longint; + ULong = LongInt; (* unsigned long integer, must be on 32 bits *) + (* NOTE : There is no 'LongWord' in Pascal, *) + (* but the unsigned ops are all in *) + (* the inline assembly routines *) + +{$IFDEF USE32} + Int = LongInt; (* the 'int' type is used for loop counters and *) +{$ELSE} (* indexes.. Their size must be the one a given *) + Int = Integer; (* system handles most easily ( 16 bits on Turbo *) +{$ENDIF} (* and 32 on Virtual Pascals ) *) + + TByteArray = array[0..1000] of Byte; + PByte = ^TByteArray; + + TShortArray = array[0..1000] of Short; + PShort = ^TShortArray; + + TUShortArray = array[0..1000] of UShort; + PUShort = ^TUShortArray; + + TStorage = array[0..16000] of Long; + PStorage = ^TStorage; + PLong = PStorage; + PULong = PStorage; + + TError = boolean; + + (***************** FreeType Internal Types *****************************) + + TCoordinates = array[0..1023] of TT_F26Dot6; + PCoordinates = ^TCoordinates; + + PTouchTable = PByte; + + TVecRecord = record + n : Int; (* number of points *) + org_x : PCoordinates; (* original coordinates arrays *) + org_y : PCoordinates; + cur_x : PCoordinates; (* current coordinates arrays *) + cur_y : PCoordinates; + touch : PTouchTable; (* touch flags array *) + end; + (* This type is used to describe each point zone in the interpreter *) + +const + + TT_Round_Off = 5; + TT_Round_To_Half_Grid = 0; + TT_Round_To_Grid = 1; + TT_Round_To_Double_Grid = 2; + TT_Round_Up_To_Grid = 4; + TT_Round_Down_To_Grid = 3; + TT_Round_Super = 6; + TT_ROund_Super_45 = 7; + + Success = False; + Failure = True; + + TT_Flag_Touched_X = $02; (* X touched flag *) + TT_Flag_Touched_Y = $04; (* Y touched flag *) + + TT_Flag_Touched_Both = TT_Flag_Touched_X or TT_FLag_Touched_Y; + + TT_Flag_On_Curve = $01; (* Point is On curve *) + +implementation + +end. diff --git a/pascal/test/codetv.pas b/pascal/test/codetv.pas new file mode 100644 index 0000000..9e9b3a0 --- /dev/null +++ b/pascal/test/codetv.pas @@ -0,0 +1,248 @@ +{****************************************************************************} +{* *} +{* CodeView.PAS *} +{* *} +{* This unit implements a simple TrueType bytecode viewer for the *} +{* FREETYPE project debugger. *} +{* *} +{****************************************************************************} + +Unit CodeTV; + +interface + +uses Objects, Views, Drivers, TTTypes, TTDebug; + +{$I DEBUGGER.INC} + +type + + { TCodeViewer } + + { This TView is a simple code list viewer ( IP + focused + breaks ) } + + PCodeViewer = ^TCodeViewer; + TCodeViewer = object( TListViewer ) + + constructor Init( var Bounds : TRect; + ARange : PRangeRec ); + + procedure Draw; virtual; + procedure HandleEvent( var Event : TEvent ); virtual; + + procedure Change_Range( ARange : PRangeRec ); + procedure Change_Focus( ALine : integer ); + + procedure Get_Cursor_Addr( P : PLong ); + + private + CodeRange : PRangeRec; + IP : Int; + end; + + { TCodeWindow } + + PCodeWindow = ^TCodeWindow; + TCodeWindow = object( TWindow ) + CodeView : PCodeViewer; + constructor Init( var Bounds : TRect; + ARange : PRangeRec ); + end; + +implementation + +{ TCodeViewer } + +constructor TCodeViewer.Init; +begin + inherited Init( Bounds, 1, nil, nil ); + + GrowMode := gfGrowHiX or gfGrowHiY; + DragMode := dmDragGrow or dmLimitLoX or dmLimitLoY; + EventMask := EventMask or evWave; + + IP := 0; + + Change_Range( ARange ); +end; + + +procedure TCodeViewer.Change_Range; +begin + codeRange := ARange; + + if codeRange <> nil then + SetRange( codeRange^.NLines ) + else + SetRange( 0 ); +end; + +procedure TCodeViewer.Change_Focus; +begin + + if ALine < 0 then + begin + IP := -1; + DrawView; + exit; + end; + + if ALine >= TopItem + Size.Y then TopItem := ALine; + + if codeRange <> nil then + begin + FocusItem( ALine ); + IP := codeRange^.Disassembled^[ALine]; + end; + DrawView; +end; + + +procedure TCodeViewer.Get_Cursor_Addr( P : PLong ); +begin + with codeRange^ do + begin + if (Focused < 0) or (Focused >= NLines) then + P^[0] := -1 + else + P^[0] := disassembled^[Focused]; + end; +end; + + +procedure TCodeViewer.HandleEvent( var Event : TEvent ); +var + Limits : TRect; + Mini, Maxi : Objects.TPoint; +begin + + inherited HandleEvent(Event); + + case Event.What of + + evCommand : case Event.Command of + + cmChangeRange : Change_Range( Event.InfoPtr ); + + cmQueryCursorAddr : Get_Cursor_Addr( Event.InfoPtr ); + + cmResize: begin + Owner^.GetExtent(Limits); + SizeLimits( Mini, Maxi ); + DragView(Event, DragMode, Limits, Mini, Maxi ); + ClearEvent(Event); + end; + + end; + + evWave : case Event.Command of + + cmReFocus : Change_Focus( Event.InfoInt ); + + end; + end; +end; + + +procedure TCodeViewer.Draw; +const + Colors : array[0..3] of byte + = ($1E,$40,$0E,$30); + Prefix : array[1..3] of Char + = ( 'f', 'c', 'g' ); +var + I, J, Item : Int; + B : TDrawBuffer; + S : String; + Indent : Int; + Ligne : Int; + + Color : word; + + On_BP : boolean; + BP : PBreakPoint; + +begin + +{ + Colors[0] := GetColor(1); (* Normal line *) + Colors[1] := GetColor(2); (* Normal breakpoint *) + Colors[2] := GetColor(3); (* Focused line *) + Colors[3] := GetColor(4); (* Focused breakpoint *) +} + if HScrollBar <> nil then Indent := HScrollBar^.Value + else Indent := 0; + + with CodeRange^ do + begin + + BP := Breaks; + + if (BP <> nil) and (NLines > TopItem) then + while (BP <> nil) and (BP^.Address < Disassembled^[TopItem]) do + BP := BP^.Next; + + for I := 0 to Self.Size.Y-1 do + begin + + Item := TopItem + I; + + Color := 0; + + if Item < NLines then + begin + + Ligne := Disassembled^[Item]; + + if (BP <> nil) and (BP^.Address = Ligne) then + begin + Color := 1; + Repeat + BP := BP^.Next + until (BP = nil) or (BP^.Address > Ligne); + end; + + if (Range > 0) and + ( Focused = Item ) then + + Color := Color or 2; + + S := ' ' + Cur_U_Line( Code, Ligne ); + + S[2] := Prefix[index]; + + S := copy( S, 1 + Indent, Self.Size.X ); + + if Ligne = IP then + begin + S[1] := '='; + S[7] := '>'; + end + end + else + begin + S := ''; + end; + + Color := Colors[Color]; + + MoveChar( B, ' ', Color, Self.Size.X ); + MoveStr( B, S, Color ); + + WriteLine( 0, I, Self.Size.X, 1, B ); + end; + end; +end; + +{ TCodeWindow } + +constructor TCodeWindow.Init; +begin + inherited Init( Bounds,'Code',wnNoNumber ); + GetExtent( Bounds ); + Bounds.Grow(-1,-1); + New( CodeView, Init( Bounds, ARange ) ); + Insert( CodeView ); +end; + +end. diff --git a/pascal/test/common.pas b/pascal/test/common.pas new file mode 100644 index 0000000..daa4064 --- /dev/null +++ b/pascal/test/common.pas @@ -0,0 +1,84 @@ +Unit Common; + +interface + +const + Max_Arguments = 1024; + +var + num_arguments : integer; + (* the number of arguments contained in the 'arguments' array *) + + arguments : array[0..Max_Arguments-1] of ^string; + (* This array will hold all arguments after wildcard expansion *) + (* note that it will not contain the original arguments that *) + (* were before 'first_argument' of Expand_Wildcards *) + + procedure Expand_WildCards( first_argument : integer; + default_extension : string ); + (* expand all wildcards into filenames *) + +implementation + +uses Dos; + + procedure Split( Original : String; + var Base : String; + var Name : String ); + var + n : integer; + begin + n := length(Original); + + while ( n > 0 ) do + if ( Original[n] = '\' ) or + ( Original[n] = '/' ) then + begin + Base := Copy( Original, 1, n-1 ); + Name := Copy( Original, n+1, length(Original) ); + exit; + end + else + dec(n); + + Base := ''; + Name := Original; + end; + + + procedure Expand_WildCards( first_argument : integer; + default_extension : string ); + var + i, n : integer; + base, name : string; + SRec : SearchRec; + begin + num_arguments := 0; + i := first_argument; + + while ( i <= ParamCount ) do + begin + Split( ParamStr(i), base, name ); + if base <> '' then + base := base + '\'; + + FindFirst( base+name, Archive+ReadOnly+Hidden, SRec ); + if DosError <> 0 then + FindFirst( base+name+default_extension, AnyFile, SRec ); + + while (DosError = 0) and (num_arguments < Max_Arguments) do + begin + GetMem( arguments[num_arguments], length(base)+length(SRec.Name)+1 ); + arguments[num_arguments]^ := base + SRec.Name; + inc( num_arguments ); + FindNext( SRec ); + end; + + {$IFDEF OS2} + FindClose( SRec ); + {$ENDIF} + inc( i ); + end; + end; + +end. diff --git a/pascal/test/debugger.inc b/pascal/test/debugger.inc new file mode 100644 index 0000000..cd09439 --- /dev/null +++ b/pascal/test/debugger.inc @@ -0,0 +1,42 @@ +{ DEBUGGER.INC : Constantes des commandes du debugger FREETYPE } + +const + + evWave = $200; { Broadcast messages } + + cmNewWin = 200; + cmFileOpen = 201; + + cmNewExecution = 300; + cmRefocus = 301; + cmChangeRange = 302; + cmQueryCursorAddr = 303; + + cmRun = 400; + kb_val_Run = kbCtrlF9; + kb_str_Run = 'Ctrl-F9'; + + cmGotoCursor = 401; + kb_val_GotoCursor = kbF4; + kb_str_GotoCursor = 'F4'; + + cmTraceInto = 402; + kb_val_TraceInto = kbF7; + kb_str_TraceInto = 'F7'; + + cmStepOver = 403; + kb_val_StepOver = kbF8; + kb_str_StepOver = 'F8'; + + cmUntilReturn = 404; + kb_val_UntilReturn = kbAltF8; + kb_str_UntilReturn = 'Alt-F8'; + + cmToggleBreak = 500; + kb_val_ToggleBreak = kbCtrlF8; + + cmClearBreaks = 501; + + cmViewGlyph = 600; + kb_val_ViewGlyph = kbF9; + kb_str_ViewGlyph = 'F9'; diff --git a/pascal/test/debugger.pas b/pascal/test/debugger.pas new file mode 100644 index 0000000..37544d1 --- /dev/null +++ b/pascal/test/debugger.pas @@ -0,0 +1,924 @@ +program Debugger; + +uses +{$IFDEF OS2} + Use32, +{$ENDIF} + +(* Turbo Vision units *) + Drivers, + Objects, + Views, + Menus, + App, + MsgBox, + + Crt, + +(* FreeType units *) + FreeType, + TTInterp, + TTTypes, + TTMemory, + TTError, + TTTables, + TTObjs, + TTFile, + TTCalc, + TTDebug, + TTRaster, + +(* graphics system units *) + GDriver, + GMain, + GEvents, + +(* Debugger's Turbo Vision enhancements *) + CodeTv, + StackTv, + StateTv, + ZoneTv; + +{$I DEBUGGER.INC} + +(* define this variable if you want to debug the CVT rather than a *) +(* glyph's instruction set.. *) +{ $DEFINE DEBUG_CVT} + +const + Precis = 64; + + Screen_Width = 640; + Screen_Height = 480; + Screen_Cols = Screen_Width div 8; + Screen_Size = Screen_Cols * Screen_Height; + + Grid_Width = Screen_Width div 16; + Grid_Height = Screen_Height div 16; + Grid_Cols = Grid_Width div 8; + Grid_Size = Grid_Cols * Grid_Height; + + Screen_Center_X = Screen_Width div 2; + Screen_Center_Y = Screen_Height div 2; + + Grid_Center_X = Grid_Width div 2; + Grid_Center_Y = Grid_Height div 2; + + Profile_Buff_Size = 64000; + + +type + TDebug_Mode = ( debug_code, view_glyph ); + + TMyApp = object( TApplication ) + constructor Init; + procedure NewWindow; virtual; + procedure InitMenuBar; virtual; + procedure HandleEvent( var Event : TEvent ); virtual; + + procedure Single_Step; + procedure Execute_Loop; + procedure New_Execution; + procedure ReFocus; + end; + + TEtat = ( etat_Termine, etat_Arret, etat_Execution ); + + TVolatileBreakPoint = record + range : Int; + address : Int; + end; + +var + CW : PCodeWindow; + SW : PStackWindow; + GW : PStateWindow; + ZW : PZoneWindow; + + Code_Range : array[1..3] of PCodeRange; + + Gen_Range : array[1..3] of TRangeRec; + + old_Range : Int; + + stream : TT_Stream; + + the_face : TT_Face; + the_glyph : TT_Glyph; + the_instance : TT_Instance; + + face : PFace; + glyph : PGlyph; + glyph2 : PGlyph; + instance : PInstance; + exec : PExec_Context; + + error : TT_Error; + + Etat : TEtat; + + Volatiles : PBreakPoint; + + xCoord : TT_PCoordinates; + yCoord : TT_PCoordinates; + Flag : TT_PTouchTable; + + Bitmap_small : TT_Raster_Map; + Bitmap_big : TT_Raster_Map; + + display_outline : boolean; + hint_glyph : boolean; + + debug_mode : TDebug_Mode; + MyApp : TMyApp; + + Range : Int; + P : PByteArray; + FileName : String; + Font_Buffer : PStorage; + Out_File : Text; + T, I : int; + + glyph_number : Int; + point_size : Int; + +procedure Initialize; +var + i : int; +begin + for i := 1 to 3 do Code_Range[i] := Get_CodeRange(exec,i); + for i := 1 to 3 do Generate_Range( Code_Range[i], i, Gen_Range[i] ); + + Volatiles := nil; + + display_outline := true; + Debug_Mode := debug_code; +end; + +(******************************************************************* + * + * Function : InitRows + * + * Description : Allocates the target bitmaps + * + *****************************************************************) + +Procedure Init_Engine; +var + P: Pointer; +begin + + (* The big bitmap will contain the grid, the glyph contours and *) + (* the magnified bitmap *) + + Bitmap_big.rows := Screen_Height; + Bitmap_big.cols := Screen_Cols; + Bitmap_big.width := Screen_Width; + Bitmap_big.flow := TT_Flow_Up; + Bitmap_big.size := Screen_Size; + + GetMem( Bitmap_big.buffer, Bitmap_big.size ); + if Bitmap_big.buffer = NIL then + begin + Writeln('ERREUR:InitRows:Not enough memory to allocate big BitMap'); + halt(1); + end; + + (* The small bitmap contains the rendered glyph, and is then later *) + (* magnified into the big bitmap *) + + Bitmap_small.rows := Grid_Height; + Bitmap_small.cols := Grid_Cols; + Bitmap_small.width := Grid_Width; + Bitmap_small.flow := TT_Flow_Up; + Bitmap_small.size := Grid_Size; + + GetMem( Bitmap_small.buffer, Bitmap_small.size ); + if Bitmap_small.buffer = NIL then + begin + Writeln('ERREUR:InitRows:Not enough memory to allocate big BitMap'); + halt(1); + end; + + FillChar( Bitmap_big.Buffer^, Bitmap_big.Size, 0 ); + FillChar( Bitmap_small.Buffer^, Bitmap_small.size, 0 ); +end; + +(******************************************************************* + * + * Function : ClearData + * + * Description : Clears the bitmaps + * + *****************************************************************) + +Procedure ClearData; +var i: integer; +begin + FillChar( Bitmap_big. Buffer^, Bitmap_big. Size, 0 ); + FillChar( Bitmap_small.Buffer^, Bitmap_small.size, 0 ); +end; + + +function Render_Magnified : boolean; +label + Exit_1; +type + TBlock = array[0..7] of Byte; + PBlock = ^TBlock; +const +{ + Grid_Empty : TBlock + = ( $10, $10, $10, $FF, $10, $10, $10, $10 ); +} + Grid_Pixel2 : TBlock + = ( $FE, $FE, $FE, $FE, $FE, $FE, $FE, $00 ); + + Pixel_Center_X = 3; + Pixel_Center_Y = 3; + + Grid_Empty : TBlock + = ( $00, $00, $00, $10, $00, $00, $00, $00 ); + + Grid_Pixel1 : TBlock + = ( $00, $00, $38, $38, $38, $00, $00, $00 ); + + Big_Center_X = Grid_Center_X*16 + Pixel_Center_X; + Big_Center_Y = Grid_Center_Y*16 + Pixel_Center_Y; + +var + r, w, w2, u, v, b, c : integer; + + x, y : Long; + + block : PBlock; + G : TT_Outline; + + pixel, + empty : PBlock; + + numPoints : integer; +begin + Render_Magnified := False; + + ClearData; + + numpoints := exec^.pts.n_points - 2; (* Remove phantom points *) + + for r := 0 to numPoints-1 do with exec^.pts do + begin + glyph2^.outline.points^[r].x := exec^.pts.cur^[r].x+64; + glyph2^.outline.points^[r].y := exec^.pts.cur^[r].y+64; + end; + + (* We begin rendering the glyph within the small bitmap *) + + G.n_contours := glyph^.outline.n_contours; + G.conEnds := glyph^.outline.conEnds; + G.Points := glyph^.outline.points; + G.points := glyph2^.outline.points; + G.Flags := glyph^.outline.flags; + + G.second_pass := True; + G.high_precision := True; + G.dropout_mode := 2; + + if Render_Glyph ( G, Bitmap_small ) then goto Exit_1; + + (* Then, we render the glyph outline in the bit bitmap *) + + for r := 0 to numPoints-1 do + begin + x := exec^.pts.cur^[r].x; + y := exec^.pts.cur^[r].y; + + x := (x - Precis*Grid_Center_X)*16 + Big_Center_X*Precis; + y := (y - Precis*Grid_Center_Y)*16 + Big_Center_Y*Precis; + + glyph2^.outline.points^[r].x := x + 8*64; + glyph2^.outline.points^[r].y := y + 8*64; + end; + + (* first compute the magnified coordinates *) + + G.n_contours := glyph^.outline.n_contours; + G.conEnds := glyph^.outline.conEnds; + G.Points := glyph^.outline.points; + G.points := glyph2^.outline.points; + G.Flags := glyph^.outline.flags; + + G.second_pass := True; + G.high_precision := True; + G.dropout_mode := 2; + + if display_outline then + if Render_Glyph ( G, Bitmap_big ) then goto Exit_1; + + (* Now, magnify the small bitmap, XORing it to the big bitmap *) + + r := 0; + w := 0; + b := 0; + + empty := @Grid_Empty; + + if display_outline then pixel := @Grid_Pixel1 + else pixel := @Grid_Pixel2; + + for y := 0 to Grid_Height-1 do + begin + + for x := 0 to Grid_Width-1 do + begin + + w2 := w; + b := b shr 1; + + if b = 0 then + begin + c := PByte(Bitmap_small.Buffer)^[r]; + b := $80; + inc( r ); + end; + + if c and b <> 0 then block := pixel + else block := empty; + + for v := 0 to 7 do + begin + PByte(Bitmap_Big.Buffer)^[w2] := PByte(Bitmap_Big.Buffer)^[w2] + xor block^[v]; + inc( w2, Bitmap_Big.cols ); + end; + + inc( w, 2 ); + + end; + + inc( w, 15*Screen_Cols ); + + end; + + + (* Display the resulting big bitmap *) + + Display_BitMap_On_Screen( Bitmap_big.Buffer^, 450, 80 ); + +Exit_1: + (* Clear the bitmaps *) + + Render_Magnified := True; +end; + + +function Render_Simple : boolean; +label + Exit_1; +var + r, w, w2, u, v, b, c : integer; + + x, y : Long; + + G : TT_Outline; + + numPoints : integer; +begin + Render_Simple := False; + + numpoints := exec^.pts.n_points - 2; (* Remove phantom points *) + + for r := 0 to numPoints-1 do with exec^.pts do + begin + glyph2^.outline.points^[r].x := exec^.pts.cur^[r].x + 32; + glyph2^.outline.points^[r].y := exec^.pts.cur^[r].y + 32; + end; + + (* We begin rendering the glyph within the small bitmap *) + + G.n_contours := glyph^.outline.n_contours; + G.conEnds := glyph^.outline.conEnds; + G.Points := glyph^.outline.points; + G.points := glyph2^.outline.points; + G.Flags := glyph^.outline.flags; + + G.second_pass := True; + G.high_precision := True; + G.dropout_mode := 2; + + + if display_outline then + if Render_Glyph ( G, Bitmap_big ) then goto Exit_1; + + (* Display the resulting big bitmap *) + + Display_BitMap_On_Screen( Bitmap_big.Buffer^, 450, 80 ); + +Exit_1: + (* Clear the bitmaps *) + + ClearData; + + Render_Simple := True; +end; + + +procedure Exit_Viewer; +begin + Restore_Screen; + debug_mode := debug_code; + MyApp.SetScreenMode( smCo80 + smFont8x8 ); + MyApp.Show; + MyApp.ReDraw; +end; + + +procedure Enter_Viewer; +begin + Set_Graph_Screen( Graphics_Mode_Mono ); + + if not Render_Magnified then + Exit_Viewer + else + debug_mode := view_glyph; +end; + + +procedure TMyApp.Execute_Loop; +var + Out : Boolean; + B : PBreakPoint; + + Event : TEvent; +begin + + Out := False; + etat := etat_Execution; + + repeat + + Single_Step; + + B := Find_BreakPoint( Volatiles, exec^.curRange, exec^.IP ); + if B <> nil then + begin + Clear_Break( Volatiles, B ); + Out := True; + end; + + if etat = etat_Execution then + begin + B := Find_BreakPoint( Gen_Range[exec^.curRange].Breaks, + exec^.curRange, + exec^.IP ); + if B <> nil then + begin + Out := True; + Etat := etat_Arret; + end; + end + else + Out := True; + + until Out; + +end; + + +procedure TMyApp.New_Execution; +var + Event : TEvent; +begin + Event.What := evWave; + Event.Command := cmNewExecution; + + HandleEvent( Event ); +end; + + +procedure TMyApp.Single_Step; +var + tempStr : string[6]; +begin + + if Run_Ins( exec ) then + begin + etat := etat_Termine; + str( exec^.error, tempStr ); + MessageBox( 'Error : '+tempStr, nil, mfError+mfOkButton ); + exit; + end; + + if exec^.IP >= exec^.codeSize then + + begin + if (exec^.curRange <> TT_CodeRange_CVT) or + Goto_CodeRange( exec, TT_CodeRange_Glyph, 0 ) then + + begin + etat := etat_Termine; + MessageBox( 'Completed', nil, mfInformation+mfOkButton ); + exit; + end; + end +end; + + +procedure TMyApp.ReFocus; +var + Event : TEvent; +begin + Event.What := evCommand; + + if Old_Range <> exec^.curRange then + begin + Old_Range := exec^.curRange; + Event.Command := cmChangeRange; + Event.InfoPtr := @Gen_Range[Old_Range]; + CW^.HandleEvent( Event ); + end; + + Event.What := evWave; + Event.Command := cmRefocus; + + if etat <> etat_Termine then + Event.InfoInt := Get_Dis_Line( Gen_Range[Old_Range], exec^.IP ) + else + Event.InfoInt := -1; + + HandleEvent( Event ); +end; + + +procedure TMyApp.NewWindow; +var + R : TRect; + RR : TRangeRec; +begin + Desktop^.GetExtent(R); + R.B.X := 32; + + Old_Range := exec^.curRange; + + New( CW, Init( R, @Gen_Range[Old_Range] ) ); + Desktop^.Insert(CW); + + Desktop^.GetExtent(R); + R.A.X := 32; + R.B.X := 50; + R.B.Y := R.B.Y div 2; + + New( SW, Init( R, exec ) ); + Desktop^.Insert(SW); + + Desktop^.GetExtent(R); + R.A.X := 50; + R.B.Y := R.B.Y div 2; + + New( GW, Init( R, exec ) ); + Desktop^.Insert(GW); + + Desktop^.GetExtent(R); + R.A.X := 32; + R.A.Y := R.B.Y div 2; + +{$IFDEF DEBUG_CVT} + New( ZW, Init( R, @exec^.twilight ) ); +{$ELSE} + New( ZW, Init( R, @exec^.pts ) ); +{$ENDIF} + Desktop^.Insert(ZW); + + etat := etat_Arret; +end; + + +procedure TMyApp.InitMenuBar; +var + R : TRect; +begin + GetExtent(R); + R.B.Y := R.A.Y + 1; + MenuBar := New( PMenuBar, Init( R, NewMenu( + NewSubMenu( '~F~ile', hcNoContext, NewMenu( + NewItem( '~O~pen','F3', kbF3, cmFileOpen, + hcNoContext, + nil )), + NewSubMenu( '~R~un', hcNoContext, + NewMenu( + NewItem( '~R~un','Ctrl-F9', kbCtrlF9, + cmRun, hcNoContext, + + NewItem( '~G~o to cursor','F4', kbF4, + cmGoToCursor, hcNoContext, + + NewItem( '~T~race into', 'F7', kbF7, + cmTraceInto, hcNoContext, + + NewItem( '~S~tep over', 'F8', kbF8, + cmStepOver, hcNoContext, + + NewItem( '~V~iew glyph', 'F9', kbF9, + cmViewGlyph, hcNoContext, + nil + ) + ) + ) + ) + ) + ), + nil + ))))); +end; + + +procedure TMyApp.HandleEvent( var Event : TEvent ); +var + Adr : Long; +begin + + if debug_mode = view_glyph then + begin + + case Event.What of + + evKeyDown : case Event.KeyCode of + + kbF2 : begin + display_outline := not display_outline; + + if not Render_Magnified then + Exit_Viewer; + + end; + + kbESC : Exit_Viewer; + + end; + end; + + ClearEvent( Event ); + exit; + + end; + + inherited HandleEvent(Event); + + case Event.What of + + evCommand : case Event.Command of + + cmNewWin : NewWindow; + + cmGoToCursor : begin + if etat = etat_Termine then exit; + + Event.Command := cmQueryCursorAddr; + Event.InfoPtr := @Adr; + + CW^.HandleEvent( Event ); + + Set_Break( Volatiles, + exec^.curRange, + Adr ); + + New_Execution; + Execute_Loop; + ReFocus; + end; + + cmTraceInto : begin + if etat = etat_termine then exit; + + New_Execution; + Single_Step; + ReFocus; + end; + + cmStepOver : begin + if etat = etat_termine then exit; + + New_Execution; + with exec^ do + case code^[IP] of + + $2A, (* LOOPCALL *) + $2B : (* CALL *) + + begin + + Set_Break( Volatiles, + exec^.curRange, + exec^.IP + + Get_Length( exec^.Code, + exec^.IP ) ); + Execute_Loop; + end; + + else + + Single_Step; + end; + + ReFocus; + end; + + cmViewGlyph : + Enter_Viewer; + + else + exit; + end; + + else + exit; + end; + + ClearEvent(Event); +end; + + +constructor TMyApp.Init; +begin + inherited Init; + SetScreenMode( smCo80 + smFont8x8 ); + NewWindow; +end; + + + +(******************************************************************* + * + * Function : LoadTrueTypeChar + * + * Description : + * + * Notes : + * + *****************************************************************) + +Function LoadTrueTypeChar( index : integer ) : boolean; +var + j, load_flag : int; + + rc : TT_Error; + +begin + LoadTrueTypeChar := FALSE; +(* + if hint_glyph then load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph + else load_flag := TT_Load_Scale_Glyph; +*) + + load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph or TT_Load_Debug; + + rc := TT_Load_Glyph( the_instance, + the_glyph, + index, + load_flag ); + if rc <> TT_Err_Ok then exit; + + LoadTrueTypeChar := TRUE; +end; + + +procedure Usage; +begin + Writeln('Simple Library Debugger -- part of the FreeType project'); + Writeln('-----------------------------------------------------'); + Writeln; + Writeln(' Usage : debugger glyph_number point_size fontfile[.ttf]'); + Writeln; + halt(2); +end; + + +var + Code : Int; + +begin + + if ParamCount <> 3 then + Usage; + + val( ParamStr(1), glyph_number, Code ); + if Code <> 0 then + Usage; + + val( ParamStr(2), point_size, Code ); + if Code <> 0 then + Usage; + + filename := ParamStr(3); + if Pos( '.', filename ) = 0 then filename := filename + '.ttf'; + + TT_Init_FreeType; + + error := TT_Open_Face( filename, the_face ); + if error <> TT_Err_Ok then + begin + Writeln('Could not open file ',filename ); + halt(1); + end; + + face := PFace(the_face.z); + + error := TT_New_Glyph( the_face, the_glyph ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR : Could not get glyph' ); + Check_Error(error); + end; + + glyph2 := PGlyph( the_glyph.z ); + + error := TT_New_Glyph( the_face, the_glyph ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR : Could not get glyph' ); + Check_Error(error); + end; + + glyph := PGlyph( the_glyph.z ); + + error := TT_New_Instance( the_face, the_instance ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR: Could not create new instance' ); + Check_Error(error); + end; + + instance := PInstance(the_instance.z); + + exec := New_Context( instance ); + if exec = nil then + begin + Writeln( 'could not create execution context' ); + halt(1); + end; + + instance^.debug := true; + instance^.context := exec; + + TT_Set_Instance_Resolutions( the_instance, 96, 96 ); + +{$IFDEF DEBUG_CVT} + exec^.curRange := 1; + + (* code taken from freetype.pas *) + + with instance^.metrics do + begin + x_scale1 := ( Long(point_size*64) * x_resolution ) div 72; + x_scale2 := instance^.owner^.fontHeader.units_per_EM; + + y_scale1 := ( Long(point_size*64) * y_resolution ) div 72; + y_scale2 := x_scale2; + + if instance^.owner^.fontHeader.flags and 8 <> 0 then + begin + x_scale1 := (x_scale1 + 32) and -64; + y_scale1 := (y_scale1 + 32) and -64; + end; + + x_ppem := x_scale1 div 64; + y_ppem := y_scale1 div 64; + end; + + instance^.metrics.pointsize := point_size*64; + instance^.valid := False; + + if Instance_Reset( instance, true ) then + Panic1('Could not reset instance before executing CVT'); +{$ELSE} + error := TT_Set_Instance_PointSize( the_instance, point_size ); + if error <> TT_Err_Ok then + begin + Writeln('Could not execute CVT program' ); + Check_Error(error); + end; +{$ENDIF} + + Init_Engine; + +{$IFNDEF DEBUG_CVT} + if not LoadTrueTypeChar( glyph_number ) then + begin + Writeln('Error while loading glyph' ); + halt(1); + end; +{$ENDIF} + + exec^.instruction_trap := true; + +{$IFNDEF DEBUG_CVT} +(* Run_Context( exec, true ); *) +{$ENDIF} + + Initialize; + + MyApp.Init; + MyApp.Run; + MyApp.Done; + + TT_Done_FreeType; +end. diff --git a/pascal/test/dump.pas b/pascal/test/dump.pas new file mode 100644 index 0000000..7600b78 --- /dev/null +++ b/pascal/test/dump.pas @@ -0,0 +1,551 @@ +{***************************************************************************} +{* *} +{* FreeType Font Tester. *} +{* *} +{* This program is used to compare computed advance widths with the *} +{* values present in the "hdmx" table. It is now useless but remains *} +{* a good base for other quick font metrics checkers.. *} +{* *} +{* This source code has been compiled and run under both Virtual Pascal *} +{* on OS/2 and Borland's BP7. *} +{* *} +{***************************************************************************} + +program Dump; + +uses Crt, + Dos, +{$IFDEF OS2} + Use32, +{$ENDIF} + GMain, + GEvents, + GDriver, + FreeType, + TTCalc, + TTObjs, + TTTables; + +{ &PMTYPE NOVIO} + +{$DEFINE DEBUG} + +type + TPathName = string[128]; + +const + Precis = 64; + + Precis2 = Precis div 2; + + PrecisAux = 1024; + + Profile_Buff_Size = 32000; + + Max_Files = 1024; + +var + face : TT_Face; + instance : TT_Instance; + glyph : TT_Glyph; + + metrics : TT_Glyph_Metrics; + imetrics : TT_Instance_Metrics; + + props : TT_Face_Properties; + + ymin, ymax, xmax, xmin, xsize : longint; + res, old_res : int; + + numPoints, numContours : int; + + Bit : TT_Raster_Map; + + Rotation : int; (* Angle modulo 1024 *) + + num_glyphs : int; + + error : TT_Error; + gray_level : Boolean; + + display_outline : boolean; + hint_glyph : boolean; + scan_type : Byte; + + old_glyph : int; + cur_glyph : int; + + scale_shift : Int; + + grayLines : array[0..2048] of Byte; + + filenames : array[0..Max_Files-1] of ^TPathName; + +(******************************************************************* + * + * Function : Set_Raster_Area + * + *****************************************************************) + + procedure Set_Raster_Area; + begin + Bit.rows := vio_Height; + Bit.width := vio_Width; + Bit.flow := TT_Flow_Up; + + if gray_level then + Bit.cols := Bit.width + else + Bit.cols := (Bit.width+7) div 8; + + Bit.size := Bit.rows * Bit.cols; + end; + +(******************************************************************* + * + * Function : Clear_Data + * + *****************************************************************) + + procedure Clear_Data; + begin + if gray_level then + fillchar( Bit.buffer^, Bit.size, gray_palette[0] ) + else + fillchar( Bit.buffer^, Bit.size, 0 ); + end; + +(******************************************************************* + * + * Function : Init_Engine + * + *****************************************************************) + + procedure Init_Engine( maxRes : Int ); + begin + Set_Raster_Area; + GetMem( Bit.buffer, Bit.size ); + Clear_Data; + end; + +(******************************************************************* + * + * Function : Reset_Scale + * + *****************************************************************) + + function Reset_Scale( res : Int ) : Boolean; + begin + error := TT_Set_Instance_Pointsize( instance, res ); + Reset_Scale := (error = TT_Err_Ok); + end; + + + procedure Split( Original : String; + var Base : String; + var Name : String ); + var + n : integer; + begin + n := length(Original); + + while ( n > 0 ) do + if ( Original[n] = '\' ) or + ( Original[n] = '/' ) then + begin + Base := Copy( Original, 1, n-1 ); + Name := Copy( Original, n+1, length(Original) ); + exit; + end + else + dec(n); + + Base := ''; + Name := Original; + end; + +(******************************************************************* + * + * Function : LoadTrueTypeChar + * + * Description : Loads a single glyph into the xcoord, ycoord and + * flag arrays, from the instance data. + * + *****************************************************************) + +Function LoadTrueTypeChar( index : integer; + hint : boolean ) : boolean; +var + j, load_flag : int; + + result : TT_Error; + +begin + LoadTrueTypeChar := True; + + if hint then load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph + else load_flag := TT_Load_Scale_Glyph; + + result := TT_Load_Glyph( instance, + glyph, + index, + load_flag ); + if result <> TT_Err_Ok then + exit; + + LoadTrueTypeChar := False; +end; + + +var + Error_String : String; + ine : Int; + +procedure Dump_AW( _face : TT_Face ); +var + i, j, n : integer; + + x, y : longint; + + start_x, + start_y, + step_x, + step_y : longint; + + fail : Int; + face : PFace; + + rec : PHdmx_Record; + +begin + + face := PFace(_face.z); + + rec := nil; + + for n := 0 to face^.hdmx.num_records-1 do + if face^.hdmx.records^[n].ppem = imetrics.x_ppem then + rec := @face^.hdmx.records^[n]; + + if rec = nil then + begin + Writeln('Pas de hdmx record pour ', imetrics.x_ppem, ' ppem'); + exit; + end; + + ine := 0; + while ine < num_glyphs do + begin + + if not LoadTrueTypeChar( ine, true ) then + begin + + TT_Get_Glyph_Metrics( glyph, metrics ); + + x := metrics.advance div 64; + + if rec^.widths^[ine] <> x then + begin + Write( '(',ine:3,':',rec^.widths^[ine]:2,' ',x:2,')' ); + end; + end; + + inc( ine ); + end; + Writeln; + Writeln; +end; + + + +procedure Erreur( s : String ); +begin + Restore_Screen; + Writeln( 'Error : ', s, ', error code = ', error ); + Halt(1); +end; + + +procedure Usage; +begin + Writeln('Simple TrueType Glyphs viewer - part of the FreeType project' ); + Writeln; + Writeln('Usage : ',paramStr(0),' FontName[.TTF]'); + Halt(1); +end; + + + +var + i: integer; + heure, + min1, + min2, + sec1, + sec2, + cent1, + cent2 : +{$IFDEF OS2} + longint; +{$ELSE} + word; +{$ENDIF} + + C : Char; + + Filename : String; + +label Fin; + +var + Fail : Int; + glyphStr : String[4]; + ev : Event; + + Code : Int; + + init_memory, end_memory : LongInt; + + num_args : Integer; + point_size : Integer; + num_files : Integer; + cur_file : Integer; + first_arg : Int; + sortie : Boolean; + + base : string; + name : string; + + SRec : SearchRec; + +begin + TextMode( co80+Font8x8 ); + + TT_Init_FreeType; + + num_args := ParamCount; + + if num_args = 0 then + Usage; + + first_arg := 1; + + gray_level := False; + + if ParamStr(first_arg) = '-g' then + begin + inc( first_arg ); + gray_level := True; + end; + + if first_arg > num_args+1 then + Usage; + + val( ParamStr(first_arg), point_size, Code ); + if Code <> 0 then + point_size := 24 + else + inc( first_arg ); + + num_files := 0; + + while first_arg <= num_args do + begin + Split( ParamStr(first_arg), base, name ); + if base <> '' then + base := base + '\'; + + FindFirst( base+name, Archive+ReadOnly+Hidden, SRec ); + if DosError <> 0 then + FindFirst( base+name+'.ttf', AnyFile, SRec ); + + while (DosError = 0) and (num_files < Max_Files) do + begin + GetMem( filenames[num_files], length(base)+length(SRec.Name)+1 ); + filenames[num_files]^ := base + SRec.Name; + inc( num_files ); + FindNext( SRec ); + end; + + {$IFDEF OS2} + FindClose( SRec ); + {$ENDIF} + inc( first_arg ); + end; + + cur_file := 0; + + if num_files = 0 then + begin + Writeln('Could not find file(s)'); + Halt(3); + end; + +(* + if gray_level then + begin + if not Set_Graph_Screen( Graphics_Mode_Gray ) then + Erreur( 'could not set grayscale graphics mode' ); + end + else + begin + if not Set_Graph_Screen( Graphics_Mode_Mono ) then + Erreur( 'could not set mono graphics mode' ); + end; +*) + + Init_Engine( point_size ); + + repeat + + FileName := Filenames[cur_file]^; + + if Pos('.',FileName) = 0 then FileName:=FileName+'.TTF'; + + error := TT_Open_Face( filename, face ); + if error <> TT_Err_Ok then + Erreur( 'Could not open '+filename ); + + TT_Get_Face_Properties( face, props ); + + num_glyphs := props.num_Glyphs; + + i := length(FileName); + while (i > 1) and (FileName[i] <> '\') do dec(i); + + FileName := Copy( FileName, i+1, length(FileName) ); + + error := TT_New_Glyph( face, glyph ); + if error <> TT_Err_Ok then + Erreur('Could not create glyph container'); + + error := TT_New_Instance( face, instance ); + if error <> TT_Err_Ok then + Erreur('Could not create instance'); + + Rotation := 0; + Fail := 0; + res := point_size; + scan_type := 2; + + if ( gray_level ) then scale_shift := 1 + else scale_shift := 0; + + Reset_Scale( res ); + + display_outline := true; + hint_glyph := true; + + old_glyph := -1; + old_res := res; + cur_glyph := 0; + + sortie := false; + + Repeat + +(* + if Render_ABC( cur_glyph ) then + inc( Fail ) + else + Display_Bitmap_On_Screen( Bit.Buffer^, Bit.rows, Bit.cols ); + + Clear_Data; + + Print_XY( 0, 0, FileName ); + + TT_Get_Instance_Metrics( instance, imetrics ); + + Print_Str(' point size = '); + Str( imetrics.pointSize:3, glyphStr ); + Print_Str( glyphStr ); + + Print_Str(' glyph = '); + Str( cur_glyph, glyphStr ); + Print_Str( glyphStr ); + + Print_XY( 0, 1, 'Hinting (''z'') : ' ); + if hint_glyph then Print_Str('on ') + else Print_Str('off'); + + Print_XY( 0, 2, 'scan type(''e'') : ' ); + case scan_type of + 0 : Print_Str('none '); + 1 : Print_Str('level 1'); + 2 : Print_Str('level 2'); + 4 : Print_Str('level 4'); + 5 : Print_Str('level 5'); + end; +*) + TT_Get_Instance_Metrics( instance, imetrics ); + Writeln( Filename,' ',imetrics.pointsize,' pts = ',imetrics.x_ppem,' ppem' ); + + Dump_AW( face ); + + Get_Event(ev); + + case ev.what of + + event_Quit : goto Fin; + + event_Keyboard : case char(ev.info) of + + 'n' : begin + sortie := true; + if cur_file+1 < num_files then + inc( cur_file ); + end; + + 'p' : begin + sortie := true; + if cur_file > 1 then + dec( cur_file ); + end; + + 'z' : hint_glyph := not hint_glyph; + + + 'e' : begin + inc( scan_type ); + if scan_type = 3 then scan_type := 4; + if scan_type >= 6 then scan_type := 0; + end; + end; + + event_Scale_Glyph : begin + inc( res, ev.info ); + if res < 1 then res := 1; + if res > 1400 then res := 1400; + end; + + event_Change_Glyph : begin + inc( cur_glyph, ev.info ); + if cur_glyph < 0 then cur_glyph := 0; + if cur_glyph >= num_glyphs + then cur_glyph := num_glyphs-1; + end; + end; + + if res <> old_res then + begin + if not Reset_Scale(res) then + Erreur( 'Could not resize font' ); + old_res := res; + end; + + Until sortie; + + TT_Done_Glyph( glyph ); + TT_Close_Face( face ); + + until false; + + Fin: + Restore_Screen; + + Writeln; + Writeln('Fails : ', Fail ); + + TT_Done_FreeType; +end. + diff --git a/pascal/test/gdriver.pas b/pascal/test/gdriver.pas new file mode 100644 index 0000000..89432c9 --- /dev/null +++ b/pascal/test/gdriver.pas @@ -0,0 +1,123 @@ +(******************************************************************* + * + * gdriver : Graphics utility driver generic interface 1.1 + * + * Generic interface for all drivers of the graphics utility used + * by the FreeType test programs. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +Unit GDriver; + +interface + +uses GEvents, GMain; + + (* Note that we now support an event based model, even with */ + /* full-screen modes. It is the responsability of the driver */ + /* to map its events to the TEvent structure when called */ + /* through Get_Event *) + +type + Event = record + what : GEvent; (* event class *) + info : Int; (* event parameter *) + end; + + (* the event classes are defined in the file 'gevents.h' included *) + (* by the test programs, not by the graphics utility *) + + procedure Get_Event( var ev : Event ); + (* get last event. In full-screen modes, a key-stroke must be */ + /* translated to an event class with a parameter. *) + + function Driver_Set_Graphics( mode : Int ) : boolean; + (* A call to this function must set the graphics mode, the Vio *) + (* variable, as well as the values vio_ScanLineWidth, vio_Width *) + (* and vio_Height *) + + function Driver_Restore_Mode : boolean; + (* Restore previous mode or release display buffer/window *) + + procedure Driver_Display_Bitmap( var buff; line, col : Int ); + (* Display bitmap on screen *) + +implementation + +{$IFDEF OS2} + + uses Os2Base, CRT; + {$I GDRV_OS2.INC} + +{$ELSE} + + uses CRT; + {$I GDRV_DOS.INC} + +{$ENDIF} + +type + Translator = record + key : char; + ev_class : GEvent; + ev_info : Int; + end; + +const + Num_Translators = 15; + + Translators : array[1..Num_Translators] of Translator + = ( + (key:#27; ev_class:event_Quit ; ev_info:0), + + (key:'x'; ev_class: event_Rotate_Glyph; ev_info: -1), + (key:'c'; ev_class: event_Rotate_Glyph; ev_info: 1), + (key:'v'; ev_class: event_Rotate_Glyph; ev_info: -16), + (key:'b'; ev_class: event_Rotate_Glyph; ev_info: 16), + + (key:'9'; ev_class: event_Change_Glyph; ev_info:-100), + (key:'0'; ev_class: event_Change_Glyph; ev_info: 100), + (key:'i'; ev_class: event_Change_Glyph; ev_info: -10), + (key:'o'; ev_class: event_Change_Glyph; ev_info: 10), + (key:'k'; ev_class: event_Change_Glyph; ev_info: -1), + (key:'l'; ev_class: event_Change_Glyph; ev_info: 1), + + (key:'+'; ev_class: event_Scale_Glyph; ev_info: 10), + (key:'-'; ev_class: event_Scale_Glyph; ev_info: -10), + (key:'u'; ev_class: event_Scale_Glyph; ev_info: 1), + (key:'j'; ev_class: event_Scale_Glyph; ev_info: -1) + ); + + procedure Get_Event( var ev : Event ); + var + i : Int; + c : char; + begin + c := ReadKey; + + for i := 1 to Num_Translators do + begin + if c = translators[i].key then + begin + ev.what := translators[i].ev_class; + ev.info := translators[i].ev_info; + exit; + end; + end; + + (* unrecognized keystroke *) + + ev.what := event_Keyboard; + ev.info := Int(c); + end; + +end. + diff --git a/pascal/test/gdrv_dos.inc b/pascal/test/gdrv_dos.inc new file mode 100644 index 0000000..f65daa5 --- /dev/null +++ b/pascal/test/gdrv_dos.inc @@ -0,0 +1,96 @@ + + { Restores screen to the original state } + + function Driver_Restore_Mode: boolean; + begin + asm + mov ax, $0003 + int $10 + end; + Driver_Restore_Mode := True; + end; + + function Driver_Set_Graphics( mode : Int ) : boolean; + var + rc : Int; + begin + Driver_Set_Graphics := False; + + rc := 0; + + case Mode of + + Graphics_Mode_Mono : begin + asm + mov ax, $0012 + int $10 + end; + Vio_ScanLineWidth := 80; + Vio_Width := 640; + Vio_Height := 480; + end; + + Graphics_Mode_Gray : begin + asm + mov ax, $0013 + int $10 + end; + Vio_ScanLineWidth := 320; + Vio_Width := 320; + Vio_Height := 200; + + (* default gray palette takes the gray levels *) + (* the standard VGA 256 colors mode *) + + gray_palette[0] := 0; + gray_palette[1] := 23; + gray_palette[2] := 27; + gray_palette[3] := 29; + gray_palette[4] := 31; + end; + else + rc := -1; + end; + + if rc <> 0 then exit; + + Vio := @Mem[$A000:0]; + + Driver_Set_Graphics := True; + end; + + + procedure Driver_Display_Bitmap; assembler; + asm + push ds + push bp + + les di, [Vio] + + cld + + mov cx,[Vio_ScanLineWidth] + mov bx,[col] + mov ax,[line] + dec ax + mul cx + add di,ax + mov dx,[line] + + lds si,[Buff] + + mov bp,bx + add bx,cx + + @1: + mov cx,bp + rep movsb + sub di,bx + dec dx + jnz @1 + + pop bp + pop ds + end; + + diff --git a/pascal/test/gdrv_os2.inc b/pascal/test/gdrv_os2.inc new file mode 100644 index 0000000..13c56de --- /dev/null +++ b/pascal/test/gdrv_os2.inc @@ -0,0 +1,148 @@ + + {$IFDEF DYNAMIC_VERSION} + {$Dynamic System} + {$L VPRTL.LIB} + {$ENDIF} + + + type + Ptr16Rec = record + Ofs,Sel: SmallWord; + end; + + var + OrgMode : VioModeInfo; + VioBufOfs : Longint; + Status : SmallWord; + + { BIOS Video Mode +#13 } + + const + VioMode_640x480x16 : VioModeInfo = + ( cb: SizeOf(VioModeInfo); + fbType: vgmt_Other + vgmt_Graphics; + Color: colors_16; + Col: 80; + Row: 35; + HRes: 640; + VRes: 480 + ); + + VioMode_320x200x256 : VioModeInfo = + ( cb: SizeOf(VioModeInfo); + fbType: vgmt_Other + vgmt_Graphics; + Color: colors_256; + Col: 40; + Row: 25; + HRes: 320; + VRes: 200 + ); + + VioBuf: VioPhysBuf = + ( pBuf: Ptr($A0000); + cb: 64*1024 + ); + + { Restores screen to the original state } + + function Driver_Restore_Mode: boolean; + begin + VioSetMode(OrgMode, 0); + Driver_Restore_Mode := True; + end; + + function Driver_Set_Graphics( mode : Int ) + : boolean; + var + rc : Int; + begin + Driver_Set_Graphics := False; + + { Save original video mode } + OrgMode.cb := SizeOf(VioModeInfo); + VioGetMode(OrgMode, 0); + + case Mode of + + Graphics_Mode_Mono : begin + rc := VioSetMode( VioMode_640x480x16, 0 ); + Vio_ScanLineWidth := 80; + Vio_Width := 640; + Vio_Height := 480; + end; + + Graphics_Mode_Gray : begin + rc := VioSetMode( VioMode_320x200x256, 0 ); + Vio_ScanLineWidth := 320; + Vio_Width := 320; + Vio_Height := 200; + + (* default gray palette takes the gray levels *) + (* the standard VGA 256 colors mode *) + + gray_palette[0] := 0; + gray_palette[1] := 23; + gray_palette[2] := 27; + gray_palette[3] := 29; + gray_palette[4] := 31; + end; + else + rc := -1; + end; + + { Set VGA 640x400x16 + video mode } + if rc <> 0 then exit; + + { Get selector for physical video buffer } + if VioGetPhysBuf(VioBuf, 0) <> 0 then exit; + + { Make flat pointer that points to the physical video buffer} + Ptr16Rec(VioBufOfs).Ofs := 0; + Ptr16Rec(VioBufOfs).Sel := VioBuf.Sel; + SelToFlat(Pointer(VioBufOfs)); + + { Clear the screen. Unlike function 0 of the BIOS INT 10h } + { VioSetMode doesn't clear the screen. } + FillChar(Pointer(VioBufOfs)^,64*1024,0); + Vio := PVioScreenBuffer(VioBufOfs); + + Driver_Set_Graphics := True; + end; + + + procedure Driver_Display_Bitmap; assembler; + asm + push esi + push edi + push ebx + push ecx + + mov esi,[Buff] + + mov ecx,[Vio_ScanLineWidth] + mov ebx,[Col] + mov eax,[Line] + + dec eax + mul ecx + + mov edi,[VioBufOfs] + add edi,eax + + mov edx,[line] + add ebx,[Vio_ScanLineWidth] + @1: + mov ecx,[col] + rep movsb + sub edi,ebx + dec edx + jnz @1 + + pop ecx + pop ebx + pop edi + pop esi + end; + diff --git a/pascal/test/gevents.pas b/pascal/test/gevents.pas new file mode 100644 index 0000000..c43466a --- /dev/null +++ b/pascal/test/gevents.pas @@ -0,0 +1,42 @@ +(******************************************************************* + * + * gevents test programs events definition 1.1 + * + * This file defines the events used by the FreeType test programs + * It is _not_ included by 'gmain.c'. This file is also used by the + * drivers to translate their own events in GEvents. + * + * Not a very good design, but we're not rewriting X.. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +Unit GEvents; + +interface + +type + GEvent = ( + event_None, + event_Quit, (* Quit program *) + + event_Keyboard, (* unknown keystroke *) + + event_Change_Glyph, + event_Rotate_Glyph, + event_Scale_Glyph, + + event_Change_ScanType, + event_Change_Instructions + ); + +implementation + +end. diff --git a/pascal/test/gmain.pas b/pascal/test/gmain.pas new file mode 100644 index 0000000..c193261 --- /dev/null +++ b/pascal/test/gmain.pas @@ -0,0 +1,474 @@ +(******************************************************************* + * + * gmain graphics utility main interface 1.1 + * + * This file defines a common interface, implemented in the body + * file 'gmain.c'. It relies on system dependent driver files, + * like 'gfs_os.c', whose interface is described in 'gdriver.h'. + * + * Copyright 1996 David Turner, Robert Wilhelm and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************) + +Unit GMain; + +interface + +const + Graphics_Mode_Mono = 1; + Graphics_Mode_Gray = 2; + +type + TVioScreenBuffer = array[0..0] of Byte; + PVioScreenBuffer = ^TVioScreenBuffer; + +{$IFDEF OS2} + Int = LongInt; +{$ELSE} + Int = Integer; +{$ENDIF} + +var + + Vio : PVioScreenBuffer; + (* pointer to VRAM or display buffer *) + + vio_ScanLineWidth : Int; + vio_Width : Int; + vio_Height : Int; + + gray_palette : array[0..4] of Byte; (* gray palette *) + + gcursor_x : int; + gcursor_y : int; + + gwindow_width : int; + gwindow_height : int; + + function Set_Graph_Screen( mode : int ) : boolean; + (* Set a Graphics Mode, chosen from the Graphics_Mode_xxx list *) + + function Restore_Screen : boolean; + (* Restore a previous ( or text ) video mode *) + + procedure Display_Bitmap_On_Screen( var buff; line, col : Int ); + (* display bitmap of 'line' line, and 'col' columns ( each *) + (* column mode of 1 byte *) + + procedure Goto_XY( x, y : int ); + + procedure Print_Str( str : string ); + + procedure Print_XY ( x, y : int; str : string ); + +implementation + +uses GDriver; + + type + TFunction_8x8 = procedure( x, y : Int; c : char ); + + TByte = array[0..0] of Byte; + PByte = ^TByte; + + var + Current_Mode : Byte; + Print_8x8 : TFunction_8x8; + + const + Font_8x8 : array[0..2047] of Byte + = ( + $00, $00, $00, $00, $00, $00, $00, $00, + $7E, $81, $A5, $81, $BD, $99, $81, $7E, + $7E, $FF, $DB, $FF, $C3, $E7, $FF, $7E, + $6C, $FE, $FE, $FE, $7C, $38, $10, $00, + $10, $38, $7C, $FE, $7C, $38, $10, $00, + $38, $7C, $38, $FE, $FE, $92, $10, $7C, + $00, $10, $38, $7C, $FE, $7C, $38, $7C, + $00, $00, $18, $3C, $3C, $18, $00, $00, + $FF, $FF, $E7, $C3, $C3, $E7, $FF, $FF, + $00, $3C, $66, $42, $42, $66, $3C, $00, + $FF, $C3, $99, $BD, $BD, $99, $C3, $FF, + $0F, $07, $0F, $7D, $CC, $CC, $CC, $78, + $3C, $66, $66, $66, $3C, $18, $7E, $18, + $3F, $33, $3F, $30, $30, $70, $F0, $E0, + $7F, $63, $7F, $63, $63, $67, $E6, $C0, + $99, $5A, $3C, $E7, $E7, $3C, $5A, $99, + $80, $E0, $F8, $FE, $F8, $E0, $80, $00, + $02, $0E, $3E, $FE, $3E, $0E, $02, $00, + $18, $3C, $7E, $18, $18, $7E, $3C, $18, + $66, $66, $66, $66, $66, $00, $66, $00, + $7F, $DB, $DB, $7B, $1B, $1B, $1B, $00, + $3E, $63, $38, $6C, $6C, $38, $86, $FC, + $00, $00, $00, $00, $7E, $7E, $7E, $00, + $18, $3C, $7E, $18, $7E, $3C, $18, $FF, + $18, $3C, $7E, $18, $18, $18, $18, $00, + $18, $18, $18, $18, $7E, $3C, $18, $00, + $00, $18, $0C, $FE, $0C, $18, $00, $00, + $00, $30, $60, $FE, $60, $30, $00, $00, + $00, $00, $C0, $C0, $C0, $FE, $00, $00, + $00, $24, $66, $FF, $66, $24, $00, $00, + $00, $18, $3C, $7E, $FF, $FF, $00, $00, + $00, $FF, $FF, $7E, $3C, $18, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $18, $3C, $3C, $18, $18, $00, $18, $00, + $6C, $6C, $6C, $00, $00, $00, $00, $00, + $6C, $6C, $FE, $6C, $FE, $6C, $6C, $00, + $18, $7E, $C0, $7C, $06, $FC, $18, $00, + $00, $C6, $CC, $18, $30, $66, $C6, $00, + $38, $6C, $38, $76, $DC, $CC, $76, $00, + $30, $30, $60, $00, $00, $00, $00, $00, + $18, $30, $60, $60, $60, $30, $18, $00, + $60, $30, $18, $18, $18, $30, $60, $00, + $00, $66, $3C, $FF, $3C, $66, $00, $00, + $00, $18, $18, $7E, $18, $18, $00, $00, + $00, $00, $00, $00, $00, $18, $18, $30, + $00, $00, $00, $7E, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $18, $18, $00, + $06, $0C, $18, $30, $60, $C0, $80, $00, + $7C, $CE, $DE, $F6, $E6, $C6, $7C, $00, + $30, $70, $30, $30, $30, $30, $FC, $00, + $78, $CC, $0C, $38, $60, $CC, $FC, $00, + $78, $CC, $0C, $38, $0C, $CC, $78, $00, + $1C, $3C, $6C, $CC, $FE, $0C, $1E, $00, + $FC, $C0, $F8, $0C, $0C, $CC, $78, $00, + $38, $60, $C0, $F8, $CC, $CC, $78, $00, + $FC, $CC, $0C, $18, $30, $30, $30, $00, + $78, $CC, $CC, $78, $CC, $CC, $78, $00, + $78, $CC, $CC, $7C, $0C, $18, $70, $00, + $00, $18, $18, $00, $00, $18, $18, $00, + $00, $18, $18, $00, $00, $18, $18, $30, + $18, $30, $60, $C0, $60, $30, $18, $00, + $00, $00, $7E, $00, $7E, $00, $00, $00, + $60, $30, $18, $0C, $18, $30, $60, $00, + $3C, $66, $0C, $18, $18, $00, $18, $00, + $7C, $C6, $DE, $DE, $DC, $C0, $7C, $00, + $30, $78, $CC, $CC, $FC, $CC, $CC, $00, + $FC, $66, $66, $7C, $66, $66, $FC, $00, + $3C, $66, $C0, $C0, $C0, $66, $3C, $00, + $F8, $6C, $66, $66, $66, $6C, $F8, $00, + $FE, $62, $68, $78, $68, $62, $FE, $00, + $FE, $62, $68, $78, $68, $60, $F0, $00, + $3C, $66, $C0, $C0, $CE, $66, $3A, $00, + $CC, $CC, $CC, $FC, $CC, $CC, $CC, $00, + $78, $30, $30, $30, $30, $30, $78, $00, + $1E, $0C, $0C, $0C, $CC, $CC, $78, $00, + $E6, $66, $6C, $78, $6C, $66, $E6, $00, + $F0, $60, $60, $60, $62, $66, $FE, $00, + $C6, $EE, $FE, $FE, $D6, $C6, $C6, $00, + $C6, $E6, $F6, $DE, $CE, $C6, $C6, $00, + $38, $6C, $C6, $C6, $C6, $6C, $38, $00, + $FC, $66, $66, $7C, $60, $60, $F0, $00, + $7C, $C6, $C6, $C6, $D6, $7C, $0E, $00, + $FC, $66, $66, $7C, $6C, $66, $E6, $00, + $7C, $C6, $E0, $78, $0E, $C6, $7C, $00, + $FC, $B4, $30, $30, $30, $30, $78, $00, + $CC, $CC, $CC, $CC, $CC, $CC, $FC, $00, + $CC, $CC, $CC, $CC, $CC, $78, $30, $00, + $C6, $C6, $C6, $C6, $D6, $FE, $6C, $00, + $C6, $C6, $6C, $38, $6C, $C6, $C6, $00, + $CC, $CC, $CC, $78, $30, $30, $78, $00, + $FE, $C6, $8C, $18, $32, $66, $FE, $00, + $78, $60, $60, $60, $60, $60, $78, $00, + $C0, $60, $30, $18, $0C, $06, $02, $00, + $78, $18, $18, $18, $18, $18, $78, $00, + $10, $38, $6C, $C6, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $FF, + $30, $30, $18, $00, $00, $00, $00, $00, + $00, $00, $78, $0C, $7C, $CC, $76, $00, + $E0, $60, $60, $7C, $66, $66, $DC, $00, + $00, $00, $78, $CC, $C0, $CC, $78, $00, + $1C, $0C, $0C, $7C, $CC, $CC, $76, $00, + $00, $00, $78, $CC, $FC, $C0, $78, $00, + $38, $6C, $64, $F0, $60, $60, $F0, $00, + $00, $00, $76, $CC, $CC, $7C, $0C, $F8, + $E0, $60, $6C, $76, $66, $66, $E6, $00, + $30, $00, $70, $30, $30, $30, $78, $00, + $0C, $00, $1C, $0C, $0C, $CC, $CC, $78, + $E0, $60, $66, $6C, $78, $6C, $E6, $00, + $70, $30, $30, $30, $30, $30, $78, $00, + $00, $00, $CC, $FE, $FE, $D6, $D6, $00, + $00, $00, $B8, $CC, $CC, $CC, $CC, $00, + $00, $00, $78, $CC, $CC, $CC, $78, $00, + $00, $00, $DC, $66, $66, $7C, $60, $F0, + $00, $00, $76, $CC, $CC, $7C, $0C, $1E, + $00, $00, $DC, $76, $62, $60, $F0, $00, + $00, $00, $7C, $C0, $70, $1C, $F8, $00, + $10, $30, $FC, $30, $30, $34, $18, $00, + $00, $00, $CC, $CC, $CC, $CC, $76, $00, + $00, $00, $CC, $CC, $CC, $78, $30, $00, + $00, $00, $C6, $C6, $D6, $FE, $6C, $00, + $00, $00, $C6, $6C, $38, $6C, $C6, $00, + $00, $00, $CC, $CC, $CC, $7C, $0C, $F8, + $00, $00, $FC, $98, $30, $64, $FC, $00, + $1C, $30, $30, $E0, $30, $30, $1C, $00, + $18, $18, $18, $00, $18, $18, $18, $00, + $E0, $30, $30, $1C, $30, $30, $E0, $00, + $76, $DC, $00, $00, $00, $00, $00, $00, + $00, $10, $38, $6C, $C6, $C6, $FE, $00, + $7C, $C6, $C0, $C6, $7C, $0C, $06, $7C, + $00, $CC, $00, $CC, $CC, $CC, $76, $00, + $1C, $00, $78, $CC, $FC, $C0, $78, $00, + $7E, $81, $3C, $06, $3E, $66, $3B, $00, + $CC, $00, $78, $0C, $7C, $CC, $76, $00, + $E0, $00, $78, $0C, $7C, $CC, $76, $00, + $30, $30, $78, $0C, $7C, $CC, $76, $00, + $00, $00, $7C, $C6, $C0, $78, $0C, $38, + $7E, $81, $3C, $66, $7E, $60, $3C, $00, + $CC, $00, $78, $CC, $FC, $C0, $78, $00, + $E0, $00, $78, $CC, $FC, $C0, $78, $00, + $CC, $00, $70, $30, $30, $30, $78, $00, + $7C, $82, $38, $18, $18, $18, $3C, $00, + $E0, $00, $70, $30, $30, $30, $78, $00, + $C6, $10, $7C, $C6, $FE, $C6, $C6, $00, + $30, $30, $00, $78, $CC, $FC, $CC, $00, + $1C, $00, $FC, $60, $78, $60, $FC, $00, + $00, $00, $7F, $0C, $7F, $CC, $7F, $00, + $3E, $6C, $CC, $FE, $CC, $CC, $CE, $00, + $78, $84, $00, $78, $CC, $CC, $78, $00, + $00, $CC, $00, $78, $CC, $CC, $78, $00, + $00, $E0, $00, $78, $CC, $CC, $78, $00, + $78, $84, $00, $CC, $CC, $CC, $76, $00, + $00, $E0, $00, $CC, $CC, $CC, $76, $00, + $00, $CC, $00, $CC, $CC, $7C, $0C, $F8, + $C3, $18, $3C, $66, $66, $3C, $18, $00, + $CC, $00, $CC, $CC, $CC, $CC, $78, $00, + $18, $18, $7E, $C0, $C0, $7E, $18, $18, + $38, $6C, $64, $F0, $60, $E6, $FC, $00, + $CC, $CC, $78, $30, $FC, $30, $FC, $30, + $F8, $CC, $CC, $FA, $C6, $CF, $C6, $C3, + $0E, $1B, $18, $3C, $18, $18, $D8, $70, + $1C, $00, $78, $0C, $7C, $CC, $76, $00, + $38, $00, $70, $30, $30, $30, $78, $00, + $00, $1C, $00, $78, $CC, $CC, $78, $00, + $00, $1C, $00, $CC, $CC, $CC, $76, $00, + $00, $F8, $00, $B8, $CC, $CC, $CC, $00, + $FC, $00, $CC, $EC, $FC, $DC, $CC, $00, + $3C, $6C, $6C, $3E, $00, $7E, $00, $00, + $38, $6C, $6C, $38, $00, $7C, $00, $00, + $18, $00, $18, $18, $30, $66, $3C, $00, + $00, $00, $00, $FC, $C0, $C0, $00, $00, + $00, $00, $00, $FC, $0C, $0C, $00, $00, + $C6, $CC, $D8, $36, $6B, $C2, $84, $0F, + $C3, $C6, $CC, $DB, $37, $6D, $CF, $03, + $18, $00, $18, $18, $3C, $3C, $18, $00, + $00, $33, $66, $CC, $66, $33, $00, $00, + $00, $CC, $66, $33, $66, $CC, $00, $00, + $22, $88, $22, $88, $22, $88, $22, $88, + $55, $AA, $55, $AA, $55, $AA, $55, $AA, + $DB, $F6, $DB, $6F, $DB, $7E, $D7, $ED, + $18, $18, $18, $18, $18, $18, $18, $18, + $18, $18, $18, $18, $F8, $18, $18, $18, + $18, $18, $F8, $18, $F8, $18, $18, $18, + $36, $36, $36, $36, $F6, $36, $36, $36, + $00, $00, $00, $00, $FE, $36, $36, $36, + $00, $00, $F8, $18, $F8, $18, $18, $18, + $36, $36, $F6, $06, $F6, $36, $36, $36, + $36, $36, $36, $36, $36, $36, $36, $36, + $00, $00, $FE, $06, $F6, $36, $36, $36, + $36, $36, $F6, $06, $FE, $00, $00, $00, + $36, $36, $36, $36, $FE, $00, $00, $00, + $18, $18, $F8, $18, $F8, $00, $00, $00, + $00, $00, $00, $00, $F8, $18, $18, $18, + $18, $18, $18, $18, $1F, $00, $00, $00, + $18, $18, $18, $18, $FF, $00, $00, $00, + $00, $00, $00, $00, $FF, $18, $18, $18, + $18, $18, $18, $18, $1F, $18, $18, $18, + $00, $00, $00, $00, $FF, $00, $00, $00, + $18, $18, $18, $18, $FF, $18, $18, $18, + $18, $18, $1F, $18, $1F, $18, $18, $18, + $36, $36, $36, $36, $37, $36, $36, $36, + $36, $36, $37, $30, $3F, $00, $00, $00, + $00, $00, $3F, $30, $37, $36, $36, $36, + $36, $36, $F7, $00, $FF, $00, $00, $00, + $00, $00, $FF, $00, $F7, $36, $36, $36, + $36, $36, $37, $30, $37, $36, $36, $36, + $00, $00, $FF, $00, $FF, $00, $00, $00, + $36, $36, $F7, $00, $F7, $36, $36, $36, + $18, $18, $FF, $00, $FF, $00, $00, $00, + $36, $36, $36, $36, $FF, $00, $00, $00, + $00, $00, $FF, $00, $FF, $18, $18, $18, + $00, $00, $00, $00, $FF, $36, $36, $36, + $36, $36, $36, $36, $3F, $00, $00, $00, + $18, $18, $1F, $18, $1F, $00, $00, $00, + $00, $00, $1F, $18, $1F, $18, $18, $18, + $00, $00, $00, $00, $3F, $36, $36, $36, + $36, $36, $36, $36, $FF, $36, $36, $36, + $18, $18, $FF, $18, $FF, $18, $18, $18, + $18, $18, $18, $18, $F8, $00, $00, $00, + $00, $00, $00, $00, $1F, $18, $18, $18, + $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, + $00, $00, $00, $00, $FF, $FF, $FF, $FF, + $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, + $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, + $FF, $FF, $FF, $FF, $00, $00, $00, $00, + $00, $00, $76, $DC, $C8, $DC, $76, $00, + $00, $78, $CC, $F8, $CC, $F8, $C0, $C0, + $00, $FC, $CC, $C0, $C0, $C0, $C0, $00, + $00, $00, $FE, $6C, $6C, $6C, $6C, $00, + $FC, $CC, $60, $30, $60, $CC, $FC, $00, + $00, $00, $7E, $D8, $D8, $D8, $70, $00, + $00, $66, $66, $66, $66, $7C, $60, $C0, + $00, $76, $DC, $18, $18, $18, $18, $00, + $FC, $30, $78, $CC, $CC, $78, $30, $FC, + $38, $6C, $C6, $FE, $C6, $6C, $38, $00, + $38, $6C, $C6, $C6, $6C, $6C, $EE, $00, + $1C, $30, $18, $7C, $CC, $CC, $78, $00, + $00, $00, $7E, $DB, $DB, $7E, $00, $00, + $06, $0C, $7E, $DB, $DB, $7E, $60, $C0, + $38, $60, $C0, $F8, $C0, $60, $38, $00, + $78, $CC, $CC, $CC, $CC, $CC, $CC, $00, + $00, $7E, $00, $7E, $00, $7E, $00, $00, + $18, $18, $7E, $18, $18, $00, $7E, $00, + $60, $30, $18, $30, $60, $00, $FC, $00, + $18, $30, $60, $30, $18, $00, $FC, $00, + $0E, $1B, $1B, $18, $18, $18, $18, $18, + $18, $18, $18, $18, $18, $D8, $D8, $70, + $18, $18, $00, $7E, $00, $18, $18, $00, + $00, $76, $DC, $00, $76, $DC, $00, $00, + $38, $6C, $6C, $38, $00, $00, $00, $00, + $00, $00, $00, $18, $18, $00, $00, $00, + $00, $00, $00, $00, $18, $00, $00, $00, + $0F, $0C, $0C, $0C, $EC, $6C, $3C, $1C, + $58, $6C, $6C, $6C, $6C, $00, $00, $00, + $70, $98, $30, $60, $F8, $00, $00, $00, + $00, $00, $3C, $3C, $3C, $3C, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00 + ); + +{$F+} + procedure Print_8x8_Mono( x, y : Int; c : char ); + var + offset, i : Int; + bitm : PByte; + begin + offset := x + y*Vio_ScanLineWidth*8; + bitm := @Font_8x8[ ord(c)*8 ]; + + for i := 0 to 7 do + begin + Vio^[offset] := bitm^[i]; + inc( offset, Vio_ScanLineWidth ); + end; + end; + + procedure Print_8x8_Gray( x, y : Int; c : char ); + var + offset, i, bit : Int; + + bitm : PByte; + begin + offset := ( x + y*Vio_ScanLineWidth )*8; + bitm := @font_8x8[ ord(c)*8 ]; + + for i := 0 to 7 do + begin + bit := $80; + while bit > 0 do + begin + if ( bit and bitm^[i] <> 0 ) then Vio^[offset] := $FF + else Vio^[offset] := $00; + bit := bit shr 1; + inc( offset ); + end; + + inc( offset, Vio_ScanLineWidth-8 ); + end; + + end; +{$F-} + + function Set_Graph_Screen( mode : Int ): boolean; + begin + Set_Graph_Screen := False; + + gcursor_x := 0; + gcursor_y := 0; + + case mode of + + Graphics_Mode_Mono : begin + if not Driver_Set_Graphics(mode) then exit; + gwindow_width := vio_ScanLineWidth; + gwindow_height := vio_Height div 8; + + Print_8x8 := Print_8x8_Mono; + end; + + Graphics_Mode_Gray : begin + if not Driver_Set_Graphics(mode) then exit; + gwindow_width := vio_ScanLineWidth div 8; + gwindow_height := vio_Height div 8; + + Print_8x8 := Print_8x8_Gray; + end; + else + exit; + end; + + Set_Graph_Screen := True; + end; + + + function Restore_Screen : boolean; + begin + gcursor_x := 0; + gcursor_y := 0; + + gwindow_height := 0; + gwindow_width := 0; + + Restore_Screen := Driver_Restore_Mode; + end; + + procedure Display_Bitmap_On_Screen; + begin + Driver_Display_Bitmap( buff, line, col ); + end; + + procedure Goto_XY( x, y : Int ); + begin + gcursor_x := x; + gcursor_y := y; + end; + + procedure Print_Str( str : string ); + var + i : Int; + begin + for i := 1 to length(str) do + begin + case str[i] of + + #13 : begin + gcursor_x := 0; + inc( gcursor_y ); + if gcursor_y > gwindow_height then gcursor_y := 0; + end; + else + Print_8x8( gcursor_x, gcursor_y, str[i] ); + inc( gcursor_x ); + if gcursor_x >= gwindow_width then + begin + gcursor_x := 0; + inc( gcursor_y ); + if gcursor_y >= gwindow_height then gcursor_y := 0; + end + end + end + end; + + procedure Print_XY( x, y : Int; str : string ); + begin + Goto_XY( x, y ); + Print_Str( str ); + end; + +end. + diff --git a/pascal/test/lint.pas b/pascal/test/lint.pas new file mode 100644 index 0000000..45e009e --- /dev/null +++ b/pascal/test/lint.pas @@ -0,0 +1,277 @@ +{***************************************************************************} +{* *} +{* FreeType Font glyph programs checker *} +{* *} +{* *} +{* This small program will load a TrueType font file and try to *} +{* render it at a given point size. *} +{* *} +{* This version will also catch differences between the engine's *} +{* computed advance widths, and the pre-calc values found in the *} +{* "hdmx" table *} +{* *} +{* This source code has been compiled and run under both Virtual Pascal *} +{* on OS/2 and Borland's BP7. *} +{* *} +{***************************************************************************} + +program Abc; + +uses Crt, + Common, +{$IFDEF OS2} + Use32, +{$ENDIF} + FreeType, + TTObjs; + +const + Precis = 64; + Precis2 = Precis div 2; + + PrecisAux = 1024; + + Screen_Width = 640; + Screen_Height = 480; + Screen_Cols = Screen_Width div 8; + Screen_Size = Screen_Cols * Screen_Height; + + Grid_Width = Screen_Width div 8; + Grid_Height = Screen_Height div 8; + Grid_Cols = Grid_Width div 8; + Grid_Size = Grid_Cols * Grid_Height; + + Screen_Center_X = Screen_Width div 2; + Screen_Center_Y = Screen_Height div 2; + + Grid_Center_X = Grid_Width div 2; + Grid_Center_Y = Grid_Height div 2; + + Profile_Buff_Size = 64000; + +var + + res, old_res : integer; + + numPoints, numContours : integer; + + Bitmap_small : TT_Raster_Map; + Bitmap_big : TT_Raster_Map; + + Rotation : integer; (* Angle modulo 1024 *) + + num_glyphs : integer; + + face : TT_Face; + instance : TT_Instance; + glyph : TT_Glyph; + + metrics : TT_Glyph_Metrics; + imetrics : TT_Instance_Metrics; + + props : TT_Face_Properties; + + point_size : integer; + error : TT_Error; + + display_outline : boolean; + hint_glyph : boolean; + scan_type : Byte; + + old_glyph : integer; + + FOut : Text; + +(******************************************************************* + * + * Function : LoadTrueTypeChar + * + * Description : Loads a single glyph into the xcoord, ycoord and + * flag arrays, from the instance data. + * + *****************************************************************) + +Function LoadTrueTypeChar( index : integer; + hint : boolean ) : TT_Error; +var + j, load_flag : integer; + + result : TT_Error; + +begin + if hint then load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph + else load_flag := TT_Load_Scale_Glyph; + + result := TT_Load_Glyph( instance, + glyph, + index, + load_flag ); + + LoadTrueTypeChar := result; +end; + + +procedure Usage; +begin + Writeln('Simple TrueType Glyphs viewer - part of the FreeType project' ); + Writeln; + Writeln('Usage : ',paramStr(0),' size fontname[.ttf] [fontname.. ]'); + Writeln; + Halt(1); +end; + + + +var i: integer; + heure, + min1, + min2, + sec1, + sec2, + cent1, + cent2 : +{$IFDEF OS2} + longint; +{$ELSE} + word; +{$ENDIF} + + C : Char; + + Filename : String; + +label Fin; + +var + Fail : Integer; + PtSize : Integer; + Param : Integer; + code : Integer; + glyphStr : String[4]; + cur_file : Integer; + valid : Boolean; + + Mem0 : Longint; + +label + Lopo; + +begin + + Mem0 := MemAvail; + + TT_Init_FreeType; + + if ParamCount < 2 then Usage; + + val( ParamStr(1), point_size, code ); + if code <> 0 then Usage; + + if ( point_size <= 0 ) then + begin + Writeln('Invalid argument : pointsize must be >= 1'); + Usage; + end; + + Expand_WildCards( 2, '.ttf' ); + + for cur_file := 0 to num_arguments-1 do + begin + + FileName := arguments[cur_file]^; + + if Pos('.',FileName) = 0 then FileName:=FileName+'.TTF'; + + Write( MemAvail:6, ' ' ); + + error := TT_Open_Face( filename, face ); + + i := length(FileName); + while (i > 1) and (FileName[i] <> '\') do dec(i); + FileName := Copy( FileName, i+1, length(FileName) ); + + Write( cur_file:3,' ', filename:12, ': ' ); + + if error <> TT_Err_Ok then + begin + Writeln( 'could not open file, error code = ', error ); + goto Lopo; + end; + + TT_Get_Face_Properties( face, props ); + num_glyphs := props.num_Glyphs; + + error := TT_New_Glyph( face, glyph ); + if error <> TT_Err_Ok then + begin + Writeln( 'could not create glyph, error code = ', + error ); + goto Lopo; + end; + + error := TT_New_Instance( face, instance ); + if error <> TT_Err_Ok then + begin + Writeln( 'could not create instance, error code = ', + error ); + goto Lopo; + end; + + error := TT_Set_Instance_PointSize( instance, point_size ); + if error <> TT_Err_Ok then + begin + Writeln( 'could not set point size, error code = ', error ); + goto Lopo; + end; + + Fail := 0; + for i := 0 to num_glyphs-1 do + begin + error := LoadTrueTypeChar( i, true ); + if error <> TT_Err_Ok then + begin + inc( Fail ); + if Fail < 10 then + Writeln( 'error hinting glyph ', i, ', code = ', + error ); + end; + +{$IFDEF RIEN} + with PGlyph(glyph.z)^ do + begin + if (precalc_width >= 0) and + (precalc_width <> computed_width) then + begin + Write( i:5,' hdmx = ',precalc_width:3 ); + Write( ', engine = ',computed_width ); + if is_composite then Write( ' (composite)' ); + Writeln; + end + end; +{$ENDIF} + + end; + + if Fail >= 10 then + Writeln( 'there were ',Fail,' failed glyphs' ); + + if Fail = 0 then + Writeln( 'ok' ); + + Lopo: + + TT_Close_Face( face ); + + end; + + Fin: + + Writeln('Memory consumed by lint = ', Mem0 - MemAvail ); + + TT_Done_FreeType; + + Writeln('Memory leaked after engine termination = ', Mem0 - MemAvail ); + +end. + + diff --git a/pascal/test/stacktv.pas b/pascal/test/stacktv.pas new file mode 100644 index 0000000..ef9c05e --- /dev/null +++ b/pascal/test/stacktv.pas @@ -0,0 +1,148 @@ +(* The Turbo Vision Stack Component. Part of the FreeType Debugger *) + +unit StackTV; + +interface + +uses Objects, Views, Drivers, TTTypes, TTObjs, TTDebug; + +type + + { TStackView } + + { A Simple stack display } + + PStackView = ^TStackView; + TStackView = object( TListViewer ) + constructor Init( var Bounds : TRect; + aexec : PExec_Context; + AVScrollBar : PScrollBar ); + + procedure HandleEvent( var Event : TEvent ); virtual; + procedure Draw; virtual; + procedure Update; + + private + exec : PExec_Context; + end; + + { TStackWindow } + + PStackWindow = ^TStackWindow; + TStackWindow = object( TWindow ) + V : PScrollBar; + S : PStackView; + constructor Init( var Bounds : TRect; + exec : PExec_Context ); + end; + +implementation + +{$I DEBUGGER.INC} + +{ TStackView } + +constructor TStackView.Init; +begin + inherited Init( Bounds, 1, nil, AVScrollBar ); + exec := aexec; + + GrowMode := gfGrowHiX or gfGrowHiY; + DragMode := dmDragGrow or dmLimitLoX or dmLimitLoY; + EventMask := EventMask or evWave; + + SetRange( exec^.stackSize ); +end; + +procedure TStackView.Draw; +const + Colors : array[0..1] of Byte = ($1E,$3E); +var + B : TDrawBuffer; + Color : Byte; + I, Item : Int; + S : String[16]; +begin + Color := Colors[0]; + + if exec^.top <= Size.Y then Item := Size.Y-1 + else Item := exec^.top-1-TopItem; + + for I := 0 to Size.Y-1 do + begin + + MoveChar( B, ' ', Color, Size.X ); + + if Item < exec^.top then + begin + S := ' ' + Hex16( Item ) + ': ' + Hex32( exec^.stack^[Item] ); + MoveStr( B, S, Color ); + end; + + WriteLine( 0, I, Size.X, 1, B ); + dec( Item ); + end; + +end; + + +procedure TStackView.Update; +begin + FocusItem( 0 ); + DrawView; +end; + +procedure TStackView.HandleEvent; +var + Limits : TRect; + Mini, Maxi : Objects.TPoint; +begin + case Event.What of + + evWave : case Event.Command of + + cmReFocus : Update; + + end; + end; + + inherited HandleEvent( Event ); + + case Event.Command of + + cmResize: begin + Owner^.GetExtent(Limits); + SizeLimits( Mini, Maxi ); + DragView(Event, DragMode, Limits, Mini, Maxi ); + ClearEvent(Event); + end; + end; + +end; + + + +{ TStackWindow } + +constructor TStackWindow.Init; +var + R : TRect; +begin + inherited Init( Bounds, 'Pile', wnNoNumber ); + + GetExtent( Bounds ); + R := Bounds; + R.A.X := R.B.X-1; + inc( R.A.Y ); + dec( R.B.Y ); + New( V, Init(R) ); + Insert( V ); + + R := Bounds; + R.Grow(-1,-1); + New( S, Init( R, exec, V )); + + Insert( S ); +end; + +end. diff --git a/pascal/test/statetv.pas b/pascal/test/statetv.pas new file mode 100644 index 0000000..bc27ce7 --- /dev/null +++ b/pascal/test/statetv.pas @@ -0,0 +1,196 @@ +unit StateTV; + +interface + +uses Objects, Views, Drivers, TTTypes, TTObjs, TTDebug; + +{$I DEBUGGER.INC} + +type + + { State Viewer } + + { A simple TView to show the current graphics state } + + PStateViewer = ^TStateViewer; + TStateViewer = object( TView ) + + constructor Init( var Bounds : TRect; + aexec : PExec_Context ); + + procedure HandleEvent( var Event : TEvent ); virtual; + procedure Draw; virtual; + + private + exec : PExec_Context; + end; + + { PStateWindow } + + PStateWindow = ^TStateWindow; + TStateWindow = object( TWindow ) + stateView : PStateViewer; + constructor Init( var Bounds : TRect; + exec : PExec_Context ); + end; + +implementation + +{ TStateViewer } + +constructor TStateViewer.Init; +begin + inherited Init( Bounds ); + exec := aexec; + Options := Options or ofSelectable; + EventMask := EventMask or evWave; +end; + +procedure TStateViewer.Draw; +var + B : TDrawBuffer; + S : String; + Color : Int; + n : Int; +begin + Color := $1E; + n := 0; + MoveChar( B, ' ', Color, Self.Size.X ); + + S := ' Loop ' + Hex16( exec^.GS.loop ); + + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Auto_flip '; + if exec^.GS.auto_flip then S := S + ' Yes' + else S := S + ' No'; + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Dual ('+Hex16(exec^.GS.dualVector.x)+','+ + Hex16(exec^.GS.dualVector.y)+')'; + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Projection ('+Hex16(exec^.GS.projVector.x)+','+ + Hex16(exec^.GS.projVector.y)+')'; + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Freedom ('+Hex16(exec^.GS.freeVector.x)+','+ + Hex16(exec^.GS.freeVector.y)+')'; + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Gep0 ' + Hex8( exec^.GS.gep0 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Gep1 ' + Hex8( exec^.GS.gep1 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Gep2 ' + Hex8( exec^.GS.gep2 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Ins_Control ' + Hex8( exec^.GS.instruct_control ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Rounding ' + Hex8( exec^.GS.round_state ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Min_Distance ' + Hex32( exec^.GS.minimum_distance ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Rp0 ' + Hex8( exec^.GS.rp0 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Rp1 ' + Hex8( exec^.GS.rp1 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Rp2 ' + Hex8( exec^.GS.rp2 ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Ctrl_Val_Cutin ' + Hex32( exec^.GS.control_value_cutin ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Sngl_Width_Cutin ' + Hex32( exec^.GS.single_width_cutin ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Sngl_Widht_Value ' + Hex32( exec^.GS.single_width_value ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + S := ' Scan_type ' + Hex8( exec^.GS.scan_type ); + MoveStr( B, S, Color ); + WriteLine( 0, n, Self.Size.X, 1, B ); + inc( n ); + + MoveChar( B, ' ', Color, Self.Size.X ); + WriteLine( 0, n, Self.Size.X, Size.Y-n, B ); + +end; + +procedure TStateViewer.HandleEvent; +var + Limits : TRect; + Mini, Maxi : Objects.TPoint; +begin + + inherited HandleEvent( Event ); + + case Event.What of + + evWave : case Event.Command of + + cmReFocus : DrawView; +(* + cmResize: begin + Owner^.GetExtent(Limits); + SizeLimits( Mini, Maxi ); + DragView(Event, DragMode, Limits, Mini, Maxi ); + ClearEvent(Event); + end; +*) + end; + end; +end; + + +constructor TStateWindow.Init; +begin + inherited Init( Bounds, 'State', wnNoNumber ); + GetExtent( Bounds ); + Bounds.Grow(-1,-1); + New( StateView, Init( Bounds, exec ) ); + Insert( StateView ); +end; + +end. diff --git a/pascal/test/timer.pas b/pascal/test/timer.pas new file mode 100644 index 0000000..d61905e --- /dev/null +++ b/pascal/test/timer.pas @@ -0,0 +1,377 @@ +{***************************************************************************} +{* *} +{* FreeType Performance Timer *} +{* *} +{* *} +{* This source code has been compiled and run under both Virtual Pascal *} +{* on OS/2 and Borland's BP7. *} +{* *} +{* *} +{* The C scan-line converter has been highly optimized, unlike the *} +{* Pascal one which is still 'aged'. Don't be surprised to see drastic *} +{* performance differences then.. *} +{* *} +{***************************************************************************} + +program Timer; + +uses +{$IFDEF OS2} + Use32, +{$ENDIF} + Crt, + Dos, (* for GetTime *) + GMain, + GEvents, + GDriver, + FreeType, + + TTError, (* for CheckError *) + TTTypes; (* for commodity types *) + +{$DEFINE VISUAL} + +{ $DEFINE DEBUG} + +{$IFDEF VISUAL} +{&PMTYPE NOVIO} +{$ENDIF} + +const + Precis = 64; + Precis2 = Precis div 2; + + PrecisAux = 1024; + + Centre_X : int = 320; + Centre_Y : int = 225; + + Max_Glyphs = 512; + +var + xC : TT_PCoordinates; + yC : TT_PCoordinates; + Fl : TT_PTouchTable; + + cons : PUShort; + + outlines : array[0..Max_Glyphs-1] of TT_Outline; + + lastp : int; + lastc : int; + + res : int; + + numPoints, numContours : int; + + Bit : TT_Raster_Map; + + Rotation : int; (* Angle modulo 1024 *) + + num_glyphs : int; + + gray_level : Boolean; + + face : TT_Face; + instance : TT_Instance; + glyph : TT_Glyph; + + metrics : TT_Glyph_Metrics; + imetrics : TT_Instance_Metrics; + + props : TT_Face_Properties; + + old_glyph : int; + cur_glyph : int; + tot_glyph : int; + + grayLines : array[0..2048] of Byte; + + error : TT_Error; + + +Procedure InitRows; +var + i: integer; + P: Pointer; +begin + + if gray_level then + begin + Bit.rows := 200; + Bit.cols := 320; + Bit.width := 320*2; + Bit.flow := TT_Flow_Down; + Bit.size := 320*200; + end + else + begin + Bit.rows := 450; + Bit.cols := 80; + Bit.width := 640; + Bit.flow := TT_Flow_Down; + Bit.size := 80*450; + end; + + GetMem( Bit.buffer, Bit.size ); + if Bit.buffer = NIL then + begin + Writeln('ERREUR:InitRows:Not enough memory to allocate BitMap'); + halt(1); + end; + + FillChar( Bit.Buffer^, Bit.Size, 0 ); +end; + + +Procedure ClearData; +var i: integer; +begin + FillChar( Bit.Buffer^, Bit.Size, 0 ); +end; + + +procedure Preload_Glyphs( var start : Int ); +var + i, j, fin, np, nc : integer; + outline : TT_Outline; + +begin + fin := start + Max_Glyphs; + if fin > num_glyphs then fin := num_glyphs; + + tot_glyph := fin-start; + + cur_glyph := 0; + lastp := 0; + lastc := 0; + + {$IFNDEF VISUAL} + Write('Loading ', fin-start,' glyphs '); + {$ENDIF} + + for i := start to fin-1 do + begin + + if TT_Load_Glyph( instance, + glyph, + i, + TT_Load_Default ) = TT_Err_Ok then + begin + TT_Get_Glyph_Outline( glyph, outline ); + + TT_New_Outline( outline.n_points, + outline.n_contours, + outlines[cur_glyph] ); + + outline.high_precision := false; + outline.second_pass := false; + + TT_Copy_Outline( outline, outlines[cur_glyph] ); + + + TT_Translate_Outline( outlines[cur_glyph], + vio_Width*16, + vio_Height*16 ); + inc( cur_glyph ); + end; + + end; + + start := fin; +end; + + + +function ConvertRaster(index : integer) : boolean; +begin + if gray_level then + error := TT_Get_Outline_Pixmap( outlines[index], Bit ) + else + error := TT_Get_Outline_Bitmap( outlines[index], Bit ); + + ConvertRaster := (error <> TT_Err_Ok); +end; + + +procedure Usage; +begin + Writeln('Simple TrueType Glyphs viewer - part of the FreeType project' ); + Writeln; + Writeln('Usage : ',paramStr(0),' FontName[.TTF]'); + Halt(1); +end; + + +function Get_Time : LongInt; +var + heure, + min, + sec, + cent : +{$IFDEF OS2} + longint; +{$ELSE} + word; +{$ENDIF} +begin + GetTime( heure, min, sec, cent ); + Get_Time := 6000*longint(min) + 100*longint(sec) + cent; +end; + + + +var i : integer; + Filename : String; + Fail : Int; + T, T0, T1 : Long; + + start : Int; + +begin + xC := NIL; + yC := NIL; + Fl := NIL; + + TT_Init_FreeType; + + if ParamCount = 0 then Usage; + + gray_level := ParamStr(1)='-g'; + + if gray_level then + if ParamCount <> 2 then Usage else + else + if ParamCount <> 1 then Usage; + + if gray_level then Filename := ParamStr(2) + else Filename := ParamStr(1); + + if Pos('.',FileName) = 0 then FileName:=FileName+'.TTF'; + + error := TT_Open_Face( filename, face ); + + if error <> TT_Err_Ok then + begin + Writeln('ERROR: Could not open ', FileName ); + Check_Error(error); + end; + + TT_Get_Face_Properties( face, props ); + + num_glyphs := props.num_Glyphs; + + i := length(FileName); + while (i > 1) and (FileName[i] <> '\') do dec(i); + + FileName := Copy( FileName, i+1, length(FileName) ); + + error := TT_New_Glyph( face, glyph ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR : Could not get glyph' ); + Check_Error(error); + end; + + i := props.max_Points * num_glyphs; + + GetMem( fl, i ); + i := i * sizeof(Long); + + GetMem( xC, i ); + GetMem( yC, i ); + + i := props.max_Contours * num_glyphs; + + GetMem( cons, i*sizeof(UShort) ); + + error := TT_New_Instance( face, instance ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR: Could not open face instance from ', Filename ); + Check_Error(error); + end; + + error := TT_Set_Instance_PointSize( instance, 400 ); + if error <> TT_Err_Ok then + begin + Writeln('ERROR: Could set pointsize' ); + Check_Error(error); + end; + + Rotation := 0; + Fail := 0; + + InitRows; + + {$IFDEF VISUAL} + if gray_level then + begin + if not Set_Graph_Screen( Graphics_Mode_Gray ) then + Panic1( 'could not set grayscale graphics mode' ); + end + else + begin + if not Set_Graph_Screen( Graphics_Mode_Mono ) then + Panic1( 'could not set mono graphics mode' ); + end; + + {$ENDIF} + + start := 0; + + T := Get_Time; + T1 := 0; + + while start < num_glyphs do + begin + + Preload_Glyphs(start); + + {$IFNDEF VISUAL} + write('... '); + {$ENDIF} + + T0 := Get_Time; + + for cur_glyph := 0 to tot_glyph-1 do + begin + if not ConvertRaster(cur_glyph) then + {$IFDEF VISUAL} + begin + Display_Bitmap_On_Screen( Bit.Buffer^, Bit.rows, Bit.cols ); + ClearData; + end + {$ELSE} + begin + end + {$ENDIF} + else + inc( Fail ); + end; + + T0 := Get_Time - T0; + writeln( T0/100:0:2,' s' ); + + inc( T1, T0 ); + + for cur_glyph := 0 to tot_glyph-1 do + TT_Done_Outline( outlines[cur_glyph] ); + end; + + T := Get_Time - T; + + {$IFDEF VISUAL} + Restore_Screen; + {$ENDIF} + + writeln; + writeln('Render time : ', T1/100:0:2,' s' ); + writeln('Total time : ', T /100:0:2,' s'); + writeln('Glyphs/second : ', Long(num_glyphs)*100/T1:0:1 ); + writeln('Fails : ',Fail ); +end. + +begin +end. + diff --git a/pascal/test/view.pas b/pascal/test/view.pas new file mode 100644 index 0000000..275e35f --- /dev/null +++ b/pascal/test/view.pas @@ -0,0 +1,523 @@ +{***************************************************************************} +{* *} +{* FreeType Glyph Viewer. *} +{* *} +{* *} +{* This small program will load a TrueType font file and allow *} +{* you to view/scale/rotate its glyphs. Glyphs are in the order *} +{* found within the 'glyf' table. *} +{* *} +{* NOTE : This version displays a magnified view of the glyph *} +{* along with the pixel grid. *} +{* *} +{* This source code has been compiled and run under both Virtual Pascal *} +{* on OS/2 and Borland's BP7. *} +{* *} +{***************************************************************************} + +program View; + +uses Crt, + Common, +{$IFDEF OS2} + Use32, +{$ENDIF} + GMain, + GEvents, + GDriver, + FreeType; + +{&PMTYPE NOVIO} + +{$DEFINE DEBUG} + +const + Precis = 64; + + Precis2 = Precis div 2; + + PrecisAux = 1024; + + Profile_Buff_Size = 32000; + + Max_Files = 1024; + +var + face : TT_Face; + instance : TT_Instance; + glyph : TT_Glyph; + + metrics : TT_Glyph_Metrics; + imetrics : TT_Instance_Metrics; + + props : TT_Face_Properties; + + ymin, ymax, xmax, xmin, xsize : longint; + res, old_res : int; + + numPoints, numContours : int; + + Bit : TT_Raster_Map; + + Rotation : int; (* Angle modulo 1024 *) + + num_glyphs : int; + + error : TT_Error; + gray_level : Boolean; + + display_outline : boolean; + hint_glyph : boolean; + scan_type : Byte; + + old_glyph : int; + cur_glyph : int; + + scale_shift : Int; + + grayLines : array[0..2048] of Byte; + +(******************************************************************* + * + * Function : Set_Raster_Area + * + *****************************************************************) + + procedure Set_Raster_Area; + begin + Bit.rows := vio_Height; + Bit.width := vio_Width; + Bit.flow := TT_Flow_Up; + + if gray_level then + Bit.cols := Bit.width + else + Bit.cols := (Bit.width+7) div 8; + + Bit.size := Bit.rows * Bit.cols; + end; + +(******************************************************************* + * + * Function : Clear_Data + * + *****************************************************************) + + procedure Clear_Data; + begin + if gray_level then + fillchar( Bit.buffer^, Bit.size, gray_palette[0] ) + else + fillchar( Bit.buffer^, Bit.size, 0 ); + end; + +(******************************************************************* + * + * Function : Init_Engine + * + *****************************************************************) + + procedure Init_Engine( maxRes : Int ); + begin + Set_Raster_Area; + GetMem( Bit.buffer, Bit.size ); + Clear_Data; + end; + +(******************************************************************* + * + * Function : Reset_Scale + * + *****************************************************************) + + function Reset_Scale( res : Int ) : Boolean; + begin + error := TT_Set_Instance_CharSize( instance, res*64 ); + Reset_Scale := (error = TT_Err_Ok); + end; + + +(******************************************************************* + * + * Function : LoadTrueTypeChar + * + * Description : Loads a single glyph into the xcoord, ycoord and + * flag arrays, from the instance data. + * + *****************************************************************) + +Function LoadTrueTypeChar( index : integer; + hint : boolean ) : TT_Error; +var + j, load_flag : int; + + result : TT_Error; + +begin + if hint then load_flag := TT_Load_Scale_Glyph or TT_Load_Hint_Glyph + else load_flag := TT_Load_Scale_Glyph; + + result := TT_Load_Glyph( instance, + glyph, + index, + load_flag ); + + LoadTrueTypeChar := result; +end; + + +var + Error_String : String; + ine : Int; + +function Render_ABC( glyph_index : integer ) : boolean; +var + i, j : integer; + + x, y : longint; + + start_x, + start_y, + step_x, + step_y : longint; + + fail : Int; +begin + + Render_ABC := True; + + TT_Get_Instance_Metrics( instance, imetrics ); + + start_x := 4; + start_y := vio_Height - 30 - imetrics.y_ppem; + + step_x := imetrics.x_ppem + 4; + step_y := imetrics.y_ppem + 10; + + x := start_x; + y := start_y; + + fail := 0; + + ine := glyph_index; + while ine < num_glyphs do + begin + + if LoadTrueTypeChar( ine, hint_glyph ) = TT_Err_Ok then + begin + + TT_Get_Glyph_Metrics( glyph, metrics ); + + if gray_level then + TT_Get_Glyph_Pixmap( glyph, Bit, x*64, y*64 ) + else + TT_Get_Glyph_Bitmap( glyph, Bit, x*64, y*64 ); + + inc( x, (metrics.advance div 64) + 1 ); + + if x > vio_Width - 40 then + begin + x := start_x; + dec( y, step_y ); + if y < 10 then + begin + Render_ABC := False; + exit; + end; + end; + end + else + inc( fail ); + + inc(ine); + end; + + Render_ABC := False; +end; + + + +procedure Erreur( s : String ); +begin + Restore_Screen; + Writeln( 'Error : ', s, ', error code = ', error ); + Halt(1); +end; + + +procedure Usage; +begin + Writeln('Simple TrueType Glyphs viewer - part of the FreeType project' ); + Writeln; + Writeln('Usage : ',paramStr(0),' FontName[.TTF]'); + Halt(1); +end; + + + +var + i: integer; + heure, + min1, + min2, + sec1, + sec2, + cent1, + cent2 : +{$IFDEF OS2} + longint; +{$ELSE} + word; +{$ENDIF} + + C : Char; + + Filename : String; + +label Fin; + +var + Fail : Int; + glyphStr : String[4]; + ev : Event; + + Code : Int; + + init_memory, end_memory : LongInt; + + num_args : Integer; + point_size : Integer; + cur_file : Integer; + first_arg : Int; + sortie : Boolean; + valid : Boolean; + errmsg : String; + +label + Lopo; + +begin + TextMode( co80+Font8x8 ); + + TT_Init_FreeType; + + num_args := ParamCount; + + if num_args = 0 then + Usage; + + first_arg := 1; + + gray_level := False; + + if ParamStr(first_arg) = '-g' then + begin + inc( first_arg ); + gray_level := True; + end; + + if first_arg > num_args+1 then + Usage; + + val( ParamStr(first_arg), point_size, Code ); + if Code <> 0 then + point_size := 24 + else + inc( first_arg ); + + Expand_Wildcards( first_arg, '.ttf' ); + + cur_file := 0; + + if num_arguments = 0 then + begin + Writeln('Could not find file(s)'); + Halt(3); + end; + + if gray_level then + begin + if not Set_Graph_Screen( Graphics_Mode_Gray ) then + Erreur( 'could not set grayscale graphics mode' ); + end + else + begin + if not Set_Graph_Screen( Graphics_Mode_Mono ) then + Erreur( 'could not set mono graphics mode' ); + end; + + Init_Engine( 24 ); + + repeat + + valid := True; + + FileName := arguments[cur_file]^; + + if Pos('.',FileName) = 0 then FileName:=FileName+'.TTF'; + + error := TT_Open_Face( filename, face ); + if error <> TT_Err_Ok then + begin + str( error, errmsg ); + errmsg := 'Could not open '+filename+', error code = '+errmsg; + valid := false; + goto Lopo; + end; + + TT_Get_Face_Properties( face, props ); + + num_glyphs := props.num_Glyphs; + + i := length(FileName); + while (i > 1) and (FileName[i] <> '\') do dec(i); + + FileName := Copy( FileName, i+1, length(FileName) ); + + error := TT_New_Glyph( face, glyph ); + if error <> TT_Err_Ok then + Erreur('Could not create glyph container'); + + error := TT_New_Instance( face, instance ); + if error <> TT_Err_Ok then + begin + str( error, errmsg ); + errmsg := 'Could not create instance, error code = '+errmsg; + valid := false; + goto Lopo; + end; + + TT_Set_Instance_Resolutions( instance, 96, 96 ); + + Rotation := 0; + Fail := 0; + res := point_size; + scan_type := 2; + + Reset_Scale( res ); + + Lopo: + + display_outline := true; + hint_glyph := true; + + old_glyph := -1; + old_res := res; + cur_glyph := 0; + + sortie := false; + + Repeat + + if valid then + begin + if Render_ABC( cur_glyph ) then + inc( Fail ) + else + Display_Bitmap_On_Screen( Bit.Buffer^, Bit.rows, Bit.cols ); + + Clear_Data; + + Print_XY( 0, 0, FileName ); + + TT_Get_Instance_Metrics( instance, imetrics ); + + Print_Str(' pt size = '); + Str( imetrics.pointSize div 64:3, glyphStr ); + Print_Str( glyphStr ); + + Print_Str(' ppem = '); + Str( imetrics.y_ppem:3, glyphStr ); + Print_Str( glyphStr ); + + Print_Str(' glyph = '); + Str( cur_glyph, glyphStr ); + Print_Str( glyphStr ); + + Print_XY( 0, 1, 'Hinting (''z'') : ' ); + if hint_glyph then Print_Str('on ') + else Print_Str('off'); + + Print_XY( 0, 2, 'scan type(''e'') : ' ); + case scan_type of + 0 : Print_Str('none '); + 1 : Print_Str('level 1'); + 2 : Print_Str('level 2'); + 4 : Print_Str('level 4'); + 5 : Print_Str('level 5'); + end; + end + else + begin + Clear_Data; + Display_Bitmap_On_Screen( Bit.buffer^, Bit.rows, Bit.cols ); + Print_XY( 0, 0, errmsg ); + end; + + Get_Event(ev); + + case ev.what of + + event_Quit : goto Fin; + + event_Keyboard : case char(ev.info) of + + 'n' : begin + sortie := true; + if cur_file+1 < num_arguments then + inc( cur_file ); + end; + + 'p' : begin + sortie := true; + if cur_file > 0 then + dec( cur_file ); + end; + + 'z' : hint_glyph := not hint_glyph; + + + 'e' : begin + inc( scan_type ); + if scan_type = 3 then scan_type := 4; + if scan_type >= 6 then scan_type := 0; + end; + end; + + event_Scale_Glyph : begin + inc( res, ev.info ); + if res < 1 then res := 1; + if res > 1400 then res := 1400; + end; + + event_Change_Glyph : begin + inc( cur_glyph, ev.info ); + if cur_glyph < 0 then cur_glyph := 0; + if cur_glyph >= num_glyphs + then cur_glyph := num_glyphs-1; + end; + end; + + if res <> old_res then + begin + if not Reset_Scale(res) then + Erreur( 'Could not resize font' ); + old_res := res; + end; + + Until sortie; + + TT_Done_Glyph( glyph ); + TT_Close_Face( face ); + + until false; + + Fin: + Restore_Screen; + + Writeln; + Writeln('Fails : ', Fail ); + + TT_Done_FreeType; +end. + diff --git a/pascal/test/zonetv.pas b/pascal/test/zonetv.pas new file mode 100644 index 0000000..aa6632c --- /dev/null +++ b/pascal/test/zonetv.pas @@ -0,0 +1,222 @@ +{****************************************************************************} +{* *} +{* ZoneTV.PAS *} +{* *} +{* This unit implements a simple TrueType zone points viewer for the *} +{* FREETYPE project debugger. *} +{* *} +{****************************************************************************} + +Unit ZoneTV; + +interface + +uses Objects, Views, Drivers, FreeType, TTTypes, TTTables, TTObjs, TTDebug; + +{$I DEBUGGER.INC} + +type + + { TZoneViewer } + + { This TView is a simple point array viewer } + + PZoneViewer = ^TZoneViewer; + TZoneViewer = object( TListViewer ) + + constructor Init( var Bounds : TRect; + AZone : PGlyph_Zone ); + + procedure Draw; virtual; + procedure HandleEvent( var Event : TEvent ); virtual; + + private + Zone : PGlyph_Zone; { Pointer to the zone being displayed } + Save : TGlyph_Zone; { A copy of the zone to highlight } + { changes } + procedure Copy_Zone; + + end; + + { TCodeWindow } + + PZoneWindow = ^TZoneWindow; + TZoneWindow = object( TWindow ) + ZoneView : PZoneViewer; + constructor Init( var Bounds : TRect; + AZone : PGlyph_Zone ); + end; + +implementation + +{ TZoneViewer } + +constructor TZoneViewer.Init; +var + n : Int; +begin + inherited Init( Bounds, 1, nil, nil ); + + GrowMode := gfGrowHiX or gfGrowHiY; + DragMode := dmDragGrow or dmLimitLoX or dmLimitLoY; + Options := Options or ofSelectable; + EventMask := EventMask or evWave; + + Zone := AZone; + + GetMem( Save.org, zone^.n_points*2*sizeof(Long) ); + GetMem( Save.cur, zone^.n_points*2*sizeof(Long) ); + GetMem( Save.flags, zone^.n_points*sizeof(Byte) ); + + Save.n_points := Zone^.n_points; + Save.n_contours := Zone^.n_contours; + + Copy_Zone; + + SetRange( Save.n_points ); +end; + + +procedure TZoneViewer.Copy_Zone; +var + n : Int; +begin + n := 2*zone^.n_points * sizeof(Long); + + (* Note that we save also the original coordinates, as we're not sure *) + (* that the debugger is debugged ! *) + + move( Zone^.org^, Save.org^, n ); + move( Zone^.cur^, Save.cur^, n ); + move( Zone^.flags^, Save.flags^, zone^.n_points ); +end; + + +procedure TZoneViewer.HandleEvent( var Event : TEvent ); +var + Limits : TRect; + Mini, Maxi : Objects.TPoint; +begin + + inherited HandleEvent(Event); + + Case Event.What of + + evWave : case Event.Command of + + cmNewExecution : Copy_Zone; + + cmRefocus : DrawView; + + end; + + evCommand : case Event.Command of + + cmResize: begin + Owner^.GetExtent(Limits); + SizeLimits( Mini, Maxi ); + DragView(Event, DragMode, Limits, Mini, Maxi ); + ClearEvent(Event); + end; + end; + end; +end; + + +procedure TZoneViewer.Draw; +const + Colors : array[0..3] of byte + = ($30,$3F,$0B,$0E); + Touchs : array[0..3] of Char + = (' ','x','y','b'); + OnOff : array[0..1] of Char + = (' ',':'); +var + I, J, Item : Int; + B : TDrawBuffer; + S : String; + Indent : Int; + Ligne : Int; + + Changed : Boolean; + + Back_Color, + Color : word; + + On_BP : boolean; + BP : PBreakPoint; + +begin + + if HScrollBar <> nil then Indent := HScrollBar^.Value + else Indent := 0; + + with Save do + begin + + for I := 0 to Self.Size.Y-1 do + begin + + MoveChar( B, ' ', Colors[0], Self.Size.X ); + + Item := TopItem + I; + + if (Range > 0) and + ( Focused = Item ) then Back_Color := 2 + else Back_Color := 0; + + if Item < n_points then + begin + + Color := Back_Color; + if ( flags^[item] <> Zone^.flags^[item] ) then inc( Color ); + + S := Hex16( Item ) + ': '; + S[1] := OnOff[Zone^.flags^[item] and 1]; + S[7] := Touchs[(Zone^.flags^[item] and TT_Flag_Touched_Both) shr 1]; + + MoveStr( B, S, Colors[Color] ); + + Color := Back_Color; + if ( org^[item].x <> Zone^.org^[item].x ) then inc( Color ); + + MoveStr ( B[8], Hex32( Zone^.org^[item].x ), Colors[Color] ); + MoveChar( B[16], ',', Colors[0], 1 ); + + Color := Back_Color; + if ( org^[item].y <> Zone^.org^[item].y ) then inc( Color ); + + MoveStr( B[17], Hex32( Zone^.org^[item].y ), Colors[Color] ); + MoveStr( B[25], ' : ', Colors[0] ); + + Color := Back_Color; + if ( cur^[item].x <> Zone^.cur^[item].x ) then inc( Color ); + + MoveStr ( B[28], Hex32( Zone^.cur^[item].x ), Colors[Color] ); + MoveChar( B[36], ',', Colors[0], 1 ); + + Color := Back_Color; + if ( cur^[item].y <> Zone^.cur^[item].y ) then inc( Color ); + + MoveStr( B[37], Hex32( Zone^.cur^[item].y ), Colors[Color] ); + + end; + + WriteLine( 0, I, Self.Size.X, 1, B ); + end; + end; +end; + +{ TZoneWindow } + +constructor TZoneWindow.Init; +begin + inherited Init( Bounds,'Zone',wnNoNumber ); + GetExtent( Bounds ); + Bounds.Grow(-1,-1); + New( ZoneView, Init( Bounds, AZone ) ); + Insert( ZoneView ); +end; + +end. + diff --git a/po/.cvsignore b/po/.cvsignore new file mode 100644 index 0000000..2c68802 --- /dev/null +++ b/po/.cvsignore @@ -0,0 +1,8 @@ +*.gmo +*.mo +Makefile +Makefile.in +POTFILES +cat-id-tbl.c +freetype.pot +stamp-cat-id diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 0000000..a4be8ff --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,216 @@ +# +# +# Makefile for freetype I18n, +# based on the Makefile.in.in that comes with gettext +# +# Erwin Dieterich, 20. 1. 1998 Erwin.Dieterich.ED@Bayer-AG.de +# +# +# +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996 Free Software Foundation, Inc. +# +# 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +PACKAGE = freetype +VERSION = @freetype_version@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = $(prefix)/@DATADIRNAME@ +localedir = @LOCALEDIR@ +gnulocaledir = @LOCALEDIR@ +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = @XGETTEXT@ +MSGMERGE = @MSGMERGE@ + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + + + +all: all-@USE_NLS@ + +all-yes: $(PACKAGE).pot $(CATALOGS) +all-no: + @echo "No support for NLS requested" + +$(PACKAGE).pot: $(POTFILES) + if test -n "$(XGETTEXT)"; then \ + $(XGETTEXT) --default-domain=freetype --directory=$(srcdir)/.. \ + --keyword=_ --files-from=$(srcdir)/POTFILES.in; \ + mv freetype.po freetype.pot; \ + else \ + echo "xgettext not available: $(PACKAGE).pot not updated" 1>&2; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + $(top_srcdir)/mkinstalldirs $(datadir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + case "$$cat" in \ + *.gmo) destdir=$(gnulocaledir);; \ + *) destdir=$(localedir);; \ + esac; \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + dir=$$destdir/$$lang/LC_MESSAGES; \ + $(top_srcdir)/mkinstalldirs $$dir; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + fi; \ + if test -r $$cat.m; then \ + $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + if test -r $(srcdir)/$$cat.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$cat.m \ + $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + true; \ + fi; \ + fi; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + done + rm -f $(gettextsrcdir)/po-Makefile.in.in + +check: all + +dvi info tags TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(PACKAGE).po *.old.po + rm -fr *.o *~ + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.gmo *.msg *.cat.m + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: update-po $(DISTFILES) + dists="$(DISTFILES)"; \ + for file in $$dists; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(PACKAGE).pot + PATH=`pwd`/../src:$$PATH; \ + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \ + mv $$lang.po $$lang.old.po; \ + echo "$$lang:"; \ + if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ + rm -f $$lang.old.po; \ + else \ + echo "msgmerge for $$cat failed!"; \ + rm -f $$lang.po; \ + mv $$lang.old.po $$lang.po; \ + fi; \ + done + +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + sed -e '/^#/d' -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" \ + -e '$$s/\(.*\) \\/\1/' < $(srcdir)/POTFILES.in > POTFILES ) + +Makefile: Makefile.in.in ../config.status POTFILES + cd .. \ + && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..71ce09d --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,10 @@ +# +# List of source files containing translatable strings +# +# +lib/extend/ftxerr18.c +test/fterror.c +test/ftdump.c +test/ftlint.c +test/ftmetric.c +test/ftsbit.c diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000..989a04c --- /dev/null +++ b/po/cs.po @@ -0,0 +1,756 @@ +# Czech messages for FreeType +# Copyright (C) 1998-9 Pavel Kaòkovský +# Pavel Kaòkovský , 1998-9 +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.3\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-08-30\n" +"Last-Translator: Pavel Kaòkovský , 1999\n" +"Language-Team: Czech\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-2\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Úspì¹né volání funkce, ¾ádná chyba." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Neplatný manipulátor písma." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Neplatný manipulátor instance." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Neplatný manipulátor litery." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Neplatný manipulátor znakové mapy." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Neplatná adresa výsledku." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Neplatný index litery." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Neplatný argument." + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "Nelze otevøít soubor." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "Soubor není kolekce písem TrueType." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "Nìkterá z povinných tabulek chybí." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Neplatná horizontální metrika (tabulka HMTX po¹kozena)." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Neplatný formát znakové mapy." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Neplatné rozmìry liter (ppem)." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Neplatná vertikální metrika (tabulka VMTX po¹kozena)." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Neplatný formát souboru." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Neplatná globální data knihovny." + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Pøíli¹ mnoho roz¹íøení." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Roz¹íøení není podporováno." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Neplatný identifikátor roz¹íøení." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "V písmu nejsou obsa¾ena ¾ádná vertikální data." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "Tabulka maximálních hodnot (MAXP) chybí." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "Tabulka HEAD chybí." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "Tabulka HHEA chybí." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "Tabulka pozic liter (LOCA) chybí." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "Tabulka jmen (NAME) chybí." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "Tabulky znakových map (CMAP) chybí." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "Tabulka horizontálních metrik (HTMX) chybí." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "Tabulka OS/2 chybí." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "Tabulka dat pro PostScript (POST) chybí." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "Tabulka liter (GLYF) chybí." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "Nedostatek pamìti." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Neplatná pozice v souboru." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Neplatné ètení ze souboru." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Neplatný pøístup k úseku souboru." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Pøíli¹ mnoho bodù." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Pøíli¹ mnoho kontur." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Neplatná kompozitní litera." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Pøíli¹ mnoho instrukcí." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Neplatný kód operace." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Pøíli¹ málo argumentù." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Pøeteèení zásobníku." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Pøeteèení oblasti instrukcí." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "©patný argument." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "Dìlení nulou." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Pøeteèení oblasti pro ukládání dat." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "Pøeteèení tabulky øídících hodnot (CVT)." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Neplatný odkaz." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Neplatná vzdálenost." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolace mezi body v soumraèné zónì." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "Ladící operace." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "Operace ENDF nalezena na ¹patném místì." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Mimo oblasti instrukcí." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Vnoøené definice funkcí." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Neplatná oblast instrukcí." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Neplatné posunutí." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "Do¹lo k zacyklení bìhem vykonávání instrukcí." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Vnoøené pøístupy k úseku souboru." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "Neplatný seznam vyrovnávací pamìti." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "Nelze najít kontext." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Objekt není v seznamu." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Pøeteèení pamìti rasterizéru." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Rasterizér: záporná vý¹ka." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Rasterizér: neplatná hodnota." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Rasterizér není incializován." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Neplatný formát tabulky kernù (KERN)." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Neplatná tabulka kernù (KERN)." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Neplatný formát tabulky PostScript (POST)." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Neplatná tabulka PostScript (POST)." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Neplatný formát podtabulky TrueType Open." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Neplatná podtabulka TrueType Open." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Jedna èi více liter bìhem prohledávání nenalezena." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Pøíli¹ mnoho vlo¾ených kontextových substitucí." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Neplatný formát tabulky substitucí liter (GSUB)." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Neplatná tabulka substitucí liter (GSUB)." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Neplatný formát tabulky umís»ování liter (GPOS)." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Neplatná tabulka umís»ování liter (GPOS)." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Neznámý kód chyby." + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Zaèátek fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Konec fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "Nelze vytvoøit kontejner liter.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "Nelze vytvoøit instanci.\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "Nelze vytvoøit druhou instanci.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Statistika pamì»ových nárokù:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "objekt písma" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "objekt litery" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "objekt instance" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "objekt provádìcího kontextu" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "celková spotøeba pamìti" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "Chybové hlá¹ení FreeType: %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "polo¾ky v tabulce jmen\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"PostScriptové jméno: %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "kódování map znakù\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "Soubor zøejmì neobsahuje ¾ádnou mapu znakù.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"%hu kódování:\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "kódování %2u: " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "Neznámá hodnota %hu" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "Neznámé" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "test roz¹íøení ftxcmap\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "kódování %2u:\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "první: index litery %hu, kód znaku 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "dal¹í: index litery %hu, kód znaku 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "poslední: glyph index %hu, character code 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Chyba bìhem naèítání tabulky vlo¾ených bitmap.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "tabulka vlo¾ených bimap\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " verze tabulky vlo¾ených bitmap: 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " poèet blokù vlo¾ených bitmap: %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " blok vlo¾ených bitmap %hu/%lu: " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu pixelù, bitová hloubka %hu, litery [%hu..%hu]\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " úsek formátu (%hu:%hu) litery %hu..%hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Chyba bìhem naèítání tabulky GSUB.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "tabulka GSUB\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Chyba bìhem prohledávání seznamu GSUB skriptù.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Chyba pøi pokusu vybrat GSUB skript \"%4.4s\".\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " skript \"%4.4s\" (index %hu):\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" +"Chyba bìhem zkoumání bì¾ného jazykového systému GSUB skriptu \"%4.4s\".\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " bì¾ný jazykový systém:\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Chyba pøi výbìru GSUB vlastnosti \"%4.4s\"\n" +"pro bì¾ný jazykový systém skriptu \"%4.4s\".\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " vlastnost \"%4.4s\" (index %hu; vyhledávání " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "Chyba bìhem zkoumání seznamu jazykù pro GSUB skript \"%4.4s\".\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "Chyba bìhem výbìru jazyka \"%4.4s\" pro GSUB skript \"%4.4s\".\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " jazyk \"%4.4s\" (index %hu):\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " po¾adovaná vlastnost (index %hu; vyhledávání " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Chyba bìhem zkoumání seznamu vlastností\n" +"pro GSUB skript \"%4.4s\", jazyk \"%4.4s\".\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Chyba bìhem výbìru vlastnosti \"%4.4s\"\n" +"pro GSUB skript \"%4.4s\", jazyk \"%4.4s\".\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "" +"Vyhledávací údaje:\n" +"\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr " %hu: typ %hu, pøíznaky 0x%x\n" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "" +"ftdump: jednoduchý výpis obsahu písma TrueType -- souèást projektu FreeType" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Pou¾ití: %s název-písma[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Chyba bìhem inicializace knihovny.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Chyba bìhem inicializace roz¹íøení pro vlo¾ené bitmapy.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Chyba bìhem inicializace roz¹íøení pro substituce liter (GSUB).\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "Nelze nalézt nebo otevøít soubor %s.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Chyba bìhem otevírání souboru %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "ftlint: test instrukcí písma TrueType -- souèást projektu FreeType" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Pou¾ití: %s ppem název-písma[.ttf|.ttc] [název-dal¹ího-písma..]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "Nelze nastavit velikost písma na %d bodù.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Výskyt chyb\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "litera %4d: %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "poèet chyb: 1\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "poèet chyb: %d\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "ftmetric: výpis metrik písma TrueType -- souèást projektu FreeType" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Pou¾ití: %s [volby viz ní¾e] bodová-velikost název-písma[.ttf|.ttc]\n" +"\n" +" -B zobraz rozmìry bitmapy (std: nezobrazuj)\n" +" -c C pou¾ij písmo indexu C z kolekce písem (std: 0)\n" +" -i index index litery (std: 0)\n" +" -r R rozli¹ení R bodù na palec (std: 72 dpi)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Poèet písem v kolekci: %d.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "V kolekci není ¾ádné písmo s indexem %d.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "V souboru písma nejsou vlo¾eny ¾ádné bitmapy.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "Nelze nastavit rozli¹ení zaøízení.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "Nelze inicializovat instanci.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Rozmìry instance: ppemX %d, ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "Nelze vytvoøit kontejner vlo¾ených bitmap.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Nelze naèíst bitmapu pro literu %d.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Rozmìry obrysu" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "Obrys litery\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "" +"ftsbit: výpis bitmap vlo¾ených do písma TrueType -- souèást projektu FreeType" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Pou¾ití: %s ppem název-písma[.ttf|.ttc] [název-dal¹ího-písma..]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "V souboru písma nelze nalézt ¾ádné vlo¾ené bitmapy.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Chyba bìhem naèítání vlo¾ených bitmap.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " litera %d nemá ¾ádnou vlo¾enou bitmapu.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "litera %d = %dx%d pixelù, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "posun = %ld, minBearing = [%ld,%ld]\n" diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..7c8b2a7 --- /dev/null +++ b/po/de.po @@ -0,0 +1,760 @@ +# German messages for FreeType. +# Copyright (C) 1997-1998 Erwin Dieterich +# Erwin Dieterich , 1997-1998. +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.0\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-05-26\n" +"Last-Translator: Werner Lemberg \n" +"Language-Team: German\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Funktionsaufruf erfolgreich." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Ungültiger Schrifthenkel." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Ungültiger Instanzenhenkel." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Ungültiger Glyphhenkel." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Ungültiger Charmaphenkel." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Ungültige Ergebnisadresse." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Ungültiger Glyphindex." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Ungültiger Übergabeparameter" + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "Datei konnte nicht geöffnet werden." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "Datei ist keine TrueType-Collection." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "Eine obligatorische Tabelle fehlt." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Ungültige horizontale Metrik (`hmtx'-Tabelle defekt)." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Ungültiges Format der Zeichenkodierungstabelle." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Ungültiger ppem-Wert." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Ungültige vertikale Metrik (`vmtx'-Tabelle defekt)." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Ungültiges Dateiformat." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Ungültige FreeType-Maschine (engine)." + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Zu viele Erweiterungen." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Erweiterungen nicht unterstützt." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Ungültige Erweiterungs-ID." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "Keine vertikale Informationen in der Schrift." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "`Maximum Profile (maxp)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "`Font Header (head)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "`Horizontal Header (hhea)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "`Index to Location (loca)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "`Naming (name)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "`Character to Glyph Index Mapping (cmap)'-Tabellen fehlen." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "`Horizontal Metrics (hmtx)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "`OS/2'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "`PostScript (post)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "`Glyph (glyf)'-Tabelle fehlt." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "Zu wenig Speicher." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Ungültiger Dateioffset." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Ungültiger Lesezugriff auf Datei." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Ungültiger Speicherrahmenzugriff." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Zu viele Punkte." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Zu viele Konturen." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Ungültiges zusammengesetztes Glyph." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Zu viele Programminstruktionen." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Ungültiger Opcode." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Zu wenig Übergabeparameter." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Stacküberlauf." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Codeüberlauf." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "Falscher Übergabeparameter." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "Division durch Null." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Speicherüberlauf." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "Überlauf der `Control Value (cvt)'-Tabelle." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Ungültige Referenz." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Ungültiger Abstand." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolation von Punkten der Zwielichtzone." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "`DEBUG'-Opcode gefunden." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "`ENDF' in Bytecode-Strom." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Außerhalb des Codebereichs." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Verschachtelte Funktionsdefinitionen." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Ungültiger Codebereich." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Ungültige Verschiebung." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "" +"Unendliche Schleife beim Ausführen\n" +"der Programminstruktionen entdeckt." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Verschachtelter Speicherrahmenzugriff." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "Ungütlige Cacheliste." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "Der Kontext konnte nicht gefunden werden." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Objekt ist nicht aufgeführt." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Überlauf des Rasterpools." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Raster: Negative Höhe gefunden." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Raster: Ungültiger Wert." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Raster nicht initialisiert." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Ungültiges Format der `Kerning (kern)'-Tabelle." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Ungültige `Kerning (kern)'-Tabelle." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Ungültiges Format der `PostScript (post)'-Tabelle." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Ungültige `PostScript (post)'-Tabelle." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Ungültiges Format einer TrueType-Open-Subtabelle." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Ungültige TrueType-Open-Subtabelle." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Glyph(en) von Lookup-Prozedur nicht erfaßt." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Zu viele verschachtelte Kontext-Substitutionen." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Ungültiges Format der `glyph substitution (GSUB)'-Tabelle." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Ungültige `glyph substitution (GSUB)'-Tabelle." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Ungültiges Format der `glyph positioning (GPOS)'-Tabelle." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Ungültige `glyph positioning (GPOS)'-Tabelle." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Ungültige Fehler-ID." + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Beginn von fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Ende von fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "Konnte den Glyphcontainer nicht erzeugen.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "Konnte die Instanz nicht erzeugen.\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "Konnte die zweite Instanz nicht erzeugen.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Speicherabdruck-Statistik:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "Schriftobjekt" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "Glyphobjekt" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "Instanzobjekt" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "Ausführbares Kontextobjekt" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "Gesamtverbrauch an Speicher" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "FreeType Fehlermeldung: %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "Einträge in der `name'-Tabelle der Schrift\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"PostScript-Name: %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "Zeichenkodierungstabellen\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "Diese Datei enthält anscheinend keine `cmap'-Tabelle.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"Es gibt %hu Kodierungen:\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "Kodierung %2u: " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "Unbekannter Wert %hu" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "Unbekannt" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "Test von ftxcmap\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "Kodierung %2u:\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "Erster Eintrag: Glyphindex %hu, Zeichenkode 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "Nächster Eintrag: Glyphindex %hu, Zeichenkode 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "Letzter Eintrag: Glyphindex %hu, Zeichenkode 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Fehler beim Laden der `embedded bitmaps'-Tabelle.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "`embedded bitmap'-Tabelle\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " Version der `embedded bitmap'-Tabelle: 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " Anzahl der eingebetteten Bitmapsätze: %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " Bitmapsatz %hu/%hu: " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu Pixel, Tiefe %hu Bit, Glyphbereich [%hu-%hu]\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " Bereichsformat (%hu:%hu) Glyphen %hu-%hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Fehler beim Laden der `GSUB'-Tabelle.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "`GSUB'-Tabelle\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Fehler bei Abfrage der GSUB Schriftenliste.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Fehler bei Auswahl der GSUB Schrift `%4.4s'.\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " Schrift `%4.4s' (Index %hu):\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" +"Fehler bei Abfrage der GSUB-Standardsprachenwerte für Schrift `%4.4s'.\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " Standardsprachenwerte:\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Fehler bei Auswahl des GSUB-Merkmals `%4.4s'\n" +"für Standardsprachenwert der Schrift `%4.4s'.\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " Merkmal `%4.4s' (Index %hu; Lookup " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "Fehler bei Abfrage der GSUB-Sprachenliste für Schrift `%4.4s'.\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "Fehler bei Auswahl der GSUB-Sprache `%4.4s' für Schrift `%4.4s'.\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " Sprache `%4.4s' (Index %hu):\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " Benötigtes Merkmal: Index %hu (Lookup " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Fehler bei Abfrage der GSUB-Merkmaltabelle\n" +"für Schrift `%4.4s', Sprache `%4.4s'.\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Fehler bei Auswahl des GSUB-Merkmals `%4.4s'\n" +"für Schrift `%4.4s', Sprache `%4.4s'.\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "" +"Lookups:\n" +"\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr " %hu: Typ %hu, Flag 0x%x\n" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "ftdump: Ein einfacher TrueType Dumper -- Teil des FreeType-Projekts" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Verwendung: %s Fontname[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Fehler beim Starten von FreeType.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Fehler bei Initialisierung der Erweiterung für eingebettete Bitmaps.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Fehler beim Starten der GSUB-Erweiterung.\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "Datei `%s' konnte nicht gefunden oder geöffnet werden.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Fehler beim Öffnen von %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" +"ftlint: Ein einfacher TTF Instruktionen-Tester -- Teil des FreeType-Projekts" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Verwendung: %s ppem Fontname[.ttf|.ttc] [Fontname2..]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "Konnte die Schriftgröße nicht auf %d Punkt setzen.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Fehler bei\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "Glyph %4u: %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "1 mal gescheitert.\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "%d mal gescheitert.\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "" +"ftmetric: Ein einfacher TTF Metrik/Glyph-Dumper -- Teil des FreeType-Projekts" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Verwendung: %s [Optionen s.u.] Punktgröße Fontname[.ttf|.ttc]\n" +"\n" +" -B zeige Metriken von eingebetteten Bitmaps (Standardwert: nein)\n" +" -c C verwende den `C'ten Fontindex der TrueType-Collection\n" +" (Standardwert: 0)\n" +" -i Index Glyphindex (Standardwert: 0)\n" +" -r R verwende Auflösung `R' dpi (Standardwert: 72)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Es gibt %d Fonts in dieser TrueType-Collection.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "In dieser Fontdatei gibt es keine Collection mit Index %d.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "Konnte keine eingebetteten Bitmaps in Fontdatei finden.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "Konnte die Geräteauflösung nicht setzen.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "Konnte die Instanz nicht neu setzen.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Instanzmetriken: ppemX %d, ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "Konnte den Glyphcontainer für Bitmaps nicht erzeugen.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Kann Bitmap für Glyph %d nicht laden.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Vektormetriken" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "Vektorglyph\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "" +"ftsbit: Ein einfacher TrueType `sbit' Dumper -- Teil des FreeType-Projekts" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Verwendung: %s ppem Fontname[.ttf|.ttc] Glyphindex [Glyphindex2..]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "Konnte keine eingebetteten Bitmaps in Fontdatei finden.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Fehler beim Laden von eingebettete Bitmaps.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " keine Bitmap für Glyph %d.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "Glyphindex %d = %dx%d Pixel, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "Vorschubbreite = %ld, `minBearing' = [%ld,%ld]\n" diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..f502c2c --- /dev/null +++ b/po/es.po @@ -0,0 +1,762 @@ +# Spanish messages for FreeType. +# Copyright (C) 1998-99 Miguel A. Pérez Valdenebro +# Miguel A. Pérez Valdenebro , 1998. +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.3\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-09-01\n" +"Last-Translator: \n" +"Language-Team: Spanish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Éxito en la llamada a función." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Ticket de diseño inválido." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Ticket de instancia inválido." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Ticket de glifo inválido." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Ticket de codificación inválido." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Dirección del resultado inválida." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Índice de glifo inválido." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Argumento inválido." + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "No se puedo abrir el fichero." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "El fichero no es una colección TrueType." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "No se encuentra une tabla obligatoria." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Dimensiones horizontales (tabla `hmtx') incorrectas." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Formato de codificación inválido." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Tamaño en pixel invalido." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Dimensiones verticales (tabla `vmtx') incorrectas." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Formato de fichero inválido." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Instancia de la biblioteca incorrecta." + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Demasiadas extensiones (max:8)." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Extensión no soportada." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Identificador de extensión inválido." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "Placa sin datos verticales." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "No se encuentra la tabla `maxp'." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "No se encuentra la cabecera (head) de la placa." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "No se encuentra la cabecera para la horizontal (hhea)." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "No se encuentra la tabla de los posiciones (loca)." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "No se encuentra la tabla de los nombres (name)." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "" +"No se encuentra la tabla de correspondencia de carácter a glifo (cmap)." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "No se encuentra la tabla de dimensiones horizontales (hmtx)." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "No se encuentra la tabla `OS/2'." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "No se encuentra la tabla PostScript (post)." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "No se encuentra los glifos (tabla `glyf')." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "No hay suficiente memoria." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Dirección en el fichero inválido." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Lectura de fichero incorrecta." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Ventana de acceso inválida." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Demasiados puntos de control." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Demasiados contornos." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Glifo compuesto inválido." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Demasiadas instrucciones." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Código de operación inválido." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Hace falta más argumentos." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Desbordamiento de pila." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Desbordamiento de código." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "Argumento incorrecto." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "División por cero." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Desbordamiento de capacidad en el almacen." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "Desbordamiento de capacidad (tabla CVT)." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Referencia incorrecta." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Distancia incorrecta." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolación de marcas (puntos de referencia)." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "Se ha encontrado la instrucción `DEBUG'." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "Se ha encontrado `ENDF' en el programa de un glifo." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Demasiados espacios de ejecución (code ranges)." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Definiciones de funciones encajadas." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Espacio de ejecución (code range) incorrecto." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Desplazamiento inválido." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "" +"Se ha encontrado bucle sin fin durante la ejecución de las instrucciones." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Ventanas de acceso encajadas." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "Lista de `cache' inválida." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "No se puede encontrar el contexto." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Este objeto no es encadenado en el `cache'." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Tramador: Desbordamiento de memoria." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Tramador: altura negativa." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Tramador: valor erroneo." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Tramador no inicializado." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Formato de la tabla `kern' incorrecto." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Tabla `kern' inválida." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Formato de tabla PostScript (post) incorrecto." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Tabla PostScript (post) inválida." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Formato de la tabla TrueType Open incorrecto." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Tabla TrueType Open inválida." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Estos glifos no existen en las tablas de busqueda (lookups)." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Demasiados cambios contextuales encajados." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Formato de la tabla de cambios de glifos (GSUB) incorrecto." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Tabla de cambios de glifos (GSUB) inválida." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Formato de la tabla de posiciones de los glifos (GPOS) incorrecto." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Tabla de posiciones de los glifos (GPOS) inválida." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Número de Error Inválido." + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Inicio de fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Fin de fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "No se puede crear una caja de glifo.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "No se puede crear una instancia.\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "No se puede crear una segunda instancia.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Estadísticas de asignación de memoria:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "objeto diseño" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "objeto glifo" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "objeto instancia" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "objeto contexto de calculo" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "uso total de memoria" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "Mensaje de error FreeType: %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "Entradas en la tabla de nombres\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"Nombre de la PostScript: %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "Codificaciones del mapa de caracteres\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "La placa no parece tener ninguna tabla de codificación.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"Hay %hu codificaciones:\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr " codificación %2u: " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "Desconocido %hu" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "Desconocido" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "Muestra de ftxcmap\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "Codificación %2u:\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "primero: glifo índice %hu, codigo de carácter 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "siguiente: glifo índice %hu, codigo de carácter 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "ultimo: glifo índice %hu, codigo de carácter 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Error durante la recuperación de los bitmaps.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "Tabla de bitmaps\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " version de la tabla de bitmap: 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " número de tamaños de bitmaps: %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " tamaño %hu en %lu: " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu pixels, en %hu bits, glifos [%hu...%hu]\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " formato intervalo (%hu:%hu) glifos %hu...%hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Error durante la creación de la tabla GSUB.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "Table de cambios de glifos (GSUB)\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Error durante la busqueda de la lista de las escrituras en GSUB.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Error durante la selección de la escritura `%4.4s' en GSUB.\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " escritura `%4.4s' (índice %hu):\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" +"Error durante la busqueda en GSUB de las informaciones\n" +"relativas a las lenguas estandar de la escritura `%4.4s'.\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " lenguas estandar:\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Error durante la selección de la información `%4.4s' en GSUB\n" +"para las lenguas estandar de la escritura `%4.4s'.\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " información `%4.4s' (índice %hu: tabla de busqueda " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "" +"Error durante la busqueda de las lenguas de la escritura `%4.4s' en GSUB.\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "" +"Error durante la selección de la lengua `%4.4s' para `%4.4s' en GSUB.\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " lengua `%4.4s' (índice %hu):\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " información obligatoria índice %hu (tabla de busqueda " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Error durante la busqueda en GSUB de las informaciones\n" +"relativas a la escritura `%4.4s', lengua `%4.4s'.\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Error durante la selección de la información `%4.4s'\n" +"relativa a la escritura `%4.4s', lengua `%4.4s' en GSUB.\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "Tabla de busqueda:\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr " %hu: tipo %hu, indicador 0x%x\n" + +# +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "" +"ftdump: información sobre placas TrueType -- parte del proyecto FreeType" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Uso: %s nombre_de_la_placa[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Error durante la inicialización de la biblioteca.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Error durante la inicialización de la extensión `bitmap'.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Error durante la inicialización de la extensión `GSUB'.\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "No se puede encontrar o abrir el fichero %s.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Error abriendo %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" +"ftlint: verificador de instrucciones TrueType -- parte del proyecto FreeType" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Uso: %s ppem nombre_de_la_placa[.ttf|.ttc] [nombre2...]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "No se puede asignar el tamaño del punto a %d.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Error con\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "glifo %4u: %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "1 error.\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "%d errores.\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "" +"ftmetric: información sobre dimensiones TrueType -- parte del proyecto " +"FreeType" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Uso: %s [optiones] ppem nombre_de_la_placa[.ttf|.ttc]\n" +"\n" +" -B muestra dimensiones de los sbit's (default: no)\n" +" -c C usa (C+1)ª placa de la collección TrueType (default: 1ª)\n" +" -i index muestra esto glifo (default: primero glifo)\n" +" -r R usa resolución R en dpi (default: 72)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Hay %d placas en esta collección.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "No hay placa con índice %d en esto fichero.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "No hay bitmaps en esto fichero.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "No se puede poner esta resolución.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "No se puede inicializar la instancia.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Dimensiones: ppemX %d, ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "No se puede crear un contenedor de bitmap.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Ne se puede crear un bitmap para el glifo %d.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Dimensiones del contorno" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "Glifo utilizando el contorno\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "ftsbit: bitmaps de una placa TrueType -- parte del proyecto FreeType" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Uso: %s ppem nombre_de_font[.ttf|.ttc] índice_de_glifo [índice2...]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "No se puede encontrar bitmaps en esto fichero.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Error durante la lectura de los bitmaps.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " no bitmap para el glifo %d.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "glifo índice %d = %dx%d pixels, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "`advance' = %ld, `bearings' = [%ld,%ld]\n" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..7a6af8b --- /dev/null +++ b/po/fr.po @@ -0,0 +1,752 @@ +# French messages for FreeType, without accents. +# Copyright (C) 1998-99 David Turner +# David Turner , 1998 +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.3\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-09-01 20:00+0200\n" +"Last-Translator: David Turner \n" +"Language-Team: French\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=us-ascii\n" +"Content-Transfer-Encoding: 7bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Appel de fonction reussi, pas d'erreur." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Mauvais handle d'oeil (face)." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Mauvais handle d'instance." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Mauvais handle de glyphe." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Mauvais handle d'encodage (charmap)." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Mauvaise adresse de resultat." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Numero de glyphe incorrect." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Argument incorrect." + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "Le fichier n'a pas pu etre ouvert." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "Ce fichier n'est pas une collection." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "Il manque une table critique." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Metriques horizontales (table `hmtx') incorrectes." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Format d'encodage (charmap) invalide." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Taille en pixels incorrecte." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Metriques verticales (table `vmtx') incorrectes." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Format de fichier invalide." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Mauvaise instance de bibliotheque (engine)" + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Trop d'extensions utilisees (max: 8)." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Extensions non disponibles." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Mauvais numero d'extension." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "Pas de donnees verticales dans cette police." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "Il manque la table `maxp'." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "Il manque l'en-tete de police (head)." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "Il manque l'en-tete pour l'horizontale (hhea)." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "Il manque les index de glyphes (table `loca')." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "Il manque la table des noms (name)." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "Il manque la table des encodages (cmap)." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "Il manque les metriques horizontales (hmtx)." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "Il manque la table `OS/2'." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "Il manque la table Postscript (post)." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "Il manque les glyphes (table `glyf')." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "Pas assez de memoire." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Adresse dans le fichier incorrecte." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Lecture du fichier impossible." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Fenetre d'access incorrecte." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Trop de points." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Trop de contours." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Glyphe compose invalide." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Trop d'instructions." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Code-operation invalide." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Il manque un ou des arguments." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Debordement de la pile." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Debordement dans le code." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "Mauvais argument." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "Division par zero." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Depassement de capacite (stockage)." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "Depassement de capacite (tableau cvt)." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Reference incorrecte." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Distance incorrecte." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolation de points de repere." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "Le code `DEBUG' a ete rencontre." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "'ENDF' invalide dans les instructions d'un glyphe." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Pas assez d'espace d'execution (code ranges)." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Definitions imbriquees de fonction." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Espace d'execution (code range) incorrect." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Deplacement invalide." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "Arret force d'une boucle infinie." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Fenetres d'acces imbriquees." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "(Mauvaise liste chainee de caches)." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "Contexte introuvable." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Objet non chaine dans le cache." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Debordement de memoire de la trameuse." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Trameuse: hauteur negative." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Trameuse: valeur incorrecte." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Trameuse: non initialisee." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Format de table de crenage (kern) invalide." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Table de crenage (kern) incorrecte." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Format de table Postscript (post) invalide." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Table Postscript (post) incorrecte." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Format de table TrueType Open invalide." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Sous-table TrueType Open incorrecte." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Des glyphes sont absents d'une table de recherche (lookup)." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Substitutions contextuelles imbriquees trop profondement." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Format de la table de substitution de glyphes (GSUB) invalide." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Table de substitution de glyphes (GSUB) incorrecte." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Format de table de positionnement des glyphes (GPOS) invalide." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Table de positionnement des glyphes (GPOS) incorrecte." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Numero d'erreur inconnu ?" + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Debut de fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Fin de fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "Impossible de creer un conteneur de glyphe.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "Impossible de creer une instance\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "Impossible de creer une deuxieme instance.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Statistiques de consommation de la memoire:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "objet oeil" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "objet glyphe" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "objet instance" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "objet contexte" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "consommation totale de memoire" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "Message d'erreur FreeType : %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "Elements du tableau des noms\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"Nom de Postscript : %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "Encodages des caracteres\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "Cette police ne semble pas avoir de table d'encodage.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"Il y a %hu encodage(s) :\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "encodage %2u : " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "(valeur inconnue %hu)" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "(inconnu)" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "Test de ftxcmap\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "encodage %2u :\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "premier : glyphe numero %hu, caractere code 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "suivant : glyphe numero %hu, caractere code 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "dernier : glyphe numero %hu, caractere code 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Erreur pendant la recuperation de la table des bitmaps.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "Table des bitmaps incorpores\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " version de la table de bitmaps : 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " nombre de tailles de bitmaps : %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " taille de bitmap %hu sur %lu : " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu pixels par %hu bit(s), glyphes de %hu a %hu\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " format intervalle (%hu:%hu) glyphes %hu a %hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Erreur en chargeant la table GSUB.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "Table des substitutions de glyphes (GSUB)\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Erreur en demandant la liste des ecritures dans GSUB.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Erreur en selectionnant l'ecriture `%4.4s' dans GSUB.\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " Ecriture `%4.4s' (numero %hu)\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "Erreur en cherchant pour les langues standards de `%4.4s' dans GSUB.\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " Langue standard :\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Erreur en selectionnant dans GSUB l'information `%4.4s'\n" +"pour la langue standard de l'ecriture `%4.4s'.\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " information `%4.4s' (numero %hu ; table(s) de recherche " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "Erreur en demandant la liste des langues pour `%4.4s' dans GSUB.\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "Erreur en selectionnant la langue `%4.4s' pour `%4.4s' dans GSUB.\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " langue `%4.4s' (numero %hu) :\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " information requise (table(s) de recherche " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Erreur en recherchant dans GSUB la liste des informations\n" +"pour l'ecriture `%4.4s', langue `%4.4s'.\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Erreur en selectionnant dans GSUB l'information `%4.4s'\n" +"pour l'ecriture `%4.4s', langue `%4.4s'.\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr " Tables de recherche :\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr "%4hu : type %hu, drapeaux 0x%x\n" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "ftdump : utilitaire d'informations TrueType -- www.freetype.org" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Utilisation : %s nompolice[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Erreur lors de l'initialisation de FreeType.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Erreur lors de l'initialisation de l'extension `bitmaps'.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Erreur lors de l'initialisation de l'extension `GSUB'.\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "Impossible de trouver ou d'ouvrir %s.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Erreur lors de l'ouverture de %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" +"ftlint : verificateur simple d'instructions TrueType - www.freetype.org" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Utilisation : %s ppem nompolice[.ttf|.ttc] [nompolice2...]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "Impossible de selectionner la taille %d.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Erreur avec\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "glyphe %4u : %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "1 echec.\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "%d echecs.\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "ftmetric : affichage des metriques TrueType -- www.freetype.org" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Utilisation : %s [options] point nompolice[.ttf|.ttc]\n" +"\n" +" -B montrer les metriques des bitmaps (defaut : non)\n" +" -c C utilise la police numero C d'une collection (defaut : 0)\n" +" -i index numero du glyphe (default : 0)\n" +" -r R resolution en dpi (defaut : 72)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Il y a %d polices dans cette collection.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "Il n'y a aucune police d'indice %d dans cette collection.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "Il n'y a pas de bitmaps dans cette police.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "Impossible de changer la resolution.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "Impossible de changer la taile.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Metriques de l'instance : ppemX %d ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "Impossible d'allouer un conteneur de glyphe.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Impossible de charger le bitmap du glyphe %d.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Metriques du dessin vectorise" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "glyphe du dessin vectorise\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "ftsbit : affichage des `sbit' TrueType -- www.freetype.org" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Utilisation : %s ppm nompolice[.ttf|.ttc] numero_glyphe [numero_glyphe2...]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "Pas de bitmaps dans cette police.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Erreur lors du chargement des bitmaps.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " pas de bitmap pour le glyphe %d.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "glyphe numero %d = %dx%d pixels, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "chasse = %ld, approches = [%ld,%ld]\n" diff --git a/po/freetype.pot b/po/freetype.pot new file mode 100644 index 0000000..aaad9ca --- /dev/null +++ b/po/freetype.pot @@ -0,0 +1,727 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "" + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "" + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "" + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "" + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "" + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "" + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "" + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "" + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "" + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "" + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "" + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "" + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "" + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "" + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "" + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "" + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "" + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "" + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "" + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "" + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "" + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "" + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "" + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "" + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "" + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "" + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "" + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "" + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "" + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "" + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "" + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "" + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "" + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "" + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "" + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "" + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "" + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "" + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "" + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "" + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "" + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "" + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "" + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "" + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "" + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "" + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "" + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "" + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "" + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "" + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "" + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "" + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "" + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "" + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "" + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "" + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "" + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "" + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "" + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "" + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "" + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "" + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "" + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "" + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "" + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "" + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr "" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr "" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr "" + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr "" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr "" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr "" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr "" + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr "" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr "" + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr "" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr "" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "" + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000..d0862c6 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,758 @@ +# Dutch messages for FreeType. +# Copyright (C) 1998-1999 Gertjan de Back +# Gertjan de Back , 1999. +# +msgid "" +msgstr "" +"Project-Id-Version: FreeType 1.0\n" +"POT-Creation-Date: 1999-09-07 12:49+0000\n" +"PO-Revision-Date: 1999-09-07\n" +"Last-Translator: Gertjan de Back \n" +"Language-Team: Dutch\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/extend/ftxerr18.c:47 +msgid "Successful function call, no error." +msgstr "Functieaanroep succesvol." + +#: lib/extend/ftxerr18.c:50 +msgid "Invalid face handle." +msgstr "Ongeldige Face handle." + +#: lib/extend/ftxerr18.c:52 +msgid "Invalid instance handle." +msgstr "Ongeldige Instance handle." + +#: lib/extend/ftxerr18.c:54 +msgid "Invalid glyph handle." +msgstr "Ongeldige Glyph handle." + +#: lib/extend/ftxerr18.c:56 +msgid "Invalid charmap handle." +msgstr "Ongeldige Charmap handle." + +#: lib/extend/ftxerr18.c:58 +msgid "Invalid result address." +msgstr "Ongeldig resultaat adres." + +#: lib/extend/ftxerr18.c:60 +msgid "Invalid glyph index." +msgstr "Ongeldige Glyph index." + +#: lib/extend/ftxerr18.c:62 +msgid "Invalid argument." +msgstr "Ongeldig argument." + +#: lib/extend/ftxerr18.c:64 +msgid "Could not open file." +msgstr "Bestand kon niet geopend worden." + +#: lib/extend/ftxerr18.c:66 +msgid "File is not a TrueType collection." +msgstr "Bestand is geen TrueType collectie." + +#: lib/extend/ftxerr18.c:69 +msgid "Mandatory table missing." +msgstr "Vereiste tabel ontbreekt." + +#: lib/extend/ftxerr18.c:71 +msgid "Invalid horizontal metrics (hmtx table broken)." +msgstr "Ongeldige horizontale metriek (hmtx tabel defect)." + +#: lib/extend/ftxerr18.c:73 +msgid "Invalid charmap format." +msgstr "Ongeldige Charmap opmaak." + +#: lib/extend/ftxerr18.c:75 +msgid "Invalid ppem value." +msgstr "Ongeldige ppem waarde." + +#: lib/extend/ftxerr18.c:77 +msgid "Invalid vertical metrics (vmtx table broken)." +msgstr "Ongeldige vertikale metriek (vmtx tabel defect)." + +#: lib/extend/ftxerr18.c:80 +msgid "Invalid file format." +msgstr "Ongeldige bestandsopmaak." + +#: lib/extend/ftxerr18.c:83 +msgid "Invalid engine." +msgstr "Ongeldige engine." + +#: lib/extend/ftxerr18.c:85 +msgid "Too many extensions." +msgstr "Te veel uitbreidingen." + +#: lib/extend/ftxerr18.c:87 +msgid "Extensions unsupported." +msgstr "Uitbreidingen niet ondersteund." + +#: lib/extend/ftxerr18.c:89 +msgid "Invalid extension id." +msgstr "Ongeldige uitbreiding id." + +#: lib/extend/ftxerr18.c:92 +msgid "No vertical data in font." +msgstr "Geen vertikale informatie in lettertype." + +#: lib/extend/ftxerr18.c:95 +msgid "Maximum Profile (maxp) table missing." +msgstr "`Maximum Profile (maxp)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:97 +msgid "Font Header (head) table missing." +msgstr "`Font Header (head)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:99 +msgid "Horizontal Header (hhea) table missing." +msgstr "`Horizontal Header (hhea)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:101 +msgid "Index to Location (loca) table missing." +msgstr "`Index to Location (loca)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:103 +msgid "Naming (name) table missing." +msgstr "`Naming (name)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:105 +msgid "Character to Glyph Index Mapping (cmap) tables missing." +msgstr "`Character to Glyph Index Mapping (cmap)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:107 +msgid "Horizontal Metrics (hmtx) table missing." +msgstr "`Horizontal Metrics (hmtx)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:109 +msgid "OS/2 table missing." +msgstr "OS/2 tabel ontbreekt." + +#: lib/extend/ftxerr18.c:111 +msgid "PostScript (post) table missing." +msgstr "`PostScript (post)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:113 +msgid "Glyph (glyf) table missing." +msgstr "`Naming (glyf)' tabel ontbreekt." + +#: lib/extend/ftxerr18.c:118 +msgid "Out of memory." +msgstr "Onvoldoende geheugen." + +#: lib/extend/ftxerr18.c:123 +msgid "Invalid file offset." +msgstr "Bestand positie ongeldig." + +#: lib/extend/ftxerr18.c:125 +msgid "Invalid file read." +msgstr "Lezen van bestand ongeldig." + +#: lib/extend/ftxerr18.c:127 +msgid "Invalid frame access." +msgstr "Toegang tot frame ongeldig." + +#: lib/extend/ftxerr18.c:132 +msgid "Too many points." +msgstr "Te veel punten." + +#: lib/extend/ftxerr18.c:134 +msgid "Too many contours." +msgstr "Te veel contouren." + +#: lib/extend/ftxerr18.c:136 +msgid "Invalid composite glyph." +msgstr "Samengestelde Glyph ongeldig." + +#: lib/extend/ftxerr18.c:138 +msgid "Too many instructions." +msgstr "Te veel instructies." + +#: lib/extend/ftxerr18.c:143 +msgid "Invalid opcode." +msgstr "Ongeldige opcode." + +#: lib/extend/ftxerr18.c:145 +msgid "Too few arguments." +msgstr "Te weinig argumenten." + +#: lib/extend/ftxerr18.c:147 +msgid "Stack overflow." +msgstr "Stack overloop." + +#: lib/extend/ftxerr18.c:149 +msgid "Code overflow." +msgstr "Code overloop." + +#: lib/extend/ftxerr18.c:151 +msgid "Bad argument." +msgstr "Foutief argument." + +#: lib/extend/ftxerr18.c:153 +msgid "Divide by zero." +msgstr "Deling door nul." + +#: lib/extend/ftxerr18.c:155 +msgid "Storage overflow." +msgstr "Opslag overloop." + +#: lib/extend/ftxerr18.c:157 +msgid "Control Value (cvt) table overflow." +msgstr "`Control Value (cvt)' tabel overloop." + +#: lib/extend/ftxerr18.c:159 +msgid "Invalid reference." +msgstr "Ongeldige referentie." + +#: lib/extend/ftxerr18.c:161 +msgid "Invalid distance." +msgstr "Ongeldige afstand." + +#: lib/extend/ftxerr18.c:163 +msgid "Interpolate twilight points." +msgstr "Interpolatie van schemer (twilight) punten." + +#: lib/extend/ftxerr18.c:165 +msgid "`DEBUG' opcode found." +msgstr "`DEBUG'-opcode gevonden." + +#: lib/extend/ftxerr18.c:167 +msgid "`ENDF' in byte-code stream." +msgstr "`ENDF' in bytecode-stroom." + +#: lib/extend/ftxerr18.c:169 +msgid "Out of code ranges." +msgstr "Onvoldoende codegebieden." + +#: lib/extend/ftxerr18.c:171 +msgid "Nested function definitions." +msgstr "Functiedefinities genest." + +#: lib/extend/ftxerr18.c:173 +msgid "Invalid code range." +msgstr "Ongeldig codegebied." + +#: lib/extend/ftxerr18.c:175 +msgid "Invalid displacement." +msgstr "Ongeldige verplaatsing." + +#: lib/extend/ftxerr18.c:177 +msgid "Endless loop encountered while executing instructions." +msgstr "Oneindige loop aangetrofffen tijdens het uitvoeren van instructies." + +#: lib/extend/ftxerr18.c:182 +msgid "Nested frame access." +msgstr "Frame toegang genest." + +#: lib/extend/ftxerr18.c:184 +msgid "Invalid cache list." +msgstr "Ongeldige cachelijst." + +#: lib/extend/ftxerr18.c:186 +msgid "Could not find context." +msgstr "Context niet gevonden." + +#: lib/extend/ftxerr18.c:188 +msgid "Unlisted object." +msgstr "Object niet aanwezig." + +#: lib/extend/ftxerr18.c:193 +msgid "Raster pool overflow." +msgstr "Overloop van Raster pool." + +#: lib/extend/ftxerr18.c:195 +msgid "Raster: negative height encountered." +msgstr "Raster: negatieve hoogte aangetroffen." + +#: lib/extend/ftxerr18.c:197 +msgid "Raster: invalid value." +msgstr "Raster: ongeldige waarde." + +#: lib/extend/ftxerr18.c:199 +msgid "Raster not initialized." +msgstr "Raster niet geinitialiseerd." + +#: lib/extend/ftxerr18.c:204 +msgid "Invalid kerning (kern) table format." +msgstr "Ongeldige `Kerning (kern)' tabel opmaak." + +#: lib/extend/ftxerr18.c:206 +msgid "Invalid kerning (kern) table." +msgstr "Ongeldige `Kerning (kern)' tabel." + +#: lib/extend/ftxerr18.c:208 +msgid "Invalid PostScript (post) table format." +msgstr "Ongeldige `PostScript (post)' tabel opmaak." + +#: lib/extend/ftxerr18.c:210 +msgid "Invalid PostScript (post) table." +msgstr "Ongeldige `PostScript (post)' tabel." + +#: lib/extend/ftxerr18.c:216 +msgid "Invalid TrueType Open subtable format." +msgstr "Ongeldige opmaak van TrueType Open subtabel." + +#: lib/extend/ftxerr18.c:218 +msgid "Invalid TrueType Open subtable." +msgstr "Ongeldige TrueType Open subtabel." + +#: lib/extend/ftxerr18.c:220 +msgid "Glyph(s) not covered by lookup." +msgstr "Glyph(s) niet door opgenomen in Lookup." + +#: lib/extend/ftxerr18.c:222 +msgid "Too many nested context substitutions." +msgstr "Te veel geneste context vervangingen." + +#: lib/extend/ftxerr18.c:224 +msgid "Invalid glyph substitution (GSUB) table format." +msgstr "Ongeldige Glyph vervanging (GSUB) tabel opmaak." + +#: lib/extend/ftxerr18.c:226 +msgid "Invalid glyph substitution (GSUB) table." +msgstr "Ongeldige Glyph vervanging (GSUB) tabel." + +#: lib/extend/ftxerr18.c:228 +msgid "Invalid glyph positioning (GPOS) table format." +msgstr "Ongeldige Glyph plaatsing (GPOS) tabel opmaak." + +#: lib/extend/ftxerr18.c:230 +msgid "Invalid glyph positioning (GPOS) table." +msgstr "Ongeldige Glyph plaatsing (GPOS) tabel." + +#: lib/extend/ftxerr18.c:237 +msgid "Invalid Error Number." +msgstr "Ongeldig foutnummer." + +#: test/fterror.c:60 +msgid "Start of fterror.\n" +msgstr "Begin van fterror.\n" + +#: test/fterror.c:68 +msgid "End of fterror.\n" +msgstr "Einde van fterror.\n" + +#: test/ftdump.c:168 test/ftlint.c:207 test/ftmetric.c:292 +msgid "Could not create glyph container.\n" +msgstr "Aanmaken Glyph container mislukt.\n" + +#: test/ftdump.c:178 test/ftlint.c:215 test/ftmetric.c:301 test/ftsbit.c:213 +msgid "Could not create instance.\n" +msgstr "Aanmaken Instance mislukt.\n" + +#: test/ftdump.c:187 +msgid "Could not create second instance.\n" +msgstr "Aanmaken tweede Instance mislukt.\n" + +#: test/ftdump.c:193 +msgid "Memory footprint statistics:\n" +msgstr "Statistieken geheugengebruik:\n" + +#: test/ftdump.c:201 +msgid "face object" +msgstr "Face object" + +#: test/ftdump.c:202 +msgid "glyph object" +msgstr "Glyph object" + +#: test/ftdump.c:203 +msgid "instance object" +msgstr "Instance object" + +#: test/ftdump.c:207 +msgid "exec. context object" +msgstr "uitv. context object" + +#: test/ftdump.c:214 +msgid "total memory usage" +msgstr "totaal geheugengebruik" + +#: test/ftdump.c:222 test/ftdump.c:574 test/ftdump.c:784 test/ftdump.c:921 +#: test/ftlint.c:274 test/ftlint.c:287 test/ftmetric.c:387 test/ftsbit.c:284 +#, c-format +msgid "FreeType error message: %s\n" +msgstr "FreeType foutmelding: %s\n" + +#: test/ftdump.c:299 +msgid "font name table entries\n" +msgstr "lettertypen in namentabel\n" + +#: test/ftdump.c:309 +#, c-format +msgid "" +"PostScript name: %s\n" +"\n" +msgstr "" +"PostScript naam: %s\n" +"\n" + +#: test/ftdump.c:332 +msgid "character map encodings\n" +msgstr "tekencodering tabellen\n" + +#: test/ftdump.c:339 test/ftdump.c:483 +msgid "The file doesn't seem to have any encoding table.\n" +msgstr "Het bestand schijnt geen codering tabellen te bevatten.\n" + +#: test/ftdump.c:343 test/ftdump.c:487 +#, c-format +msgid "" +"There are %hu encodings:\n" +"\n" +msgstr "" +"Er zijn %hu coderingen:\n" +"\n" + +#: test/ftdump.c:348 +#, c-format +msgid "encoding %2u: " +msgstr "codering %2u: " + +#: test/ftdump.c:375 test/ftdump.c:384 test/ftdump.c:447 +#, c-format +msgid "Unknown value %hu" +msgstr "Waarde %hu onbekend" + +#: test/ftdump.c:454 +msgid "Unknown" +msgstr "Onbekend" + +#: test/ftdump.c:476 +msgid "ftxcmap test\n" +msgstr "ftxcmap test\n" + +#: test/ftdump.c:493 +#, c-format +msgid "encoding %2u:\n" +msgstr "codering %2u:\n" + +#: test/ftdump.c:498 +#, c-format +msgid "first: glyph index %hu, character code 0x%lx\n" +msgstr "eerste: Glyph index %hu, karakter code 0x%lx\n" + +#: test/ftdump.c:502 +#, c-format +msgid "next: glyph index %hu, character code 0x%lx\n" +msgstr "volgende: Glyph index %hu, karakter code 0x%lx\n" + +#: test/ftdump.c:506 +#, c-format +msgid "last: glyph index %hu, character code 0x%lx\n" +msgstr "laatste: Glyph index %hu, karakter code 0x%lx\n" + +#: test/ftdump.c:528 test/ftmetric.c:282 +msgid "Error while retrieving embedded bitmaps table.\n" +msgstr "Fout bij het ophalen van ingebedde bitmap tabel.\n" + +#: test/ftdump.c:532 +msgid "embedded bitmap table\n" +msgstr "ingebedde bitmap tabel\n" + +#: test/ftdump.c:535 +#, c-format +msgid " version of embedded bitmap table: 0x%lx\n" +msgstr " versie van ingebedde bitmap tabel: 0x%lx\n" + +#: test/ftdump.c:537 +#, c-format +msgid " number of embedded bitmap strikes: %lu\n" +msgstr " aantal ingebedde bitmap treffers: %lu\n" + +#: test/ftdump.c:547 +#, c-format +msgid " bitmap strike %hu/%lu: " +msgstr " bitmap treffer %hu/%lu: " + +#: test/ftdump.c:550 +#, c-format +msgid "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" +msgstr "%hux%hu pixels, %hu-bit diepte, Glyphs [%hu..%hu]\n" + +#: test/ftdump.c:559 +#, c-format +msgid " range format (%hu:%hu) glyphs %hu..%hu\n" +msgstr " bereik formaat (%hu:%hu) Glyphs %hu..%hu\n" + +#: test/ftdump.c:610 +msgid "Error while loading GSUB table.\n" +msgstr "Fout bij het laden van GSUB tabel.\n" + +#: test/ftdump.c:614 +msgid "GSUB table\n" +msgstr "GSUB tabel\n" + +#: test/ftdump.c:621 +msgid "Error while querying GSUB script list.\n" +msgstr "Fout bij het opvragen van GSUB script lijst.\n" + +#: test/ftdump.c:634 +#, c-format +msgid "Error while selecting GSUB script `%4.4s'.\n" +msgstr "Fout bij het selecteren van GSUB script `%4.4s'.\n" + +#: test/ftdump.c:639 +#, c-format +msgid " script `%4.4s' (index %hu):\n" +msgstr " script `%4.4s' (index %hu):\n" + +#: test/ftdump.c:647 +#, c-format +msgid "Error while querying GSUB default language system for script `%4.4s'.\n" +msgstr "" +"Fout bij het opvragen van GSUB standaard taal systeem voor script `%4.4s'.\n" + +#: test/ftdump.c:652 +msgid " default language system:\n" +msgstr " standaard taal systeem:\n" + +#: test/ftdump.c:665 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for default language system of script `%4.4s'.\n" +msgstr "" +"Fout bij het selecteren van GSUB kenmerk `%4.4s'\n" +"voor standaard taal systeem van script `%4.4s'.\n" + +#: test/ftdump.c:671 test/ftdump.c:752 +#, c-format +msgid " feature `%4.4s' (index %hu; lookup " +msgstr " kenmerk `%4.4s' (index %hu; lookup " + +#: test/ftdump.c:687 +#, c-format +msgid "Error while querying GSUB language list for script `%4.4s'.\n" +msgstr "Fout bij het opvragen van GSUB taal lijst voor script `%4.4s'.\n" + +#: test/ftdump.c:704 +#, c-format +msgid "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" +msgstr "Fout bij het selecteren van GSUB taal `%4.4s' voor script `%4.4s'.\n" + +#: test/ftdump.c:709 +#, c-format +msgid " language `%4.4s' (index %hu):\n" +msgstr " taal `%4.4s' (index %hu):\n" + +#: test/ftdump.c:714 +#, c-format +msgid " required feature index %hu (lookup " +msgstr " benodigde kenmerk index %hu (lookup " + +#: test/ftdump.c:729 +#, c-format +msgid "" +"Error while querying GSUB feature list\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Fout bij het opvragen van GSUB kenmerken lijst\n" +"voor script `%4.4s', taal `%4.4s'.\n" + +#: test/ftdump.c:746 +#, c-format +msgid "" +"Error while selecting GSUB feature `%4.4s'\n" +"for script `%4.4s', language `%4.4s'.\n" +msgstr "" +"Fout bij het selecteren van GSUB kenmerk `%4.4s'\n" +"voor script `%4.4s', taal `%4.4s'.\n" + +#: test/ftdump.c:771 +msgid "" +"Lookups:\n" +"\n" +msgstr "" +"Lookups:\n" +"\n" + +#: test/ftdump.c:774 +#, c-format +msgid " %hu: type %hu, flag 0x%x\n" +msgstr " %hu: type %hu, vlag 0x%x\n" + +#: test/ftdump.c:809 +msgid "ftdump: Simple TrueType Dumper -- part of the FreeType project" +msgstr "" +"ftdump: eenvoudige TrueType dumper -- onderdeel van het FreeType project" + +#: test/ftdump.c:813 +#, c-format +msgid "" +"Usage: %s fontname[.ttf|.ttc]\n" +"\n" +msgstr "" +"Gebruik: %s lettertype[.ttf|.ttc]\n" +"\n" + +#: test/ftdump.c:845 test/ftlint.c:134 test/ftmetric.c:226 test/ftsbit.c:126 +msgid "Error while initializing engine.\n" +msgstr "Fout bij het starten van de FreeType engine.\n" + +#: test/ftdump.c:852 test/ftmetric.c:234 test/ftsbit.c:133 +msgid "Error while initializing embedded bitmap extension.\n" +msgstr "Fout bij het starten de ingebedde bitmap toevoeging.\n" + +#: test/ftdump.c:859 +msgid "Error while initializing GSUB extension.\n" +msgstr "Fout bij het starten van de GSUB toevoeging.\n" + +#: test/ftdump.c:875 test/ftlint.c:187 test/ftmetric.c:249 test/ftsbit.c:181 +#, c-format +msgid "Could not find or open %s.\n" +msgstr "Kan %s niet vinden of openen.\n" + +#: test/ftdump.c:878 test/ftlint.c:193 test/ftmetric.c:252 test/ftsbit.c:187 +#, c-format +msgid "Error while opening %s.\n" +msgstr "Fout bij het openen van %s.\n" + +#: test/ftlint.c:94 +msgid "" +"ftlint: Simple TrueType instruction tester -- part of the FreeType project" +msgstr "" +"ftlint: TrueType instructie tester -- onderdeel van het FreeType project" + +#: test/ftlint.c:99 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n" +"\n" +msgstr "" +"Gebruik: %s ppem lettertype[.ttf|.ttc] [lettertype2..]\n" +"\n" + +#: test/ftlint.c:226 test/ftsbit.c:224 +#, c-format +msgid "Could not set point size to %d.\n" +msgstr "Instellen van puntgrootte %d mislukt.\n" + +#: test/ftlint.c:239 +msgid "" +"Error with\n" +" " +msgstr "" +"Fout met\n" +" " + +#: test/ftlint.c:240 +#, c-format +msgid "glyph %4u: %s\n" +msgstr "Glyph %4u: %s\n" + +#: test/ftlint.c:253 +msgid "1 fail.\n" +msgstr "1 misser.\n" + +#: test/ftlint.c:255 +#, c-format +msgid "%d fails.\n" +msgstr "%d missers.\n" + +#: test/ftmetric.c:68 +msgid "" +"ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" +msgstr "" +"ftmetric: TTF metriek/Glyph dumper -- onderdeel van het FreeType project" + +#: test/ftmetric.c:72 +#, c-format +msgid "" +"Usage: %s [options below] point fontname[.ttf|.ttc]\n" +"\n" +" -B show sbit's metrics (default: none)\n" +" -c C use C'th font index of TrueType collection (default: 0)\n" +" -i index glyph index (default: 0)\n" +" -r R use resolution R dpi (default: 72)\n" +"\n" +msgstr "" +"Gebruik: %s [opties hieronder] punt lettertype[.ttf|.ttc]\n" +"\n" +" -B toon sbit's metriek (standaard: geen)\n" +" -c C gebruik 'C'e lettertype index van TrueType collectie (standaard: " +"0)\n" +" -i index Glyph index (standaard: 0)\n" +" -r R gebruik resolutie van R dpi (standaard: 72)\n" +"\n" + +#: test/ftmetric.c:259 +#, c-format +msgid "There are %d fonts in this collection.\n" +msgstr "Er zijn %d lettertypen in deze collectie.\n" + +#: test/ftmetric.c:264 +#, c-format +msgid "There is no collection with index %d in this font file.\n" +msgstr "Er is geen collectie met index %d in dit lettertype.\n" + +#: test/ftmetric.c:278 +msgid "There is no embedded bitmap data in the font.\n" +msgstr "Er is geen ingebedde bitmap informatie in het lettertype.\n" + +#: test/ftmetric.c:308 +msgid "Could not set device resolutions.\n" +msgstr "Instellen van resolutie is mislukt.\n" + +#: test/ftmetric.c:315 +msgid "Could not reset instance.\n" +msgstr "Her-instellen van Instance mislukt.\n" + +#: test/ftmetric.c:321 +#, c-format +msgid "Instance metrics: ppemX %d, ppemY %d\n" +msgstr "Instance metriek: ppemX %d, ppemY %d\n" + +#: test/ftmetric.c:331 test/ftsbit.c:233 +msgid "Could not allocate glyph bitmap container.\n" +msgstr "Toewijzen van Glyph bitmap container mislukt.\n" + +#: test/ftmetric.c:339 test/ftsbit.c:257 +#, c-format +msgid "Can't load bitmap for glyph %d.\n" +msgstr "Laden van bitmap voor Glyph %d mislukt.\n" + +#: test/ftmetric.c:366 +msgid "Outline's metrics" +msgstr "Omtrek metriek" + +#: test/ftmetric.c:368 +msgid "Outline glyph\n" +msgstr "Omtrek Glyph\n" + +#: test/ftsbit.c:89 +msgid "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" +msgstr "ftsbit: TrueType `sbit' dumper -- onderdeel van het FreeType project" + +#: test/ftsbit.c:94 +#, c-format +msgid "" +"Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" +msgstr "" +"Gebruik: %s ppem lettertype[.ttf|.ttc] glyph_index [glyph_index2..]\n" +"\n" + +#: test/ftsbit.c:199 +msgid "Could not find embedded bitmaps in this font.\n" +msgstr "Ingebedde bitmaps niet gevonden in dit lettertype.\n" + +#: test/ftsbit.c:205 +msgid "Error while loading embedded bitmaps.\n" +msgstr "Fout bij het laden van ingebedde bitmaps.\n" + +#: test/ftsbit.c:251 +#, c-format +msgid " no bitmap for glyph %d.\n" +msgstr " geen bitmap voor Glyph %d.\n" + +#: test/ftsbit.c:263 +#, c-format +msgid "glyph index %d = %dx%d pixels, " +msgstr "Glyph index %d = %dx%d pixels, " + +#: test/ftsbit.c:266 +#, c-format +msgid "advance = %ld, minBearing = [%ld,%ld]\n" +msgstr "advance = %ld, minBearing = [%ld,%ld]\n" diff --git a/readme.1st b/readme.1st new file mode 100644 index 0000000..81a1c7c --- /dev/null +++ b/readme.1st @@ -0,0 +1,10 @@ + + DISCLAIMER + + + PLEASE READ THE FILE `PATENTS' BEFORE ANYTHING ELSE! IT + CONTAINS *CRITICAL* INFORMATION REGARDING THE FREE USE OF THIS + LIBRARY. + + +--- end of readme.1st --- diff --git a/test/.cvsignore b/test/.cvsignore new file mode 100644 index 0000000..0f0d086 --- /dev/null +++ b/test/.cvsignore @@ -0,0 +1,12 @@ +.libs +ftview +fttimer +ftlint +ftdump +ftzoom +ftstring +ftstrpnm +fterror +ftsbit +ftmetric +ftstrtto diff --git a/test/README b/test/README new file mode 100644 index 0000000..364b1eb --- /dev/null +++ b/test/README @@ -0,0 +1,6 @@ + +The instructions how to use the test programs can be found in the +main `README' file located in the parent directory. + + +--- end of README --- diff --git a/test/arabic.c b/test/arabic.c new file mode 100644 index 0000000..76b9b2b --- /dev/null +++ b/test/arabic.c @@ -0,0 +1,386 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* arabic -- An implementation of the contextual algorithm given in the */ +/* Unicode 2.0 book to assign the `isolated', `initial', `medial', and */ +/* `final' properties to an input string of character codes for the Arabic */ +/* script. */ +/* */ +/****************************************************************************/ + +#include +#include + +#include "arabic.h" +#include "freetype.h" +#include "ftxopen.h" + + + /* + + Here a table of the joining classes for characters in the range + U+0620 - U+06FF. + + The following character also has a joining class: + + U+200C ZERO WIDTH NON-JOINER -> causing + + All other characters are given the joining class `none'. + + */ + + joining_class arabic[] = + { + /* U+0620 */ + none, none, right, right, + right, right, dual, right, + dual, right, dual, dual, + dual, dual, dual, right, + + /* U+0630 */ + right, right, right, dual, + dual, dual, dual, dual, + dual, dual, dual, none, + none, none, none, none, + + /* U+0640 */ + causing, dual, dual, dual, + dual, dual, dual, dual, + right, right, dual, transparent, + transparent, transparent, transparent, transparent, + + /* U+0650 */ + transparent, transparent, transparent, none, + none, none, none, none, + none, none, none, none, + none, none, none, none, + + /* U+0660 */ + none, none, none, none, + none, none, none, none, + none, none, none, none, + none, none, none, none, + + /* U+0670 */ + transparent, none, right, right, + none, right, right, right, + dual, dual, dual, dual, + dual, dual, dual, dual, + + /* U+0680 */ + dual, dual, dual, dual, + dual, dual, dual, dual, + right, right, right, right, + right, right, right, right, + + /* U+0690 */ + right, right, right, right, + right, right, right, right, + right, right, dual, dual, + dual, dual, dual, dual, + + /* U+06A0 */ + dual, dual, dual, dual, + dual, dual, dual, dual, + dual, dual, dual, dual, + dual, dual, dual, dual, + + /* U+06B0 */ + dual, dual, dual, dual, + dual, dual, dual, dual, + dual, dual, dual, dual, + dual, dual, dual, dual, + + /* U+06C0 */ + right, dual, right, right, + right, right, right, right, + right, right, right, right, + dual, right, dual, right, + + /* U+06D0 */ + dual, dual, right, right, + none, none, none, transparent, + transparent, transparent, transparent, transparent, + transparent, transparent, transparent, transparent, + + /* U+06E0 */ + transparent, transparent, transparent, transparent, + transparent, none, none, transparent, + transparent, none, transparent, transparent, + transparent, transparent, none, none, + + /* U+06F0 */ + none, none, none, none, + none, none, none, none, + none, none, dual, dual, + dual, none, none, none + }; + + + struct cgc_ + { + TT_UShort char_code; + TT_UShort glyph_index; + TT_UShort class; + }; + + typedef struct cgc_ cgc; + + + int compare_cgc( const void* a, + const void* b ) + { + return ( ((cgc*)a)->glyph_index > ((cgc*)b)->glyph_index ) ? + 1 : ( ( ((cgc*)a)->glyph_index == ((cgc*)b)->glyph_index ) ? + 0 : -1 ); + } + + + TT_Error Build_Arabic_Glyph_Properties( TT_CharMap char_map, + TT_UShort max_glyphs, + TTO_GDEFHeader** gdef ) + { + TT_UShort i, j, num_glyphs; + + cgc Arabic[0x0700 - 0x0620]; + + TT_UShort glyph_indices[0x700 - 0x0620]; + TT_UShort classes[0x700 - 0x0620]; + + if ( !gdef ) + return TT_Err_Invalid_Argument; + + j = 0; + + for ( i = 0x0620; i < 0x0700; i++ ) + { + Arabic[j].char_code = i; + Arabic[j].class = ( arabic[i - 0x0620] == transparent ) ? + MARK_GLYPH : SIMPLE_GLYPH; + Arabic[j].glyph_index = TT_Char_Index( char_map, i ); + if ( Arabic[j].glyph_index ) + j++; + } + num_glyphs = j; + + if ( !num_glyphs ) + { + /* no Arabic font */ + *gdef = NULL; + return TT_Err_Ok; + } + + /* sort it */ + + qsort( Arabic, num_glyphs, sizeof ( cgc ), compare_cgc ); + + /* write it to the arrays, removing duplicates */ + + glyph_indices[0] = Arabic[0].glyph_index; + classes[0] = Arabic[0].class; + + j = 1; + + for ( i = 1; i < num_glyphs; i++ ) + { + glyph_indices[j] = Arabic[i].glyph_index; + classes[j] = Arabic[i].class; + + if ( glyph_indices[j - 1] != glyph_indices[j] ) + j++; + } + num_glyphs = j; + + TT_GDEF_Build_ClassDefinition( *gdef, max_glyphs, num_glyphs, + glyph_indices, classes ); + + return TT_Err_Ok; + } + + + /* The joining rules as given in the Unicode 2.0 book (characters are + here specified as appearing in the byte stream, i.e. *not* in + visual order). Joining classes are given in angle brackets, glyph + forms in square brackets. Glyphs affected by a specific rule are + enclosed with vertical bars. + + Note: The description of the joining algorithm in the book is + severely broken. You can get a corrected version from + www.unicode.org (as of 29-Jun-1999, this hasn't appeared). + + R1: + + apply joining rules for + -> [shape1] [shape2] + + -> [shape1] [isolated] [shape2] + + R2: || + + -> [final] + + R3: || + + -> [initial] + + R4: || + + -> [medial] + + R5: || + + -> [final] + + R6: || + + -> [initial] + + R7: If R1-R6 fail: + + -> [isolated] */ + + + /* `direction' can be -1, 0, or 1 to indicate the last non-transparent + glyph, the current glyph, and the next non-transparent glyph, + respectively. */ + + static joining_class Get_Joining_Class( TT_UShort* string, + TT_UShort pos, + TT_UShort length, + int direction ) + { + joining_class j; + + + while ( 1 ) + { + if ( pos == 0 && direction < 0 ) + return none; + + pos += direction; + + if ( pos >= length ) + return none; + + if ( string[pos] < 0x0620 || + string[pos] >= 0x0700 ) + { + if ( string[pos] == 0x200C ) + return causing; + else + return none; + } + else + j = arabic[string[pos] - 0x0620]; + + if ( !direction || j != transparent ) + return j; + } + } + + + TT_Error Assign_Arabic_Properties( TT_UShort* string, + TT_UShort* properties, + TT_UShort length ) + { + joining_class previous, current, next; + + TT_UShort i; + + + if ( !string || !properties || length == 0 ) + return TT_Err_Invalid_Argument; + + for ( i = 0; i < length; i++ ) + { + previous = Get_Joining_Class( string, i, length, -1 ); + current = Get_Joining_Class( string, i, length, 0 ); + next = Get_Joining_Class( string, i, length, 1 ); + + /* R1 */ + + if ( current == transparent ) + { + properties[i] |= isolated_p; + continue; + } + + /* R2 */ + + if ( previous == causing || + previous == left || + previous == dual ) + if ( current == right ) + { + properties[i] |= final_p; + continue; + } + + /* R3 */ + + if ( current == left ) + if ( next == causing || + next == right || + next == dual ) + { + properties[i] |= initial_p; + continue; + } + + /* R4 */ + + if ( previous == causing || + previous == left || + previous == dual ) + if ( current == dual ) + if ( next == causing || + next == right || + next == dual ) + { + properties[i] |= medial_p; + continue; + } + + /* R5 */ + + if ( previous == causing || + previous == left || + previous == dual ) + if ( current == dual ) + if ( !( next == causing || + next == right || + next == dual ) ) + { + properties[i] |= final_p; + continue; + } + + /* R6 */ + + if ( !( previous == causing || + previous == left || + previous == dual ) ) + if ( current == dual ) + if ( next == causing || + next == right || + next == dual ) + { + properties[i] |= initial_p; + continue; + } + + /* R7 */ + + if ( current != none ) + properties[i] |= isolated_p; + } + + return TT_Err_Ok; + } + + +/* End */ diff --git a/test/arabic.h b/test/arabic.h new file mode 100644 index 0000000..0e9fe05 --- /dev/null +++ b/test/arabic.h @@ -0,0 +1,66 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* arabic -- An implementation of the contextual algorithm given in the */ +/* Unicode 2.0 book to assign the `isolated', `initial', `medial', and */ +/* `final' properties to an input string of character codes for the Arabic */ +/* script. */ +/* */ +/****************************************************************************/ + + +#include "freetype.h" +#include "ftxopen.h" + + + enum joining_type_ + { + isolated = 1, /* nominal */ + final = 2, /* right_joining */ + initial = 4, /* left_joining */ + medial = 8 /* double_joining */ + }; + + typedef enum joining_type_ joining_type; + + + /* A glyph's property value as needed by e.g. TT_GSUB_Apply_String() + specifies which features should *not* be applied */ + + enum arabic_glyph_property_ + { + isolated_p = final | initial | medial, + final_p = isolated | initial | medial, + initial_p = isolated | final | medial, + medial_p = isolated | final | initial + }; + + typedef enum arabic_glyph_property_ arabic_glyph_property; + + + enum joining_class_ + { + right, + left, /* not used */ + dual, + causing, + none, + transparent + }; + + typedef enum joining_class_ joining_class; + + + TT_Error Assign_Arabic_Properties( TT_UShort* string, + TT_UShort* properties, + TT_UShort length ); + TT_Error Build_Arabic_Glyph_Properties( TT_CharMap char_map, + TT_UShort max_glyphs, + TTO_GDEFHeader** gdef ); + + +/* End */ diff --git a/test/arch/amigaos/Makefile.gcc b/test/arch/amigaos/Makefile.gcc new file mode 100644 index 0000000..b543ce9 --- /dev/null +++ b/test/arch/amigaos/Makefile.gcc @@ -0,0 +1,106 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for amiga using ADE. +# +# You will need GNU make. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/amigaos/Makefile.gcc + +ARCH = arch/amigaos +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +CFLAGS = -ansi -Wall -g -noixemul $(INCDIRS) +# CFLAGS = -Wall -noixemul -O2 -Ilib $(INCDIRS) + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(ARCH)/gw_amiga.c +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ @^ + + +EXEFILES = ftdump \ + fterror \ + ftlint \ + ftmetric \ + ftsbit \ + ftstring \ + ftstrpnm \ + ftstrtto \ + fttimer \ + ftview \ + ftzoom + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump: ftdump.o common.o $(LIBDIR)/libttf.a +ftstring: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftsbit: ftsbit.o common.o $(LIBDIR)/libttf.a +ftstrpnm: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftmetric: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -rm dep.end core + -rm $(EXE) + +do_clean: + -rm *.o + -rm arch/amigaos/*.o + + +depend: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $(SRC) $(GSRC) > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/test/arch/amigaos/TODO b/test/arch/amigaos/TODO new file mode 100644 index 0000000..d09a4e2 --- /dev/null +++ b/test/arch/amigaos/TODO @@ -0,0 +1,16 @@ + + * To test the window oriented driver. + + * To improve the window oriented driver to use ROM functions like + WriteChunkyPixel() (or similar) instead of the current routine. + + * To build a truetype.library from libttf.a + + * truetype.datatype. + + * Program to convert truetype fonts in Amiga fonts. + + Suggestions, bug reports, code improvements, support for other compilers, + ... are welcome ! + + Send them to: map@medusa.es or to freetype@lists.lrz-muenchen.de diff --git a/test/arch/amigaos/gfsamiga.c b/test/arch/amigaos/gfsamiga.c new file mode 100644 index 0000000..76bac1e --- /dev/null +++ b/test/arch/amigaos/gfsamiga.c @@ -0,0 +1,428 @@ +/******************************************************************* + * + * gfsamiga.c graphics utility fullscreen Amiga driver. 1.0 + * + * This is the driver for fullscreen Amiga display, used by the + * graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +/* standard includes */ + +#include +#include + +/* AmigaOS includes */ + +#include +#include +#include +#include + +#ifdef __GNUC__ + +#include +#include +#include +#include + +#else + +#include +#include +#include +#include + +#endif + +/* FreeType includes */ + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + +/* some screen definitions */ + +#define MONO_SCREEN_WIDTH 640 +#define MONO_SCREEN_HEIGHT 512 +#define MONO_SCREEN_DEPTH 1 + +#define GRAY_SCREEN_WIDTH 320 +#define GRAY_SCREEN_HEIGHT 256 +#define GRAY_SCREEN_DEPTH 3 + +#define DISPLAY_MEM ( 1024 * 64 ) + + + /* external variables */ + + extern struct Library* SysBase; + extern struct Library* DOSBase; + + extern int vio_ScanLineWidth; + extern char* Vio; + extern char gray_palette[5]; + + /* global variables */ + + struct Library* IntuitionBase = NULL; + struct Library* GfxBase = NULL; + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + /* local variables */ + + static struct Screen* fts = NULL; + static struct Window* ftw = NULL; + + static int graphx_mode; + + + /* exit gracefully */ + + static void AmigaCleanUp( void ) + { + if ( ftw ) + CloseWindow( ftw ); + + if ( fts ) + CloseScreen( fts ); + + if ( IntuitionBase ) + CloseLibrary( IntuitionBase ); + + if ( GfxBase ) + CloseLibrary( GfxBase ); + + if ( graphx_mode == Graphics_Mode_Gray ) + if ( Vio ) + FreeMem( Vio, DISPLAY_MEM ); + } + + + static void SetPalette( void ) + { + short color[] = { 0x0000, + 0x0333, + 0x0777, + 0x0BBB, + 0x0FFF, + 0x0A00, + 0x00A0, + 0x000A + }; + short i; + + + for ( i = 0; i < 8; i++ ) + { + if ( i < 5 ) + gray_palette[i] = i; + + SetRGB4( &fts->ViewPort, i, (UBYTE)(color[i] >> 8 & 0x0f), + (UBYTE)(color[i] >> 4 & 0x0f), + (UBYTE)(color[i] & 0x0f ) ); + } + } + + + /* open libraries & custom screen */ + + static int AmigaInit( void ) + { + /* cleanup at exit */ + if ( atexit( AmigaCleanUp ) ) + { + PutStr( "atexit() failed\n" ); + return -1; + } + + /* open intuition library */ + + IntuitionBase = (struct Library*)OpenLibrary( "intuition.library", 37L ); + if ( IntuitionBase == NULL ) + { + PutStr( "Could not open intuition library\n" ); + return -1; + } + + /* Open graphics library */ + + GfxBase = OpenLibrary( "graphics.library", 37L ); + if ( GfxBase == NULL ) + { + PutStr( "Could not open graphics library\n" ); + return -1; + } + + if ( graphx_mode == Graphics_Mode_Gray ) + { + /* open custom screen */ + fts = (struct Screen*)OpenScreenTags( + NULL, + SA_DisplayID, (PAL_MONITOR_ID | LORES_KEY), + SA_Width, GRAY_SCREEN_WIDTH, + SA_Height, GRAY_SCREEN_HEIGHT, + SA_Depth, GRAY_SCREEN_DEPTH, + SA_ShowTitle, FALSE, + TAG_DONE ); + + if ( fts == NULL ) + { + PutStr( "Could not open custom screen\n" ); + return -1; + } + + /* set gray palette */ + SetPalette(); + } + else + { + /* open custom screen */ + fts = (struct Screen*)OpenScreenTags( + NULL, + SA_DisplayID, (PAL_MONITOR_ID | HIRESLACE_KEY), + SA_Width, MONO_SCREEN_WIDTH, + SA_Height, MONO_SCREEN_HEIGHT, + SA_Depth, MONO_SCREEN_DEPTH, + SA_ShowTitle, FALSE, + TAG_DONE ); + + if ( fts == NULL ) + { + PutStr( "Could not open custom screen\n" ); + return -1; + } + } + + /* open intuition window */ + ftw = OpenWindowTags( + NULL, + WA_Left, 0, + WA_Width, fts->Width, + WA_Top, 0, + WA_Height, fts->Height, + WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS, + WA_Flags, WFLG_BACKDROP | WFLG_BORDERLESS | + WFLG_RMBTRAP | WFLG_ACTIVATE, + WA_Gadgets, NULL, + WA_Title, NULL, + WA_CustomScreen, fts, + TAG_DONE ); + + if ( ftw == NULL ) + { + PutStr( "Could not open intuition window\n" ); + return -1; + } + + if ( graphx_mode == Graphics_Mode_Gray ) + { + Vio = (char*)AllocMem( DISPLAY_MEM, MEMF_ANY ); + + if ( !Vio ) + { + PutStr( "Cannot AllocMem() display memory\n" ); + return -1; + } + + vio_Width = vio_ScanLineWidth = GRAY_SCREEN_WIDTH; + vio_Height = GRAY_SCREEN_HEIGHT; + } + else + { + Vio = (char*)fts->BitMap.Planes[0]; + vio_ScanLineWidth = fts->BitMap.BytesPerRow; + vio_Width = MONO_SCREEN_WIDTH; + vio_Height = MONO_SCREEN_HEIGHT; + } + + return 0; + } + + + /* get events in the window */ + + static char Get_Intuition_Event( void ) + { + struct IntuiMessage* msg; + ULONG class; + USHORT code; + + + WaitPort( ftw->UserPort ); + + while ( ( msg = (struct IntuiMessage*)GetMsg( ftw->UserPort ) ) ) + { + class = msg->Class; + code = msg->Code; + + ReplyMsg( (struct Message*)msg ); + + switch ( class ) + { + case IDCMP_MOUSEBUTTONS: + return (char)27; + + case IDCMP_VANILLAKEY: + return (char)code; + } + } + + return '\0'; + } + + + /* set Amiga graphics mode */ + + int Driver_Set_Graphics( int mode ) + { + graphx_mode = mode; + + + if ( AmigaInit() == -1 ) + return 0; /* failure */ + + return 1; /* success */ + } + + + /* restore screen to its original state */ + + int Driver_Restore_Mode( void ) + { + /* do nothing */ + + return 1; /* success */ + } + + + /* display bitmap */ + + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int y, z; + char* target; + char old = -1; + + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { + CopyMem( buffer, target, col ); + target -= vio_ScanLineWidth; + buffer += col; + } + + if ( graphx_mode == Graphics_Mode_Gray ) + { + /* clear screen */ + SetRast( &fts->RastPort, 0 ); + + /* draw glyph */ + for ( y = 0; y < line; y++ ) + { + for ( z = 0; z < col; z++ ) + { + int c = Vio[y * vio_ScanLineWidth + z]; + + if ( c != 0 ) + { + if ( old != c ) + { + if ( c < 0 || c > 5 ) + { + PutStr( "Unexpected value!\n" ); + SetAPen( &fts->RastPort, 7 ); + } + else + { + old = c; + SetAPen( &fts->RastPort, c ); + } + } + + WritePixel( &fts->RastPort, z, y ); + } + } + } + } + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + int i; + char c; + + + c = Get_Intuition_Event(); + + if ( c != '\0' ) + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + /* unrecognized keystroke */ + + event->what = event_Keyboard; + event->info = (int)c; + + return; + } + + +/* End */ diff --git a/test/arch/amigaos/gw_amiga.c b/test/arch/amigaos/gw_amiga.c new file mode 100644 index 0000000..73116bd --- /dev/null +++ b/test/arch/amigaos/gw_amiga.c @@ -0,0 +1,522 @@ +/******************************************************************* + * + * gw_amiga.c graphics utility Intuition Amiga driver. + * + * This is the driver for windowed display under Amiga WorkBench, + * used by the graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +/* modified by Richard Griffith + open largest window we can, and adapt accordingly + gray and mono both appear black on white + display Header message in Window title + add simple menus + */ + +/* standard includes */ + +#include +#include + +/* AmigaOS includes */ + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif + +/* FreeType includes */ + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +/* some screen definitions */ + +#define MONO_WINDOW_WIDTH 0xFFFF +#define MONO_WINDOW_HEIGHT 0xFFFF + +#define GRAY_WINDOW_WIDTH 0xFFFF +#define GRAY_WINDOW_HEIGHT 0xFFFF + +#define DISPLAY_MEM ( 1024 * 64 ) + + + /* external variables */ + extern struct Library* SysBase; + extern struct Library* DOSBase; + + extern int vio_ScanLineWidth; + extern char* Vio; +/* extern char gray_palette[5]; */ + + /* global variables */ + struct Library* IntuitionBase = NULL; + struct Library* GfxBase = NULL; + struct Library *GadToolsBase = NULL; + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + /* local variables */ + static struct Screen* fts = NULL; + static struct Window* ftw = NULL; + static APTR VisualInfo = NULL; + static struct Menu *ftmenus = NULL; + + static int graphx_mode; + + static ULONG vio_allocsize; + + static struct NewMenu ftNewMenu[] = { + {NM_TITLE, (STRPTR)"File", NULL, 0, NULL, NULL}, + {NM_ITEM, (STRPTR)"Next", (STRPTR)"n", 0, 0L, (APTR)'n'}, + {NM_ITEM, (STRPTR)"Previous",(STRPTR)"p", 0, 0L, (APTR)'p'}, + {NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL}, + {NM_ITEM, (STRPTR)"Quit", (STRPTR)"q", 0, 0L, (APTR)'q'}, + {NM_TITLE, (STRPTR)"Options", NULL, 0, NULL, NULL}, + {NM_ITEM, (STRPTR)"Scale Up", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"Fine", (STRPTR)"u", 0, 0L, (APTR)'u'}, + {NM_SUB, (STRPTR)"Fast", (STRPTR)"+", 0, 0L, (APTR)'+'}, + {NM_ITEM, (STRPTR)"Scale Down", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"Fine", (STRPTR)"j", 0, 0L, (APTR)'j'}, + {NM_SUB, (STRPTR)"Fast", (STRPTR)"-", 0, 0L, (APTR)'-'}, + {NM_ITEM, (STRPTR)"Toggle Hinting", (STRPTR)"h", 0, 0L, (APTR)'h'}, + {NM_ITEM, (STRPTR)"Toggle Kerning", (STRPTR)"K", 0, 0L, (APTR)'K'}, + {NM_ITEM, (STRPTR)"Toggle sbit", (STRPTR)"B", 0, 0L, (APTR)'B'}, + {NM_ITEM, (STRPTR)"Toggle GSUB", (STRPTR)"G", 0, 0L, (APTR)'G'}, + {NM_TITLE, (STRPTR)"Glyph", NULL, 0, NULL, NULL}, + {NM_ITEM, (STRPTR)"Next", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"1", (STRPTR)"l", 0, 0L, (APTR)'l'}, + {NM_SUB, (STRPTR)"10", (STRPTR)"o", 0, 0L, (APTR)'o'}, + {NM_SUB, (STRPTR)"100", (STRPTR)"0", 0, 0L, (APTR)'0'}, + {NM_SUB, (STRPTR)"1000", (STRPTR)")", 0, 0L, (APTR)')'}, + {NM_SUB, (STRPTR)"10000",(STRPTR)"}", 0, 0L, (APTR)'}'}, + {NM_ITEM, (STRPTR)"Previous", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"1", (STRPTR)"k", 0, 0L, (APTR)'k'}, + {NM_SUB, (STRPTR)"10", (STRPTR)"i", 0, 0L, (APTR)'i'}, + {NM_SUB, (STRPTR)"100", (STRPTR)"9", 0, 0L, (APTR)'9'}, + {NM_SUB, (STRPTR)"1000", (STRPTR)"(", 0, 0L, (APTR)'('}, + {NM_SUB, (STRPTR)"10000",(STRPTR)"{", 0, 0L, (APTR)'{'}, + {NM_TITLE, (STRPTR)"Rotate", NULL, 0, NULL, NULL}, + {NM_ITEM, (STRPTR)"Clockwise", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"Fine", (STRPTR)"c", 0, 0L, (APTR)'c'}, + {NM_SUB, (STRPTR)"Fast", (STRPTR)"b", 0, 0L, (APTR)'b'}, + {NM_ITEM, (STRPTR)"Counter-clockwise", NULL, 0, NULL, NULL}, + {NM_SUB, (STRPTR)"Fine", (STRPTR)"x", 0, 0L, (APTR)'x'}, + {NM_SUB, (STRPTR)"Fast", (STRPTR)"v", 0, 0L, (APTR)'v'}, + {NM_END, NULL, NULL, 0, 0L, NULL} }; + + + /* Exit gracefully */ + static void AmigaCleanUp( void ) + { + if ( Vio ) + FreeMem( Vio, vio_allocsize ); + + ReleasePen( fts->ViewPort.ColorMap, gray_palette[0] ); + ReleasePen( fts->ViewPort.ColorMap, gray_palette[1] ); + + if ( graphx_mode == Graphics_Mode_Gray ) + { + ReleasePen( fts->ViewPort.ColorMap, gray_palette[2] ); + ReleasePen( fts->ViewPort.ColorMap, gray_palette[3] ); + ReleasePen( fts->ViewPort.ColorMap, gray_palette[4] ); + } + + if ( ftmenus ) + { + ClearMenuStrip( ftw ); + FreeMenus( ftmenus ); + } + + if ( ftw ) + CloseWindow( ftw ); + + if ( VisualInfo ) + FreeVisualInfo( VisualInfo ); + + if ( GfxBase ) + CloseLibrary( GfxBase ); + + if ( GadToolsBase ) + CloseLibrary( GadToolsBase ); + + if ( IntuitionBase ) + CloseLibrary( IntuitionBase ); + + } + + + /* open libraries & custom screen */ + static int AmigaInit( void ) + { + /* cleanup at exit */ + if ( atexit( AmigaCleanUp ) ) + { + PutStr( "atexit() failed\n" ); + return -1; + } + + /* open intuition library */ + IntuitionBase = (struct Library*)OpenLibrary( "intuition.library", 39L ); + if ( IntuitionBase == NULL ) + { + PutStr( "Could not open intuition library\n" ); + return -1; + } + + /* open gaadtools library */ + GadToolsBase = (struct Library*)OpenLibrary( "gadtools.library", 39L ); + if ( GadToolsBase == NULL ) + { + PutStr( "Could not open gadtools library\n" ); + return -1; + } + + /* open graphics library */ + GfxBase = OpenLibrary( "graphics.library", 39L ); + if ( GfxBase == NULL ) + { + PutStr( "Could not open graphics library\n" ); + return -1; + } + + /* get public screen */ + fts = LockPubScreen( NULL ); + + if ( fts == NULL ) + { + PutStr( "Could not lock public screen\n" ); + return -1; + } + + if ( ! ( VisualInfo = GetVisualInfo( fts, TAG_DONE ))) + { + PutStr( "Could not get VisualInfo\n" ); + return -1; + } + + if ( graphx_mode == Graphics_Mode_Gray ) + { + vio_ScanLineWidth = GRAY_WINDOW_WIDTH; + vio_Width = GRAY_WINDOW_WIDTH; + vio_Height = GRAY_WINDOW_HEIGHT; + + gray_palette[4] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0x00000000, 0x00000000, 0x00000000, NULL ); + gray_palette[3] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0x33333300, 0x33333300, 0x33333300, NULL ); + gray_palette[2] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0x77777700, 0x77777700, 0x77777700, NULL ); + gray_palette[1] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0xBBBBBB00, 0xBBBBBB00, 0xBBBBBB00, NULL ); + gray_palette[0] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0xFFFFFF00, 0xFFFFFF00, 0xFFFFFF00, NULL ); + } + else + { + vio_ScanLineWidth = MONO_WINDOW_WIDTH / 8; + vio_Width = MONO_WINDOW_WIDTH; + vio_Height = MONO_WINDOW_HEIGHT; + + gray_palette[0] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0xFFFFFF00, 0xFFFFFF00, 0xFFFFFF00, NULL ); + gray_palette[1] = ObtainBestPenA( fts->ViewPort.ColorMap, + 0x00000000, 0x00000000, 0x00000000, NULL ); + } + + if ( ! ( ftmenus = CreateMenus( ftNewMenu, GTMN_FrontPen, 0L, TAG_DONE))) + { + PutStr( "Could not create menus\n" ); + return -1; + } + + LayoutMenus( ftmenus, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE ); + + /* open intuition window */ + ftw = OpenWindowTags( + NULL, + WA_InnerWidth, vio_Width, + WA_InnerHeight, vio_Height, + WA_IDCMP, IDCMP_MENUPICK | IDCMP_VANILLAKEY | IDCMP_CLOSEWINDOW, + /* WA_AutoAdjust, TRUE, */ + WA_CloseGadget, TRUE, + WA_Activate, TRUE, + WA_DragBar, TRUE, + WA_SmartRefresh, TRUE, + WA_Gadgets, NULL, + WA_Flags, WFLG_DEPTHGADGET | WFLG_SMART_REFRESH, + WA_Title, (UBYTE*)"FreeType Project", + WA_NewLookMenus, TRUE, + WA_PubScreen, fts, + TAG_DONE ); + + if ( ftw == NULL ) + { + PutStr( "Could not open intuition window\n" ); + return -1; + } + + SetMenuStrip( ftw, ftmenus ); + + UnlockPubScreen( NULL, fts ); + + vio_Height = ftw->Height - ftw->BorderTop - ftw->BorderBottom - 2; + vio_Width = (ftw->Width - ftw->BorderLeft - ftw->BorderRight) & 0xFFFFFC; + + if ( graphx_mode == Graphics_Mode_Gray ) + { + vio_ScanLineWidth = vio_Width; + } else { + vio_ScanLineWidth = vio_Width / 8; + } + vio_allocsize = vio_Height * vio_ScanLineWidth; + + Vio = (char*)AllocMem( vio_allocsize, MEMF_ANY ); + if ( Vio == NULL ) + { + PutStr( "Could not allocate memory\n" ); + return -1; + } + + return 0; + } + + + /* get events in the window */ + static char Get_Intuition_Event( void ) + { + struct IntuiMessage* msg; + ULONG class; + USHORT code; + int rc; + struct MenuItem *n; + + + WaitPort( ftw->UserPort ); + + while ( ( msg = (struct IntuiMessage*)GetMsg( ftw->UserPort ) ) ) + { + class = msg->Class; + code = msg->Code; + + ReplyMsg( (struct Message*)msg ); + + switch( class ) + { + case IDCMP_REFRESHWINDOW: + GT_BeginRefresh( ftw ); + GT_EndRefresh( ftw, TRUE ); + break; + + case IDCMP_CLOSEWINDOW: + return (char)27; + + case IDCMP_VANILLAKEY: + return (char)code; + + case IDCMP_MENUPICK: + while( code != MENUNULL ) + { + n = ItemAddress( ftmenus, code ); + rc = (int)GTMENUITEM_USERDATA( n ); + code = n->NextSelect; + } /* despite loop, we only do one */ + return (char)rc; + } + } + + + return '\0'; + } + + + /* Set Amiga graphics mode */ + int Driver_Set_Graphics( int mode ) + { + graphx_mode = mode; + + if ( AmigaInit() == -1 ) + return 0; /* failure */ + + return 1; /* success */ + } + + + /* restore screen to its original state */ + int Driver_Restore_Mode( void ) + { + /* Do nothing */ + + return 1; /* success */ + } + + + /* display bitmap */ + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int y, z; + char* target; + char old = 0; + extern char Header[]; + + SetWindowTitles(ftw,Header,Header); + + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { + CopyMem( buffer, target, col ); + target -= vio_ScanLineWidth; + buffer += col; + } + + /* clear window */ + /* SetRast( ftw->RPort, gray_palette[0] ); */ + + SetAPen( ftw->RPort, gray_palette[0] ); + + RectFill( ftw->RPort, ftw->BorderLeft, ftw->BorderTop, + ftw->Width - ftw->BorderRight - 1, + ftw->Height - ftw->BorderBottom - 1 ); + + if ( graphx_mode != Graphics_Mode_Gray ) + { + SetAPen( ftw->RPort, gray_palette[1] ); + old = 1; + } + + /* Draw glyph */ + for ( y = 0; y < line; y++ ) + { + for ( z = 0; z < col; z++ ) + { + int c = Vio[y * vio_ScanLineWidth + z]; + + if ( graphx_mode == Graphics_Mode_Gray ) + { + if ( c != 0 && c != gray_palette[0] ) + { + if ( old != c ) + { + old = c; + /* printf("x = %d, y = %d, color = %d\n", z, y, c ); */ + SetAPen( ftw->RPort, c ); + } + + WritePixel( ftw->RPort, ftw->BorderLeft + z, ftw->BorderTop + y ); + } + } + else + { + int mask = 0x80; + int counter = 0; + + while ( mask ) + { + if ( mask & c ) + WritePixel( ftw->RPort, ftw->BorderLeft + z * 8 + counter, + ftw->BorderTop + y ); + + counter++; + mask >>= 1; + } + } + } + } + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + int i; + char c; + + + c = Get_Intuition_Event(); + + if ( c != '\0' ) + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + /* unrecognized keystroke */ + + event->what = event_Keyboard; + event->info = (int)c; + + return; + } + + +/* End */ diff --git a/test/arch/amigaos/smakefile b/test/arch/amigaos/smakefile new file mode 100644 index 0000000..b68944a --- /dev/null +++ b/test/arch/amigaos/smakefile @@ -0,0 +1,180 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for amiga using SAS/C +# and smake +# +# Use this file while in the 'test/arch/amigaos' directory with +# the following statements: +# +# smake assign +# smake +# +# the 'assign' step creates an assignment to simplify referencing +# the core library module, as smake has quite a few limitations in +# dealing with multi-directory projects. + +OBJB = ttapi.o ttcache.o ttcalc.o ttcmap.o ttdebug.o \ + ttextend.o ttfile.o ttgload.o ttinterp.o ttload.o \ + ttmemory.o ttmutex.o ttobjs.o ttraster.o + +OBJS = freetype.o + +OBJX = ftxgasp.o ftxkern.o ftxpost.o ftxcmap.o ftxwidth.o ftxerr18.o \ + ftxsbit.o ftxgsub.o ftxopen.o + +CORE = FT:lib/ +COREXT = $(CORE)extend/ +TST = FT:test/ + +OPTIMIZER = optimize optcomp=5 optdep=4 optinlocal optrdep=4 + +SCFLAGS = idlen=40 idir=$(CORE)arch/amigaos idir=$(CORE) + +TSCFLAGS = $(SCFLAGS) idir=$(TST) idir=$(COREXT) + +LIB=ttf.lib +TOPTS=$(TSCFLAGS) link lib=$(LIB) lib=lib:scm.lib \ + lib=lib:sc.lib lib=lib:amiga.lib + +EXE = ftzoom ftlint ftview fttimer ftmetric \ + ftdump ftstring ftstrpnm ftsbit ftstrtto + +TOBJ = gw_amiga.o gmain.o common.o blitter.o + +all: ttf.lib $(EXE) + +assign: + assign FT: /// + +ttf.lib: $(OBJS) $(OBJX) + oml $@ r $(OBJS) $(OBJX) + +ttfdbg.lib: $(OBJB) $(OBJX) + oml $@ r $(OBJB) $(OBJX) + +clean: + -delete \#?.o + -delete //\#?.o + -delete \#?.lib + -delete $(EXE) + + +# +# freetype library core single object +# +freetype.o: $(CORE)arch/amigaos/freetype.c + sc $(SCFLAGS) code=far $(OPTIMIZER) objname=$@ $< + +# +# freetype library core as separate objects +# +ttapi.o: $(CORE)ttapi.c + sc $(SCFLAGS) objname=$@ $< +ttcache.o: $(CORE)ttcache.c + sc $(SCFLAGS) objname=$@ $< +ttcalc.o: $(CORE)ttcalc.c + sc $(SCFLAGS) objname=$@ $< +ttcmap.o: $(CORE)ttcmap.c + sc $(SCFLAGS) objname=$@ $< +ttdebug.o: $(CORE)ttdebug.c + sc $(SCFLAGS) objname=$@ $< +ttextend.o: $(CORE)ttextend.c + sc $(SCFLAGS) objname=$@ $< +ttfile.o: $(CORE)ttfile.c + sc $(SCFLAGS) objname=$@ $< +ttgload.o: $(CORE)ttgload.c + sc $(SCFLAGS) objname=$@ $< +ttinterp.o: $(CORE)ttinterp.c + sc $(SCFLAGS) objname=$@ $< +ttload.o: $(CORE)ttload.c + sc $(SCFLAGS) objname=$@ $< +ttmemory.o: $(CORE)ttmemory.c + sc $(SCFLAGS) objname=$@ $< +ttmutex.o: $(CORE)ttmutex.c + sc $(SCFLAGS) objname=$@ $< +ttobjs.o: $(CORE)ttobjs.c + sc $(SCFLAGS) objname=$@ $< +ttraster.o: $(CORE)ttraster.c + sc $(SCFLAGS) objname=$@ $< + +# +# library extentions +# +ftxgasp.o: $(COREXT)ftxgasp.c + sc $(SCFLAGS) objname=$@ $< +ftxkern.o: $(COREXT)ftxkern.c + sc $(SCFLAGS) objname=$@ $< +ftxpost.o: $(COREXT)ftxpost.c + sc $(SCFLAGS) objname=$@ $< +ftxcmap.o: $(COREXT)ftxcmap.c + sc $(SCFLAGS) objname=$@ $< +ftxwidth.o: $(COREXT)ftxwidth.c + sc $(SCFLAGS) objname=$@ $< +ftxerr18.o: $(COREXT)ftxerr18.c + sc $(SCFLAGS) objname=$@ $< +ftxsbit.o: $(COREXT)ftxsbit.c + sc $(SCFLAGS) objname=$@ $< +ftxgsub.o: $(COREXT)ftxgsub.c + sc $(SCFLAGS) objname=$@ $< +ftxopen.o: $(COREXT)ftxopen.c + sc $(SCFLAGS) objname=$@ $< + +# +# Test programs +# +ftzoom: $(TST)ftzoom.c $(TOBJ) $(LIB) + sc $(TST)ftzoom.c programname=$@ $(TOBJ) $(TOPTS) + +ftlint: $(TST)ftlint.c common.o $(LIB) + sc $(TST)ftlint.c programname=$@ common.o $(TOPTS) + +ftdump: $(TST)ftdump.c common.o $(LIB) + sc $(TST)ftdump.c programname=$@ common.o $(TOPTS) + +# use unsigned char so full latin1 encoding may be used in string argument +ftstring: $(TST)ftstring.c $(TOBJ) display.o $(LIB) + sc $(TST)ftstring.c uchar programname=$@ $(TOBJ) display.o $(TOPTS) + +ftview: $(TST)ftview.c $(TOBJ) display.o $(LIB) + sc $(TST)ftview.c programname=$@ $(TOBJ) display.o $(TOPTS) + +fttimer: $(TST)fttimer.c $(TOBJ) $(LIB) + sc $(TST)fttimer.c programname=$@ $(TOBJ) $(TOPTS) + +ftstrpnm: $(TST)ftstrpnm.c common.o $(LIB) + sc $(TST)ftstrpnm.c uchar programname=$@ common.o $(TOPTS) + +ftsbit: $(TST)ftsbit.c common.o $(LIB) + sc $(TST)ftsbit.c programname=$@ common.o $(TOPTS) + +ftmetric: $(TST)ftmetric.c common.o $(LIB) + sc $(TST)ftmetric.c programname=$@ common.o $(TOPTS) + +# use unsigned char so full latin1/UTF8 encoding may be used in argument +ftstrtto: $(TST)ftstrtto.c $(TOBJ) display.o arabic.o $(LIB) + sc $(TST)ftstrtto.c uchar programname=$@ $(TOBJ) \ + arabic.o display.o $(TOPTS) + +# +# Test program support modules +# + +gw_amiga.o: gw_amiga.c + sc gw_amiga.c $(TSCFLAGS) + +common.o: $(TST)common.c + sc $(TSCFLAGS) objname=$@ $< + +blitter.o: $(TST)blitter.c + sc $(TSCFLAGS) objname=$@ $< + +display.o: $(TST)display.c + sc $(TSCFLAGS) objname=$@ $< + +gmain.o: $(TST)gmain.c + sc $(TSCFLAGS) objname=$@ $< + +arabic.o: $(TST)arabic.c + sc $(TSCFLAGS) objname=$@ $< + +# end of smakefile diff --git a/test/arch/debugger/Makefile b/test/arch/debugger/Makefile new file mode 100644 index 0000000..9c37019 --- /dev/null +++ b/test/arch/debugger/Makefile @@ -0,0 +1,99 @@ +# This file is part of the FreeType project. +# +# It builds the debugger for emx-gcc under OS/2 resp. under Unix. +# +# You will need GNU make. +# +# Use this file while in the `test' directory with the following statement: +# +# make -f arch/debugger/Makefile + +ARCH = arch/debugger +FT_MAKEFILE = $(ARCH)/Makefile + +CC = gcc + +LIBDIR = ../lib +LIBTTF = $(LIBDIR)/$(ARCH)/libttf.a + +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/extend -I$(LIBDIR)/$(ARCH) -I. + +# Note: The debugger uses non-ANSI functions to read the keyboard +# on OS/2 -- do not set the `-ansi flag here. +# +CFLAGS = -Wall -O0 -g $(INCDIRS) + + +SRC = fdebug.c common.c + +ALLSRC = $(SRC) +ALLOBJ = $(ALLSRC:.c=.o) + +# on OS/2, do not use the curses library +# +ifdef OS2_SHELL +EXE := fdebug.exe +OS := OS2 +EFENCE := +EXTRAFLAGS := +RM := del +else +EXE := fdebug +OS := UNIX +EFENCE := -lefence +RM := rm -f +# +# POSIX TERMIOS: Do not define if you use OLD U*ix like 4.2BSD. +# +EXTRAFLAGS := HAVE_POSIX_TERMIOS +endif + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< -D$(OS) -D$(EXTRAFLAGS) + +%.exe: + $(CC) $(CFLAGS) -o $@ $^ + + + +EXEFILES = $(EXE) + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +$(EXE): fdebug.o common.o $(LIBTTF) +$(EXE): + $(CC) $(CFLAGS) -o $@ $^ $(EFENCE) + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -$(RM) dep.end $(EXEFILES) core + +do_clean: + -$(RM) $(subst /,\,$(ALLOBJ)) + + +depend: $(ALLSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.emx diff --git a/test/arch/msdos/Makefile.BC b/test/arch/msdos/Makefile.BC new file mode 100644 index 0000000..825395b --- /dev/null +++ b/test/arch/msdos/Makefile.BC @@ -0,0 +1,181 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for BC++ under MSDOS, large model. +# +# Tested with Borland C++ v.3.1, 4.02, 5.0 +# You will need Borland MAKE (v.3.6 and above should be OK, for oldest +# versions refer to the instructions below). +# +# +# Use this file while in the 'test' directory with the following statement: +# +# make -farch\msdos\Makefile.BC +# +# +# Debug versions can be obtained with +# +# make -DDEBUG -farch\msdos\Makefile.BC +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# make -DBIGFONTS -farch\msdos\Makefile.BC + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.BC + +CC = bcc + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR);$(LIBDIR)\$(ARCH);.;$(LIBDIR)\extend +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -w-pia + +# Credits go to Dave Hoo for pointing out that modern +# Borland compilers (from BC++ 3.1 on) can increase the limit of +# the length of identifiers. +!if ! $d(DEBUG) +CFLAGS = -ml -A -O2 -3 -i40 $(INCDIRS) $(SPURIOUS_WARNINGS) +LDFLAGS = -ml +!else +CFLAGS = -v -N -ml -A -i40 $(INCDIRS) $(SPURIOUS_WARNINGS) +LDFLAGS = -v -ml +!endif + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)\.\gfs_dos.c + +DISPLAY = display.c + +G1SRC = gmain.c blitter.c $(GDRIVER) +GSRC = $(DISPLAY) $(G1SRC) + +GOBJ = $(GSRC:.c=.obj) +G1OBJ = $(G1SRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!if !$d(DEBUG) +# Skipped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +!if $d(BIGFONTS) +MAKEBIG = -DBIGFONTS +!endif + +freetype: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG $(MAKEBIG) debug + cd ..\test + + +# Borland C compilers are unable to include in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| + +.obj.exe: + $(CC) -e$* @&&| + $(LDFLAGS) $** +| + +# Borland versions of make are unable to use the $** variable inside +# implicit rules (like .obj.exe:). The job has to be done by hand. :-( +ftzoom.exe: $(G1OBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftzoom.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftview.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstring.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrtto.obj $(GOBJ) common.obj arabic.obj \ + $(LIBDIR)\libttf.lib + +fttimer.exe: $(G1OBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftlint.obj common.obj $(LIBDIR)\libttf.lib + +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftdump.obj common.obj $(LIBDIR)\libttf.lib + +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftsbit.obj common.obj $(LIBDIR)\libttf.lib + +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftmetric.obj common.obj $(LIBDIR)\libttf.lib + +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + del time.h # clean the ugly hack for Turbo C... + +!include "$(ARCH)\depend.dos" + +# end of Makefile diff --git a/test/arch/msdos/Makefile.MS b/test/arch/msdos/Makefile.MS new file mode 100644 index 0000000..46d6950 --- /dev/null +++ b/test/arch/msdos/Makefile.MS @@ -0,0 +1,142 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft C for MS-DOS, +# large model. It also works for Visual C++ 1.x 16-bits compiler, but +# you should instead use the Makefile customized for it, Makefile.VC. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\msdos\Makefile.MS +# +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\msdos\Makefile.MS +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# nmake BIGFONTS=1 /f arch\msdos\Makefile.MS + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.MS +FT_MAKE = $(MAKE) /nologo + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G2 $(INCDIRS) +LDFLAGS = /AL +!else +CFLAGS = /Zi /AL /Za /W2 /G2 $(INCDIRS) +LDFLAGS = /Zi /AL +!endif + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)\gfs_dos.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +!ifdef BIGFONTS +MAKEBIG = BIGFONTS=1 +!endif + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 $(MAKEBIG) debug + cd ..\test + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + + +!include "$(ARCH)\depend.dos" + +# end of Makefile.MS diff --git a/test/arch/msdos/Makefile.TC b/test/arch/msdos/Makefile.TC new file mode 100644 index 0000000..9422329 --- /dev/null +++ b/test/arch/msdos/Makefile.TC @@ -0,0 +1,196 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Turbo C under MSDOS, large model. +# +# You will need Borland MAKE. +# Tested with Turbo C v.1.5, v.2.0, Turbo C++ v.1.0 +# Turbo C v.1.0 (May '87) is too old (lack of structure assignment) +# to compile FreeType. Update your compiler. ;-) +# +# +# Use this file while in the 'test' directory with the following statement: +# +# make -farch\msdos\Makefile.TC +# +# +# Debug versions can be obtained (except for TC 1.5) with +# +# make -DDEBUG -farch\msdos\Makefile.TC + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.TC + +CC = tcc + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR);$(LIBDIR)\$(ARCH);.;$(LIBDIR)\extend + +!if ! $d(DEBUG) +CFLAGS = -ml -A -O -Z -G -a -w-stv -w-sig $(INCDIRS) +LDFLAGS = -ml +!else +# For Turbo C v.1.5, replace the -v option below by -y. +CFLAGS = -v -N -ml -A -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig $(INCDIRS) +LDFLAGS = -v -ml +!endif + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)\.\gfs_dos.obj + +# the line below does not work with these old versions of make... +# GOBJ = $(GSRC:.c=.o) + +DISPLAY = display.obj + +G1OBJ = gmain.obj blitter.obj $(GDRIVER) +GOBJ = $(DISPLAY) $(G1OBJ) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = arabic.obj \ + common.obj \ + ftdump.obj \ + fterror.obj \ + ftlint.obj \ + ftmetric.obj \ + ftsbit.obj \ + ftstring.obj \ + ftstrpnm.obj \ + ftstrtto.obj \ + fttimer.obj \ + ftview.obj \ + ftzoom.obj + + +.c.obj: + $(CC) $(CFLAGS) -c -o$* $< + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + + +!if !$d(DEBUG) +# Skipped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +freetype: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG debug + cd ..\test + + +# Borland C compilers are unable to include in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER): + $(CC) $(CFLAGS) -A- -c -o$* $*.c + +!if $(__MAKE__) < 0x0300 +# Also, Turbo C v.1.5 and v.2.0 are not fully ANSI compliant with regard to +# , particularly the clock() function. +# So we use an ugly hack here: a modified version of time.h, with the +# necessary machinery, is included in the arch\msdos directory. +time.h: $(ARCH)\time_tc.h + copy $(ARCH)\time_tc.h time.h + +# Below is the special rule for forcing recompilation of fttimer.obj +# using our , without using the rule that is pulled in by +# !include "$(ARCH)\depend.dos" at the end of the Makefile... +fttimer.exe: $(G1OBJ) fttimer.c time.h common.obj $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) -c -o$* $*.c + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +!else +# Normal behaviour +fttimer.exe: $(G1OBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib +!endif + + +# This old gr... make is unable to have a $ variable to name all the +# dependencies. :-( So the job have to be done by hand... +ftzoom.exe: $(G1OBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftzoom.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftview.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstring.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrtto.obj $(GOBJ) common.obj \ + arabic.obj $(LIBDIR)\libttf.lib + +# fttimer.exe is handled above (because of hack) + +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftlint.obj common.obj $(LIBDIR)\libttf.lib + +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftdump.obj common.obj $(LIBDIR)\libttf.lib + +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftsbit.obj common.obj $(LIBDIR)\libttf.lib + +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftmetric.obj common.obj $(LIBDIR)\libttf.lib + +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + del time.h # clean the ugly hack for Turbo C... + +!include "$(ARCH)\depend.dos" + +# end of Makefile diff --git a/test/arch/msdos/Makefile.VC b/test/arch/msdos/Makefile.VC new file mode 100644 index 0000000..c39bb16 --- /dev/null +++ b/test/arch/msdos/Makefile.VC @@ -0,0 +1,143 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft Visual C++ 1.x +# and Microsoft C/C++ v.7.0 16-bit compilers for MS-DOS, large model. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\msdos\Makefile.VC +# +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\msdos\Makefile.VC +# +# A special version enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# nmake BIGFONTS=1 /f arch\msdos\Makefile.VC + +ARCH = arch\msdos +FT_MAKEFILE = $(ARCH)\Makefile.VC +FT_MAKE = $(MAKE) /nologo + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +# One can also consider using "set MSC_CMD_FLAGS=/Gr /Op- /Gy /YX". +# With Microsoft C/C++ 7.0, use /G2 instead of /G3. +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G3 $(INCDIRS) +LDFLAGS = /AL +!else +CFLAGS = /Zi /Ge /AL /Za /W2 /G3 $(INCDIRS) +LDFLAGS = /Zi /AL +!endif + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)\gfs_dos.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +!ifdef BIGFONTS +MAKEBIG = BIGFONTS=1 +!endif + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 $(MAKEBIG) debug + cd ..\test + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + + +!include "$(ARCH)\depend.dos" + +# end of Makefile.VC diff --git a/test/arch/msdos/Makefile.dm b/test/arch/msdos/Makefile.dm new file mode 100644 index 0000000..19a4d05 --- /dev/null +++ b/test/arch/msdos/Makefile.dm @@ -0,0 +1,145 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc and djgpp under MSDOS. +# +# You will need dmake. +# +# Use this file while in the 'test' directory with the following statement: +# +# dmake -r -f arch/msdos/Makefile.dm + +ARCH = arch/msdos +FT_MAKEFILE = $(ARCH)/Makefile.dm +FT_MAKE = dmake -r + +.IMPORT: COMSPEC +SHELL := $(COMSPEC) +SHELLFLAGS := /c +GROUPSHELL := $(SHELL) +GROUPFLAGS := $(SHELLFLAGS) +GROUPSUFFIX := .bat +SHELLMETAS := *"?<>&| + +CC = gcc + +LIBDIR = ../lib +LIBDIR_DOS = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +CFLAGS = -Wall -ansi -O2 -g $(INCDIRS) +# CFLAGS = -ansi -Wall -O2 -s $(INCDIRS) + +# full-screen MSDOS driver +GDRIVER = $(ARCH)/gfs_dos.c + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(GDRIVER) +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ @$(mktmp $(&:t"\n")\n) + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean do_distclean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +freetype: +[ + cd $(LIBDIR_DOS) + $(FT_MAKE) -f $(FT_MAKEFILE) all + cd $(MAKEDIR) +] + +freetype_debug: +[ + cd $(LIBDIR_DOS) + $(FT_MAKE) -f $(FT_MAKEFILE) debug + cd $(MAKEDIR) +] + +ftzoom.exe: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean +[ + cd $(LIBDIR_DOS) + $(FT_MAKE) -f $(FT_MAKEFILE) clean + cd $(MAKEDIR) +] + +distclean: do_clean do_distclean +[ + cd $(LIBDIR_DOS) + $(FT_MAKE) -f $(FT_MAKEFILE) distclean + cd $(MAKEDIR) +] + +do_distclean: +-[ + del dep.end + del *.exe + del core +] + +do_clean: +-[ + del *.o + del $(ARCH)\gfs_dos.o +] + +#depend: $(SRC) $(GSRC) +#[ +# cd $(LIBDIR_DOS) +# $(FT_MAKE) -f $(FT_MAKEFILE) depend +# cd $(MAKEDIR) +# $(CC) -E -M $(INCDIRS) @$(mktmp $(<:t"\n")\n) > dep.end +#] +# +#ifeq (dep.end,$(wildcard dep.end)) +# include dep.end +#endif + +# end of Makefile.dm diff --git a/test/arch/msdos/Makefile.gcc b/test/arch/msdos/Makefile.gcc new file mode 100644 index 0000000..806ca87 --- /dev/null +++ b/test/arch/msdos/Makefile.gcc @@ -0,0 +1,130 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc and djgpp under MSDOS. +# +# You will need a recent GNU make DOS port. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/msdos/Makefile.gcc +# +# +# If you have the GNU gettext package installed with DJGPP, you can also try +# +# make -f arch/msdos/Makefile.gcc HAVE_GETTEXT + +ARCH = arch/msdos +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +ifndef GETTEXT +GETTEXT=NO_GETTEXT +endif + +CFLAGS = -Wall -ansi -O2 -g $(INCDIRS) -D$(GETTEXT) +# CFLAGS = -ansi -Wall -O2 -s $(INCDIRS) -D$(GETTEXT) + + +# full-screen MSDOS driver +GDRIVER = $(ARCH)/gfs_dos.c + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(GDRIVER) +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +ifeq ($(GETTEXT),HAVE_GETTEXT) +%.exe: + $(CC) $(CFLAGS) -o $@ $^ -lintl +else +%.exe: + $(CC) $(CFLAGS) -o $@ $^ +endif + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +HAVE_GETTEXT: + $(MAKE) -f $(FT_MAKEFILE) GETTEXT=HAVE_GETTEXT all + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom.exe: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +fterror.exe: fterror.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -del dep.end + -del *.exe + -del core + +do_clean: + -del *.o + -del response + -del $(ARCH)\gfs_dos.o + +depend: $(SRC) $(GSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/test/arch/msdos/depend.dos b/test/arch/msdos/depend.dos new file mode 100644 index 0000000..3abb6f8 --- /dev/null +++ b/test/arch/msdos/depend.dos @@ -0,0 +1,50 @@ +# This dependency file to be used with various MS-DOS compilers +# has been generated automatically with the script `makedep' on +# 03-Sep-1999. + +arabic.obj: arabic.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h +blitter.obj: blitter.c blitter.h +common.obj: common.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +display.obj: display.c display.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gmain.h +fdebug.obj: fdebug.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\tttypes.h ..\lib\ttconfig.h \ + ..\lib\arch\msdos\ft_conf.h ..\lib\ttdebug.h ..\lib\ttobjs.h \ + ..\lib\ttengine.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +ftdump.obj: ftdump.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxcmap.h ..\lib\extend\ftxopen.h \ + ..\lib\extend\ftxgdef.h ..\lib\extend\ftxgsub.h \ + ..\lib\extend\ftxgpos.h ..\lib\extend\ftxsbit.h ..\lib\ttobjs.h \ + ..\lib\ttconfig.h ..\lib\arch\msdos\ft_conf.h ..\lib\ttengine.h \ + ..\lib\tttypes.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +fterror.obj: fterror.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxerr18.h \ + ..\lib\arch\msdos\ft_conf.h +ftlint.obj: ftlint.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\arch\msdos\ft_conf.h +ftmetric.obj: ftmetric.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\msdos\ft_conf.h +ftsbit.obj: ftsbit.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\msdos\ft_conf.h +ftstring.obj: ftstring.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h display.h gevents.h gdriver.h gmain.h +ftstrpnm.obj: ftstrpnm.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +ftstrtto.obj: ftstrtto.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h blitter.h common.h \ + display.h ..\lib\extend\ftxkern.h ..\lib\extend\ftxsbit.h gdriver.h \ + gevents.h gmain.h +fttimer.obj: fttimer.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gdriver.h gevents.h gmain.h +ftview.obj: ftview.c blitter.h common.h display.h \ + ..\lib\extend\ftxsbit.h gdriver.h gevents.h gmain.h +ftzoom.obj: ftzoom.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxpost.h gdriver.h gevents.h gmain.h +gmain.obj: gmain.c gdriver.h gmain.h +arch\msdos\gfs_dos.obj: arch\msdos\gfs_dos.c gdriver.h gevents.h gmain.h diff --git a/test/arch/msdos/gfs_dos.c b/test/arch/msdos/gfs_dos.c new file mode 100644 index 0000000..78a7023 --- /dev/null +++ b/test/arch/msdos/gfs_dos.c @@ -0,0 +1,357 @@ +/******************************************************************* + * + * gfs_dos.c graphics utility fullscreen Dos driver. 1.0 + * + * This is the driver for fullscreen Dos display, used by the + * graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#if defined( __STDC__ ) || defined( __TURBOC__ ) +#include +#else +#include +#endif + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +/* The following #ifdef are used to define the following macros : */ +/* */ +/* - int86 : function to call an interrupt */ +/* - reg_ax : the 'ax' register as stored in the REGS struct */ +/* */ + +/* ---- DJGPP dos compiler support --------------------------------------- */ + +/* DJGPP v1.x */ +#if !defined( __DJGPP__ ) && defined( __GO32__ ) + +#define DJGPP1 +#undef __STRICT_ANSI__ +#include +#include +#include +#include + +#define reg_ax regs.x.ax + +#endif + +/* DJGPP v2.x */ +#ifdef __DJGPP__ + +#define DJGPP2 +#undef __STRICT_ANSI__ +#include +#include +#include +#define int86( a, b, c ) int86( a, b, c ) +#define reg_ax regs.x.ax + +#endif + +/* ---- Microsoft C compilers support ------------------------------------ */ + +#if defined( M_I86 ) || defined( _M_I86 ) + +#include +#include + +#define reg_ax regs.x.ax + +#ifdef _M_I86 /* a recent compiler, which do not pollute name spaces */ +#define getch() _getch() +#define REGS _REGS +#define int86( a, b, c ) _int86( a, b, c ) +#endif + +#ifndef MK_FP +#ifdef _MK_FP +#define MK_FP( seg, ofs ) _MK_FP( seg, ofs ) +#else +#ifndef _M_I86 /* old versions */ +#define __far _far +#endif +#define MK_FP( seg, offset ) (void __far *)( ((unsigned long)seg << 16) + \ + (unsigned long)(unsigned)offset ) +#endif /* _MK_FP */ +#endif /* MK_FP */ + +#endif /* Microsoft compilers */ + +/* ---- Borland C compiler support --------------------------------------- */ + +#ifdef __TURBOC__ +#ifdef __STDC__ +#error "MK_FP is incompatible with ANSI mode. Use the `-A-' switch." +#endif + +#include /* Includes the declaration of int86 */ +#include /* for getch */ + +#define reg_ax regs.x.ax +#define int86( a, b, c ) int86( a, b, c ) + +#endif + +/* ---- Phar Lap 286|DOS extender support -------------------------------- */ + +#ifdef DOSX286 +/* The symbol DOSX286 must be specified on the command line. */ + +#include +#endif + +/* ---- EMX/Dos compiler support ----------------------------------------- */ + +#ifdef __EMX__ + +#include +#include +#include /* for getch */ + extern _read_kbd(); /* to avoid an ANSI warning during compilation */ + +#define int86 _int86 +#define reg_ax regs.x.ax + +#endif + +/* ---- WATCOM Dos/16 & Dos/32 support ----------------------------------- */ + +#ifdef __WATCOMC__ + +#include + +#define reg_ax regs.w.ax + +#ifdef __386__ +#define int86 int386 +#endif + +#endif + + +#if !defined( reg_ax ) || !defined( int86 ) +#error "Your compiler is not (yet) supported. Check the source file!" +#endif + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + /* Set Graphics Mode */ + + int Driver_Set_Graphics( int mode ) + { + union REGS regs; + + + switch ( mode ) + { + case Graphics_Mode_Mono: /* Standard VGA 640x480x16 mode */ + reg_ax = 0x12; + int86( 0x10, ®s, ®s ); + + vio_ScanLineWidth = 80; + vio_Width = 640; + vio_Height = 480; + break; + + case Graphics_Mode_Gray: /* Standard VGA 320x200x256 mode */ + reg_ax = 0x13; + int86( 0x10, ®s, ®s ); + + vio_ScanLineWidth = 320; + vio_Width = 320; + vio_Height = 200; + + /* default gray_palette takes the gray levels of the standard VGA */ + /* 256 colors mode */ + + gray_palette[0] = 0; + gray_palette[1] = 23; + gray_palette[2] = 27; + gray_palette[3] = 29; + gray_palette[4] = 31; + break; + + default: + return 0; /* failure */ + } + +#if defined( __EMX__ ) + Vio = _memaccess( 0xA0000, 0xAFFFF, 1 ); +#elif defined( DJGPP1 ) || defined( DJGPP2 ) + Vio = (char *)0xA0000; +#elif defined( __WATCOMC__ ) && defined( __386__ ) + Vio = (char *)0xA0000; +#elif defined( DOSX286 ) + { + unsigned short sel; + + + if ( DosMapRealSeg( 0xA000, (long)vio_ScanLineWidth*vio_Height, &sel ) ) + return 0; /* failure */ + + Vio = (char*)MK_FP( sel, 0 ); + } +#else + Vio = (char*)MK_FP( 0xA000, 0 ); +#endif + + return 1; /* success */ + } + + + /* Revert to text mode */ + + int Driver_Restore_Mode() + { + union REGS regs; + + + reg_ax = 0x3; + int86( 0x10, ®s, ®s ); + +#ifdef DOSX286 + +#ifndef FP_SEG +#define FP_SEG(fp) (*((unsigned __far *)&(fp) + 1)) +#endif + + DosFreeSeg( FP_SEG( Vio ) ); +#endif + + return 1; /* success */ + } + + + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int y, used_col; + char* target; + + +#ifdef DJGPP2 + char cbuf = 0; + int i; + for( i = 0; i < vio_Height*vio_ScanLineWidth; i++ ) + dosmemput( &cbuf, 1, (unsigned long) Vio+i ); +#else + +#ifdef DJGPP1 + __djgpp_nearptr_enable(); + Vio += __djgpp_conventional_base; + +#else + + memset( Vio, 0, vio_Height * vio_ScanLineWidth ); + +#endif /* DJGPP1 */ + +#endif /* DJGPP2 */ + + if ( line > vio_Height ) + line = vio_Height; + if ( col > vio_ScanLineWidth ) + used_col = vio_ScanLineWidth; + else + used_col = col; + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { +#ifdef DJGPP2 + dosmemput( buffer, used_col, (unsigned long)target ); +#else + memcpy( target, buffer, used_col ); +#endif + target -= vio_ScanLineWidth; + buffer += col; + } + +#ifdef DJGPP1 + __djgpp_nearptr_disable(); + Vio -= __djgpp_conventional_base; +#endif + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + int i; + char c; + + + c = getch(); + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + /* unrecognized keystroke */ + + event->what = event_Keyboard; + event->info = (int)c; + return; + } + + +/* End */ diff --git a/test/arch/msdos/makedep b/test/arch/msdos/makedep new file mode 100644 index 0000000..a5ace5a --- /dev/null +++ b/test/arch/msdos/makedep @@ -0,0 +1,22 @@ +# makedep +# +# This shell script creates a dependency file necessary for older compilers +# on the MS-DOS platform. + +echo "\ +# This dependency file to be used with various MS-DOS compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.dos + +(cd ../.. + gcc -MM -I../lib/arch/msdos -I../lib -I../lib/extend -I. *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.dos + +(cd ../.. + gcc -MM -I../lib/arch/win16 -I../lib -I../lib/extend -I. \ + -Dreg_ax -Dint86 arch/msdos/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\msdos\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.dos + +# eof diff --git a/test/arch/msdos/time_tc.h b/test/arch/msdos/time_tc.h new file mode 100644 index 0000000..d28a7c2 --- /dev/null +++ b/test/arch/msdos/time_tc.h @@ -0,0 +1,124 @@ +/******************************************************************* + * + * time.h Replacement for buggy of old Turbo C compilers + * + * This file is a hack! It replaces when compiling with + * old versions of Borland Turbo C compilers that lack clock(), + * and provide its own version. + * + * Written by Antoine Leca + * Copyright 1999 Antoine Leca, David Turner, Robert Wilhelm + * and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#if !defined __TURBOC__ || !defined __MSDOS__ || __TURBOC__>0x200 +/* + * We are not running on a Borland compiler, or either on + * a recent version that does not need the hack. + * Certainly the user does not clean up the directory. + * Stop the compilation. + */ +#error Remove the file time.h in directory test + +#endif + +#ifndef _TIME_H_DEFINED +#define _TIME_H_DEFINED + +#if defined _TM_DEFINED || defined _TIME_T +#error Another version of seems to have been already included +#endif + +#ifndef __TIME_T +#define __TIME_T +typedef long time_t; +#endif + +#ifndef __CLOCK_T +#define __CLOCK_T +typedef long clock_t; +#define CLK_TCK 18.2 +#endif + +#define CLOCKS_PER_SEC CLK_TCK + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + + +clock_t clock (void); +double difftime(time_t time2, time_t time1); +time_t time (time_t *timer); + +char *asctime (const struct tm *tblock); +char *ctime (const time_t *time); +struct tm *gmtime (const time_t *timer); +struct tm *localtime(const time_t *timer); + + +#if __TURBOC__ <= 0x0150 + +/******************************************************************* + * + * Function : clock + * + * Description : Turbo C v.1.x lacks the clock() function that is + * needed for at least fttimer. + * So this is a replacement that does more or less + * the functionnality of clock(), using the BIOS. + * Since we do not know exactly when the process + * started (as clock() is supposed to do), we cheat + * a little here. + * + * Input : None + * + * Output : None + * + * Notes : Use two static objects. + * NEED_CLOCK_HERE is a macro that should be defined + * in only ONE module (otherwise, the linker will complain). + * + ******************************************************************/ + +extern long biostime(int cmd, long newtime); + +static long CountOfTicks; +static long DateOfReference = 0; + +clock_t clock (void) +{ + + if (DateOfReference == 0) /* this is the first call */ + { + DateOfReference = time(NULL) / 86400L; + CountOfTicks = biostime(0,0L) - CLOCKS_PER_SEC; + /* pretend we start one second ago */ + return CLOCKS_PER_SEC; /* to avoid returning 0 */ + } + + return (time(NULL) / 86400L - DateOfReference) * 0x1800B0L + + biostime(0,0L) - CountOfTicks; +} + +#endif /* Turbo C v.1.x */ + +#endif /* defined __TIME_H_DEFINED */ + + +/* End */ diff --git a/test/arch/os2/Makefile.dm b/test/arch/os2/Makefile.dm new file mode 100644 index 0000000..c770086 --- /dev/null +++ b/test/arch/os2/Makefile.dm @@ -0,0 +1,143 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2 +# +# You will need dmake. +# +# Use this file while in the 'test' directory with the following statement: +# +# dmake -r -f arch/os2/Makefile.dm + +ARCH = arch/os2 +FT_MAKEFILE = $(ARCH)/Makefile.dm +FT_MAKE = dmake -r + +.IMPORT: COMSPEC +SHELL := $(COMSPEC) +SHELLFLAGS := /c +GROUPSHELL := $(SHELL) +GROUPFLAGS := $(SHELLFLAGS) +GROUPSUFFIX := .cmd +SHELLMETAS := *"?<>&| + +CC = gcc + +LIBDIR = ../lib +LIBDIR_OS2 = $(subst,/,\ $(LIBDIR)) +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +# CFLAGS = -Wall -ansi -O2 -g $(INCDIRS) +CFLAGS = -ansi -Wall -O2 -s -Zcrtdll $(INCDIRS) + +# full-screen MSDOS driver +GFSDRIVER = $(ARCH)/gfs_os2.c +GPMDRIVER = $(ARCH)/gpm_os2.c +GPM_DEF = $(ARCH)/gpm_os2.def + +DISPLAY = display.c + +SRC = ftlint.c fttimer.c ftview.c ftzoom.c ftdump.c ftstring.c ftstrpnm.c \ + ftsbit.c common.c blitter.c ftmetric.c ftstrtto.c arabic.c + +GSRC = gmain.c display.c blitter.c +GFSSRC = $(GSRC) $(GFSDRIVER) +GPMSRC = $(GSRC) $(GPMDRIVER) + +GFSOBJ = $(GFSSRC:.c=.o) +GPMOBJ = $(GPMSRC:.c=.o) + +ALLSRC = $(SRC) $(GSRC) $(GFSDRIVER) $(GPMDRIVER) +ALLOBJ = $(ALLSRC:.c=.o) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ @$(mktmp $(&:t"\n")\n) + + +EXEFILES = ftview.exe ftviewfs.exe \ + ftlint.exe \ + fttimer.exe fttimefs.exe \ + ftdump.exe \ + ftstring.exe ftstrfs.exe \ + ftzoom.exe ftzoomfs.exe \ + ftstrpnm.exe \ + ftsbit.exe \ + ftmetric.exe \ + ftstrtto.exe ftstrtfs.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean do_distclean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + + +freetype: +[ + cd $(LIBDIR_OS2) + $(FT_MAKE) -f $(FT_MAKEFILE) all + cd $(MAKEDIR) +] + +freetype_debug: +[ + cd $(LIBDIR_OS2) + $(FT_MAKE) -f $(FT_MAKEFILE) debug + cd $(MAKEDIR) +] + +ftzoom.exe: $(GPMOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftzoomfs.exe: $(GFSOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GPMOBJ) ftview.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftviewfs.exe: $(GFSOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GPMOBJ) ftstring.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftstrfs.exe: $(GFSOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GPMOBJ) fttimer.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +fttimefs.exe: $(GFSOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GPMOBJ) ftstrtto.o common.o arabic.o \ + $(LIBDIR)/libttf.a $(GPM_DEF) +ftstrtfs.exe: $(GFSOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean +[ + cd $(LIBDIR_OS2) + $(FT_MAKE) -f $(FT_MAKEFILE) clean + cd $(MAKEDIR) +] + +distclean: do_clean do_distclean +[ + cd $(LIBDIR_OS2) + $(FT_MAKE) -f $(FT_MAKEFILE) distclean + cd $(MAKEDIR) +] + +do_distclean: + -+del dep.end $(EXEFILES) core + +do_clean: + -+del $(subst,/,\ $(ALLOBJ)) + +# depend: $(ALLSRC) +#[ +# cd $(LIBDIR_OS2) +# $(FT_MAKE) -f $(FT_MAKEFILE) depend +# cd $(MAKEDIR) +# $(CC) -E -M $(INCDIRS) @$(mktmp $(<:t"\n")\n) > dep.end +#] +# +# ifeq (dep.end,$(wildcard dep.end)) +# include dep.end +# endif + +# end of Makefile.dm diff --git a/test/arch/os2/Makefile.emx b/test/arch/os2/Makefile.emx new file mode 100644 index 0000000..b0b4c5b --- /dev/null +++ b/test/arch/os2/Makefile.emx @@ -0,0 +1,108 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for emx-gcc under OS/2. +# +# You will need GNU make. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/os2/Makefile.emx + +ARCH = arch/os2 +FT_MAKEFILE = $(ARCH)/Makefile.emx + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/extend -I$(LIBDIR)/$(ARCH) -I. + +CFLAGS = -Wall -ansi -O0 -g $(INCDIRS) +# CFLAGS = -ansi -Wall -O2 -s -Zcrtdll $(INCDIRS) + +GFSDRIVER = $(ARCH)/gfs_os2.c +GPMDRIVER = $(ARCH)/gpm_os2.c +GPM_DEF = $(ARCH)/gpm_os2.def + +SRC = fttimer.c ftview.c ftlint.c ftzoom.c ftdump.c ftstring.c ftstrpnm.c \ + ftsbit.c common.c blitter.c ftmetric.c ftstrtto.c arabic.c + +GSRC = gmain.c display.c blitter.c +GFSSRC = $(GSRC) $(GFSDRIVER) +GPMSRC = $(GSRC) $(GPMDRIVER) +GFSOBJ = $(GFSSRC:.c=.o) +GPMOBJ = $(GPMSRC:.c=.o) + +ALLSRC = $(SRC) $(GSRC) $(GFSDRIVER) $(GPMDRIVER) +ALLOBJ = $(ALLSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.exe: + $(CC) $(CFLAGS) -o $@ $^ + + +EXEFILES = ftview.exe ftviewfs.exe \ + fttimer.exe fttimefs.exe \ + ftlint.exe \ + ftstring.exe ftstrfs.exe \ + ftstrpnm.exe \ + ftzoom.exe ftzoomfs.exe \ + ftsbit.exe \ + ftdump.exe \ + ftmetric.exe \ + ftstrtto.exe ftstrtfs.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom.exe: $(GPMOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftzoomfs.exe: $(GFSOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GPMOBJ) ftview.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftviewfs.exe: $(GFSOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GPMOBJ) ftstring.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +ftstrfs.exe: $(GFSOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GPMOBJ) fttimer.o common.o $(LIBDIR)/libttf.a $(GPM_DEF) +fttimefs.exe: $(GFSOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GPMOBJ) ftstrtto.o common.o arabic.o \ + $(LIBDIR)/libttf.a $(GPM_DEF) +ftstrtfs.exe: $(GFSOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -del dep.end $(EXEFILES) core + +do_clean: + -del $(subst /,\,$(ALLOBJ)) + + +depend: $(ALLSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.emx diff --git a/test/arch/os2/Makefile.icc b/test/arch/os2/Makefile.icc new file mode 100644 index 0000000..4bd3817 --- /dev/null +++ b/test/arch/os2/Makefile.icc @@ -0,0 +1,145 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for IBM VisualAge C++ under OS/2. +# +# You will need nmake. +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake -f arch\os2\Makefile.icc + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.icc +FT_MAKE = $(MAKE) -nologo + +CC = icc + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\extend -I$(LIBDIR)\$(ARCH) -I. +CFLAGS = -O+ -Gd+ -Gn+ -Gl+ -Ti- -Tm- -Q+ -Wpro- -Wcnd- $(INCDIRS) + +# Fullscreen OS/2 driver +GFSDRIVER_SRC = $(ARCH)\gfs_os2.c +GFSDRIVER = $(ARCH)\gfs_os2.obj + +# PM OS/2 Driver +GPMDRIVER = $(ARCH)\gpm_os2.obj +GPMDRIVER_SRC = $(ARCH)\gpm_os2.c +GPM_DEF = $(ARCH)\gpm_os2.def + +SRC = gmain.c display.c common.c arabic.c \ + ftzoom.c ftview.c fttimer.c ftlint.c ftdump.c ftstring.c \ + ftstrpnm.c ftsbit.c ftmetric.c ftstrtto.c \ + $(GFSDRIVER_SRC) + +COMMON = common.obj +GFSOBJS = gmain.obj display.obj $(GFSDRIVER) $(COMMON) blitter.obj +GPMOBJS = gmain.obj display.obj $(GPMDRIVER) $(COMMON) blitter.obj +OBJ1 = ftzoom.obj +OBJ2 = fttimer.obj +OBJ3 = ftview.obj +OBJ4 = ftlint.obj +OBJ5 = ftdump.obj +OBJ6 = ftstring.obj +OBJ7 = ftstrpnm.obj +OBJ8 = ftsbit.obj +OBJ9 = ftmetric.obj +OBJ10 = ftstrtto.obj + + +EXEFILES = fttimefs.exe fttimer.exe \ + ftzoom.exe ftzoomfs.exe \ + ftviewfs.exe ftview.exe \ + ftlint.exe \ + ftdump.exe \ + ftstring.exe ftstrfs.exe \ + ftstrpnm.exe \ + ftsbit.exe \ + ftmetric.exe \ + ftstrtto.exe ftstrtfs.exe + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + + +freetype: + cd $(LIBDIR) + $(FT_MAKE) -f $(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) -f $(FT_MAKEFILE) debug + cd ..\test + +$(GFSDRIVER): $(GFSDRIVER_SRC) + $(CC) $(CFLAGS) /c /Fo$@ $** -I. + +$(GPMDRIVER): $(GPMDRIVER_SRC) + $(CC) $(CFLAGS) /c /Fo$@ $** -I. + +ftzoomfs.exe: $(GFSOBJS) $(OBJ1) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +ftzoom.exe: $(GPMOBJS) $(OBJ1) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + +fttimefs.exe: $(GFSOBJS) $(OBJ2) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +fttimer.exe: $(GPMOBJS) $(OBJ2) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + +ftviewfs.exe: $(GFSOBJS) $(OBJ3) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +ftview.exe: $(GPMOBJS) $(OBJ3) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + +ftlint.exe: $(OBJ4) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftdump.exe: $(OBJ5) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftstrfs.exe: $(GFSOBJS) $(OBJ6) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +ftstring.exe: $(GPMOBJS) $(OBJ6) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + +ftstrpnm.exe: $(OBJ7) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftsbit.exe: $(OBJ8) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftmetric.exe: $(OBJ9) $(LIBDIR)\libttf.lib $(COMMON) + $(CC) $(CFLAGS) /Fe$@ $** + +ftstrtfs.exe: $(GFSOBJS) $(OBJ10) $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) /Fe$@ $** + +ftstrtto.exe: $(GPMOBJS) $(OBJ10) arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(CFLAGS) $(GPM_DEF) /Fe$@ $** + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) -f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) -f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(GFSDRIVER) + -del $(GPMDRIVER) + +# end of Makefile.icc diff --git a/test/arch/os2/Makefile.wat b/test/arch/os2/Makefile.wat new file mode 100644 index 0000000..e8df0af --- /dev/null +++ b/test/arch/os2/Makefile.wat @@ -0,0 +1,155 @@ +# This file is part of the FreeType project +# +# This builds the test programs with the Watcom compiler +# +# You'll need Watcom's wmake +# +# Invoke by "wmake -f arch\os2\Makefile.wat" when in the "test" directory + +ARCH = arch\os2 +FT_MAKEFILE = $(ARCH)\Makefile.wat +FT_MAKE = wmake -h + +.EXTENSIONS: +.EXTENSIONS: .exe .obj .c .h +.obj:. +.c:. +.h:.;..\lib + +CC = wcl386 + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I$(LIBDIR)\extend +LIBFILE = $(LIBDIR)\libttf.lib + +LINK_OPTS = + +OBJ_CFLAGS = /c /otexanl+ /s /w4 /zq $(INCDIRS) + +CCFLAGS = /otexanl+ /s /w4 /zq $(INCDIRS) + +GFSDRIVER = $(ARCH)\gfs_os2.obj +GFSDRIVER_SRC = $(ARCH)\gfs_os2.c + +GPMDRIVER = $(ARCH)\gpm_os2.obj +GPMDRIVER_SRC = $(ARCH)\gpm_os2.c +GPMDRIVER_DEF = $(ARCH)\gpm_os2.def + +SRC = gmain.c display.c blitter.c & + fttimer.c ftview.c ftlint.c ftzoom.c ftdump.c ftstring.c & + ftstrpnm.c ftsbit.c ftmetric.c ftstrtto.c & + $(GPMDRIVER_SRC) $(GFSDRIVER_SRC) + +GFSOBJ = gmain.obj $(GFSDRIVER) blitter.obj display.obj +GPMOBJ = gmain.obj $(GPMDRIVER) blitter.obj display.obj + +PM = $(LIBFILE) $(GPMOBJ) common.obj +FS = $(LIBFILE) $(GFSOBJ) common.obj + + +# graphics utility and test driver + +EXEFILES = ftview.exe ftviewfs.exe & + fttimer.exe fttimefs.exe & + ftlint.exe & + ftdump.exe & + ftstring.exe ftstrfs.exe & + ftzoom.exe ftzoomfs.exe & + ftstrpnm.exe & + ftsbit.exe & + ftmetric.exe & + ftstrtto.exe ftstrtfs.exe + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + + +freetype: .symbolic + cd ..\lib + $(FT_MAKE) -f $(FT_MAKEFILE) all + cd ..\test + +freetype_debug: .symbolic + cd ..\lib + $(FT_MAKE) -f $(FT_MAKEFILE) debug + cd ..\test + +# implicit rules +# +.c.obj : + $(CC) $(OBJ_CFLAGS) $[* /fo=$[*.obj + + +# the full-screen graphics driver +# +$(GFSDRIVER): $(GFSDRIVER_SRC) + $(CC) $(OBJ_CFLAGS) $[*.c /fo=$[*.obj + +# the pm graphics driver +# +$(GPMDRIVER): $(GPMDRIVER_SRC) + $(CC) $(OBJ_CFLAGS) $[*.c /fo=$[*.obj + +ftzoom.exe : ftzoom.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +ftzoomfs.exe : ftzoom.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[@ /fe=ftzoomfs.exe + +ftview.exe : ftview.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +ftviewfs.exe : ftview.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[*.c /fe=ftviewfs.exe + +ftstring.exe : ftstring.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +ftstrfs.exe : ftstring.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[*.c /fe=ftstrfs.exe + +fttimer.exe: fttimer.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +fttimefs.exe: fttimer.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[*.c /fe=fttimefs.exe + +ftlint.exe: ftlint.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftdump.exe: ftdump.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftstrpnm.exe: ftstrpnm.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftsbit.exe: ftsbit.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftmetric.exe: ftmetric.obj $(LIBFILE) + $(CC) $(CCFLAGS) $(LIBFILE) common.obj $[*.c /fe=$[*.exe + +ftstrtto.exe : ftstrtto.obj arabic.obj $(LIBFILE) $(PM) $(GPMDRIVER_DEF) + $(CC) $(CCFLAGS) -l=os2v2_pm $(PM) $[*.c /fe=$[*.exe + +ftstrtfs.exe : ftstrtto.obj arabic.obj $(LIBFILE) $(FS) + $(CC) $(CCFLAGS) $(FS) $[*.c /fe=ftstrtfs.exe + + +clean: .symbolic + @-erase *.obj + @-erase $(ARCH)\*.obj + +distclean: .symbolic clean + @-erase *.exe + @-erase *.err + cd ..\lib + $(FT_MAKE) -f $(FT_MAKEFILE) distclean + cd ..\test + +new: .symbolic + @-wtouch *.c + +# end of Makefile.wat diff --git a/test/arch/os2/gfs_os2.c b/test/arch/os2/gfs_os2.c new file mode 100644 index 0000000..0ecd5a5 --- /dev/null +++ b/test/arch/os2/gfs_os2.c @@ -0,0 +1,219 @@ +/******************************************************************* + * + * gfs_os2.c graphics utility fullscreen OS/2 driver. 1.0 + * + * This is the driver for fullscreen OS/2 display, used by the + * graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include + +#define INCL_SUB +#include + +#ifdef __EMX__ +#include +#endif + +#if defined(__EMX__)||defined(__IBMC__) +#include /* for getch */ + extern _read_kbd(); /* to avoid an ANSI warning during compilation */ +#endif + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + static VIOMODEINFO OrgMode; + static long VioBufOfs; + + + /* BIOS video modes */ + + static VIOMODEINFO VioMode_640x480x16 = + { + sizeof ( VIOMODEINFO ), + VGMT_OTHER + VGMT_GRAPHICS, + COLORS_16, + 80, + 35, + 640, + 480 + }; + + static VIOMODEINFO VioMode_320x200x256 = + { + sizeof ( VIOMODEINFO ), + VGMT_OTHER + VGMT_GRAPHICS, + 8, + 40, + 25, + 320, + 200 + }; + + static VIOPHYSBUF VioBuf = + { + (void*)0xA0000L, + 64*1024 + }; + + + /* Restores screen to its original state */ + + int Driver_Restore_Mode() + { + VioSetMode( &OrgMode, 0 ); + return 1; + } + + + /* Sets graphics mode */ + + int Driver_Set_Graphics( int mode ) + { + int rc; + + + OrgMode.cb = sizeof ( VIOMODEINFO ); + VioGetMode( &OrgMode, 0 ); + + switch ( mode ) + { + case Graphics_Mode_Mono: + rc = VioSetMode( &VioMode_640x480x16, 0 ); + vio_ScanLineWidth = 80; + vio_Width = 640; + vio_Height = 480; + break; + + case Graphics_Mode_Gray: + rc = VioSetMode( &VioMode_320x200x256, 0 ); + vio_ScanLineWidth = 320; + vio_Width = 320; + vio_Height = 200; + + /* default gray_palette takes the gray levels of the standard VGA */ + /* 256 colors mode */ + + gray_palette[0] = 0; + gray_palette[1] = 23; + gray_palette[2] = 27; + gray_palette[3] = 29; + gray_palette[4] = 31; + break; + + default: + rc = -1; + break; + } + + if ( rc ) return 0; /* failure */ + + if ( VioGetPhysBuf( &VioBuf, 0 ) ) return 0; /* Could not access VRAM */ + + VioBufOfs = (long)MAKEP( VioBuf.asel[0], 0 ); + + memset( (void*)VioBufOfs, 0, 64 * 1024 ); + + Vio = (char*)VioBufOfs; + + return 1; /* success */ + } + + + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int y; + char* target; + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { + memcpy( target, buffer, col ); + target -= vio_ScanLineWidth; + buffer += col; + } + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + int i; + char c; + + + c = getch(); + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + /* unrecognized keystroke */ + + event->what = event_Keyboard; + event->info = (int)c; + return; + } + + +/* End */ diff --git a/test/arch/os2/gpm_os2.c b/test/arch/os2/gpm_os2.c new file mode 100644 index 0000000..22ed397 --- /dev/null +++ b/test/arch/os2/gpm_os2.c @@ -0,0 +1,654 @@ +/******************************************************************* + * + * gpm_os2.c graphics OS/2 Presentation Manager Window driver. 0.2 + * + * This is the driver for windowed OS/2 display, used by the + * graphics utility of the FreeType test suite. + * + * written by Eric Olson (eolson@imag.net) + * + * Borrowing liberally from the other FreeType drivers. + * Some bitmap manipulations are derived from fastgpi.c, + * a sample program written by Donald Graft (dgraft@gate.net). + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include + +#define INCL_DOS +#define INCL_WIN +#define INCL_GPI +#define INCL_SUB + +#include + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +#define VIO_WIDTH 640u /* these can be changed but VIO_WIDTH should remain */ +#define VIO_HEIGHT 360u /* for now a multiple of 32 to avoid padding issues */ +#define MAG_WIDTH VIO_WIDTH +#define MAG_HEIGHT 120u +#define MAX_MAG 16 /* should be less than Min(MAG_WIDTH, MAG_HEIGHT) */ + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + + static HAB habt; + static HAB hab; + static HWND hwndFrame, hwndClient; + static HWND hwndTitle; + static HDC hdcMemory; + static HPS hpsMemory = (HPS) NULL; + + /* Threads and semaphores */ + TID MessageThread; + HMTX hmtxPSMemoryLock; + HEV hevKeyLock; + + /* Bitmap information */ + static PBITMAPINFO2 pbmi; + static HBITMAP hbm; + BYTE Bitmap[VIO_WIDTH * VIO_HEIGHT]; + BOOL ready = FALSE; + + /* Coordinates for the bitblt of whole graphic area */ + POINTL aptlFull[4] = {{ 0u, MAG_HEIGHT }, + { VIO_WIDTH, VIO_HEIGHT + MAG_HEIGHT }, + { 0u, 0u }, + { VIO_WIDTH, VIO_HEIGHT }}; + + /* Coordinates for the magnification bitblt */ + POINTL aptlMagd[4] = {{ 0u, 0u }, + { MAG_WIDTH, MAG_HEIGHT }, /* target */ + { 0u, 0u }, + { VIO_WIDTH, VIO_HEIGHT }}; /* source */ + + /* level of magnification and center of magnification window */ + static int magnification=1; + static POINTL view_target = {0, 0}; + static SIZEL mag_win_size; + + /* local event to pass on */ + TEvent ourevent = { event_Rotate_Glyph, 0 }; + + /* grayscale vs b/w mode */ + int Colourmode; + + /* array defined in the test programs */ + extern char Header[]; + + + void RunPMWindow( ULONG ); + MRESULT EXPENTRY Message_Process( HWND, ULONG, MPARAM, MPARAM ); + + + + /* restores screen to its original state */ + + int Driver_Restore_Mode() + { + /* PMWindow has probably already destroyed itself */ + if ( hwndFrame ) + WinDestroyWindow( hwndFrame ); + + WinReleasePS( hpsMemory ); + WinTerminate( habt ); + + return 1; + } + + + /* set graphics mode */ + + int Driver_Set_Graphics( int mode ) + { + LONG palette[5]; + int x; + POINTL coords; + SIZEL sizl = { 0, 0 }; + + PTIB thread_block; + PPIB process_block; + + /* XXX : This is a very nasty hack, it fools OS/2 and let the program */ + /* call PM functions, even though stdin/stdout/stderr are still */ + /* directed to the standard i/o streams.. */ + /* The program must be compiled with WINDOWCOMPAT */ + /* */ + /* Credits go to Michal for finding this !! */ + /* */ + DosGetInfoBlocks( &thread_block, &process_block ); + process_block->pib_ultype = 3; + + /* save mono vs grayscale status */ + Colourmode = mode; + + /* event semaphore to signal reraster event */ + DosCreateEventSem( NULL, &hevKeyLock, 0, TRUE ); + + /* mutex semaphore for access to the presentation space */ + DosCreateMutexSem( NULL, &hmtxPSMemoryLock, 0, FALSE ); + + /* Start thread with Presentation Manager window */ + DosCreateThread( &MessageThread, (PFNTHREAD)RunPMWindow, 0UL, 0UL, 32920 ); + + /* open anchor block to permit Gpi calls from this thread */ + habt = WinInitialize( 0 ); + + /* create device context and presentation space for our graphic */ + hdcMemory = DevOpenDC( hab, OD_MEMORY, (PSZ)"*", 0L, 0L, 0L ); + + DosRequestMutexSem( hmtxPSMemoryLock, SEM_INDEFINITE_WAIT ); + hpsMemory = GpiCreatePS( + habt, hdcMemory, &sizl, + PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT ); + GpiSetBackMix( hpsMemory, BM_OVERPAINT ); + + /* create bitmap for raster image of graphic */ + + /* find some memory for the bitmap header */ + DosAllocMem( (PPVOID)&pbmi, + sizeof ( BITMAPINFO2 ) + sizeof ( RGB2 ) * 256, + PAG_COMMIT | PAG_READ | PAG_WRITE); + /* 256 should really be 2 if not grayscale */ + + /* initialize the header to appropriate values */ + memset( pbmi, 0, sizeof ( BITMAPINFO2 ) + sizeof ( RGB2 ) * 256 ); + + pbmi->cbFix = sizeof ( BITMAPINFOHEADER2 ); + pbmi->cx = VIO_WIDTH; + pbmi->cy = VIO_HEIGHT; + pbmi->cPlanes = 1; + + switch ( mode ) + { + case Graphics_Mode_Mono: + pbmi->cBitCount = 1; + break; + + case Graphics_Mode_Gray: + pbmi->cBitCount = 8; + break; + } + + hbm = GpiCreateBitmap( hpsMemory, (PBITMAPINFOHEADER2)pbmi, + 0L, NULL, NULL ); + + /* associate it with the presentation space */ + GpiSetBitmap( hpsMemory, hbm ); + pbmi->cbFix = sizeof ( BITMAPINFOHEADER2 ); + GpiQueryBitmapInfoHeader( hbm, (PBITMAPINFOHEADER2) pbmi ); + + switch ( mode ) + { + case Graphics_Mode_Mono: + DosReleaseMutexSem( hmtxPSMemoryLock ); + + vio_ScanLineWidth = VIO_WIDTH / 8; + vio_Width = VIO_WIDTH; + vio_Height = VIO_HEIGHT; + + gray_palette[0] = 0; /* to avoid testing for grayscale... */ + break; + + case Graphics_Mode_Gray: + vio_ScanLineWidth = VIO_WIDTH; + vio_Width = VIO_WIDTH; + vio_Height = VIO_HEIGHT; + + /* set gray_palette by convoluted procedure */ + + /* create logical color palette */ + palette[0] = 0xffffffL; /* White */ + palette[1] = 0xbbbbbbL; + palette[2] = 0x777777L; /* Gray */ + palette[3] = 0x333333L; + palette[4] = 0L; /* Black */ + + GpiCreateLogColorTable( hpsMemory, (ULONG)LCOL_PURECOLOR, + (LONG)LCOLF_CONSECRGB, (LONG)0L, + (LONG)5L, (PLONG)palette ); + + /* plot to presentation space in all five gray shades */ + for (x = 0 ; x < 5 ; x++) + { + GpiSetColor( hpsMemory, (LONG)x ); + coords.x = x; + coords.y = 0; + GpiSetPel( hpsMemory, &coords ); + } + + /* retrieve the 5 pixels as gray_palette */ + GpiQueryBitmapInfoHeader( hbm, (PBITMAPINFOHEADER2) pbmi ); + GpiQueryBitmapBits( hpsMemory, 0L, (LONG)VIO_HEIGHT - 2, + &Bitmap[0], pbmi ); + for ( x = 0; x < 5; x++ ) + { + gray_palette[x] = Bitmap[x]; + } + + /* initialization in case we paint before Driver_Display is called */ + memset( &Bitmap[0], gray_palette[0], vio_Height * vio_ScanLineWidth ); + DosReleaseMutexSem( hmtxPSMemoryLock ); + break; + + default: + return 0; /* Unknown mode */ + } + + return 1; /* success even if windows were not setup right */ + } + + + int Driver_Display_Bitmap( char* buffer, int lines, int cols ) + { + int y, target; + + + /* copy the bitmap and blt to presentation space */ + if ( (lines == vio_Height) & (cols == vio_ScanLineWidth) ) + memcpy( &Bitmap[0], buffer, lines * cols ); + else + { + memset( &Bitmap[0], gray_palette[0], vio_Height * vio_ScanLineWidth ); + /* temporary hack to center any bitmap */ + target = ( vio_Height - lines ) / 2 * vio_ScanLineWidth + + ( vio_ScanLineWidth - cols ) / 2; + + for ( y = 0 ; y < lines ; y++ ) + { + memcpy( &Bitmap[target], buffer, cols ); + target += vio_ScanLineWidth; + buffer += cols; + } + } + + /* Get permission and write to in-memory ps */ + DosRequestMutexSem( hmtxPSMemoryLock, SEM_INDEFINITE_WAIT ); + GpiSetBitmapBits( hpsMemory, 0L, (LONG)VIO_HEIGHT - 2, &Bitmap[0], pbmi ); + DosReleaseMutexSem( hmtxPSMemoryLock ); + ready = TRUE; + + /* Invalidate and ask for redraw now */ + WinInvalidateRect( hwndClient, NULL, FALSE ); + WinUpdateWindow( hwndFrame ); + + return 1; /* success */ + } + + + void Get_Event( TEvent* event ) + { + ULONG ulRequestCount; + + + /* the Get_Event function blocks until there is an event to process */ + DosWaitEventSem( hevKeyLock, SEM_INDEFINITE_WAIT ); + DosQueryEventSem( hevKeyLock, &ulRequestCount ); + DosResetEventSem( hevKeyLock, &ulRequestCount ); + event->what = ourevent.what; + event->info = ourevent.info; + return; + } + + + void RunPMWindow( ULONG dummy ) + { + unsigned char classname[] = "DisplayClass"; + ULONG flClassFlags; + static HMQ hmq; + QMSG qmsg; + + + if ( (hab = WinInitialize( 0 )) == 0 ) + { + printf( "Error doing WinInitialize()\n" ); + return; + } + + if ( (hmq = WinCreateMsgQueue( hab, 0 )) == (HMQ)NULL ) + { + printf( "Error doing WinCreateMsgQueue()\n" ); + return; + } + + if ( !WinRegisterClass( hab, (PSZ)classname, (PFNWP)Message_Process, + CS_SIZEREDRAW, 0 ) ) + { + printf( "Error doing WinRegisterClass()\n" ); + return; + } + + flClassFlags = FCF_TITLEBAR | FCF_MINBUTTON | FCF_DLGBORDER | + FCF_TASKLIST | FCF_SYSMENU; + if ( (hwndFrame = WinCreateStdWindow( HWND_DESKTOP, + WS_VISIBLE, + &flClassFlags, + (PSZ)classname, + (PSZ)"FreeType PM Graphics", + WS_VISIBLE, + 0, 0, &hwndClient )) == 0 ) + { + printf( "Error doing WinCreateStdWindow()\n" ); + return; + } + + /* find the title window handle */ + hwndTitle = WinWindowFromID( hwndFrame, FID_TITLEBAR ); + + /* set Window size and position */ + WinSetWindowPos( + hwndFrame, 0L, + (SHORT)60, + (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - + ( VIO_HEIGHT + MAG_HEIGHT + 100 ), + (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME ) * 2 + + VIO_WIDTH, + (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) + + WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME ) * 2 + + VIO_HEIGHT + MAG_HEIGHT, + SWP_SIZE | SWP_MOVE ) ; + + /* run the message queue till the end */ + while ( WinGetMsg( hab, &qmsg, (HWND)NULL, 0, 0 ) ) + WinDispatchMsg( hab, &qmsg ); + + /* clean-up */ + WinDestroyWindow( hwndFrame ); + hwndFrame = (HWND)NULL; + WinDestroyMsgQueue( hmq ); + WinTerminate( hab ); + + /* await death... */ + while ( 1 ) + DosSleep( 100 ); + } + + + void Adjust_Mag_Rectangle( void ) + { + SIZEL source, + target; + + + /* Step 1, find optimal source size for this mag and window size */ + source.cx = mag_win_size.cx / magnification; + if (source.cx > vio_Width) source.cx = vio_Width; + source.cy = mag_win_size.cy / magnification; + if (source.cy > vio_Height) source.cy = vio_Height; + + target.cx = source.cx * magnification; + target.cy = source.cy * magnification; + + aptlMagd[0].x = (mag_win_size.cx - target.cx) / 2; + aptlMagd[0].y = (mag_win_size.cy - target.cy) / 2; + aptlMagd[1].x = aptlMagd[0].x + target.cx - 1; + aptlMagd[1].y = aptlMagd[0].x + target.cy - 1; + + /* Step 2, try crosshairs point dependent coordinates */ + aptlMagd[2].x = view_target.x - source.cx / 2; + aptlMagd[2].y = view_target.y - source.cy / 2; + if (aptlMagd[2].x < 0 ) aptlMagd[2].x = 0; + if (aptlMagd[2].y < 0 ) aptlMagd[2].y = 0; + if (aptlMagd[2].x > vio_Width - source.cx) + aptlMagd[2].x = vio_Width - source.cx; + if (aptlMagd[2].y > vio_Height - source.cy) + aptlMagd[2].y = vio_Height - source.cy; + + aptlMagd[3].x = aptlMagd[2].x + source.cx - 1; + aptlMagd[3].y = aptlMagd[2].y + source.cy - 1; + + } /* End of Adjust_Mag_Rectangle; */ + + + /* Message processing for our PM Window class */ + MRESULT EXPENTRY Message_Process( HWND handle, ULONG mess, + MPARAM parm1, MPARAM parm2 ) + { + static HDC hdc; + static HPS hps; + static BOOL minimized; + + POINTL top_corner, bottom_corner; + SWP swp; + int i; + + + switch( mess ) + { + case WM_DESTROY: + /* warn the main thread to quit if it didn't know */ + ourevent.what = event_Quit; + ourevent.info = 0; + DosPostEventSem( hevKeyLock ); + break; + + case WM_CREATE: + /* set original magnification */ + magnification = 4; + minimized = FALSE; + + /* create Device Context and Presentation Space for screen. */ + /* could we use a cached one ? */ + hdc = WinOpenWindowDC( handle ); + mag_win_size.cx = 0; + mag_win_size.cy = 0; + hps = GpiCreatePS( hab, hdc, &mag_win_size, + PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT ); + + /* Set to size of magnifier window */ + mag_win_size.cx = MAG_WIDTH; + mag_win_size.cy = MAG_HEIGHT; + Adjust_Mag_Rectangle(); + + /* take the input focus */ + WinFocusChange( HWND_DESKTOP, handle, 0L ); + break; + + case WM_BUTTON1DOWN: + if ( MOUSEMSG( &mess )->y >= MAG_HEIGHT ) + { + view_target.x = MOUSEMSG( &mess )->x; + view_target.y = MOUSEMSG( &mess )->y - MAG_HEIGHT; + Adjust_Mag_Rectangle(); + WinInvalidateRect( hwndClient, NULL, FALSE ); + } + + return WinDefWindowProc( handle, mess, parm1, parm2 ); + break; + + case WM_MINMAXFRAME: + /* to update minimized if changed */ + swp = *((PSWP) parm1); + if ( swp.fl & SWP_MINIMIZE ) + minimized = TRUE; + if ( swp.fl & SWP_RESTORE ) + minimized = FALSE; + return WinDefWindowProc( handle, mess, parm1, parm2 ); + break; + + case WM_ERASEBACKGROUND: + case WM_PAINT: + /* reset the window title only if not minimized */ + if ( !minimized ) + WinSetWindowText( hwndTitle, Header ); + + /* copy the memory image of the screen out to the real screen */ + DosRequestMutexSem( hmtxPSMemoryLock, SEM_INDEFINITE_WAIT ); + WinBeginPaint( handle, hps, NULL ); + + /* main image and magnified picture */ + GpiBitBlt( hps, hpsMemory, 4L, aptlFull, ROP_SRCCOPY, BBO_AND ); + GpiBitBlt( hps, hpsMemory, 4L, aptlMagd, ROP_SRCCOPY, BBO_AND ); + + /* double-dash the magnifing bounding box. Paint the mag liner? */ + if ( magnification != 1 ) + { + GpiSetLineType( hps, LINETYPE_LONGDASH ); + + bottom_corner.x = aptlMagd[2].x - 1; + bottom_corner.y = aptlMagd[2].y + MAG_HEIGHT - 1; + top_corner.x = aptlMagd[3].x ; + top_corner.y = aptlMagd[3].y + MAG_HEIGHT; + + GpiMove( hps, &bottom_corner ); + GpiBox( hps, DRO_OUTLINE, &top_corner, 0L, 0L ); + +#if 0 + GpiSetClipRegion(); + GpiErase(); +#endif + } + + WinEndPaint( hps ); + DosReleaseMutexSem( hmtxPSMemoryLock ); + break; + + case WM_CHAR: + if ( CHARMSG( &mess )->fs & KC_KEYUP ) + break; + + switch ( CHARMSG( &mess )->vkey ) + { + case VK_ESC: + ourevent.what = event_Quit; + ourevent.info = 0; + DosPostEventSem( hevKeyLock ); + break; + + case VK_PAGEDOWN: + if ( magnification < MAX_MAG ) + { + magnification += 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_PAGEUP: + if ( magnification > 1 ) + { + magnification -= 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_LEFT: + if ( view_target.x > 0 ) + { + view_target.x -= 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_RIGHT: + if ( view_target.x < VIO_WIDTH - 1 ) + { + view_target.x += 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_DOWN: + if ( view_target.y > 0 ) + { + view_target.y -= 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_UP: + if ( view_target.y < VIO_HEIGHT - 1 ) + { + view_target.y += 1; + Adjust_Mag_Rectangle(); + WinInvalidateRect( handle, NULL, FALSE ); + } + break; + + case VK_F1: /* bring up help and about dialog window */ + break; + } + + if ( CHARMSG( &mess )->fs & KC_CHAR ) + { + char c = (CHAR)CHARMSG( &mess )->chr ; + + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + ourevent.what = trans[i].event_class; + ourevent.info = trans[i].event_info; + DosPostEventSem( hevKeyLock ); + return (MRESULT)TRUE; + } + } + + /* unrecognized keystroke */ + ourevent.what = event_Keyboard; + ourevent.info = (int)c; + DosPostEventSem( hevKeyLock ); + } + break; + + default: + return WinDefWindowProc( handle, mess, parm1, parm2 ); + } + + return (MRESULT) FALSE; + } + + +/* End */ diff --git a/test/arch/os2/gpm_os2.def b/test/arch/os2/gpm_os2.def new file mode 100644 index 0000000..4a77c63 --- /dev/null +++ b/test/arch/os2/gpm_os2.def @@ -0,0 +1,5 @@ +NAME WINDOWCOMPAT + +DESCRIPTION 'FreeType Graphics' +HEAPSIZE 8192 +STACKSIZE 40888 diff --git a/test/arch/unix/.cvsignore b/test/arch/unix/.cvsignore new file mode 100644 index 0000000..f3c7a7c --- /dev/null +++ b/test/arch/unix/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/test/arch/unix/Makefile.in b/test/arch/unix/Makefile.in new file mode 100644 index 0000000..fc6cc2b --- /dev/null +++ b/test/arch/unix/Makefile.in @@ -0,0 +1,170 @@ +# This file is part of the FreeType project. +# +# test/arch/unix/Makefile.in + +ARCH = arch/unix + +top_builddir=.. + +VPATH = @srcdir@/../.. +srcdir = @srcdir@/../.. + +RM = @RM@ +RMF = @RM@ -f +RMDIR = @RMDIR@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +CC = @CC@ +CPP = @CPP@ + +LIBTOOL = $(top_builddir)/libtool +MKINSTALLDIRS = $(srcdir)/../mkinstalldirs + +include $(top_builddir)/MakeSub + +FT_LIBDIR = $(srcdir)/../lib +INCDIRS = -I. -I$(srcdir) -I$(top_builddir) \ + -I$(FT_LIBDIR) -I$(FT_LIBDIR)/extend + +CFLAGS = @CFLAGS@ @X_CFLAGS@ @XX_CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +FT_CFLAGS = $(INCDIRS) $(CFLAGS) $(CPPFLAGS) -DX11 -DLOCALEDIR='"@LOCALEDIR@"' + +FT_LIBS = @X_LIBS@ @X_PRE_LIBS@ @X_EXTRA_LIBS@ @LIBS@ + +SRC = $(srcdir)/arabic.c \ + $(srcdir)/common.c \ + $(srcdir)/ftdump.c \ + $(srcdir)/fterror.c \ + $(srcdir)/ftlint.c \ + $(srcdir)/ftmetric.c \ + $(srcdir)/ftsbit.c \ + $(srcdir)/ftstring.c \ + $(srcdir)/ftstrpnm.c \ + $(srcdir)/fttimer.c \ + $(srcdir)/ftview.c \ + $(srcdir)/ftzoom.c \ + $(srcdir)/ftstrtto.c \ + $(srcdir)/gmain.c \ + $(srcdir)/$(ARCH)/gwin_x11.c + +DISPOBJS = common.o gmain.o display.o gwin_x11.o blitter.o + +PROGRAMS = ftview fttimer ftlint ftdump ftzoom ftsbit \ + ftstring ftstrpnm fterror ftmetric ftstrtto + +# set this variable to nil if you don't need to use Electric-Fence +EFENCE = +#EFENCE = -lefence + + +# variables used to compile either with libtool or not +# +PROCESS = $(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) +#PROCESS = $(CC) $(FT_CFLAGS) + +LIBTTF = $(top_builddir)/lib/libttf.la +#LIBTTF =$(top_builddir)/lib/libttf.a + +.c.o: + $(CC) -c $(FT_CFLAGS) $< + + +all: $(PROGRAMS) + + +gwin_x11.o: $(srcdir)/$(ARCH)/gwin_x11.c + $(CC) -c $(FT_CFLAGS) $(srcdir)/$(ARCH)/gwin_x11.c + +ftzoom: ftzoom.o $(DISPOBJS) $(LIBTTF) + $(PROCESS) -o ftzoom ftzoom.o $(DISPOBJS) \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + +fttimer: fttimer.o $(DISPOBJS) $(LIBTTF) + $(PROCESS) -o fttimer fttimer.o $(DISPOBJS) \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + +ftview: ftview.o $(DISPOBJS) $(LIBTTF) + $(PROCESS) -o ftview ftview.o $(DISPOBJS) \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + +ftlint: ftlint.o common.o $(LIBTTF) + $(PROCESS) -o ftlint ftlint.o common.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) + +ftdump: ftdump.o common.o $(LIBTTF) + $(PROCESS) -o ftdump ftdump.o common.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) + +ftmetric: ftmetric.o common.o $(LIBTTF) + $(PROCESS) -o ftmetric ftmetric.o common.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) + +ftsbit: ftsbit.o common.o $(LIBTTF) + $(PROCESS) -o ftsbit ftsbit.o common.o \ + $(EFENCE) $(LIBTTF) + +ftstring: ftstring.o $(DISPOBJS) $(LIBTTF) + $(PROCESS) -o ftstring ftstring.o $(DISPOBJS) \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + +# ftstrpnm does not need any extra libraries +ftstrpnm: ftstrpnm.o common.o $(LIBTTF) + $(PROCESS) -o ftstrpnm ftstrpnm.o common.o \ + $(EFENCE) $(LIBTTF) + +fterror: fterror.o common.o $(LIBTTF) + $(PROCESS) -o fterror fterror.o common.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) + +ftstrtto: ftstrtto.o $(DISPOBJS) arabic.o $(LIBTTF) + $(PROCESS) -o ftstrtto ftstrtto.o $(DISPOBJS) arabic.o \ + $(EFENCE) $(LIBTTF) $(FT_LIBS) -lX11 + + +install: $(PROGRAMS) + $(MKINSTALLDIRS) $(bindir) + for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$P $(bindir)/$$P ; \ + done + +uninstall: + -for P in $(PROGRAMS) ; do \ + $(LIBTOOL) --mode=uninstall $(RM) $(bindir)/$$P ; \ + done + +clean: do_clean + +distclean: do_clean + -$(RMF) $(PROGRAMS) + -$(RMF) *~ *.orig core *.core + -$(RMF) config.cache config.log config.status + -$(RMF) $(ARCH)/Makefile + -$(RMF) .libs/* + -$(RMDIR) .libs + +do_clean: + -$(RMF) *.o + +depend: + (echo '/^#.* PUT NO STUFF BELOW/,$$d' ; echo w ; echo q) | \ + ed - $(ARCH)/Makefile + echo '# Dependencies generated by make depend: PUT NO STUFF BELOW' \ + >> $(ARCH)/Makefile + for file in $(SRC) ; do \ + $(CPP) $(CPPFLAGS) $(INCDIRS) $$file | \ + sed -n -e 's|^# [1-9][0-9]* "\([^/].*\.h\)".*|\1|p' \ + -e 's|^# [1-9][0-9]* "\($(srcdir)/.*\.h\)".*|\1|p' | \ + sed -e 's|/\./|.|g' -e "s/^/`basename $$file .c`.o: /" ; \ + done | \ + sort -u | \ + awk '{ if (LINE == 1) \ + { line = last = $$1 } \ + else if ($$1 != last) \ + { print line ; line = last = $$1 } \ + line = line " " $$2 } \ + END { print line }' >> $(ARCH)/Makefile + +# Dependencies generated by make depend: PUT NO STUFF BELOW diff --git a/test/arch/unix/gwin_x11.c b/test/arch/unix/gwin_x11.c new file mode 100644 index 0000000..760c213 --- /dev/null +++ b/test/arch/unix/gwin_x11.c @@ -0,0 +1,451 @@ +/******************************************************************* + * + * gwin_x11.c graphics utility X-Window driver. 1.0 + * + * This is the driver for windowed display under X11, used by the + * graphics utility of the FreeType test suite. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "common.h" /* for Panic() */ +#include "freetype.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + + /* Translator added to ease changes to control keys */ + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + /* End of translators addition. See Get_Event() below */ + + extern char Header[]; /* defined in the test programs */ + + static Window win; + static GC gcblack; + static XColor color[5]; + + Display* display; + static char* displayname = ""; + + static XImage* image; + + static Visual* visual; + static Colormap colormap; + static int depth; + static Bool gray; + + static Cursor idle; + static Cursor busy; + + static int win_origin_x, win_origin_y, + win_width, win_height; + static int image_width, image_height; + + long vioBufOfs; + + + + /* restore acreen to its original state */ + + int Driver_Restore_Mode( void ) + { + XUnmapWindow( display, win ); + XCloseDisplay( display ); + + return 1; /* success */ + } + + + /* set graphics mode */ + + void x11init( void ) + { + int screen_num, i; + XTextProperty xtp; + XSizeHints xsh; + XSetWindowAttributes xswa; + +#if 1 + unsigned short colors[5] = { 0, 16, 32, 48, 63 }; /* gamma = 1.0 */ +#else + unsigned short colors[5] = { 0, 34, 46, 55, 63 }; /* gamma = 2.2 */ +#endif + + + XrmInitialize(); + + if( !( display = XOpenDisplay( displayname ) ) ) + Panic( "ERROR: cannot open display\n" ); + + screen_num = DefaultScreen ( display ); + colormap = DefaultColormap( display, screen_num ); + depth = DefaultDepth ( display, screen_num ); + visual = DefaultVisual ( display, screen_num ); + + idle = XCreateFontCursor( display, XC_left_ptr ); + busy = XCreateFontCursor( display, XC_watch ); + + if ( gray ) + { + int count; + XPixmapFormatValues* formats; + + + formats = XListPixmapFormats( display, &count ); + vio_ScanLineWidth = 0; + + while ( count > 0 ) + { + --count; + if ( formats[count].depth == depth ) + { + int bits; + + bits = win_width * formats[count].bits_per_pixel; + if ( bits % formats[count].scanline_pad ) + { + bits -= bits % formats[count].scanline_pad; + bits += formats[count].scanline_pad; + } + + vio_ScanLineWidth = bits / 8; + break; + } + } + if ( !vio_ScanLineWidth ) + Panic( "ERROR: the display doesn't offer a suitable pixmap format\n" ); + + XFree( formats ); + } + + Vio = (char*)malloc( win_height * vio_ScanLineWidth ); + + if ( !Vio ) + Panic( "ERROR: cannot malloc display memory\n" ); + + xswa.border_pixel = BlackPixel( display, screen_num ); + xswa.background_pixel = WhitePixel( display, screen_num ); + xswa.cursor = busy; + + xswa.event_mask = KeyPressMask | ExposureMask; + + win = XCreateWindow( display, + RootWindow( display, screen_num ), + win_origin_x, + win_origin_y, + win_width, + win_height, + 10, + depth, + InputOutput, + visual, + CWBackPixel | CWBorderPixel | CWEventMask | CWCursor, + &xswa ); + + XMapWindow( display, win ); + + gcblack = XCreateGC( display, RootWindow( display, screen_num ), + 0L, NULL ); + XSetForeground( display, gcblack, BlackPixel( display, screen_num ) ); + XSetBackground( display, gcblack, WhitePixel( display, screen_num ) ); + + /* allocate colors */ + + if ( gray ) + for ( i = 0; i < 5; i++ ) + { + gray_palette[i] = i; + + color[i].red = + color[i].green = + color[i].blue = 65535 - ( colors[i] * 65535 ) / 63; + + if ( !XAllocColor( display, colormap, &color[i] ) ) + Panic( "ERROR: cannot allocate Color\n" ); + } + + image = XCreateImage( display, + visual, + gray ? depth : 1, + gray ? ZPixmap : XYBitmap, + 0, + (char*)Vio, + win_width, + win_height, + 8, + 0 ); + if ( !image ) + Panic( "ERROR: cannot create image\n" ); + + if ( !gray ) + { + image->byte_order = MSBFirst; + image->bitmap_bit_order = MSBFirst; + } + + /* make window manager happy :-) */ + xtp.value = (unsigned char*)"FreeType"; + xtp.encoding = 31; + xtp.format = 8; + xtp.nitems = strlen( (char*)xtp.value ); + + xsh.x = win_origin_x; + xsh.y = win_origin_y; + + xsh.width = win_width; + xsh.height = win_height; + xsh.flags = (PPosition | PSize); + xsh.flags = 0; + + XSetWMProperties( display, win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL ); + } + + + int Driver_Set_Graphics( int mode ) + { + if ( mode == Graphics_Mode_Gray ) + { + gray = 1; + vio_ScanLineWidth = 320; + + win_origin_x = 0; + win_origin_y = 0; + win_width = 320; + win_height = 200; + } + else if ( mode == Graphics_Mode_Mono ) + { + gray = 0; + vio_ScanLineWidth = 80; + + win_origin_x = 0; + win_origin_y = 0; + win_width = 640; + win_height = 450; + } + else + Panic( "ERROR: mode %d not supported\n", mode ); + + vio_Width = win_width; + vio_Height = win_height; + + x11init(); + + return 1; /* success */ + } + + + void Put_Image( int x, int y, int w, int h ) + { + XPutImage( display, win, gcblack, image, x, y, x, y, w, h ); + } + + + int Driver_Display_Bitmap( char* buffer, int line, int col ) + { + int z, y, used_col; + char* target; + + + XClearWindow( display, win ); + + /* this displays the Header string in the window title */ + XStoreName( display, win, Header ); + + if ( line > win_height ) + line = win_height; + + if ( !gray ) + { + if ( col > vio_ScanLineWidth ) + used_col = vio_ScanLineWidth; + else + used_col = col; + + target = Vio + ( line - 1 ) * vio_ScanLineWidth; + + for ( y = 0; y < line; y++ ) + { + memcpy( (char*)target, buffer, used_col ); + target -= vio_ScanLineWidth; + buffer += col; + } + + Put_Image( 0, 0, used_col * 8, line ); + image_width = used_col * 8; + image_height = line; + } + else + { + if ( col > win_width ) + used_col = win_width; + else + used_col = col; + + for ( y = line - 1; y >= 0; y-- ) + { + char* bufp; + + + bufp = buffer; + + for ( z = 0; z < used_col; z++ ) + { + int c; + + + c = *bufp++; + + if ( c < 0 || c >= 5 ) /* security check */ + { + /* Message( "weird grayshade: %d\n", c ); */ + c = 0; + } + XPutPixel( image, z, y, color[c].pixel ); + } + + buffer += col; + } + + Put_Image( 0, 0, used_col, line ); + image_width = used_col; + image_height = line; + } + + return 1; + } + + + /* This function maps X keystrokes into GEvents. Note that */ + /* currently only keystrokes events exit this function. */ + + void Get_Event( TEvent* event ) + { + static char key_buffer[10]; + static int key_cursor = 0; + static int key_number = 0; + static XEvent x_event; + KeySym key; + + int i, bool_exit; + char c; + + XComposeStatus compose; + + + bool_exit = key_cursor < key_number; + + XDefineCursor( display, win, idle ); + + while ( !bool_exit ) + { + XNextEvent( display, &x_event ); + + switch ( x_event.type ) + { + case KeyPress: + key_number = XLookupString( &x_event.xkey, + key_buffer, + sizeof ( key_buffer ), + &key, + &compose ); + key_cursor = 0; + + if ( key_number > 0 ) + bool_exit = 1; + break; + + case MappingNotify: + XRefreshKeyboardMapping( &x_event.xmapping ); + break; + + case Expose: +#if 0 + Put_Image( x_event.xexpose.x, + x_event.xexpose.y, + x_event.xexpose.width, + x_event.xexpose.height ); +#else + /* we always redraw the whole image */ + Put_Image( 0, 0, image_width, image_height ); +#endif + break; + + /* You should add more cases to handle mouse events, etc. */ + } + } + + XDefineCursor( display, win, busy ); + XFlush ( display ); + + c = key_buffer[key_cursor++]; + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + event->what = trans[i].event_class; + event->info = trans[i].event_info; + return; + } + } + + event->what = event_Keyboard; + event->info = (int)c; + } + + +/* End */ diff --git a/test/arch/win16/Makefile.BC b/test/arch/win16/Makefile.BC new file mode 100644 index 0000000..cf246c3 --- /dev/null +++ b/test/arch/win16/Makefile.BC @@ -0,0 +1,212 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for BC++ for 16-bit Windows, +# using large model, and using Easy-Win to display console outputs. +# +# Tested with Borland C++ v.4.02, 5.0 +# You will need Borland MAKE (v.3.6 and above should be OK, for oldest +# versions refer to the instructions below). +# +# +# Use this file while in the 'test' directory with the following statement: +# +# make -farch\win16\Makefile.BC +# +# +# A DLL version of the library can be built and then used with +# +# make -DDLL -farch/win16/Makefile.BC dll +# +# (do not forget to define DLL, otherwise the link phase will fail). +# +# +# Debug versions can be obtained with +# +# make -DDEBUG -farch\win16\Makefile.BC +# +# Special versions enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# make -DBIGFONTS -farch\msdos\Makefile.BC + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.BC +FT_DLL = ft13_16.dll + +CC = bcc + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR);$(LIBDIR)\$(ARCH);.;$(LIBDIR)\extend +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -w-pia + +# Credits go to Dave Hoo for pointing out that modern +# Borland compilers (from BC++ 3.1 on) can increase the limit of +# the length of identifiers. +CFLAGS = -WSE -ml -A -i40 $(INCDIRS) $(SPURIOUS_WARNINGS) + +!if ! $d(DEBUG) +CFLAGS = $(CFLAGS) -O2 -3 +LDFLAGS = -ml -W -lC +!else +CFLAGS = $(CFLAGS) -v -N +LDFLAGS = -v -ml -W -lC +!endif + +!if $d(DLL) +CFLAGS = $(CFLAGS) -DFREETYPE_DLL +!endif + + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win16.c + +DISPLAY = display.c + +G1SRC = gmain.c blitter.c $(GDRIVER) +GSRC = $(DISPLAY) $(G1SRC) + +GOBJ = $(GSRC:.c=.obj) +G1OBJ = $(G1SRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!if !$d(DEBUG) +# Skipped if DEBUG build +all: freetype $(EXEFILES) + +dll: the_dll $(EXEFILES) + +!else +# Skipped if non-DEBUG build +default_target: debug +dll: the_debug_dll $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + + +!if $d(BIGFONTS) +MAKEBIG = -DBIGFONTS +!endif + +freetype: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG $(MAKEBIG) debug + cd ..\test + +the_dll: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDLL $(MAKEBIG) dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + +the_debug_dll: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG -DDLL $(MAKEBIG) dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + + +# C compilers are unable to include 16-bit in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| + + +# Borland versions of make are unable to use the $** variable inside +# implicit rules (like .obj.exe:). The job have to be done by hand. :-( +ftzoom.exe: $(G1OBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftzoom.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftview.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstring.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrtto.obj $(GOBJ) common.obj arabic.obj \ + $(LIBDIR)\libttf.lib + +fttimer.exe: $(G1OBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftlint.obj common.obj $(LIBDIR)\libttf.lib + +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftdump.obj common.obj $(LIBDIR)\libttf.lib + +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftsbit.obj common.obj $(LIBDIR)\libttf.lib + +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftmetric.obj common.obj $(LIBDIR)\libttf.lib + +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + -del *.dll + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + +!include "$(ARCH)\depend.win" + +# end of Makefile diff --git a/test/arch/win16/Makefile.MS b/test/arch/win16/Makefile.MS new file mode 100644 index 0000000..6cb13bf --- /dev/null +++ b/test/arch/win16/Makefile.MS @@ -0,0 +1,145 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft C compilers +# for 16-bit Windows, large model, using QuickWin to display console +# outputs. It also works for Visual C++ 1.x 16-bits compiler, but +# you should instead use the Makefile customized for it, Makefile.VC. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\win16\Makefile.MS +# +# +# A debug version can be obtained with +# +# nmake DEBUG=1 /f arch\win16\Makefile.MS + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.MS +FT_MAKE = $(MAKE) /nologo + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G2 $(INCDIRS) +LDFLAGS = /AL +!else +CFLAGS = /Zi /AL /Za /W2 /G2 $(INCDIRS) +LDFLAGS = /Zi /AL +!endif + +CFLAGS = $(CFLAGS) /GA /Mq +LDFLAGS = $(LDFLAGS) /GA /Mq + + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win16.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 debug + cd ..\test + + +# C compilers are unable to include 16-bit in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + @$(CC) /c /Fo$* @<< + $(CFLAGS) /Ze $(GDRIVER) +<< + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + + +!include "$(ARCH)\depend.win" + +# end of Makefile.MS diff --git a/test/arch/win16/Makefile.VC b/test/arch/win16/Makefile.VC new file mode 100644 index 0000000..2a9205f --- /dev/null +++ b/test/arch/win16/Makefile.VC @@ -0,0 +1,187 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft Visual C++ 1.x +# and Microsoft C/C++ v.7.0 compilers for 16-bit Windows, large model, +# using QuickWin to display console outputs. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\win16\Makefile.VC +# +# A DLL version of the library can be built and then used with +# +# nmake DLL=1 /f arch\win16\Makefile.VC dll +# +# (do not forget to define DLL, otherwise the link phase will fail). +# +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\win16\Makefile.VC +# +# Special versions enabled to handle big fonts (with more than 16,384 +# glyphs) can be obtained with +# +# nmake BIGFONTS=1 /f arch\win16\Makefile.VC + +ARCH = arch\win16 +FT_MAKEFILE = $(ARCH)\Makefile.VC +FT_MAKE = $(MAKE) /nologo +FT_DLL = ft13_16.dll + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +# One can also consider using "set MSC_CMD_FLAGS=/Gr /Op- /Gy /YX". +# With Microsoft C/C++ 7.0, use /G2 instead of /G3. +!ifndef DEBUG +CFLAGS = /Ox /AL /Za /W2 /G3 $(INCDIRS) +LDFLAGS = /AL +!else +CFLAGS = /Zi /Ge /AL /Za /W2 /G3 $(INCDIRS) +LDFLAGS = /Zi /AL +!endif + +CFLAGS = $(CFLAGS) /Mq +LDFLAGS = $(LDFLAGS) /Mq + +!ifdef DLL +CFLAGS = $(CFLAGS) /DFREETYPE_DLL +!endif + + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win16.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +dll: the_dll $(EXEFILES) + +!else +# Skipped if non-DEBUG build +default_target: debug +dll: the_debug_dll $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +!ifdef BIGFONTS +MAKEBIG = BIGFONTS=1 +!endif + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) $(MAKEBIG) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 $(MAKEBIG) debug + cd ..\test + +the_dll: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DLL=1 $(MAKEBIG) dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + +the_debug_dll: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 DLL=1 $(MAKEBIG) dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + + +# C compilers are unable to include 16-bit in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + @$(CC) /c /Fo$* @<< + $(CFLAGS) /Ze $(GDRIVER) +<< + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + -del *.dll + -del *.pdb + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + + +!include "$(ARCH)\depend.win" + +# end of Makefile.VC diff --git a/test/arch/win16/depend.win b/test/arch/win16/depend.win new file mode 100644 index 0000000..7b3dd26 --- /dev/null +++ b/test/arch/win16/depend.win @@ -0,0 +1,52 @@ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script `makedep' on +# 02-Sep-1999. + +arabic.obj: arabic.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h +blitter.obj: blitter.c blitter.h +common.obj: common.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +display.obj: display.c display.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gmain.h +fdebug.obj: fdebug.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\tttypes.h ..\lib\ttconfig.h \ + ..\lib\arch\win16\ft_conf.h ..\lib\ttdebug.h ..\lib\ttobjs.h \ + ..\lib\ttengine.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +ftdump.obj: ftdump.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxcmap.h ..\lib\extend\ftxopen.h \ + ..\lib\extend\ftxgdef.h ..\lib\extend\ftxgsub.h \ + ..\lib\extend\ftxgpos.h ..\lib\extend\ftxsbit.h ..\lib\ttobjs.h \ + ..\lib\ttconfig.h ..\lib\arch\win16\ft_conf.h ..\lib\ttengine.h \ + ..\lib\tttypes.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +fterror.obj: fterror.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxerr18.h \ + ..\lib\arch\win16\ft_conf.h +ftlint.obj: ftlint.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\arch\win16\ft_conf.h +ftmetric.obj: ftmetric.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\win16\ft_conf.h +ftsbit.obj: ftsbit.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\win16\ft_conf.h +ftstring.obj: ftstring.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h display.h gevents.h gdriver.h gmain.h +ftstrpnm.obj: ftstrpnm.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +ftstrtto.obj: ftstrtto.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h blitter.h common.h \ + display.h ..\lib\extend\ftxkern.h ..\lib\extend\ftxsbit.h gdriver.h \ + gevents.h gmain.h +fttimer.obj: fttimer.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gdriver.h gevents.h gmain.h +ftview.obj: ftview.c blitter.h common.h display.h \ + ..\lib\extend\ftxsbit.h gdriver.h gevents.h gmain.h +ftzoom.obj: ftzoom.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxpost.h gdriver.h gevents.h gmain.h +gmain.obj: gmain.c gdriver.h gmain.h +!ifndef __MAKE__ +arch\win16\gw_win16.obj: arch\win16\gw_win16.c gdriver.h gevents.h gmain.h +!endif diff --git a/test/arch/win16/gw_win16.c b/test/arch/win16/gw_win16.c new file mode 100644 index 0000000..be4bdc3 --- /dev/null +++ b/test/arch/win16/gw_win16.c @@ -0,0 +1,430 @@ +/******************************************************************* + * + * gw_win16.c graphics driver for 16-bit Windows platform. 0.1 + * + * This is the driver for displaying inside a window under 16-bit + * Microsoft Windows, used by the graphics utility of the + * FreeType test suite. + * + * Written by Antoine Leca. + * Copyright 1999 by Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Borrowing liberally from the other FreeType drivers. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include + +#include + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +/* The following #ifdef are used to define the following macros : */ +/* */ +/* - hInst : variable containing the handle of the current instance. */ +/* - hPrev : variable containing the handle of the previous instance. */ +/* */ + +/* ---- Microsoft C compilers support ------------------------------------ */ + +#if defined( M_I86 ) || defined( _M_I86 ) + +extern HINSTANCE _hInstance, _hPrevInstance; +#define hInst _hInstance +#define hPrev _hPrevInstance + +#endif + +/* ---- Borland C compiler support --------------------------------------- */ + +#ifdef __TURBOC__ + +#pragma option -A- + +extern HINSTANCE _hInstance, _hPrev; +#define hInst _hInstance +#define hPrev _hPrev + +#endif + + +#if !defined ( hInst ) || !defined ( hPrev ) +#error Your compiler is not (yet) supported. Check the source file! +#endif + +/* ---- Common initialisations ------------------------------------------- */ + +/* Size of the window. */ +#define WIN_WIDTH 640u +#define WIN_HEIGHT 400u +/* The values will be divided by 2 for gray-scale rendering. */ + +/* These values can be changed, but WIN_WIDTH should remain for now a */ +/* multiple of 32 to avoid padding issues. */ + +/* Also, to avoid 16-bit overflowing issues, the product */ +/* WIN_WIDTH * WIN_HEIGHT should not excess 512K for monochrome */ +/* rendering, and 256K for gray-scale rendering. */ + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + /* handle of the window. */ + static HWND hwndGraphic; + + /* bitmap information */ + static LPBITMAPINFO pbmi; + static HBITMAP hbm; + + /* local event to pass on */ + static TEvent ourevent = { event_Quit, 0 }; + static int eventToProcess = 0; + + /* array defined in the test programs */ + extern char Header[]; + + +/* restores screen to its original state */ + +int Driver_Restore_Mode() + { + /* The graphical window has perhaps already destroyed itself */ + if ( hwndGraphic ) { + DestroyWindow ( hwndGraphic ); + PostMessage ( hwndGraphic, WM_QUIT, 0, 0 ); + } + + if ( pbmi ) free ( pbmi ); + + return 1; + } + + +/* + * set graphics mode + * and create the window class and the message handling. + */ + +/* Declarations of the Windows-specific functions that are below. */ +static BOOL RegisterTheClass ( void ); +static BOOL CreateTheWindow ( int width, int height ); + + +int Driver_Set_Graphics ( int mode ) + { + int i; + static const RGBQUAD gray_scale[5] = { + { 0xFF, 0xFF, 0xFF, 0 }, /* white */ + { 0xC0, 0xC0, 0xC0, 0 }, + { 0x80, 0x80, 0x80, 0 }, + { 0x40, 0x40, 0x40, 0 }, + { 0, 0, 0, 0 } }; /* black */ + + if( ! RegisterTheClass() ) return 0; /* if already running, fails. */ + + /* find some memory for the bitmap header */ + if ( (pbmi = malloc ( sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ) ) + /* 256 should really be 2 if not grayscale */ + == NULL ) + /* lack of memory; fails the process */ + return 0; + + /* initialize the header to appropriate values */ + memset( pbmi, 0, sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ); + + switch ( mode ) + { + case Graphics_Mode_Mono: + pbmi->bmiHeader.biBitCount = 1; + pbmi->bmiColors[0] = gray_scale[0]; + pbmi->bmiColors[1] = gray_scale[4]; + + vio_ScanLineWidth = WIN_WIDTH / 8; + vio_Width = WIN_WIDTH; + vio_Height = WIN_HEIGHT; + + break; + + case Graphics_Mode_Gray: + pbmi->bmiHeader.biBitCount = 8; + pbmi->bmiHeader.biClrUsed = 5; + + memcpy ( &pbmi->bmiColors[0], gray_scale, sizeof gray_scale ); + + vio_ScanLineWidth = WIN_WIDTH / 2; + vio_Width = WIN_WIDTH / 2; + vio_Height = WIN_HEIGHT/ 2; + + for ( i = 0; i < 5; ++i ) + gray_palette[i] = i; + + break; + + default: + + free ( pbmi ); + return 0; /* Unknown mode */ + } + + pbmi->bmiHeader.biSize = sizeof ( BITMAPINFOHEADER ); + pbmi->bmiHeader.biWidth = vio_Width; + pbmi->bmiHeader.biHeight = vio_Height; + pbmi->bmiHeader.biPlanes = 1; + + if ( (long) vio_Height * vio_ScanLineWidth > 0xFFE0ul ) + /* too big to work on 16-bit; fails the process */ + { + free ( pbmi ); + return 0; + } + + if( ! CreateTheWindow ( vio_Width, vio_Height ) ) + { + free ( pbmi ); + return 0; + } + + return 1; /* success even if the window was not built. */ + } + + +int Driver_Display_Bitmap ( char* buffer, int lines, int cols ) + { + HDC hDC; + + if ( cols * 8 != pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount ) + pbmi->bmiHeader.biWidth = cols * 8 / pbmi->bmiHeader.biBitCount; + + hDC = GetDC ( hwndGraphic ); + SetDIBits ( hDC, hbm, 0, lines, buffer, pbmi, DIB_RGB_COLORS ); + ReleaseDC ( hwndGraphic, hDC ); + + ShowWindow( hwndGraphic, SW_SHOW ); + InvalidateRect ( hwndGraphic, NULL, FALSE ); + UpdateWindow ( hwndGraphic ); + + return 1; /* success */ + } + + +void Get_Event( TEvent* event ) + { + MSG msg; + + if ( hwndGraphic ) + { + SetWindowText ( hwndGraphic, Header ); + } + + do { + while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) { + TranslateMessage ( &msg ); + DispatchMessage ( &msg ); + } + if ( ! eventToProcess ) + WaitMessage(); + } while ( ! eventToProcess ); + + event->what = ourevent.what; + event->info = ourevent.info; + eventToProcess = 0; + return; + } + + +/* ---- Windows-specific stuff ------------------------------------------- */ + +LRESULT CALLBACK Message_Process( HWND, UINT, WPARAM, LPARAM ); + +static +BOOL RegisterTheClass ( void ) + { + WNDCLASS ourClass = { + /* UINT style */ 0, + /* WNDPROC lpfnWndProc */ Message_Process, + /* int cbClsExtra */ 0, + /* int cbWndExtra */ 0, + /* HANDLE hInstance */ 0, + /* HICON hIcon */ 0, + /* HCURSOR hCursor */ 0, + /* HBRUSH hbrBackground*/ 0, + /* LPCTSTR lpszMenuName */ NULL, + /* LPCTSTR lpszClassName*/ "FreeTypeTestGraphicDriver16" + }; + + if( hPrev ) + /* There is another instance of the same program. */ + /* No need to register the class. */ + return 1; + + ourClass.hInstance = hInst; + ourClass.hIcon = LoadIcon(0, IDI_APPLICATION); + ourClass.hCursor = LoadCursor(0, IDC_ARROW); + ourClass.hbrBackground= GetStockObject(BLACK_BRUSH); + + return RegisterClass(&ourClass) != 0; /* return False if it fails. */ + } + +static +BOOL CreateTheWindow ( int width, int height ) + { + if ( ! (hwndGraphic = CreateWindow( + /* LPCSTR lpszClassName; */ "FreeTypeTestGraphicDriver16", + /* LPCSTR lpszWindowName; */ "FreeType Test Graphic Driver", + /* DWORD dwStyle; */ WS_OVERLAPPED | WS_SYSMENU, + /* int x; */ CW_USEDEFAULT, + /* int y; */ CW_USEDEFAULT, + /* int nWidth; */ width + 2*GetSystemMetrics(SM_CXBORDER), + /* int nHeight; */ height+ GetSystemMetrics(SM_CYBORDER) + + GetSystemMetrics(SM_CYCAPTION), + /* HWND hwndParent; */ HWND_DESKTOP, + /* HMENU hmenu; */ 0, + /* HINSTANCE hinst; */ hInst, + /* void FAR* lpvParam; */ NULL)) + ) + /* creation failed... */ + return 0; + + return 1; + } + + /* Message processing for our Windows class */ +LRESULT CALLBACK Message_Process( HWND handle, UINT mess, + WPARAM wParam, LPARAM lParam ) + { + + switch( mess ) + { + case WM_DESTROY: + /* warn the main thread to quit if it didn't know */ + ourevent.what = event_Quit; + ourevent.info = 0; + eventToProcess = 1; + hwndGraphic = 0; + PostQuitMessage ( 0 ); + DeleteObject ( hbm ); + break; + + case WM_CREATE: + { + HDC hDC; + + hDC = GetDC ( handle ); + hbm = CreateDIBitmap ( + /* HDC hdc; handle of device context */ hDC, + /* BITMAPINFOHEADER FAR* lpbmih; addr.of header*/ &pbmi->bmiHeader, + /* DWORD dwInit; CBM_INIT to initialize bitmap */ 0, + /* const void FAR* lpvBits; address of values */ NULL, + /* BITMAPINFO FAR* lpbmi; addr.of bitmap data */ pbmi, + /* UINT fnColorUse; RGB or palette indices */ DIB_RGB_COLORS); + ReleaseDC ( handle, hDC ); + break; + } + + case WM_PAINT: + { + HDC hDC, memDC; + HANDLE oldbm; + PAINTSTRUCT ps; + + hDC = BeginPaint ( handle, &ps ); + memDC = CreateCompatibleDC(hDC); + oldbm = SelectObject(memDC, hbm); + BitBlt ( hDC, 0, 0, vio_Width, vio_Height, memDC, 0, 0, SRCCOPY); + ReleaseDC ( handle, hDC ); + SelectObject ( memDC, oldbm ); + DeleteObject ( memDC ); + EndPaint ( handle, &ps ); + } + + case WM_KEYDOWN: + switch ( wParam ) + { + case VK_ESCAPE: + ourevent.what = event_Quit; + ourevent.info = 0; + eventToProcess = 1; + break; + + case VK_F1: /* bring up help and about dialog window */ + break; + } + break; + + case WM_CHAR: + { + char c = wParam ; + int i; + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + ourevent.what = trans[i].event_class; + ourevent.info = trans[i].event_info; + eventToProcess = 1; + return 0; + } + } + + /* unrecognized keystroke */ + ourevent.what = event_Keyboard; + ourevent.info = (int)c; + eventToProcess = 1; + } + break; + + default: + return DefWindowProc( handle, mess, wParam, lParam ); + } + + return 0; + } + +/* End */ diff --git a/test/arch/win16/makedep b/test/arch/win16/makedep new file mode 100644 index 0000000..6bfe565 --- /dev/null +++ b/test/arch/win16/makedep @@ -0,0 +1,30 @@ +# makedep +# +# This shell script creates a dependency file necessary for older compilers +# on the Windows 16-bit platform. +# +# If you run this script under non-Windows operating systems, expect +# warnings that `windows.h' can't be found. + +echo "\ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.win + +(cd ../.. + gcc -MM -I../lib/arch/win16 -I../lib -I../lib/extend -I. \ + *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.win + +echo "!ifndef __MAKE__" >> depend.win + +(cd ../.. + gcc -MM -I../lib/arch/win16 -I../lib -I../lib/extend -I. \ + -DhInst -DhPrev arch/win16/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\win16\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.win + +echo "!endif" >> depend.win + +# eof diff --git a/test/arch/win32/Makefile.BC b/test/arch/win32/Makefile.BC new file mode 100644 index 0000000..9acb6ca --- /dev/null +++ b/test/arch/win32/Makefile.BC @@ -0,0 +1,197 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for BC++ for Win32. +# +# Tested with Borland C++ v.4.02, 5.0, and Borland C++ builder 4. +# You will need Borland MAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# make -farch\win32\Makefile.BC +# +# +# A DLL version of the library can be built and then used with +# +# make -DDLL -farch/win16/Makefile.BC dll +# +# (do not forget to define DLL, otherwise the link phase will fail). +# +# +# A debug version can be obtained with +# +# make -DDEBUG -farch\win32\Makefile.BC + +ARCH = arch\win32 +FT_MAKEFILE = $(ARCH)\Makefile.BC +FT_DLL = ft13_32.dll + +CC = bcc32 + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR);$(LIBDIR)\$(ARCH);.;$(LIBDIR)\extend +SPURIOUS_WARNINGS = -w-nak -w-par -w-use -w-aus -w-stu -w-stv -w-cln -w-sig -w-pia +CFLAGS = -i48 $(INCDIRS) $(SPURIOUS_WARNINGS) + +!ifndef DEBUG +CFLAGS = $(CFLAGS) -O2 -A +LDFLAGS = -WC +!else +CFLAGS = $(CFLAGS) -v +LDFLAGS = -v -WC +!endif + +!ifdef DLL +CFLAGS = $(CFLAGS) -DFREETYPE_DLL +!endif + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win32.c + +DISPLAY = display.c + +G1SRC = gmain.c blitter.c $(GDRIVER) +GSRC = $(DISPLAY) $(G1SRC) + +GOBJ = $(GSRC:.c=.obj) +G1OBJ = $(G1SRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + $(CC) -c -o$* @&&| + $(CFLAGS) $< +| + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skipped if DEBUG build +all: freetype $(EXEFILES) + +dll: the_dll $(EXEFILES) + +!else +# Skipped if non-DEBUG build +default_target: debug +dll: the_debug_dll $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +freetype: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG debug + cd ..\test + +the_dll: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDLL dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + +the_debug_dll: + cd $(LIBDIR) + make -f$(FT_MAKEFILE) -DDEBUG -DDLL dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + + +# C compilers are unable to include in ANSI mode, +# because of the // comments... +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + $(CC) -c -o$* @&&| + $(CFLAGS) -A- $*.c +| + + +# Borland versions of make are unable to use the $** variable inside +# implicit rules (like .obj.exe:). The job have to be done by hand. :-( +ftzoom.exe: $(G1OBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftzoom.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftview.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstring.obj $(GOBJ) common.obj $(LIBDIR)\libttf.lib + +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrtto.obj $(GOBJ) common.obj arabic.obj \ + $(LIBDIR)\libttf.lib + +fttimer.exe: $(G1OBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fttimer.obj $(G1OBJ) common.obj $(LIBDIR)\libttf.lib + +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftlint.obj common.obj $(LIBDIR)\libttf.lib + +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftdump.obj common.obj $(LIBDIR)\libttf.lib + +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib + +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftsbit.obj common.obj $(LIBDIR)\libttf.lib + +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) ftmetric.obj common.obj $(LIBDIR)\libttf.lib + +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + $(CC) $(LDFLAGS) fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + make -f$(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + -del *.dll + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + -del *.tds + +!include "$(ARCH)\depend.win" + +# end of Makefile diff --git a/test/arch/win32/Makefile.CL b/test/arch/win32/Makefile.CL new file mode 100644 index 0000000..246c71f --- /dev/null +++ b/test/arch/win32/Makefile.CL @@ -0,0 +1,175 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for Microsoft Visual C++. +# +# You will need NMAKE. +# +# +# Use this file while in the 'test' directory with the following statement: +# +# nmake /f arch\win32\Makefile.CL +# +# A DLL version of the library can be built and then used with +# +# nmake DLL=1 /f arch\win32\Makefile.CL dll +# +# (do not forget to define DLL, otherwise the link phase will fail). +# +# +# Debug versions can be obtained with +# +# nmake DEBUG=1 /f arch\win32\Makefile.CL + +ARCH = arch\win32 +FT_MAKEFILE = $(ARCH)\Makefile.CL +FT_MAKE = $(MAKE) /nologo +FT_DLL = ft13_32.dll + +CC = cl /nologo + +LIBDIR = ..\lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)\$(ARCH) -I. -I$(LIBDIR)\extend + +CFLAGS_ANSI = /Za +!ifndef DEBUG +CFLAGS = /Ox /W2 $(INCDIRS) +LDFLAGS = +!else +CFLAGS = /Zi /Ge /W2 $(INCDIRS) +LDFLAGS = /Zi +!endif + +!ifdef DLL +CFLAGS = $(CFLAGS) /DEXPORT_DEF=__declspec(dllexport) /DFREETYPE_DLL +!endif + + +# Windows graphic driver +GDRIVER = $(ARCH)\gw_win32.c + +GSRC = display.c gmain.c blitter.c $(GDRIVER) + +GOBJ = $(GSRC:.c=.obj) + + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +OBJ = $(SRC:.c=.obj) + + +.c.obj: + @$(CC) /c /Fo$* @<< + $(CFLAGS) $(CFLAGS_ANSI) $< +<< + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +!ifndef DEBUG +# Skiped if DEBUG build +all: freetype $(EXEFILES) + +dll: the_dll $(EXEFILES) + +!else +# Skipped if non-DEBUG build +default_target: debug +dll: the_debug_dll $(EXEFILES) + +!endif + +debug: freetype_debug $(EXEFILES) + +freetype: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) all + cd ..\test + +freetype_debug: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 debug + cd ..\test + +the_dll: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DLL=1 dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + +the_debug_dll: + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) DEBUG=1 DLL=1 dll + cd ..\test + -copy $(LIBDIR)\$(FT_DLL) + + +# C compilers are unable to include 32-bit in ANSI mode. +# So we have a special rule for this file, to build it outside ANSI. +$(GDRIVER:.c=.obj): + $(CC) /c /Fo$* @<< + $(CFLAGS) /Ze $(GDRIVER) +<< + +.obj.exe: + $(CC) /Fe$* @<< + $(LDFLAGS) $** GDI32.LIB USER32.LIB +<< + +ftzoom.exe: $(GOBJ) ftzoom.obj common.obj $(LIBDIR)\libttf.lib +ftview.exe: $(GOBJ) ftview.obj common.obj $(LIBDIR)\libttf.lib +ftstring.exe: $(GOBJ) ftstring.obj common.obj $(LIBDIR)\libttf.lib +ftstrtto.exe: $(GOBJ) ftstrtto.obj common.obj arabic.obj $(LIBDIR)\libttf.lib +fttimer.exe: $(GOBJ) fttimer.obj common.obj $(LIBDIR)\libttf.lib +ftlint.exe: ftlint.obj common.obj $(LIBDIR)\libttf.lib +ftdump.exe: ftdump.obj common.obj $(LIBDIR)\libttf.lib +ftstrpnm.exe: ftstrpnm.obj common.obj $(LIBDIR)\libttf.lib +ftsbit.exe: ftsbit.obj common.obj $(LIBDIR)\libttf.lib +ftmetric.exe: ftmetric.obj common.obj $(LIBDIR)\libttf.lib +fterror.exe: fterror.obj common.obj $(LIBDIR)\libttf.lib + + +clean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) clean + cd ..\test + +distclean: do_clean + cd $(LIBDIR) + $(FT_MAKE) /f $(FT_MAKEFILE) distclean + cd ..\test + -del *.exe + -del *.dll + -del *.pdb + +do_clean: + -del *.obj + -del $(ARCH)\*.obj + -del *.ilk + -del *.pch + -del *.exp + + +!include "$(ARCH)\depend.win" + +# end of Makefile.CL diff --git a/test/arch/win32/Makefile.Min b/test/arch/win32/Makefile.Min new file mode 100644 index 0000000..e0c05c2 --- /dev/null +++ b/test/arch/win32/Makefile.Min @@ -0,0 +1,122 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for MinGW32 gcc under Win9x. +# +# You will need a port of GNU make; the MingW32 port works. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/win32/Makefile.min + +ARCH = arch/win32 +FT_MAKEFILE = $(ARCH)/Makefile.min + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +ifdef DEBUG + +CFLAGS = -ansi -pedantic -Wall -O2 -g $(INCDIRS) +LDFLAGS = -g -luser32 -lgdi32 + +else + +CFLAGS = -ansi -pedantic -Wall -O2 -s $(INCDIRS) +LDFLAGS = -s -luser32 -lgdi32 + +endif + + +# graphic Windows driver +GDRIVER = $(ARCH)/gw_win32.c + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(GDRIVER) +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +%.exe: + $(CC) $(LDFLAGS) -o $@ $^ + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom.exe: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +fterror.exe: fterror.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -del dep.end + -del *.exe + -del core + +do_clean: + -del *.o + -del response + -del $(subst /,\,$(GDRIVER:.c=.o)) + +depend: $(SRC) $(GSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/test/arch/win32/Makefile.gcc b/test/arch/win32/Makefile.gcc new file mode 100644 index 0000000..01ccb6c --- /dev/null +++ b/test/arch/win32/Makefile.gcc @@ -0,0 +1,131 @@ +# This file is part of the FreeType project. +# +# It builds the library and test programs for gcc under Win32. +# +# You will need GNU make. +# +# Use this file while in the 'test' directory with the following statement: +# +# make -f arch/win32/Makefile.gcc +# +# +# If you have the GNU gettext package installed, you can also try +# +# make -f arch/win32/Makefile.gcc HAVE_GETTEXT + +ARCH = arch/win32 +FT_MAKEFILE = $(ARCH)/Makefile.gcc + +CC = gcc + +LIBDIR = ../lib +INCDIRS = -I$(LIBDIR) -I$(LIBDIR)/$(ARCH) -I. -I$(LIBDIR)/extend + +ifndef GETTEXT +GETTEXT=NO_GETTEXT +endif + +CFLAGS = -Wall -ansi -O2 -g $(INCDIRS) +# -D$(GETTEXT) +# CFLAGS = -ansi -Wall -O2 -s $(INCDIRS) -D$(GETTEXT) + + +# graphic Windows driver +GDRIVER = $(ARCH)/gw_win32.c + +SRC = arabic.c \ + common.c \ + ftdump.c \ + fterror.c \ + ftlint.c \ + ftmetric.c \ + ftsbit.c \ + ftstring.c \ + ftstrpnm.c \ + ftstrtto.c \ + fttimer.c \ + ftview.c \ + ftzoom.c + +GSRC = gmain.c display.c blitter.c $(GDRIVER) +GOBJ = $(GSRC:.c=.o) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +ifeq ($(GETTEXT),HAVE_GETTEXT) +%.exe: + $(CC) $(CFLAGS) -o $@ $^ -lintl +else +%.exe: + $(CC) $(CFLAGS) -o $@ $^ +endif + + +EXEFILES = ftdump.exe \ + fterror.exe \ + ftlint.exe \ + ftmetric.exe \ + ftsbit.exe \ + ftstring.exe \ + ftstrpnm.exe \ + ftstrtto.exe \ + fttimer.exe \ + ftview.exe \ + ftzoom.exe + +.PHONY: all debug freetype freetype_debug \ + clean distclean do_clean depend + + +all: freetype $(EXEFILES) + +debug: freetype_debug $(EXEFILES) + +HAVE_GETTEXT: + $(MAKE) -f $(FT_MAKEFILE) GETTEXT=HAVE_GETTEXT all + +freetype: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) all + +freetype_debug: + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) debug + +ftzoom.exe: $(GOBJ) ftzoom.o common.o $(LIBDIR)/libttf.a +ftview.exe: $(GOBJ) ftview.o common.o $(LIBDIR)/libttf.a +ftlint.exe: ftlint.o common.o $(LIBDIR)/libttf.a +ftdump.exe: ftdump.o common.o $(LIBDIR)/libttf.a +fterror.exe: fterror.o common.o $(LIBDIR)/libttf.a +ftstring.exe: $(GOBJ) ftstring.o common.o $(LIBDIR)/libttf.a +fttimer.exe: $(GOBJ) fttimer.o common.o $(LIBDIR)/libttf.a +ftstrpnm.exe: ftstrpnm.o common.o $(LIBDIR)/libttf.a +ftsbit.exe: ftsbit.o common.o $(LIBDIR)/libttf.a +ftmetric.exe: ftmetric.o common.o $(LIBDIR)/libttf.a +ftstrtto.exe: $(GOBJ) ftstrtto.o common.o arabic.o $(LIBDIR)/libttf.a + + +clean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) clean + +distclean: do_clean + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) distclean + -del dep.end + -del *.exe + -del core + +do_clean: + -del *.o + -del response + -del $(GDRIVER:.c=.o) + +depend: $(SRC) $(GSRC) + $(MAKE) -C $(LIBDIR) -f $(FT_MAKEFILE) depend + $(CC) -E -M $(INCDIRS) $^ > dep.end + +ifeq (dep.end,$(wildcard dep.end)) + include dep.end +endif + +# end of Makefile.gcc diff --git a/test/arch/win32/depend.win b/test/arch/win32/depend.win new file mode 100644 index 0000000..69916dd --- /dev/null +++ b/test/arch/win32/depend.win @@ -0,0 +1,52 @@ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script `makedep' on +# 03-Sep-1999. + +arabic.obj: arabic.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h +blitter.obj: blitter.c blitter.h +common.obj: common.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +display.obj: display.c display.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gmain.h +fdebug.obj: fdebug.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\tttypes.h ..\lib\ttconfig.h \ + ..\lib\arch\win32\ft_conf.h ..\lib\ttdebug.h ..\lib\ttobjs.h \ + ..\lib\ttengine.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +ftdump.obj: ftdump.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxcmap.h ..\lib\extend\ftxopen.h \ + ..\lib\extend\ftxgdef.h ..\lib\extend\ftxgsub.h \ + ..\lib\extend\ftxgpos.h ..\lib\extend\ftxsbit.h ..\lib\ttobjs.h \ + ..\lib\ttconfig.h ..\lib\arch\win32\ft_conf.h ..\lib\ttengine.h \ + ..\lib\tttypes.h ..\lib\ttmutex.h ..\lib\ttcache.h ..\lib\tttables.h \ + ..\lib\ttcmap.h +fterror.obj: fterror.c ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxerr18.h \ + ..\lib\arch\win32\ft_conf.h +ftlint.obj: ftlint.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\arch\win32\ft_conf.h +ftmetric.obj: ftmetric.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\win32\ft_conf.h +ftsbit.obj: ftsbit.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxsbit.h ..\lib\arch\win32\ft_conf.h +ftstring.obj: ftstring.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h display.h gevents.h gdriver.h gmain.h +ftstrpnm.obj: ftstrpnm.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h +ftstrtto.obj: ftstrtto.c arabic.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxopen.h ..\lib\extend\ftxgdef.h \ + ..\lib\extend\ftxgsub.h ..\lib\extend\ftxgpos.h blitter.h common.h \ + display.h ..\lib\extend\ftxkern.h ..\lib\extend\ftxsbit.h gdriver.h \ + gevents.h gmain.h +fttimer.obj: fttimer.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h gdriver.h gevents.h gmain.h +ftview.obj: ftview.c blitter.h common.h display.h \ + ..\lib\extend\ftxsbit.h gdriver.h gevents.h gmain.h +ftzoom.obj: ftzoom.c common.h ..\lib\freetype.h ..\lib\fterrid.h \ + ..\lib\ftnameid.h ..\lib\extend\ftxpost.h gdriver.h gevents.h gmain.h +gmain.obj: gmain.c gdriver.h gmain.h +!ifndef __MAKE__ +arch\win32\gw_win32.obj: arch\win32\gw_win32.c gdriver.h gevents.h gmain.h +!endif diff --git a/test/arch/win32/gw_win32.c b/test/arch/win32/gw_win32.c new file mode 100644 index 0000000..3b34c80 --- /dev/null +++ b/test/arch/win32/gw_win32.c @@ -0,0 +1,378 @@ +/******************************************************************* + * + * gw_win32.c graphics driver for Win32 platform. 0.1 + * + * This is the driver for displaying inside a window under Win32, + * used by the graphics utility of the FreeType test suite. + * + * Written by Antoine Leca. + * Copyright 1999 by Antoine Leca, + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * Borrowing liberally from the other FreeType drivers. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +/* Size of the window. */ +#define WIN_WIDTH 640u +#define WIN_HEIGHT 450u + +/* These values can be changed, but WIN_WIDTH should remain for now a */ +/* multiple of 32 to avoid padding issues. */ + + + typedef struct _Translator + { + char key; + GEvent event_class; + int event_info; + } Translator; + +#define NUM_Translators 20 + + static const Translator trans[NUM_Translators] = + { + { (char)27, event_Quit, 0 }, + { 'q', event_Quit, 0 }, + + { 'x', event_Rotate_Glyph, -1 }, + { 'c', event_Rotate_Glyph, 1 }, + { 'v', event_Rotate_Glyph, -16 }, + { 'b', event_Rotate_Glyph, 16 }, + + { '{', event_Change_Glyph, -10000 }, + { '}', event_Change_Glyph, 10000 }, + { '(', event_Change_Glyph, -1000 }, + { ')', event_Change_Glyph, 1000 }, + { '9', event_Change_Glyph, -100 }, + { '0', event_Change_Glyph, 100 }, + { 'i', event_Change_Glyph, -10 }, + { 'o', event_Change_Glyph, 10 }, + { 'k', event_Change_Glyph, -1 }, + { 'l', event_Change_Glyph, 1 }, + + { '+', event_Scale_Glyph, 10 }, + { '-', event_Scale_Glyph, -10 }, + { 'u', event_Scale_Glyph, 1 }, + { 'j', event_Scale_Glyph, -1 } + }; + + /* handle of the window. */ + static HWND hwndGraphic; + + /* bitmap information */ + static LPBITMAPINFO pbmi; + static HBITMAP hbm; + + /* local event to pass on */ + static TEvent ourevent = { event_Quit, 0 }; + static int eventToProcess = 0; + + /* array defined in the test programs */ + extern char Header[]; + + +/* restores screen to its original state */ + +int Driver_Restore_Mode() + { + /* The graphical window has perhaps already destroyed itself */ + if ( hwndGraphic ) { + DestroyWindow ( hwndGraphic ); + PostMessage( hwndGraphic, WM_QUIT, 0, 0 ); + } + + if ( pbmi ) free ( pbmi ); + + return 1; + } + + +/* + * set graphics mode + * and create the window class and the message handling. + */ + +/* Declarations of the Windows-specific functions that are below. */ +static BOOL RegisterTheClass ( void ); +static BOOL CreateTheWindow ( int width, int height ); + + +int Driver_Set_Graphics ( int mode ) + { + int i; + static RGBQUAD gray_scale[5] = { + { 0xFF, 0xFF, 0xFF, 0 }, /* white */ + { 0xC0, 0xC0, 0xC0, 0 }, + { 0x80, 0x80, 0x80, 0 }, + { 0x40, 0x40, 0x40, 0 }, + { 0, 0, 0, 0 } }; /* black */ + + if( ! RegisterTheClass() ) return 0; /* if already running, fails. */ + + /* find some memory for the bitmap header */ + if ( (pbmi = malloc ( sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ) ) + /* 256 should really be 2 if not grayscale */ + == NULL ) + /* lack of memory; fails the process */ + return 0; + + /* initialize the header to appropriate values */ + memset( pbmi, 0, sizeof ( BITMAPINFO ) + sizeof ( RGBQUAD ) * 256 ); + + switch ( mode ) + { + case Graphics_Mode_Mono: + pbmi->bmiHeader.biBitCount = 1; + pbmi->bmiColors[0] = gray_scale[0]; + pbmi->bmiColors[1] = gray_scale[4]; + + vio_ScanLineWidth = WIN_WIDTH / 8; + vio_Width = WIN_WIDTH; + vio_Height = WIN_HEIGHT; + + break; + + case Graphics_Mode_Gray: + pbmi->bmiHeader.biBitCount = 8; + pbmi->bmiHeader.biClrUsed = 5; + + memcpy ( &pbmi->bmiColors[0], gray_scale, sizeof gray_scale ); + + vio_ScanLineWidth = WIN_WIDTH; + vio_Width = WIN_WIDTH; + vio_Height = WIN_HEIGHT; + + for ( i = 0; i < 5; ++i ) + gray_palette[i] = i; + + break; + + default: + free ( pbmi ); + return 0; /* Unknown mode */ + } + + pbmi->bmiHeader.biSize = sizeof ( BITMAPINFOHEADER ); + pbmi->bmiHeader.biWidth = vio_Width; + pbmi->bmiHeader.biHeight = vio_Height; + pbmi->bmiHeader.biPlanes = 1; + + if( ! CreateTheWindow(vio_Width, vio_Height) ) + { + free ( pbmi ); + return 0; + } + + return 1; /* success even if the window was not built. */ + } + + +int Driver_Display_Bitmap ( char* buffer, int lines, int cols ) + { + HDC hDC; + + if ( cols * 8 != pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount ) + pbmi->bmiHeader.biWidth = cols * 8 / pbmi->bmiHeader.biBitCount; + + hDC = GetDC ( hwndGraphic ); + SetDIBits ( hDC, hbm, 0, lines, buffer, pbmi, DIB_RGB_COLORS ); + ReleaseDC ( hwndGraphic, hDC ); + + ShowWindow( hwndGraphic, SW_SHOW ); + InvalidateRect ( hwndGraphic, NULL, FALSE ); + UpdateWindow ( hwndGraphic ); + + return 1; /* success */ + } + + +void Get_Event( TEvent* event ) + { + MSG msg; + + if ( hwndGraphic ) + { + SetWindowText ( hwndGraphic, Header ); + } + + do { + while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) { + TranslateMessage ( &msg ); + DispatchMessage ( &msg ); + } + if ( ! eventToProcess ) + WaitMessage(); + } while ( ! eventToProcess ); + + event->what = ourevent.what; + event->info = ourevent.info; + eventToProcess = 0; + return; + } + + +/* ---- Windows-specific stuff ------------------------------------------- */ + +LRESULT CALLBACK Message_Process( HWND, UINT, WPARAM, LPARAM ); + +static +BOOL RegisterTheClass ( void ) + { + WNDCLASS ourClass = { + /* UINT style */ 0, + /* WNDPROC lpfnWndProc */ Message_Process, + /* int cbClsExtra */ 0, + /* int cbWndExtra */ 0, + /* HANDLE hInstance */ 0, + /* HICON hIcon */ 0, + /* HCURSOR hCursor */ 0, + /* HBRUSH hbrBackground*/ 0, + /* LPCTSTR lpszMenuName */ NULL, + /* LPCTSTR lpszClassName*/ "FreeTypeTestGraphicDriver" + }; + + ourClass.hInstance = GetModuleHandle( NULL ); + ourClass.hIcon = LoadIcon(0, IDI_APPLICATION); + ourClass.hCursor = LoadCursor(0, IDC_ARROW); + ourClass.hbrBackground= GetStockObject(BLACK_BRUSH); + + return RegisterClass(&ourClass) != 0; /* return False if it fails. */ + } + +static +BOOL CreateTheWindow ( int width, int height ) + { + + if ( ! (hwndGraphic = CreateWindow( + /* LPCSTR lpszClassName; */ "FreeTypeTestGraphicDriver", + /* LPCSTR lpszWindowName; */ "FreeType Test Graphic Driver", + /* DWORD dwStyle; */ WS_OVERLAPPED | WS_SYSMENU, + /* int x; */ CW_USEDEFAULT, + /* int y; */ CW_USEDEFAULT, + /* int nWidth; */ width + 2*GetSystemMetrics(SM_CXBORDER), + /* int nHeight; */ height+ GetSystemMetrics(SM_CYBORDER) + + GetSystemMetrics(SM_CYCAPTION), + /* HWND hwndParent; */ HWND_DESKTOP, + /* HMENU hmenu; */ 0, + /* HINSTANCE hinst; */ GetModuleHandle( NULL ), + /* void FAR* lpvParam; */ NULL)) + ) + /* creation failed... */ + return 0; + + return 1; + } + + /* Message processing for our Windows class */ +LRESULT CALLBACK Message_Process( HWND handle, UINT mess, + WPARAM wParam, LPARAM lParam ) + { + + switch( mess ) + { + case WM_DESTROY: + /* warn the main thread to quit if it didn't know */ + ourevent.what = event_Quit; + ourevent.info = 0; + eventToProcess = 1; + hwndGraphic = 0; + PostQuitMessage ( 0 ); + DeleteObject ( hbm ); + break; + + case WM_CREATE: + { + HDC hDC; + + hDC = GetDC ( handle ); + hbm = CreateDIBitmap ( + /* HDC hdc; handle of device context */ hDC, + /* BITMAPINFOHEADER FAR* lpbmih; addr.of header*/ &pbmi->bmiHeader, + /* DWORD dwInit; CBM_INIT to initialize bitmap */ 0, + /* const void FAR* lpvBits; address of values */ NULL, + /* BITMAPINFO FAR* lpbmi; addr.of bitmap data */ pbmi, + /* UINT fnColorUse; RGB or palette indices */ DIB_RGB_COLORS); + ReleaseDC ( handle, hDC ); + break; + } + + case WM_PAINT: + { + HDC hDC, memDC; + HANDLE oldbm; + PAINTSTRUCT ps; + + hDC = BeginPaint ( handle, &ps ); + memDC = CreateCompatibleDC(hDC); + oldbm = SelectObject(memDC, hbm); + BitBlt ( hDC, 0, 0, vio_Width, vio_Height, memDC, 0, 0, SRCCOPY); + ReleaseDC ( handle, hDC ); + SelectObject ( memDC, oldbm ); + DeleteObject ( memDC ); + EndPaint ( handle, &ps ); + } + + case WM_KEYDOWN: + switch ( wParam ) + { + case VK_ESCAPE: + ourevent.what = event_Quit; + ourevent.info = 0; + eventToProcess = 1; + break; + + case VK_F1: /* bring up help and about dialog window */ + break; + } + break; + + case WM_CHAR: + { + char c = wParam ; + int i; + + for ( i = 0; i < NUM_Translators; i++ ) + { + if ( c == trans[i].key ) + { + ourevent.what = trans[i].event_class; + ourevent.info = trans[i].event_info; + eventToProcess = 1; + return 0; + } + } + + /* unrecognized keystroke */ + ourevent.what = event_Keyboard; + ourevent.info = (int)c; + eventToProcess = 1; + } + break; + + default: + return DefWindowProc( handle, mess, wParam, lParam ); + } + + return 0; + } + +/* End */ diff --git a/test/arch/win32/makedep b/test/arch/win32/makedep new file mode 100644 index 0000000..8336f57 --- /dev/null +++ b/test/arch/win32/makedep @@ -0,0 +1,29 @@ +# makedep +# +# This shell script creates a dependency file necessary for some compilers +# on the Windows 32-bit platform. +# +# If you run this script under non-Windows operating systems, expect +# warnings that `windows.h' can't be found. + +echo "\ +# This dependency file to be used with various Windows compilers +# has been generated automatically with the script \`makedep' on +# `date +%d-%b-%Y`. +" > depend.win + +(cd ../.. + gcc -MM -I../lib/arch/win32 -I../lib -I../lib/extend -I. *.c | \ + sed -e "s/\.o:/.obj:/" -e "s:/:\\\\:g") >> depend.win + +echo "!ifndef __MAKE__" >> depend.win + +(cd ../.. + gcc -MM -I../lib/arch/win32 -I../lib -I../lib/extend -I. \ + arch/win32/*.c | \ + sed -e "s/^\(.*\)\.o:/arch\\\\win32\\\\\1.obj:/" \ + -e "s:/:\\\\:g") >> depend.win + +echo "!endif" >> depend.win + +# eof diff --git a/test/blitter.c b/test/blitter.c new file mode 100644 index 0000000..26f040c --- /dev/null +++ b/test/blitter.c @@ -0,0 +1,492 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* blitter.c: Support for blitting of bitmaps with various depth. */ +/* */ +/****************************************************************************/ + +#include "blitter.h" + + + typedef struct TBlitter_ + { + int width; /* width in pixels of the written area */ + int height; /* height in pixels of the written area */ + + int xread; /* x position of start point in read area */ + int yread; /* y position of start point in read area */ + + int xwrite; /* x position of start point in write area */ + int ywrite; /* y position of start point in write area */ + + int right_clip; /* amount of right clip */ + + char* read; /* top left corner of source map */ + char* write; /* top left corner of target map */ + + int read_line; /* byte increment to go down one row in read area */ + int write_line; /* byte increment to go down one row in write area */ + + TT_Raster_Map source; + TT_Raster_Map target; + + int source_depth; + int target_depth; + + } TBlitter; + + + static + int compute_clips( TBlitter* blit, + int x_offset, + int y_offset ) + { + int xmin, ymin, xmax, ymax, width, height, target_width; + + + /* perform clipping and setup variables */ + width = blit->source.width; + height = blit->source.rows; + + switch ( blit->source_depth ) + { + case 1: + width = (width + 7) & -8; + break; + + case 4: + width = (width + 1) & -2; + break; + } + + xmin = x_offset; + ymin = y_offset; + xmax = xmin + width-1; + ymax = ymin + height-1; + + /* clip if necessary */ + if ( width == 0 || height == 0 || + xmax < 0 || xmin >= blit->target.width || + ymax < 0 || ymin >= blit->target.rows ) + return 1; + + /* set up clipping and cursors */ + blit->yread = 0; + if ( ymin < 0 ) + { + blit->yread -= ymin; + height += ymin; + blit->ywrite = 0; + } + else + blit->ywrite = ymin; + + if ( ymax >= blit->target.rows ) + height -= ymax - blit->target.rows + 1; + + blit->xread = 0; + if ( xmin < 0 ) + { + blit->xread -= xmin; + width += xmin; + blit->xwrite = 0; + } + else + blit->xwrite = xmin; + + target_width = blit->target.width; + + switch ( blit->target_depth ) + { + case 1: + target_width = (target_width + 7) & -8; + break; + case 4: + target_width = (target_width + 1) & -2; + break; + } + + blit->right_clip = xmax - target_width + 1; + if ( blit->right_clip > 0 ) + width -= blit->right_clip; + else + blit->right_clip = 0; + + blit->width = width; + blit->height = height; + + /* set read and write to the top-left corner of the the read */ + /* and write area before clipping. */ + + blit->read = (char*)blit->source.bitmap; + blit->write = (char*)blit->target.bitmap; + + if ( blit->source.flow == TT_Flow_Up ) + { + blit->read_line = -blit->source.cols; + blit->read += (blit->source.rows-1) * blit->source.cols; + } + else + blit->read_line = blit->source.cols; + + if ( blit->target.flow == TT_Flow_Up ) + { + blit->write_line = -blit->target.cols; + blit->write += (blit->target.rows-1) * blit->target.cols; + } + else + blit->write_line = blit->target.cols; + + /* now go to the start line. Note that we do not move the */ + /* x position yet, as this is dependent on the pixel format */ + blit->read += blit->yread * blit->read_line; + blit->write += blit->ywrite * blit->write_line; + + return 0; + } + + +/**************************************************************************/ +/* */ +/* blit_bitmap_to_bitmap */ +/* */ +/**************************************************************************/ + + static + void blit_bitmap_to_bitmap( TBlitter* blit ) + { + int shift, left_clip, x, y; + unsigned char* read; + unsigned char* write; + + + left_clip = ( blit->xread > 0 ); + shift = ( blit->xwrite - blit->xread ) & 7; + + read = (unsigned char*)blit->read + (blit->xread >> 3); + write = (unsigned char*)blit->write + (blit->xwrite >> 3); + + if ( shift == 0 ) + { + y = blit->height; + do + { + unsigned char* _read = read; + unsigned char* _write = write; + + + x = blit->width; + + do + { + *_write++ |= *_read++; + x -= 8; + } while ( x > 0 ); + + read += blit->read_line; + write += blit->write_line; + y--; + } while ( y > 0 ); + } + else + { + int first, last, count; + + + first = blit->xwrite >> 3; + last = (blit->xwrite + blit->width-1) >> 3; + + count = last - first; + + if ( blit->right_clip ) + count++; + + y = blit->height; + + do + { + unsigned char* _read = read; + unsigned char* _write = write; + unsigned char old; + int shift2 = (8-shift); + + + if ( left_clip ) + old = (*_read++) << shift2; + else + old = 0; + + x = count; + while ( x > 0 ) + { + unsigned char val; + + + val = *_read++; + *_write++ |= ( (val >> shift) | old ); + old = val << shift2; + x--; + } + + if ( !blit->right_clip ) + *_write |= old; + + read += blit->read_line; + write += blit->write_line; + y--; + + } while ( y > 0 ); + } + } + + +/**************************************************************************/ +/* */ +/* blit_bitmap_to_pixmap8 */ +/* */ +/**************************************************************************/ + + static + void blit_bitmap_to_pixmap8( TBlitter* blit, + unsigned char color ) + { + int x, y; + unsigned int left_mask; + unsigned char* read; + unsigned char* write; + + + read = (unsigned char*)blit->read + (blit->xread >> 3); + write = (unsigned char*)blit->write + blit->xwrite; + + left_mask = 0x80 >> (blit->xread & 7); + + y = blit->height; + do + { + unsigned char* _read = read; + unsigned char* _write = write; + unsigned int mask = left_mask; + unsigned int val = 0; + + + x = blit->width; + do + { + if ( mask == 0x80 ) + val = *_read++; + + if ( val & mask ) + *_write = (unsigned char)color; + + mask >>= 1; + if ( mask == 0 ) + mask = 0x80; + + _write++; + x--; + } while ( x > 0 ); + + read += blit->read_line; + write += blit->write_line; + y--; + } while ( y > 0 ); + } + + +/**************************************************************************/ +/* */ +/* blit_bitmap_to_pixmap4 */ +/* */ +/**************************************************************************/ + + static + void blit_bitmap_to_pixmap4( TBlitter* blit, + unsigned char color ) + { + int x, y, phase; + unsigned int left_mask; + unsigned char* read; + unsigned char* write; + + + color = color & 15; + + read = (unsigned char*)blit->read + (blit->xread >> 3); + write = (unsigned char*)blit->write + (blit->xwrite >> 1); + + /* now begin blit */ + left_mask = 0x80 >> (blit->xread & 7); + phase = blit->xwrite & 1; + + y = blit->height; + do + { + unsigned char* _read = read; + unsigned char* _write = write; + unsigned int mask = left_mask; + int _phase = phase; + unsigned int val = 0; + + x = blit->width; + do + { + if ( mask == 0x80 ) + val = *_read++; + + if ( val & mask ) + { + if ( _phase ) + *_write = (*_write & 0xF0) | color; + else + *_write = (*_write & 0x0F) | (color << 4); + } + + mask >>= 1; + if ( mask == 0 ) + mask = 0x80; + + _write += _phase; + _phase ^= 1; + x--; + } while ( x > 0 ); + + read += blit->read_line; + write += blit->write_line; + y--; + } while ( y > 0 ); + } + + +/**************************************************************************/ +/* */ +/* blit_bitmap_to_pixmap16 */ +/* */ +/**************************************************************************/ + + static + void blit_bitmap_to_pixmap16( TBlitter* blit, + unsigned short color ) + { + int x, y; + unsigned int left_mask; + unsigned char* read; + unsigned short* write; + + + read = (unsigned char*)blit->read + (blit->xread >> 3); + write = (unsigned short*)(blit->write + blit->xwrite*2); + + left_mask = 0x80 >> (blit->xread & 7); + + y = blit->height; + do + { + unsigned char* _read = read; + unsigned short* _write = write; + unsigned int mask = left_mask; + unsigned int val = 0; + + x = blit->width; + do + { + if ( mask == 0x80 ) + val = *_read++; + + if ( val & mask ) + *_write = color; + + mask >>= 1; + if ( mask == 0 ) + mask = 0x80; + + _write++; + x--; + } while ( x > 0 ); + + read += blit->read_line; + write += blit->write_line; + y--; + } while ( y > 0 ); + } + + + /* */ + /* Blit_Bitmap */ + /* */ + /* */ + /* blit a source bitmap to a target bitmap or pixmap */ + /* */ + /* */ + /* target :: target bitmap or pixmap */ + /* source :: source bitmap (depth must be 1) */ + /* target_depth :: pixel bit depth of target map */ + /* x_offset :: horizontal offset of source in target */ + /* y_offset :: vertical offset of source in target */ + /* color :: color to use when blitting to color pixmap */ + /* */ + /* */ + /* error code. 0 means success */ + /* */ + /* */ + /* an error occurs when the target bit depth isn't supported, or */ + /* if the source's bit depth isn't 1. */ + /* */ + /* the offsets are relative to the top-left corner of the target */ + /* map. Positive y are downwards. */ + /* */ + extern + int Blit_Bitmap( TT_Raster_Map* target, + TT_Raster_Map* source, + int target_depth, + int x_offset, + int y_offset, + int color ) + { + TBlitter blit; + + + if ( !target || !source ) + return -1; + + blit.source = *source; + blit.target = *target; + blit.source_depth = 1; + blit.target_depth = target_depth; + + /* set up blitter and compute clipping. Return immediately if needed */ + if ( compute_clips( &blit, x_offset, y_offset ) ) + return 0; + + /* now perform the blit */ + switch ( target_depth ) + { + case 1: + blit_bitmap_to_bitmap( &blit ); + break; + + case 4: + blit_bitmap_to_pixmap4( &blit, (unsigned char)color ); + break; + + case 8: + blit_bitmap_to_pixmap8( &blit, (unsigned char)color ); + break; + + case 16: + blit_bitmap_to_pixmap16( &blit, (unsigned short)color ); + break; + + default: + return -2; + } + + return 0; + } + + +/* End */ diff --git a/test/blitter.h b/test/blitter.h new file mode 100644 index 0000000..a506ea4 --- /dev/null +++ b/test/blitter.h @@ -0,0 +1,52 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* blitter.h: Support for blitting of bitmaps with various depth. */ +/* */ +/****************************************************************************/ + +#ifndef BLITTER_H +#define BLITTER_H + +#include + + /* */ + /* Blit_Bitmap */ + /* */ + /* */ + /* blit a source bitmap to a target bitmap or pixmap */ + /* */ + /* */ + /* target :: target bitmap or pixmap */ + /* source :: source bitmap (depth must be 1) */ + /* target_depth :: pixel bit depth of target map */ + /* x_offset :: horizontal offset of source in target */ + /* y_offset :: vertical offset of source in target */ + /* color :: color to use when blitting to color pixmap */ + /* */ + /* */ + /* error code. 0 means success */ + /* */ + /* */ + /* an error occurs when the target bit depth isn't supported, or */ + /* if the source's bit depth isn't 1. */ + /* */ + /* the offsets are relative to the top-left corner of the target */ + /* map. Positive y are downwards. */ + /* */ + extern + int Blit_Bitmap( TT_Raster_Map* target, + TT_Raster_Map* source, + int target_depth, + int x_offset, + int y_offset, + int color ); + +#endif + + +/* End */ diff --git a/test/common.c b/test/common.c new file mode 100644 index 0000000..f77ade3 --- /dev/null +++ b/test/common.c @@ -0,0 +1,310 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* common.c: Various utility functions. */ +/* */ +/****************************************************************************/ + + +/* + * This is a cheap replacement for getopt() because that routine is not + * available on some platforms and behaves differently on other platforms. + * This code was written from scratch without looking at any other + * implementation. + * + * This code is hereby expressly placed in the public domain. + * mleisher@crl.nmsu.edu (Mark Leisher) + * 10 October 1997 + */ + +#ifndef lint +#ifdef __GNUC__ + static char rcsid[] __attribute__ ((unused)) = "$Id: common.c,v 1.14 1999/08/13 12:54:34 werner Exp $"; +#else + static char rcsid[] = "$Id: common.c,v 1.14 1999/08/13 12:54:34 werner Exp $"; +#endif +#endif + +#include +#include +#include +#include + +#include "common.h" +#include "freetype.h" /* TT_Raster_Map */ + + /* + * Externals visible to programs. + */ + + int ft_opterr = 1; + int ft_optind = 1; + char* ft_optarg; + + /* + * Internal variables that are used to detect when the global values + * need to be reset. + */ + + static int cmdac; +#ifdef __STDC__ + static const char* cmdname; + static char* const* cmdav; +#else + static char* cmdname; + static char** cmdav; +#endif + + + int +#ifdef __STDC__ + ft_getopt( int ac, char* const* av, const char* pat ) +#else + ft_getopt( ac, av, pat ) + int ac; + char** av; + char* pat; +#endif + { + int opt; +#ifdef __STDC__ + const char* p; + const char* pp; +#else + char* p; + char* pp; +#endif + + + /* + * If there is no pattern, indicate the parsing is done. + */ + if ( pat == 0 || *pat == 0 ) + return -1; + + /* + * Always reset the option argument to NULL. + */ + ft_optarg = 0; + + /* + * If the number of arguments or argument list do not match the last + * values seen, reset the internal pointers and the globals. + */ + if ( ac != cmdac || av != cmdav ) + { + ft_optind = 1; + cmdac = ac; + cmdav = av; + + /* + * Determine the command name in case it is needed for warning + * messages. + */ + for ( cmdname = 0, p = av[0]; *p; p++ ) + { + if ( *p == '/' || *p == '\\' ) + cmdname = p; + } + + /* + * Skip the path separator if the name was assigned. + */ + if ( cmdname ) + cmdname++; + else + cmdname = av[0]; + } + + /* + * If the next index is greater than or equal to the number of + * arguments, then the command line is done. + */ + if ( ft_optind >= ac ) + return -1; + + /* + * Test the next argument for one of three cases: + * 1. The next argument does not have an initial '-'. + * 2. The next argument is '-'. + * 3. The next argument is '--'. + * + * In either of these cases, command line processing is done. + */ + if ( av[ft_optind][0] != '-' || + strcmp( av[ft_optind], "-" ) == 0 || + strcmp( av[ft_optind], "--" ) == 0 ) + return -1; + + /* + * Point at the next command line argument and increment the + * command line index. + */ + p = av[ft_optind++]; + + /* + * Look for the first character of the command line option. + */ + for ( opt = *(p + 1), pp = pat; *pp && *pp != opt; pp++ ) + ; + + /* + * If nothing in the pattern was recognized, then issue a warning + * and return a '?'. + */ + if ( *pp == 0 ) + { + if ( ft_opterr ) + fprintf( stderr, "%s: illegal option -- %c\n", cmdname, opt ); + return '?'; + } + + /* + * If the option expects an argument, get it. + */ + if ( *(pp + 1) == ':' && (ft_optarg = av[ft_optind]) == 0 ) + { + /* + * If the option argument is NULL, issue a warning and return a '?'. + */ + if ( ft_opterr ) + fprintf( stderr, "%s: option requires an argument -- %c\n", + cmdname, opt ); + opt = '?'; + } + else if ( ft_optarg ) + /* + * Increment the option index past the argument. + */ + ft_optind++; + + /* + * Return the option character. + */ + return opt; + } + + +/****************************************************************************/ +/* */ +/* ft_basename(): */ +/* */ +/* a stupid but useful function... */ +/* */ +/* rewritten by DavidT to get rid of GPLed programs in the FreeType engine. */ +/* */ +/****************************************************************************/ + + char* +#ifdef __STDC__ + ft_basename( const char* name ) +#else + ft_basename( name ) + char* name; +#endif + { +#ifdef __STDC__ + const char* base; + const char* current; +#else + char* base; + char* current; +#endif + char c; + + + base = name; + current = name; + + c = *current; + + while ( c ) + { + if ( c == '/' || c == '\\' ) + base = current + 1; + + current++; + c = *current; + } + + return (char*)base; + } + + + void +#ifdef __STDC__ + Panic( const char* fmt, ... ) +#else + Panic( fmt ) + const char* fmt; +#endif + { + va_list ap; + + + va_start( ap, fmt ); + vprintf( fmt, ap ); + va_end( ap ); + + exit( EXIT_FAILURE ); + } + + + void +#ifdef __STDC__ + Show_Single_Glyph( const TT_Raster_Map* map ) +#else + Show_Single_Glyph( map ) + const TT_Raster_Map* map; +#endif + { + int y; + + unsigned char* line = map->bitmap; + + + for ( y = 0; y < map->rows; y++, line += map->cols ) + { + unsigned char* ptr = line; + int x; + unsigned char mask = 0x80; + + + for ( x = 0; x < map->width; x++ ) + { + printf( "%c", (ptr[0] & mask) ? '*' : '.' ); + mask >>= 1; + if ( mask == 0 ) + { + mask = 0x80; + ptr++; + } + } + printf( "\n" ); + } + } + + + void +#ifdef __STDC__ + separator_line( FILE* out, const int length ) +#else + separator_line( out, length ) + FILE* out; + int length; +#endif + { + int i; + + + for ( i = 0; i < length; i++ ) + fputc( '-', out ); + fprintf( out, "\n\n" ); + } + + +/* End */ diff --git a/test/common.h b/test/common.h new file mode 100644 index 0000000..c214f6c --- /dev/null +++ b/test/common.h @@ -0,0 +1,82 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* common.h: Various utility functions. */ +/* */ +/****************************************************************************/ + +#ifndef COMMON_H +#define COMMON_H + +#include + +#include "freetype.h" /* TT_Raster_Map */ + +/* + * This is a cheap replacement for getopt() because that routine is not + * available on some platforms and behaves differently on other platforms. + * + * This code is hereby expressly placed in the public domain. + * mleisher@crl.nmsu.edu (Mark Leisher) + * 10 October 1997 + */ + +#ifdef __cplusplus + extern "C" { +#endif + + extern int ft_opterr; + extern int ft_optind; + extern char* ft_optarg; + + extern int ft_getopt( +#ifdef __STDC__ + int argc, + char* const* argv, + const char* pattern +#endif + ); + + + extern char* ft_basename( +#ifdef __STDC__ + const char* name +#endif + ); + + + /* print a message and exit */ + extern void Panic( +#ifdef __STDC__ + const char* fmt, ... +#endif + ); + + + extern void Show_Single_Glyph( +#ifdef __STDC__ + const TT_Raster_Map* map +#endif + ); + + + extern void separator_line( +#ifdef __STDC__ + FILE* out, + const int length +#endif + ); + + +#ifdef __cplusplus + } +#endif + +#endif /* COMMON_H */ + + +/* End */ diff --git a/test/display.c b/test/display.c new file mode 100644 index 0000000..5df26d1 --- /dev/null +++ b/test/display.c @@ -0,0 +1,299 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* display.c: Display component used by all test programs. */ +/* */ +/* This file is used to display glyphs and strings in a target window */ +/* using the graphics drivers provided by gmain.c, gevents.h, etc. */ +/* */ +/* Its role is to be shared and heavely commented to let people understand */ +/* how we do the job... */ +/* */ +/****************************************************************************/ + +#include /* malloc() and free() */ +#include /* memset() */ + +#include "display.h" +#include "freetype.h" +#include "gmain.h" + + /* The target bitmap or pixmap -- covering the full display window/screen */ + TT_Raster_Map Bit; + + /* A smaller intermediate bitmap used to render individual glyphs when */ + /* font smoothing mode is activated. It is then or-ed to `Bit'. */ + TT_Raster_Map Small_Bit; + +/* The magic of or-ing gray-levels: */ +/* */ +/* When gray-level mode (a.k.a. font-smoothing) is on, `Bit' is an 8-bit */ +/* pixmap of the size of the display window or screen. */ +/* */ +/* The gray-level palette to use for display is system-dependent, and */ +/* given by the "gray_palette" variable defined in 'gmain.c'. It is */ +/* set up by the graphics driver, and we cannot assume anything about its */ +/* values. */ +/* */ +/* The function TT_Get_Glyph_Pixmap() can use any palette to render each */ +/* individual glyph, however we'll later need to "or" the glyph to */ +/* the display pixmap `Bit' to be able to form strings of text by */ +/* juxtaposing several glyphs together. */ +/* */ +/* If we use the gray_palette directly, we'll encounter trouble doing */ +/* the "or". Example: */ +/* */ +/* Suppose that gray_palette = { 0, 32, 64, 128, 255 } */ +/* */ +/* Let's render a glyph with this palette and "or" it to */ +/* the `Bit' pixmap. If, by chance, we superpose two distinct non-zero */ +/* colors, we will get strange results, like 32+64 = 96, which isn't in */ +/* our gray palette! */ +/* */ +/* There are two ways to solve this problem: */ +/* */ +/* - perform a "slow or" where we check all possible combinations */ +/* and solve conflicts. */ +/* */ +/* - render all pixmaps using a special "virtual" palette that eases */ +/* the "oring" process, then convert the whole display pixmap to */ +/* "display" colors at once. */ +/* */ +/* We choose the second solution, of course; this means that: */ +/* */ +/* - the virtual palette used is simply = { 0, 1, 2, 3, 4 }, defined in */ +/* the variable "palette" below. The `Bit' and `Small_Bit' pixmaps will */ +/* always contain pixels within these values, with the exception of */ +/* post-render display, where `Bit' will be converted to display values */ +/* by the Convert_To_Display_Palette() function. */ +/* */ +/* - as or-ing values between 0 and 4 will give us values between */ +/* 0 and 7, we use a second palette, called "bounding_palette" */ +/* to maintain all values within the virtual palette. */ +/* */ +/* in effect bounding_palette = { 0, 1, 2, 3, 4, 4, 4, 4 } */ +/* */ +/* which means that (3|4) == 7 => 4 after bounding */ +/* */ + + /* the virtual palette */ + unsigned char virtual_palette[5] = { 0, 1, 2, 3, 4 }; + + /* Or-ing the possible palette values gets us from 0 to 7 */ + /* We must bound check these... */ + unsigned char bounded_palette[8] = { 0, 1, 2, 3, 4, 4, 4, 4 }; + + + /* Clears the Bit bitmap/pixmap */ + void Clear_Display( void ) + { + memset( Bit.bitmap, 0, Bit.size ); + } + + + /* Clears the Small_Bit pixmap */ + void Clear_Small( void ) + { + memset( Small_Bit.bitmap, 0, Small_Bit.size ); + } + + + /* Initialize the display bitmap named Bit */ + int Init_Display( int font_smoothing ) + { + Bit.rows = vio_Height; /* the whole window */ + Bit.width = vio_Width; + Bit.flow = TT_Flow_Up; + + if ( font_smoothing ) + Bit.cols = (Bit.width+3) & -4; /* must be 32-bits aligned */ + else + Bit.cols = (Bit.width+7) >> 3; + + Bit.size = (long)Bit.cols * Bit.rows; + + if ( Bit.bitmap ) + free( Bit.bitmap ); + Bit.bitmap = malloc( (int)Bit.size ); + if ( !Bit.bitmap ) + return -1; + + Clear_Display(); + return 0; + } + + + /* Convert the display pixmap from virtual to display palette */ + void Convert_To_Display_Palette( void ) + { + unsigned char* p; + long i; + + p = Bit.bitmap; + for ( i = 0; i < Bit.size; i++ ) + { + *p = gray_palette[(int)*p]; + p++; + } + } + + + /* Init Small Bitmap */ + int Init_Small( int x_ppem, int y_ppem ) + { + if ( Small_Bit.bitmap ) + free( Small_Bit.bitmap ); + + Small_Bit.rows = y_ppem + 32; + Small_Bit.width = x_ppem + 32; + Small_Bit.cols = ( Small_Bit.width+3 ) & -4; /* pad to 32-bits */ + Small_Bit.flow = TT_Flow_Up; + Small_Bit.size = (long)Small_Bit.rows * Small_Bit.cols; + + Small_Bit.bitmap = malloc( (int)Small_Bit.size ); + if ( Small_Bit.bitmap ) + return -1; + + Clear_Small(); + return 0; + } + + + /* Render a single glyph into the display bit/pixmap */ + /* */ + /* Note that in b/w mode, we simply render the glyph directly into */ + /* the display map, as the scan-line converter or-es the glyph into */ + /* the target bitmap. */ + /* */ + /* In gray mode, however, the glyph is first rendered indivdually in */ + /* the Small_Bit map, then 'or-ed' with bounding into the display */ + /* pixmap. */ + /* */ + + TT_Error Render_Single_Glyph( int font_smoothing, + TT_Glyph glyph, + int x_offset, + int y_offset ) + { + if ( !font_smoothing ) + return TT_Get_Glyph_Bitmap( glyph, &Bit, + (long)x_offset*64, (long)y_offset*64 ); + else + { + TT_Glyph_Metrics metrics; + + TT_Error error; + TT_F26Dot6 x, y, xmin, ymin, xmax, ymax; + int ioff, iread; + char *off, *read, *_off, *_read; + + + /* font-smoothing mode */ + + /* we begin by grid-fitting the bounding box */ + TT_Get_Glyph_Metrics( glyph, &metrics ); + + xmin = metrics.bbox.xMin & -64; + ymin = metrics.bbox.yMin & -64; + xmax = (metrics.bbox.xMax+63) & -64; + ymax = (metrics.bbox.yMax+63) & -64; + + /* now render the glyph in the small pixmap */ + + /* IMPORTANT NOTE: the offset parameters passed to the function */ + /* TT_Get_Glyph_Bitmap() must be integer pixel values, i.e., */ + /* multiples of 64. HINTING WILL BE RUINED IF THIS ISN'T THE CASE! */ + /* This is why we _did_ grid-fit the bounding box, especially xmin */ + /* and ymin. */ + + Clear_Small(); + error = TT_Get_Glyph_Pixmap( glyph, &Small_Bit, -xmin, -ymin ); + if ( error ) + return error; + + /* Blit-or the resulting small pixmap into the biggest one */ + /* We do that by hand, and provide also clipping. */ + + xmin = (xmin >> 6) + x_offset; + ymin = (ymin >> 6) + y_offset; + xmax = (xmax >> 6) + x_offset; + ymax = (ymax >> 6) + y_offset; + + /* Take care of comparing xmin and ymin with signed values! */ + /* This was the cause of strange misplacements when Bit.rows */ + /* was unsigned. */ + + if ( xmin >= (int)Bit.width || + ymin >= (int)Bit.rows || + xmax < 0 || + ymax < 0 ) + return TT_Err_Ok; /* nothing to do */ + + /* Note that the clipping check is performed _after_ rendering */ + /* the glyph in the small bitmap to let this function return */ + /* potential error codes for all glyphs, even hidden ones. */ + + /* In exotic glyphs, the bounding box may be larger than the */ + /* size of the small pixmap. Take care of that here. */ + + if ( xmax-xmin + 1 > Small_Bit.width ) + xmax = xmin + Small_Bit.width - 1; + + if ( ymax-ymin + 1 > Small_Bit.rows ) + ymax = ymin + Small_Bit.rows - 1; + + /* set up clipping and cursors */ + + iread = 0; + if ( ymin < 0 ) + { + iread -= ymin * Small_Bit.cols; + ioff = 0; + ymin = 0; + } + else + ioff = ymin * Bit.cols; + + if ( ymax >= Bit.rows ) + ymax = Bit.rows-1; + + if ( xmin < 0 ) + { + iread -= xmin; + xmin = 0; + } + else + ioff += xmin; + + if ( xmax >= Bit.width ) + xmax = Bit.width - 1; + + _read = (char*)Small_Bit.bitmap + iread; + _off = (char*)Bit.bitmap + ioff; + + for ( y = ymin; y <= ymax; y++ ) + { + read = _read; + off = _off; + + for ( x = xmin; x <= xmax; x++ ) + { + *off = bounded_palette[*off | *read]; + off++; + read++; + } + _read += Small_Bit.cols; + _off += Bit.cols; + } + + return TT_Err_Ok; + } + } + + + +/* End */ diff --git a/test/display.h b/test/display.h new file mode 100644 index 0000000..2e9e634 --- /dev/null +++ b/test/display.h @@ -0,0 +1,73 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* display.h: Display component interface used by test programs */ +/* */ +/* This file is used to display glyphs and strings in a target window */ +/* using the graphics drivers provided by gmain.c, gevents.h, etc. */ +/* */ +/* Its role is to be shared and heavely commented to let people understand */ +/* how we do the job... */ +/* */ +/* See comments in display.c for a full description! */ +/* */ +/****************************************************************************/ + +#ifndef DISPLAY_H +#define DISPLAY_H + +#include "freetype.h" /* TT_Raster_Map */ + + /* The target bitmap or pixmap -- covering the full display window/screen */ + extern TT_Raster_Map Bit; + + /* A smaller intermediate bitmap used to render individual glyphs when */ + /* font smoothing mode is activated. It is then or-ed to `Bit'. */ + extern TT_Raster_Map Small_Bit; + + /* the virtual palette */ + extern unsigned char virtual_palette[5]; + + /* Or-ing the possible palette values gets us from 0 to 7 */ + /* We must bound check these... */ + extern unsigned char bounded_palette[8]; + + + /* Clears the Bit bitmap/pixmap */ + void Clear_Display( void ); + + /* Clears the Small_Bit pixmap */ + void Clear_Small( void ); + + /* Initialize the display bitmap named Bit */ + int Init_Display( int font_smoothing ); + + /* Initialize Small Bitmap */ + int Init_Small( int x_ppem, int y_ppem ); + + /* Convert the display pixmap from virtual to display palette */ + void Convert_To_Display_Palette( void ); + + /* Render a single glyph into the display bit/pixmap. */ + /* */ + /* Note that in b/w mode, we simply render the glyph directly into */ + /* the display map, as the scan-line converter or-es the glyph into */ + /* the target bitmap. */ + /* */ + /* In gray mode, however, the glyph is first rendered individually in */ + /* the Small_Bit map, then 'or-ed' with bounding into the display */ + /* pixmap. */ + /* */ + TT_Error Render_Single_Glyph( int font_smoothing, + TT_Glyph glyph, + int x_offset, + int y_offset ); + +#endif /* DISPLAY_H */ + + +/* End */ diff --git a/test/fdebug.c b/test/fdebug.c new file mode 100644 index 0000000..31025ba --- /dev/null +++ b/test/fdebug.c @@ -0,0 +1,285 @@ +/****************************************************************************} +{* *} +{* The FreeType project - a Free and Portable Quality TrueType Renderer. *} +{* *} +{* Copyright 1996-1999 by *} +{* D. Turner, R.Wilhelm, and W. Lemberg *} +{* *} +{* fdebug : A very simple TrueType bytecode debugger. *} +{* *} +{* NOTE : You must compile the interpreter with the DEBUG_INTERPRETER *} +{* macro defined in order to link this program! *} +{* *} +{****************************************************************************/ + +#include /* libc ANSI */ +#include +#include +#include + +#include "freetype.h" +#include "tttypes.h" +#include "ttdebug.h" +#include "ttobjs.h" + + +#ifdef UNIX +#ifndef HAVE_POSIX_TERMIOS +#include +#include +#else +#ifndef HAVE_TCGETATTR +#define HAVE_TCGETATTR +#endif /* HAVE_TCGETATTR */ +#ifndef HAVE_TCSETATTR +#define HAVE_TCSETATTR +#endif /* HAVE_TCSETATTR */ +#include +#endif /* HAVE_POSIX_TERMIOS */ +#endif + + /* MAGIC: This variable is only defined in ttinterp.c if the */ + /* macro DEBUG_INTERPRETER is set. It specifies the code */ + /* range to debug. By default, it is TT_CodeRange_Glyph. */ + /* */ + extern + int debug_coderange; + + +#define Font_Buff_Size 256000 /* this buffer holds all */ + /* font specific data. */ + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_Error error; + + TT_Face_Properties properties; + + int num_glyphs; + int ptsize; + + Int Fail; + Int Num; + int mode = 2; + unsigned char autorun; + +/********************************************************************* + * + * Usage : print usage message + * + *********************************************************************/ + + static + void Usage( const char* execname ) + { + TT_Message( "fdebug: a simple TrueType bytecode debugger - part of the FreeType project\n" ); + TT_Message( "--------------------------------------------------------------------------\n\n"); + TT_Message( "Usage: %s glyphnum ppem fontname[.ttf]\n", execname ); + TT_Message( " or %s --cvt ppem fontname[.ttf]\n", execname ); + TT_Message( " or %s --font fontname[.ttf]\n\n", execname ); + exit( EXIT_FAILURE ); + } + + +/********************************************************************* + * + * Init_Keyboard : set the input file descriptor to char-by-char + * mode on Unix.. + * + *********************************************************************/ + +#ifdef UNIX + + struct termios old_termio; + + static + void Init_Keyboard( void ) + { + struct termios termio; + + +#ifndef HAVE_TCGETATTR + ioctl( 0, TCGETS, &old_termio ); +#else + tcgetattr( 0, &old_termio ); +#endif + + termio = old_termio; + + termio.c_lflag &= ~(ICANON+ECHO+ECHOE+ECHOK+ECHONL+ECHOKE); + +#ifndef HAVE_TCSETATTR + ioctl( 0, TCSETS, &termio ); +#else + tcsetattr( 0, TCSANOW, &termio ); +#endif + } + + static + void Reset_Keyboard( voi ) + { +#ifndef HAVE_TCSETATTR + ioctl( 0, TCSETS, &old_termio ); +#else + tcsetattr( 0, TCSANOW, &old_termio ); +#endif + + } + +#else + + static + void Init_Keyboard( void ) + { + } + + static + void Reset_Keyboard( voi ) + { + } + +#endif + + static + void Print_Banner( void ) + { + TT_Message( "fdebug - a simple TrueType bytecode debugger for FreeType\n" ); + TT_Message( "------------------------------------------------------------\n" ); + TT_Message( "type '?' for help - copyright 1996-1999 the FreeType Project\n\n" ); + } + + + static + void Error( const char* message, + const char* filename ) + { + static char tempstr[256]; + + sprintf( tempstr, "ERROR (%s): %s\n", filename, message ); + TT_Message( tempstr ); + + sprintf( tempstr, " code = 0x%04lx\n", error ); + TT_Message( tempstr ); + + Reset_Keyboard(); + exit( EXIT_FAILURE ); + } + + + static + void Init_Face( const char* filename ) + { + error = TT_Init_FreeType(&engine); + if (error) Error( "could not initialise FreeType", filename ); + + /* open face object */ + error = TT_Open_Face( engine, filename, &face ); + if (error) Error( "could not find or open file", filename ); + + /* get properties */ + TT_Get_Face_Properties( face, &properties ); + num_glyphs = properties.num_Glyphs; + + /* create instance */ + error = TT_New_Instance( face, &instance ); + if (error) Error( "could not create instance", filename ); + + error = TT_New_Glyph( face, &glyph ); + if (error) Error( "could not create glyph container", filename ); + + TT_Set_Instance_Resolutions( instance, 96, 96 ); + + error = TT_Set_Instance_CharSize( instance, ptsize << 6 ); + if (error) Error( "could not set text size", filename ); + } + + + int main( int argc, char** argv ) + { + int i; + char filename[128+4]; + char* execname; + + + execname = argv[0]; + if ( argc < 2 ) + Usage( execname ); + + if ( strcmp( argv[1], "--font" ) == 0 ) + { + debug_coderange = TT_CodeRange_Font; + mode = 0; + argc--; + argv++; + } + else if ( strcmp( argv[1], "--cvt" ) == 0 ) + { + debug_coderange = TT_CodeRange_Cvt; + argv++; + argc--; + mode = 1; + } + else if ( sscanf( argv[1], "%d", &Num ) == 1 ) + { + mode = 2; + argv++; + argc--; + } + else + Usage( execname ); + + /* read the point size for cvt and glyph modes */ + if (mode > 0) + { + if ( sscanf( argv[1], "%d", &ptsize ) != 1 ) + Usage( execname ); + argc--; + argv++; + } + + if ( argc != 2 ) + Usage(execname); + + i = strlen( argv[1] ); + while ( i > 0 && argv[1][i] != '\\' ) + { + if ( argv[1][i] == '.' ) + i = 0; + i--; + } + + filename[128] = 0; + + strncpy( filename, argv[1], 128 ); + if ( i >= 0 ) + strncpy( filename + strlen(filename), ".ttf", 4 ); + + Init_Keyboard(); + + if (mode == 2) + { + Init_Face( filename ); + Print_Banner(); + + error = TT_Load_Glyph( instance, glyph, Num, TTLOAD_DEFAULT ); + if (error) Error( "Error during bytecode execution", filename ); + } + else + { + Print_Banner(); + Init_Face( filename ); + } + + TT_Done_FreeType(engine); + + Reset_Keyboard(); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftdump.c b/test/ftdump.c new file mode 100644 index 0000000..655aab4 --- /dev/null +++ b/test/ftdump.c @@ -0,0 +1,928 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftdump: Simple TrueType font file resource profiler. */ +/* */ +/* This program dumps various properties of a given font file. */ +/* */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" /* for Panic() etc. */ +#include "freetype.h" +#include "ftxcmap.h" +#include "ftxopen.h" /* TrueType Open support */ +#include "ftxsbit.h" /* embedded bitmap support */ + +/* + * The following comment should be ignored. The "ttobjs.h" file does + * already include ft_conf.h. + * + * ------------------------------------------------------------------ + * + * IGNORE> Basically, an external program using FreeType shouldn't depend on an + * IGNORE> internal file of the FreeType library, especially not on ft_conf.h -- but + * IGNORE> to avoid another configure script which tests for the existence of the + * IGNORE> i18n stuff we include ft_conf.h here since we can be sure that our test + * IGNORE> programs use the same configuration options as the library itself. + */ + +#include "ttobjs.h" /* We're going to access internal tables directly */ + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include "ftxerr18.h" +#include +#else +#define gettext( x ) ( x ) +#endif + + + TT_Error error; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Instance_Metrics imetrics; + TT_Outline outline; + TT_Glyph_Metrics metrics; + + TT_Face_Properties properties; + + int num_glyphs; + int ptsize; + + int Fail; + int Num; + + int flag_memory = 1; + int flag_names = 1; + int flag_encodings = 1; + int flag_cmap = 1; + int flag_sbits = 1; + int flag_ttopen = 1; + +#ifdef FREETYPE_DLL + + /* If the library is linked as a DLL, TTMemory_Allocated() */ + /* (which is not exported) cannot be accessed. */ + /* In this case, some compilers report an error because */ + /* they try to link against a non-existing symbol. */ + /* */ + /* We thus avoid the external reference on these compilers. */ + + #define TTMemory_Allocated 0L + +#else + extern long TTMemory_Allocated; +#endif + + long org_memory, old_memory, cur_memory; + + const char* Apple_Encodings[33] = + { + "Roman", "Japanese", "Chinese", "Korean", "Arabic", "Hebrew", + "Greek", "Russian", "RSymbol", "Devanagari", "Gurmukhi", + "Gujarati", "Oriya", "Bengali", "Tamil", "Telugu", "Kannada", + "Malayalam", "Sinhalese", "Burmese", "Khmer", "Tai", "Laotian", + "Georgian", "Armenian", "Maldivian/Simplif. Chinese", "Tibetan", + "Mongolian", "Geez", "Slavic", "Vietnamese", "Sindhi", "Uninterpreted" + }; + + struct + { + long initial_overhead; + long face_object; + long glyph_object; + long first_instance; + long second_instance; + + } memory_footprint; + + + /* We ignore error message strings with this function */ + +#ifndef HAVE_LIBINTL_H + static char* + TT_ErrToString18( TT_Error error ) + { + static char temp[32]; + + + sprintf( temp, "0x%04lx", error ); + return temp; + } +#endif + + + void + Save_Memory( long* var ) + { + *var = TTMemory_Allocated - old_memory; + old_memory += *var; + } + +#define FOOTPRINT( field ) Save_Memory( &memory_footprint.##field ) + + + static void + Print_Mem( long val, char* string ) + { + printf( "%6ld Bytes (%4ld kByte): %s\n", + val, + ( val + 1023L ) / 1024, + string ); + } + +#define PRINT_MEM( field, string ) \ + Print_Mem( memory_footprint.##field, string ) + + + /* Print the memory footprint */ + + void + Print_Memory( void ) + { + /* create glyph */ + error = TT_New_Glyph( face, &glyph ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create glyph container.\n" ) ); + goto Failure; + } + + FOOTPRINT( glyph_object ); + + /* create instance */ + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create instance.\n" ) ); + goto Failure; + } + + FOOTPRINT( first_instance ); + + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create second instance.\n" ) ); + goto Failure; + } + + FOOTPRINT( second_instance ); + + printf( gettext( "Memory footprint statistics:\n" ) ); + separator_line( stdout, 78 ); + + /* NOTE: In our current implementation, the face's execution */ + /* context object is created lazily with the first */ + /* instance. However, all later instances share the */ + /* the same context. */ + + PRINT_MEM( face_object, gettext( "face object" ) ); + PRINT_MEM( glyph_object, gettext( "glyph object" ) ); + PRINT_MEM( second_instance, gettext( "instance object" ) ); + + Print_Mem( memory_footprint.first_instance - + memory_footprint.second_instance, + gettext( "exec. context object" ) ); + + separator_line( stdout, 78 ); + + Print_Mem( memory_footprint.face_object + + memory_footprint.glyph_object + + memory_footprint.first_instance, + gettext( "total memory usage" ) ); + + printf( "\n" ); + + return; + + Failure: + fprintf( stderr, " " ); + Panic( gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + } + + + static char name_buffer[257]; + static int name_len = 0; + + + static char* + LookUp_Name( int index ) + { + unsigned short i, n; + + unsigned short platform, encoding, language, id; + char* string; + unsigned short string_len; + + int j, found; + + + n = properties.num_Names; + + for ( i = 0; i < n; i++ ) + { + TT_Get_Name_ID( face, i, &platform, &encoding, &language, &id ); + TT_Get_Name_String( face, i, &string, &string_len ); + + if ( id == index ) + { + + /* The following code was inspired from Mark Leisher's */ + /* ttf2bdf package */ + + found = 0; + + /* Try to find a Microsoft English name */ + + if ( platform == 3 ) + for ( j = 1; j >= 0; j-- ) + if ( encoding == j ) /* Microsoft ? */ + if ( (language & 0x3FF) == 0x009 ) /* English language */ + { + found = 1; + break; + } + + if ( !found && platform == 0 && language == 0 ) + found = 1; + + /* Found a Unicode Name. */ + + if ( found ) + { + if ( string_len > 512 ) + string_len = 512; + + name_len = 0; + + for ( i = 1; i < string_len; i += 2 ) + name_buffer[name_len++] = string[i]; + + name_buffer[name_len] = '\0'; + + return name_buffer; + } + } + } + + /* Not found */ + return NULL; + } + + + static void + Print_Names( void ) + { + printf( gettext( "font name table entries\n" ) ); + separator_line( stdout, 78 ); + + if ( LookUp_Name( 4 ) ) + printf( "%s - ", name_buffer ); + + if ( LookUp_Name( 5 ) ) + printf( "%s\n\n", name_buffer ); + + if ( LookUp_Name( 6 ) ) + printf( gettext( "PostScript name: %s\n\n" ), name_buffer ); + + if ( LookUp_Name( 0 ) ) + printf( "%s\n\n", name_buffer ); + + if ( LookUp_Name( 7 ) ) + printf( name_buffer ); + + printf( "\n" ); + separator_line( stdout, 78 ); + } + + + static void + Print_Encodings( void ) + { + unsigned short n, i; + unsigned short platform, encoding; + char* platStr, *encoStr; + + char tempStr[128]; + + + printf( gettext( "character map encodings\n" ) ); + separator_line( stdout, 78 ); + + n = properties.num_CharMaps; + if ( n == 0 ) + { + printf( gettext( + "The file doesn't seem to have any encoding table.\n" ) ); + return; + } + + printf( gettext( "There are %hu encodings:\n\n" ), n ); + + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + printf( gettext( "encoding %2u: " ), i ); + + platStr = encoStr = NULL; + + switch ( platform ) + { + case TT_PLATFORM_APPLE_UNICODE: + platStr = "Apple Unicode"; + switch ( encoding ) + { + case TT_APPLE_ID_DEFAULT: + encoStr = ""; + break; + + case TT_APPLE_ID_UNICODE_1_1: + encoStr = "(v.1.1)"; + break; + + case TT_APPLE_ID_ISO_10646: + encoStr = "(ISO 10646-1:1993)"; + break; + + case TT_APPLE_ID_UNICODE_2_0: + encoStr = "(v.2.0)"; + break; + + default: + sprintf( tempStr, gettext( "Unknown value %hu" ), encoding ); + encoStr = tempStr; + } + break; + + case TT_PLATFORM_MACINTOSH: + platStr = "Apple"; + if ( encoding > 32 ) + { + sprintf( tempStr, gettext( "Unknown value %hu" ), encoding ); + encoStr = tempStr; + } + else + encoStr = (char*)Apple_Encodings[encoding]; + break; + + case TT_PLATFORM_ISO: + platStr = "Iso"; + switch ( encoding ) + { + case TT_ISO_ID_7BIT_ASCII: + platStr = "Ascii"; + encoStr = "7-bit"; + break; + + case TT_ISO_ID_10646: + encoStr = "10646"; + break; + + case TT_ISO_ID_8859_1: + encoStr = "8859-1"; + break; + + default: + sprintf( tempStr, "%hu", encoding ); + encoStr = tempStr; + } + break; + + case TT_PLATFORM_MICROSOFT: + platStr = "Windows"; + switch ( encoding ) + { + case TT_MS_ID_SYMBOL_CS: + encoStr = "Symbol"; + break; + + case TT_MS_ID_UNICODE_CS: + encoStr = "Unicode"; + break; + + case TT_MS_ID_SJIS: + encoStr = "Shift-JIS"; + break; + + case TT_MS_ID_GB2312: + encoStr = "GB2312"; + break; + + case TT_MS_ID_BIG_5: + encoStr = "Big 5"; + break; + + case TT_MS_ID_WANSUNG: + encoStr = "WanSung"; + break; + + case TT_MS_ID_JOHAB: + encoStr = "Johab"; + break; + + default: + sprintf( tempStr, gettext( "Unknown value %hu" ), encoding ); + encoStr = tempStr; + } + break; + + default: + sprintf( tempStr, "%hu - %hu", platform, encoding ); + platStr = gettext( "Unknown" ); + encoStr = tempStr; + } + + printf( "%s %s\n", platStr, encoStr ); + } + + printf( "\n" ); + separator_line( stdout, 78 ); + } + + + static void + Print_Cmap( void ) + { + TT_CharMap charmap; + TT_UShort glyph_index; + TT_Long char_index; + unsigned short n, i; + unsigned short platform, encoding; + + + printf( gettext( "ftxcmap test\n" ) ); + separator_line( stdout, 78 ); + + n = properties.num_CharMaps; + if ( n == 0 ) + { + printf( gettext( + "The file doesn't seem to have any encoding table.\n" ) ); + return; + } + + printf( gettext( "There are %hu encodings:\n\n" ), n ); + + for ( i = 0; i < n; i++ ) + { + + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + printf( gettext( "encoding %2u:\n" ), i ); + + TT_Get_CharMap( face, i, &charmap); + + char_index = TT_CharMap_First( charmap, &glyph_index ); + printf( gettext( "first: glyph index %hu, character code 0x%lx\n" ), + glyph_index, char_index ); + + char_index = TT_CharMap_Next( charmap, char_index, &glyph_index ); + printf( gettext( "next: glyph index %hu, character code 0x%lx\n" ), + glyph_index, char_index ); + + char_index = TT_CharMap_Last( charmap, &glyph_index ); + printf( gettext( "last: glyph index %hu, character code 0x%lx\n" ), + glyph_index, char_index ); + } + + printf( "\n" ); + separator_line( stdout, 78 ); + } + + + static void + Print_SBits( void ) + { + TT_EBLC eblc; + TT_Error error; + + + error = TT_Get_Face_Bitmaps( face, &eblc ); + if ( error == TT_Err_Table_Missing ) + return; + if ( error ) + { + fprintf( stderr, gettext( + "Error while retrieving embedded bitmaps table.\n" ) ); + goto Failure; + } + + printf( gettext( "embedded bitmap table\n" ) ); + separator_line( stdout, 78 ); + + printf( gettext( " version of embedded bitmap table: 0x%lx\n" ), + eblc.version ); + printf( gettext( " number of embedded bitmap strikes: %lu\n" ), + eblc.num_strikes ); + + { + TT_SBit_Strike* strike = eblc.strikes; + int count = 0; + + + for ( ; count < eblc.num_strikes; count++, strike++ ) + { + printf( gettext( " bitmap strike %hu/%lu: " ), + count + 1, eblc.num_strikes ); + + printf( gettext( "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" ), + strike->x_ppem, strike->y_ppem, strike->bit_depth, + strike->start_glyph, strike->end_glyph ); + { + TT_SBit_Range* range = strike->sbit_ranges; + TT_SBit_Range* limit = range + strike->num_ranges; + + + for ( ; range < limit; range++ ) + printf( gettext( " range format (%hu:%hu) glyphs %hu..%hu\n" ), + range->index_format, + range->image_format, + range->first_glyph, + range->last_glyph ); + } + } + } + printf( "\n" ); + separator_line( stdout, 78 ); + + return; + + Failure: + fprintf( stderr, " " ); + Panic( gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + } + + +#define TAG2STRING( t, s ) s[0] = (char)(t >> 24), \ + s[1] = (char)(t >> 16), \ + s[2] = (char)(t >> 8), \ + s[3] = (char)(t ) + + + static void + Print_GSUB( void ) + { + TTO_GSUBHeader gsub; + TT_Error error; + + TT_UShort i; + TTO_Feature f; + TTO_Lookup* lo; + + TT_ULong *script_tag_list, *stl; + TT_ULong *language_tag_list, *ltl; + TT_ULong *feature_tag_list, *ftl; + + TT_UShort script_index, language_index, + feature_index, req_feature_index; + + char script_tag[4], language_tag[4], feature_tag[4]; + + + error = TT_Load_GSUB_Table( face, &gsub, NULL ); + if ( error == TT_Err_Table_Missing ) + return; + if ( error ) + { + fprintf( stderr, gettext( "Error while loading GSUB table.\n" ) ); + goto Failure; + } + + printf( gettext( "GSUB table\n" ) ); + separator_line( stdout, 78 ); + + error = TT_GSUB_Query_Scripts( &gsub, &script_tag_list ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while querying GSUB script list.\n" ) ); + goto Failure; + } + + stl = script_tag_list; + for ( ; *stl; stl++ ) + { + TAG2STRING( *stl, script_tag ); + + error = TT_GSUB_Select_Script( &gsub, *stl, &script_index ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while selecting GSUB script `%4.4s'.\n" ), + script_tag ); + goto Failure; + } + + printf( gettext( " script `%4.4s' (index %hu):\n" ), + script_tag, script_index ); + + error = TT_GSUB_Query_Features( &gsub, script_index, 0xFFFF, + &feature_tag_list ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while querying GSUB default language system for script `%4.4s'.\n" ), + script_tag ); + goto Failure; + } + + printf( gettext( " default language system:\n" ) ); + + ftl = feature_tag_list; + for ( ; *ftl; ftl++ ) + { + TAG2STRING( *ftl, feature_tag ); + + error = TT_GSUB_Select_Feature( &gsub, *ftl, + script_index, 0xFFFF, + &feature_index ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while selecting GSUB feature `%4.4s'\n" + "for default language system of script `%4.4s'.\n" ), + feature_tag, script_tag ); + goto Failure; + } + + printf( gettext( " feature `%4.4s' (index %hu; lookup " ), + feature_tag, feature_index ); + + f = gsub.FeatureList.FeatureRecord[feature_index].Feature; + + for ( i = 0; i < f.LookupListCount - 1; i++ ) + printf( "%hu, ", f.LookupListIndex[i] ); + printf( "%hu)\n", f.LookupListIndex[i] ); + } + free( feature_tag_list ); + + error = TT_GSUB_Query_Languages( &gsub, script_index, + &language_tag_list ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while querying GSUB language list for script `%4.4s'.\n" ), + script_tag ); + goto Failure; + } + + ltl = language_tag_list; + for ( ; *ltl; ltl++ ) + { + TAG2STRING( *ltl, language_tag ); + + error = TT_GSUB_Select_Language( &gsub, *ltl, + script_index, + &language_index, + &req_feature_index ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" ), + language_tag, script_tag ); + goto Failure; + } + + printf( gettext( " language `%4.4s' (index %hu):\n" ), + language_tag, language_index ); + + if ( req_feature_index != 0xFFFF ) + { + printf( gettext( " required feature index %hu (lookup " ), + req_feature_index ); + + f = gsub.FeatureList.FeatureRecord[req_feature_index].Feature; + + for ( i = 0; i < f.LookupListCount - 1; i++ ) + printf( "%hu, ", f.LookupListIndex[i] ); + printf( "%hu)\n", f.LookupListIndex[i] ); + } + + error = TT_GSUB_Query_Features( &gsub, script_index, language_index, + &feature_tag_list ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while querying GSUB feature list\n" + "for script `%4.4s', language `%4.4s'.\n" ), + script_tag, language_tag ); + goto Failure; + } + + ftl = feature_tag_list; + for ( ; *ftl; ftl++ ) + { + TAG2STRING( *ftl, feature_tag ); + + error = TT_GSUB_Select_Feature( &gsub, *ftl, + script_index, language_index, + &feature_index ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while selecting GSUB feature `%4.4s'\n" + "for script `%4.4s', language `%4.4s'.\n" ), + feature_tag, script_tag, language_tag ); + goto Failure; + } + + printf( gettext( " feature `%4.4s' (index %hu; lookup " ), + feature_tag, feature_index ); + + f = gsub.FeatureList.FeatureRecord[feature_index].Feature; + + for ( i = 0; i < f.LookupListCount - 1; i++ ) + printf( "%hu, ", f.LookupListIndex[i] ); + printf( "%hu)\n", f.LookupListIndex[i] ); + } + free( feature_tag_list ); + } + free( language_tag_list ); + } + free( script_tag_list ); + + printf( "\n" ); + + lo = gsub.LookupList.Lookup; + + printf( gettext( "Lookups:\n\n" ) ); + + for ( i = 0; i < gsub.LookupList.LookupCount; i++ ) + printf( gettext( " %hu: type %hu, flag 0x%x\n" ), + i, lo[i].LookupType, lo[i].LookupFlag ); + + printf( "\n" ); + separator_line( stdout, 78 ); + + return; + + Failure: + fprintf( stderr, " " ); + Panic( gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + } + + + int + main( int argc, char** argv ) + { + int i; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + char* gt; + + +#ifdef HAVE_LIBINTL_H + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); +#endif + + execname = argv[0]; + + if ( argc != 2 ) + { + gt = gettext( "ftdump: Simple TrueType Dumper -- part of the FreeType project" ); + fprintf( stderr, "%s\n", gt ); + separator_line( stderr, strlen( gt ) ); + + fprintf( stderr, gettext( "Usage: %s fontname[.ttf|.ttc]\n\n" ), + execname ); + + exit( EXIT_FAILURE ); + } + + i = strlen( argv[1] ); + while ( i > 0 && argv[1][i] != '\\' ) + { + if ( argv[1][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[1], 128 ); + strncpy( alt_filename, argv[1], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Initialize engine */ + + old_memory = 0; + + if ( (error = TT_Init_FreeType( &engine )) ) + { + fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); + goto Failure; + } + + if ( (error = TT_Init_SBit_Extension( engine )) ) + { + fprintf( stderr, gettext( + "Error while initializing embedded bitmap extension.\n" ) ); + goto Failure; + } + + if ( (error = TT_Init_GSUB_Extension( engine )) ) + { + fprintf( stderr, gettext( + "Error while initializing GSUB extension.\n" ) ); + goto Failure; + } + + FOOTPRINT( initial_overhead ); + + /* Open and Load face */ + + error = TT_Open_Face( engine, filename, &face ); + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( gettext( "Could not find or open %s.\n" ), filename ); + if ( error ) + { + fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); + goto Failure; + } + + FOOTPRINT( face_object ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + num_glyphs = properties.num_Glyphs; + + /* Now do various dumps */ + + if ( flag_names ) + Print_Names(); + + if ( flag_encodings ) + Print_Encodings(); + + if ( flag_cmap ) + Print_Cmap(); + + if ( flag_sbits ) + Print_SBits(); + + if ( flag_ttopen ) + Print_GSUB(); + +#ifndef FREETYPE_DLL /* the statistics are meaningless if we use a DLL. */ + if ( flag_memory ) + Print_Memory(); +#endif + + TT_Close_Face( face ); + + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + + Failure: + fprintf( stderr, " " ); + Panic( gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/fterror.c b/test/fterror.c new file mode 100644 index 0000000..b15d9fb --- /dev/null +++ b/test/fterror.c @@ -0,0 +1,76 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* E. Dieterich */ +/* */ +/* fterror: test errstr functionality. */ +/* */ +/****************************************************************************/ + + +#include +#include + +#include "freetype.h" +#include "ftxerr18.h" + +/* + * Basically, an external program using FreeType shouldn't depend on an + * internal file of the FreeType library, especially not on ft_conf.h -- but + * to avoid another configure script which tests for the existence of the + * i18n stuff we include ft_conf.h here since we can be sure that our test + * programs use the same configuration options as the library itself. + */ + +#include "ft_conf.h" + + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include + +#else /* HAVE_LIBINTL_H */ + +#define gettext( x ) ( x ) + +#endif /* HAVE_LIBINTL_H */ + + + int + main( void ) + { + int i; +#ifdef HAVE_LIBINTL_H + char* domain; + + + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + domain = textdomain( "freetype" ); +#endif + +#if 0 + printf( "domain: %s\n", domain = textdomain( "" ) ); +#endif + printf( gettext( "Start of fterror.\n" ) ); + + for ( i = 0; i < 10; i++ ) + printf( "Code: %i, %s\n", i, TT_ErrToString18( i ) ); + +#if 0 + printf( "domain: %s\n", domain = textdomain( "" ) ); +#endif + printf( gettext( "End of fterror.\n" ) ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftlint.c b/test/ftlint.c new file mode 100644 index 0000000..3cf137f --- /dev/null +++ b/test/ftlint.c @@ -0,0 +1,296 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftlint: a simple TrueType instruction tester. */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" +#include "freetype.h" + +/* + * Basically, an external program using FreeType shouldn't depend on an + * internal file of the FreeType library, especially not on ft_conf.h -- but + * to avoid another configure script which tests for the existence of the + * i18n stuff we include ft_conf.h here since we can be sure that our test + * programs use the same configuration options as the library itself. + */ + +#include "ft_conf.h" + + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include +#include "ftxerr18.h" + +#else /* !HAVE_LIBINTL */ + +#define gettext( x ) ( x ) + + /* We ignore error message strings with this function */ + + static char* + TT_ErrToString18( TT_Error error ) + { + static char temp[32]; + + + sprintf( temp, "0x%04lx", error ); + return temp; + } + +#endif /* !HAVE_LIBINTL */ + + + TT_Error error; + + TT_Engine engine; + + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Outline outline; + TT_Glyph_Metrics metrics; + + TT_Face_Properties properties; + + unsigned int num_glyphs; + int ptsize; + + int Fail; + int Num; + + + static TT_Error + LoadTrueTypeChar( int idx ) + { + return TT_Load_Glyph( instance, glyph, idx, TTLOAD_DEFAULT ); + } + + + static void + Usage( char* name ) + { + char* gt; + + + gt = gettext( "ftlint: Simple TrueType instruction tester -- part of the FreeType project" ); + fprintf( stderr, "%s\n", gt ); + separator_line( stderr, strlen( gt ) ); + + fprintf( stderr, gettext( + "Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n\n" ), name ); + + exit( EXIT_FAILURE ); + } + + + int + main( int argc, char** argv ) + { + int i, file_index; + unsigned int id; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + char* fname; + + +#ifdef HAVE_LIBINTL_H + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); +#endif + + execname = argv[0]; + + if ( argc < 3 ) + Usage( execname ); + + if ( sscanf( argv[1], "%d", &ptsize ) != 1 ) + Usage( execname ); + + /* Initialize engine */ + if ( (error = TT_Init_FreeType( &engine )) ) + { + fprintf( stderr, + gettext( "Error while initializing engine.\n" ) ); + goto Failure; + } + + /* Now check all files */ + for ( file_index = 2; file_index < argc; file_index++ ) + { + fname = argv[file_index]; + i = strlen( fname ); + while ( i > 0 && fname[i] != '\\' && fname[i] != '/' ) + { + if ( fname[i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, fname, 128 ); + strncpy( alt_filename, fname, 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + i = strlen( filename ); + fname = filename; + + while ( i >= 0 ) + if ( filename[i] == '/' || filename[i] == '\\' ) + { + fname = filename + i + 1; + i = -1; + } + else + i--; + + fprintf( stderr, "%s: ", fname ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + fprintf( stderr, gettext( "Could not find or open %s.\n" ), + filename ); + goto Fail_Face; + } + if ( error ) + { + fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); + goto Fail_Face; + } + + /* get face properties */ + + TT_Get_Face_Properties( face, &properties ); + num_glyphs = properties.num_Glyphs; + + /* create glyph */ + error = TT_New_Glyph( face, &glyph ); + if ( error ) + { + fprintf( stderr, + gettext( "Could not create glyph container.\n" ) ); + goto Fail_Glyph; + } + + /* create instance */ + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create instance.\n" ) ); + goto Fail_Instance; + } + + error = TT_Set_Instance_PixelSizes( instance, + ptsize, + ptsize, + ptsize*3/4 ); + if ( error ) + { + fprintf( stderr, + gettext( "Could not set point size to %d.\n" ), + ptsize ); + goto Fail_Set; + } + + Fail = 0; + + for ( id = 0; id < num_glyphs; id++ ) + { + if ( (error = LoadTrueTypeChar( id )) ) + { + if ( Fail < 10 ) + { + fprintf( stderr, !Fail ? gettext( "Error with\n " ) : " " ); + fprintf( stderr, gettext( "glyph %4u: %s\n" ), + id, TT_ErrToString18( error ) ); + } + Fail++; + } + } + + if ( Fail == 0 ) + fprintf( stderr, "OK.\n" ); + else + { + fprintf( stderr, " " ); + if ( Fail == 1 ) + fprintf( stderr, gettext( "1 fail.\n" ) ); + else + fprintf( stderr, gettext( "%d fails.\n" ), Fail ); + } + + /* hush complaints at the end of the loop */ + error = 0; + + Fail_Set: + TT_Done_Instance( instance ); + Fail_Instance: + TT_Done_Glyph( glyph ); + Fail_Glyph: + TT_Close_Face( face ); + Fail_Face: + ; + + + if ( error ) + { + fprintf( stderr, " " ); + fprintf( stderr, gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + } + } + + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + + Failure: + fprintf( stderr, " " ); + fprintf( stderr, gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + + exit( EXIT_FAILURE ); + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftmetric.c b/test/ftmetric.c new file mode 100644 index 0000000..7b5f02b --- /dev/null +++ b/test/ftmetric.c @@ -0,0 +1,396 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1999 by */ +/* Yamano'uchi H. and W. Lemberg */ +/* */ +/* ftmetric: dump metrics and a glyph. */ +/* */ +/* NOTE: This is just a test program that is used to debug */ +/* the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" +#include "freetype.h" +#include "ftxsbit.h" + +/* + * Basically, an external program using FreeType shouldn't depend on an + * internal file of the FreeType library, especially not on ft_conf.h -- but + * to avoid another configure script which tests for the existence of the + * i18n stuff we include ft_conf.h here since we can be sure that our test + * programs use the same configuration options as the library itself. + */ + +#include "ft_conf.h" + + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include +#include "ftxerr18.h" + +#else /* !HAVE_LIBINTL */ + +#define gettext( x ) ( x ) + + /* We ignore error message strings with this function */ + + static char* + TT_ErrToString18( TT_Error error ) + { + static char temp[32]; + + + sprintf( temp, "0x%04lx", error ); + return temp; + } + +#endif /* !HAVE_LIBINTL */ + + static void + usage( char* execname ) + { + char* gt; + + + fprintf( stderr, "\n" ); + gt = gettext( "ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" ); + fprintf( stderr, "%s\n", gt ); + separator_line( stderr, strlen( gt ) ); + fprintf( stderr, gettext( + "Usage: %s [options below] point fontname[.ttf|.ttc]\n" + "\n" + " -B show sbit's metrics (default: none)\n" + " -c C use C'th font index of TrueType collection (default: 0)\n" + " -i index glyph index (default: 0)\n" + " -r R use resolution R dpi (default: 72)\n" + "\n" ), execname ); + + exit( EXIT_FAILURE ); + } + + + static void + Show_Metrics( TT_Big_Glyph_Metrics metrics, + char* title ) + { + int show_advance = 1; + + + printf("%s: xMin %d, xMax %d, yMin %d, yMax %d", + title, + (int)(metrics.bbox.xMin / 64), + (int)(metrics.bbox.xMax / 64), + (int)(metrics.bbox.yMin / 64), + (int)(metrics.bbox.yMax / 64)); + + + if ( show_advance ) + printf( ", advance width %d", (int)(metrics.horiAdvance / 64) ); + + printf("\n"); + return; + } + + + int + main( int argc, char** argv ) + { + int i, orig_ptsize, file; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + int option; + + int ptsize; + int num_Faces = 0; + int glyph_index = 0; + int load_flags = TTLOAD_DEFAULT; + + int force_sbit = 0; + + TT_Engine engine; + + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Raster_Map map; + + TT_Big_Glyph_Metrics metrics; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + + TT_EBLC eblc; + TT_SBit_Image* bitmap = NULL; + + TT_Error error; + + + int res = 72; + +#ifdef HAVE_LIBINTL_H + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); +#endif + + execname = ft_basename( argv[0] ); + + while ( 1 ) + { + option = ft_getopt( argc, argv, "c:r:i:B" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + usage( execname ); + break; + + case 'c': + num_Faces = atoi( ft_optarg ); + if ( num_Faces < 0 ) + usage( execname ); + break; + + case 'i': + glyph_index = atoi( ft_optarg ); + if ( glyph_index < 0 ) + usage( execname ); + break; + + case 'B': + force_sbit = 1; + break; + + default: + usage( execname ); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 1 ) + usage( execname ); + + if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 ) + orig_ptsize = 64; + + file = 1; + + ptsize = orig_ptsize; + + i = strlen( argv[file] ); + while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) + { + if ( argv[file][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[file], 128 ); + strncpy( alt_filename, argv[file], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Initialize engine */ + + error = TT_Init_FreeType( &engine ); + if ( error ) + { + fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); + goto Failure; + } + + error = TT_Init_SBit_Extension( engine ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while initializing embedded bitmap extension.\n" ) ); + goto Failure; + } + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( gettext( "Could not find or open %s.\n" ), filename ); + if ( error ) + { + fprintf( stderr, gettext( "Error while opening %s.\n" ), + filename ); + goto Failure; + } + + TT_Get_Face_Properties( face, &properties ); + + printf( gettext( "There are %d fonts in this collection.\n" ), + (int)(properties.num_Faces) ); + + if ( num_Faces >= properties.num_Faces ) + Panic( gettext( + "There is no collection with index %d in this font file.\n" ), + num_Faces ); + + TT_Close_Face( face ); + + error = TT_Open_Collection( engine, filename, num_Faces, &face ); + + /* get face properties and eblc */ + + TT_Get_Face_Properties( face, &properties ); + if ( force_sbit ) + { + error = TT_Get_Face_Bitmaps( face, &eblc ); + if ( error == TT_Err_Table_Missing ) + Panic( gettext( "There is no embedded bitmap data in the font.\n" ) ); + if ( error ) + { + fprintf( stderr, gettext( + "Error while retrieving embedded bitmaps table.\n" ) ); + goto Failure; + } + } + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create glyph container.\n" ) ); + goto Failure; + } + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create instance.\n" ) ); + goto Failure; + } + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + { + fprintf( stderr, gettext( "Could not set device resolutions.\n" ) ); + goto Failure; + } + + error = TT_Set_Instance_CharSize( instance, ptsize*64 ); + if ( error ) + { + fprintf( stderr, gettext( "Could not reset instance.\n" ) ); + goto Failure; + } + + TT_Get_Instance_Metrics( instance, &imetrics ); + + printf( gettext( "Instance metrics: ppemX %d, ppemY %d\n" ), + imetrics.x_ppem, + imetrics.y_ppem ); + + if ( force_sbit ) + { + error = TT_New_SBit_Image( &bitmap ); + if ( error ) + { + fprintf( stderr, gettext( + "Could not allocate glyph bitmap container.\n" ) ); + goto Failure; + } + + error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); + if ( error ) + { + fprintf( stderr, gettext( + "Can't load bitmap for glyph %d.\n" ), glyph_index ); + goto Failure; + } + + Show_Metrics( bitmap->metrics, "SBit's metrics" ); + + printf( "SBit glyph:\n" ); + Show_Single_Glyph( &bitmap->map ); + } + else + { + TT_Load_Glyph( instance, glyph, glyph_index, load_flags ); + TT_Get_Glyph_Big_Metrics( glyph, &metrics ); + + map.width = ( metrics.bbox.xMax - metrics.bbox.xMin ) / 64; + map.rows = ( metrics.bbox.yMax - metrics.bbox.yMin ) / 64; + map.cols = ( map.width + 7 ) / 8; + map.size = map.cols * map.rows; + map.bitmap = malloc( map.size ); + map.flow = TT_Flow_Down; + + memset( map.bitmap, 0, map.size ); + + error = TT_Get_Glyph_Bitmap( glyph, &map, + -metrics.bbox.xMin, + -metrics.bbox.yMin ); + + Show_Metrics( metrics, gettext( "Outline's metrics" ) ); + + printf( gettext( "Outline glyph\n" ) ); + Show_Single_Glyph( &map ); + } + + free( map.bitmap ); + + if ( bitmap ) + TT_Done_SBit_Image( bitmap ); + + TT_Done_Instance( instance ); + TT_Done_Glyph( glyph ); + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + + Failure: + fprintf( stderr, " " ); + fprintf( stderr, gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + + exit( EXIT_FAILURE ); + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftsbit.c b/test/ftsbit.c new file mode 100644 index 0000000..b6d1fa1 --- /dev/null +++ b/test/ftsbit.c @@ -0,0 +1,293 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftsbit: a _very_ simple embedded bitmap dumper for FreeType 1.x. */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" + +#include "freetype.h" +#include "ftxsbit.h" + +/* + * Basically, an external program using FreeType shouldn't depend on an + * internal file of the FreeType library, especially not on ft_conf.h -- but + * to avoid another configure script which tests for the existence of the + * i18n stuff we include ft_conf.h here since we can be sure that our test + * programs use the same configuration options as the library itself. + */ + +#include "ft_conf.h" + + +#ifdef HAVE_LIBINTL_H + +#ifdef HAVE_LOCALE_H +#include +#endif + +#include +#include "ftxerr18.h" + +#else /* !HAVE_LIBINTL */ + +#define gettext( x ) ( x ) + + /* We ignore error message strings with this function */ + + static char* TT_ErrToString18( TT_Error error ) + { + static char temp[32]; + + + sprintf( temp, "0x%04lx", error ); + return temp; + } + +#endif /* !HAVE_LIBINTL */ + + + TT_Error error; + + TT_Engine engine; + + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Outline outline; + TT_Glyph_Metrics metrics; + + TT_Face_Properties properties; + TT_EBLC eblc; + TT_SBit_Image* bitmap; + + unsigned int num_glyphs; + int ptsize; + + int Fail; + int Num; + + + static void Usage( char* name ) + { + char* gt; + + + gt = gettext( "ftsbit: Simple TrueType `sbit' dumper -- part of the FreeType project" ); + fprintf( stderr, "%s\n", gt ); + separator_line( stderr, strlen( gt ) ); + + fprintf( stderr, gettext( + "Usage: %s ppem fontname[.ttf|.ttc] glyph_index [glyph_index2..]\n\n" ), name ); + + exit( EXIT_FAILURE ); + } + + + int main( int argc, char** argv ) + { + int i; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + char* fname; + + +#ifdef HAVE_LIBINTL_H + setlocale( LC_ALL, "" ); + bindtextdomain( "freetype", LOCALEDIR ); + textdomain( "freetype" ); +#endif + + execname = argv[0]; + + if ( argc < 3 ) + Usage( execname ); + + if ( sscanf( argv[1], "%d", &ptsize ) != 1 ) + Usage( execname ); + + /* Initialize engine */ + if ( (error = TT_Init_FreeType( &engine )) ) + { + fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); + goto Failure; + } + + if ( (error = TT_Init_SBit_Extension( engine )) ) + { + fprintf( stderr, gettext( + "Error while initializing embedded bitmap extension.\n" ) ); + goto Failure; + } + + /* Now check all files */ + fname = argv[2]; + i = strlen( fname ); + while ( i > 0 && fname[i] != '\\' && fname[i] != '/' ) + { + if ( fname[i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, fname, 128 ); + strncpy( alt_filename, fname, 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + error = TT_Open_Face( engine, filename, &face ); + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + i = strlen( filename ); + fname = filename; + + while ( i >= 0 ) + if ( filename[i] == '/' || filename[i] == '\\' ) + { + fname = filename + i + 1; + i = -1; + } + else + i--; + + if ( error ) + { + fprintf( stderr, gettext( "Could not find or open %s.\n" ), + filename ); + goto Failure; + } + if ( error ) + { + fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); + goto Failure; + } + + /* get face properties */ + TT_Get_Face_Properties( face, &properties ); + num_glyphs = properties.num_Glyphs; + + error = TT_Get_Face_Bitmaps( face, &eblc ); + if ( error == TT_Err_Table_Missing ) + { + fprintf( stderr, gettext( + "Could not find embedded bitmaps in this font.\n" ) ); + goto Failure; + } + if ( error ) + { + fprintf( stderr, gettext( + "Error while loading embedded bitmaps.\n" ) ); + goto Failure; + } + + /* create instance */ + error = TT_New_Instance( face, &instance ); + if ( error ) + { + fprintf( stderr, gettext( "Could not create instance.\n" ) ); + goto Failure; + } + + error = TT_Set_Instance_PixelSizes( instance, + ptsize, + ptsize, + ptsize*3/4 ); + if ( error ) + { + fprintf( stderr, + gettext( "Could not set point size to %d.\n" ), + ptsize ); + goto Failure; + } + + error = TT_New_SBit_Image( &bitmap ); + if ( error ) + { + fprintf( stderr, gettext( + "Could not allocate glyph bitmap container.\n" ) ); + goto Failure; + } + + for ( i = 3; i < argc; i++ ) + { + unsigned short glyph_index; + + + /* we use %i to allow the prefixes `0x' and `0' */ + if ( sscanf( argv[i], "%hi", &glyph_index ) != 1 ) + Usage( execname ); + + error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); + + if ( error == TT_Err_Invalid_Glyph_Index ) + { + fprintf( stderr, gettext( + " no bitmap for glyph %d.\n" ), glyph_index ); + continue; + } + if ( error ) + { + fprintf( stderr, gettext( + "Can't load bitmap for glyph %d.\n" ), glyph_index ); + goto Failure; + } + + /* Dump the resulting bitmap */ + { + printf( gettext( "glyph index %d = %dx%d pixels, " ), + glyph_index, bitmap->map.rows, bitmap->map.width ); + + printf( gettext( "advance = %ld, minBearing = [%ld,%ld]\n" ), + (long)(bitmap->metrics.horiAdvance / 64), + (long)(bitmap->metrics.horiBearingX / 64), + (long)(bitmap->metrics.horiBearingY / 64)); + + Show_Single_Glyph( &bitmap->map ); + } + } + + TT_Done_SBit_Image( bitmap ); + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + + Failure: + fprintf( stderr, " " ); + fprintf( stderr, gettext( "FreeType error message: %s\n" ), + TT_ErrToString18( error ) ); + + exit( EXIT_FAILURE ); + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftstring.c b/test/ftstring.c new file mode 100644 index 0000000..286a136 --- /dev/null +++ b/test/ftstring.c @@ -0,0 +1,486 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftstring: Making string text from individual glyph information. */ +/* */ +/* Keys: */ +/* */ +/* + : fast scale up */ +/* - : fast scale down */ +/* u : fine scale down */ +/* j : fine scale up */ +/* */ +/* h : toggle hinting */ +/* */ +/* ESC : exit */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" /* for Panic() and Message() only */ +#include "display.h" +#include "freetype.h" + +#include "gevents.h" +#include "gdriver.h" +#include "gmain.h" + +#define Pi 3.1415926535 + +#define MAXPTSIZE 500 /* dtp */ +#define Center_X ( Bit.width / 2 ) /* dtp */ +#define Center_Y ( Bit.rows / 2 ) /* dtp */ + + char Header[128]; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_CharMap char_map; + + TT_Glyph_Metrics metrics; + TT_Outline outline; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + + int num_glyphs; + + int ptsize; + int hinted; + + int Rotation; + int Fail; + int Num; + unsigned char autorun; + + int gray_render; + + short glyph_code[128]; + int num_codes; + +/* Convert an ASCII string to a string of glyph indexes. */ +/* */ +/* IMPORTANT NOTE: */ +/* */ +/* There is no portable way to convert from any system's char. code */ +/* to Unicode. This function simply takes a char. string as argument */ +/* and "interprets" each character as a Unicode char. index with no */ +/* further check. */ +/* */ +/* This mapping is only valid for the ASCII character set (i.e., */ +/* codes 32 to 127); all other codes (like accentuated characters) */ +/* will produce more or less random results, depending on the system */ +/* being run. */ + + static void CharToUnicode( char* source ) + { + unsigned short i, n; + unsigned short platform, encoding; + + /* First, look for a Unicode charmap */ + + n = properties.num_CharMaps; + + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + if ( (platform == 3 && encoding == 1 ) || + (platform == 0 && encoding == 0 ) ) + { + TT_Get_CharMap( face, i, &char_map ); + i = n + 1; + } + } + + if ( i == n ) + Panic( "Sorry, but this font doesn't contain any Unicode mapping table\n" ); + + for ( n = 0; n < 128 && source[n]; n++ ) + glyph_code[n] = TT_Char_Index( char_map, (short)source[n] ); + +#if 0 + /* Note, if you have a function, say ToUnicode(), to convert from */ + /* char codes to Unicode, use the following line instead: */ + + glyph_code[n] = TT_Char_Index( char_map, ToUnicode( source[n] ) ); +#endif + + num_codes = n; + } + + + static TT_Error Reset_Scale( int pointSize ) + { + TT_Error error; + + + if ( (error = TT_Set_Instance_PointSize( instance, pointSize )) ) + { + RestoreScreen(); + printf( "error = 0x%x\n", (int)error ); + Panic( "could not reset instance\n" ); + } + + TT_Get_Instance_Metrics( instance, &imetrics ); + + /* now re-allocate the small bitmap */ + if ( gray_render ) + { + Init_Small( imetrics.x_ppem, imetrics.y_ppem ); + Clear_Small(); + } + + return TT_Err_Ok; + } + + + static TT_Error LoadTrueTypeChar( int idx, int hint ) + { + int flags; + + + flags = TTLOAD_SCALE_GLYPH; + if ( hint ) + flags |= TTLOAD_HINT_GLYPH; + + return TT_Load_Glyph( instance, glyph, idx, flags ); + } + + + static TT_Error Render_All( void ) + { + TT_F26Dot6 x, y, z, minx, miny, maxx, maxy; + int i; + + TT_Error error; + + + /* On the first pass, we compute the compound bounding box */ + + x = y = 0; + + minx = miny = maxx = maxy = 0; + + for ( i = 0; i < num_codes; i++ ) + { + if ( !(error = LoadTrueTypeChar( glyph_code[i], hinted )) ) + { + TT_Get_Glyph_Metrics( glyph, &metrics ); + + z = x + metrics.bbox.xMin; + if ( minx > z ) + minx = z; + + z = x + metrics.bbox.xMax; + if ( maxx < z ) + maxx = z; + + z = y + metrics.bbox.yMin; + if ( miny > z ) + miny = z; + + z = y + metrics.bbox.yMax; + if ( maxy < z ) + maxy = z; + + x += metrics.advance & -64; + } + else + Fail++; + } + + /* We now center the bbox inside the target bitmap */ + + minx = ( minx & -64 ) >> 6; + miny = ( miny & -64 ) >> 6; + + maxx = ( (maxx+63) & -64 ) >> 6; + maxy = ( (maxy+63) & -64 ) >> 6; + + maxx -= minx; + maxy -= miny; + + minx = (Bit.width - maxx)/2; + miny = (Bit.rows + miny)/2; + + maxx += minx; + maxy += maxy; + + /* On the second pass, we render each glyph to its centered position. */ + /* This is slow, because we reload each glyph to render it! */ + + x = minx; + y = miny; + + for ( i = 0; i < num_codes; i++ ) + { + if ( !(error = LoadTrueTypeChar( glyph_code[i], hinted )) ) + { + TT_Get_Glyph_Metrics( glyph, &metrics ); + + Render_Single_Glyph( gray_render, glyph, x, y ); + + x += metrics.advance/64; + } + } + + return TT_Err_Ok; + } + + + static int Process_Event( TEvent* event ) + { + switch ( event->what ) + { + case event_Quit: /* ESC or q */ + return 0; + + case event_Keyboard: + if ( event->info == 'h' ) /* Toggle hinting */ + hinted = !hinted; + break; + + case event_Rotate_Glyph: + break; + + case event_Scale_Glyph: + ptsize += event->info; + if ( ptsize < 1 ) ptsize = 1; + if ( ptsize > MAXPTSIZE ) ptsize = MAXPTSIZE; + break; + + case event_Change_Glyph: + break; + } + + return 1; + } + + + static void usage( char* execname ) + { + printf( "\n" ); + printf( "ftstring: simple String Test Display -- part of the FreeType project\n" ); + printf( "--------------------------------------------------------------------\n" ); + printf( "\n" ); + printf( "Usage: %s [options below] ppem fontname[.ttf|.ttc] [string]\n", + execname ); + printf( "\n" ); + printf( " -g gray-level rendering (default: none)\n" ); + printf( " -r R use resolution R dpi (default: 96)\n" ); + printf( "\n" ); + + exit( EXIT_FAILURE ); + } + + + int main( int argc, char** argv ) + { + int i, old_ptsize, orig_ptsize, file; + int XisSetup = 0; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + int option; + int res = 96; + + TT_Error error; + TEvent event; + + + execname = argv[0]; + + while ( 1 ) + { + option = ft_getopt( argc, argv, "gr:" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'g': + gray_render = 1; + break; + + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + usage( execname ); + break; + + default: + usage( execname ); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 1 ) + usage( execname ); + + if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 ) + orig_ptsize = 64; + + file = 1; + + /* Initialize engine */ + + if ( (error = TT_Init_FreeType( &engine )) ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + ptsize = orig_ptsize; + hinted = 1; + + i = strlen( argv[file] ); + while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) + { + if ( argv[file][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[file], 128 ); + strncpy( alt_filename, argv[file], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else if (error) + Panic( "Error while opening %s, error code = 0x%x.\n", + filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + + num_glyphs = properties.num_Glyphs; + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container.\n" ); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for %s.\n", filename ); + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + Panic( "Could not set device resolutions." ); + + if ( !XisSetup ) + { + XisSetup = 1; + + if ( gray_render ) + { + if ( !SetGraphScreen( Graphics_Mode_Gray ) ) + Panic( "Could not set up grayscale graphics mode.\n" ); + + TT_Set_Raster_Gray_Palette( engine, virtual_palette ); + } + else + { + if ( !SetGraphScreen( Graphics_Mode_Mono ) ) + Panic( "Could not set up mono graphics mode.\n" ); + } + } + + Init_Display( gray_render ); + + Reset_Scale( ptsize ); + + old_ptsize = ptsize; + + Fail = 0; + Num = 0; + + CharToUnicode( ( argv[2] ? argv[2] : + "The quick brown fox jumps over the lazy dog" ) ); + + for ( ;; ) + { + int key; + + + Clear_Display(); + Render_All(); + if ( gray_render ) + Convert_To_Display_Palette(); + + sprintf( Header, "%s: ptsize: %4d hinting: %s", + ft_basename( filename ), ptsize, + hinted ? "on" : "off" ); + + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + +#ifndef X11 +#ifndef OS2 + Print_XY( 0, 0, Header ); +#endif +#endif + + Get_Event( &event ); + if ( !( key = Process_Event( &event ) ) ) + goto Fin; + + if ( ptsize != old_ptsize ) + { + if ( Reset_Scale( ptsize ) ) + Panic( "Could not resize font.\n" ); + + old_ptsize = ptsize; + } + } + + Fin: + RestoreScreen(); + + TT_Done_FreeType( engine ); + + printf( "Execution completed successfully.\n" ); + printf( "Fails = %d.\n", Fail ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/ftstrpnm.c b/test/ftstrpnm.c new file mode 100644 index 0000000..a5ee67e --- /dev/null +++ b/test/ftstrpnm.c @@ -0,0 +1,510 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftstrpnm: convert text to image (in PGM or PBM format) */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#define PROGNAME "ftstrpnm" + +#include +#include +#include + +#include "common.h" /* for ft_getopt() */ +#include "freetype.h" + +#define TT_VALID( handle ) ( ( handle ).z != NULL ) + + + /* Global variables */ + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + + TT_Face_Properties properties; + + TT_Raster_Map bit; + TT_Raster_Map small_bit; /* used when font-smoothing is enabled */ + + int pnm_width, pnm_height; + int pnm_x_shift, pnm_y_shift; + + + /* Loaded glyphs for all characters */ + + TT_Glyph *glyphs = NULL; + + + /* Options */ + + int dpi = 96; + int ptsize = 12; + int hinted = 1; + int smooth = 0; + int border = 0; + + + /* raster map management */ + + static void Init_Raster_Map( TT_Raster_Map* bit, int width, int height ) + { + bit->rows = height; + bit->width = ( width + 3 ) & -4; + bit->flow = TT_Flow_Down; + + if ( smooth ) + { + bit->cols = bit->width; + bit->size = bit->rows * bit->width; + } + else + { + bit->cols = ( bit->width + 7 ) / 8; /* convert to # of bytes */ + bit->size = bit->rows * bit->cols; /* number of bytes in buffer */ + } + + bit->bitmap = (void *) malloc( bit->size ); + if ( !bit->bitmap ) + Panic( "Not enough memory to allocate bitmap!\n" ); + } + + + static void Done_Raster_Map( TT_Raster_Map *bit ) + { + free( bit->bitmap ); + bit->bitmap = NULL; + } + + + static void Clear_Raster_Map( TT_Raster_Map* bit ) + { + memset( bit->bitmap, 0, bit->size ); + } + + + static void Blit_Or( TT_Raster_Map* dst, TT_Raster_Map* src, + int x_off, int y_off ) + { + int x, y; + int x1, x2, y1, y2; + char *s, *d; + + + /* clipping */ + + x1 = x_off < 0 ? -x_off : 0; + y1 = y_off < 0 ? -y_off : 0; + + x2 = (int)dst->cols - x_off; + if ( x2 > src->cols ) + x2 = src->cols; + + y2 = (int)dst->rows - y_off; + if ( y2 > src->rows ) + y2 = src->rows; + + if ( x1 >= x2 ) + return; + + /* do the real work now */ + + for ( y = y1; y < y2; ++y ) + { + s = ( (char*)src->bitmap ) + y * src->cols + x1; + d = ( (char*)dst->bitmap ) + ( y + y_off ) * dst->cols + x1 + x_off; + + for ( x = x1; x < x2; ++x ) + *d++ |= *s++; + } + } + + + static void Dump_Raster_Map( TT_Raster_Map* bit, FILE* file ) + { + /* kudos for this code snippet go to Norman Walsh */ + + char* bmap; + int i; + + + bmap = (char *)bit->bitmap; + + if ( smooth ) + { + fprintf( file, "P5\n%d %d\n4\n", pnm_width, pnm_height ); + for ( i = bit->size - 1; i >= 0; --i ) + bmap[i] = bmap[i] > 4 ? 0 : 4 - bmap[i]; + for ( i = pnm_height; i > 0; --i, bmap += bit->cols ) + fwrite( bmap, 1, pnm_width, file ); + } + else + { + fprintf( file, "P4\n%d %d\n", pnm_width, pnm_height ); + for ( i = pnm_height; i > 0; --i, bmap += bit->cols ) + fwrite( bmap, 1, (pnm_width+7) / 8, file ); + } + + fflush( file ); + } + + + /* glyph management */ + + static void Load_Glyphs( char* txt, int txtlen ) + { + unsigned short i, n, code, load_flags; + unsigned short num_glyphs = 0, no_cmap = 0; + unsigned short platform, encoding; + TT_Error error; + TT_CharMap char_map; + + + /* First, look for a Unicode charmap */ + + n = properties.num_CharMaps; + + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + if ( (platform == 3 && encoding == 1 ) || + (platform == 0 && encoding == 0 ) ) + { + TT_Get_CharMap( face, i, &char_map ); + break; + } + } + + if ( i == n ) + { + TT_Face_Properties properties; + + + TT_Get_Face_Properties( face, &properties ); + + no_cmap = 1; + num_glyphs = properties.num_Glyphs; + } + + + /* Second, allocate the array */ + + glyphs = (TT_Glyph*)malloc( 256 * sizeof ( TT_Glyph ) ); + memset( glyphs, 0, 256 * sizeof ( TT_Glyph ) ); + + /* Finally, load the glyphs you need */ + + load_flags = TTLOAD_SCALE_GLYPH; + if ( hinted ) + load_flags |= TTLOAD_HINT_GLYPH; + + for ( i = 0; i < txtlen; ++i ) + { + unsigned char j = txt[i]; + + + if ( TT_VALID( glyphs[j] ) ) + continue; + + if ( no_cmap ) + { + code = (j - ' ' + 1) < 0 ? 0 : (j - ' ' + 1); + if ( code >= num_glyphs ) + code = 0; + } + else + code = TT_Char_Index( char_map, j ); + + (void)( + ( error = TT_New_Glyph( face, &glyphs[j] ) ) || + ( error = TT_Load_Glyph( instance, glyphs[j], code, load_flags ) ) + ); + + if ( error ) + Panic( "Cannot allocate and load glyph: error 0x%x.\n", error ); + } + } + + + static void Done_Glyphs( void ) + { + int i; + + + if ( !glyphs ) + return; + + for ( i = 0; i < 256; ++i ) + TT_Done_Glyph( glyphs[i] ); + + free( glyphs ); + + glyphs = NULL; + } + + + /* face & instance management */ + + static void Init_Face( const char* filename ) + { + TT_Error error; + + + /* load the typeface */ + + error = TT_Open_Face( engine, filename, &face ); + if ( error ) + { + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else + Panic( "Error while opening %s, error code = 0x%x.\n", + filename, error ); + } + + TT_Get_Face_Properties( face, &properties ); + + /* create and initialize instance */ + + (void) ( + ( error = TT_New_Instance( face, &instance ) ) || + ( error = TT_Set_Instance_Resolutions( instance, dpi, dpi ) ) || + ( error = TT_Set_Instance_PointSize( instance, ptsize ) ) + ); + + if ( error ) + Panic( "Could not create and initialize instance: error 0x%x.\n", + error ); + } + + + static void Done_Face( void ) + { + TT_Done_Instance( instance ); + TT_Close_Face( face ); + } + + + /* rasterization stuff */ + + static void Init_Raster_Areas( const char* txt, int txtlen ) + { + int i, upm, ascent, descent; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + TT_Glyph_Metrics gmetrics; + + + /* allocate the large bitmap */ + + TT_Get_Face_Properties( face, &properties ); + TT_Get_Instance_Metrics( instance, &imetrics ); + + upm = properties.header->Units_Per_EM; + ascent = ( properties.horizontal->Ascender * imetrics.y_ppem ) / upm; + descent = ( properties.horizontal->Descender * imetrics.y_ppem ) / upm; + + pnm_width = 2 * border; + pnm_height = 2 * border + ascent - descent; + + for ( i = 0; i < txtlen; ++i ) + { + unsigned char j = txt[i]; + + + if ( !TT_VALID( glyphs[j] ) ) + continue; + + TT_Get_Glyph_Metrics( glyphs[j], &gmetrics ); + pnm_width += gmetrics.advance / 64; + } + + Init_Raster_Map( &bit, pnm_width, pnm_height ); + Clear_Raster_Map( &bit ); + + pnm_x_shift = border; + pnm_y_shift = border - descent; + + /* allocate the small bitmap if you need it */ + + if ( smooth ) + Init_Raster_Map( &small_bit, imetrics.x_ppem + 32, pnm_height ); + } + + + static void Done_Raster_Areas( void ) + { + Done_Raster_Map( &bit ); + if ( smooth ) + Done_Raster_Map( &small_bit ); + } + + + static void Render_Glyph( TT_Glyph glyph, + int x_off, int y_off, + TT_Glyph_Metrics* gmetrics ) + { + if ( !smooth ) + TT_Get_Glyph_Bitmap( glyph, &bit, x_off * 64L, y_off * 64L); + else + { + TT_F26Dot6 xmin, ymin, xmax, ymax; + + + /* grid-fit the bounding box */ + + xmin = gmetrics->bbox.xMin & -64; + ymin = gmetrics->bbox.yMin & -64; + xmax = (gmetrics->bbox.xMax + 63) & -64; + ymax = (gmetrics->bbox.yMax + 63) & -64; + + /* now render the glyph in the small pixmap */ + /* and blit-or the resulting small pixmap into the biggest one */ + + Clear_Raster_Map( &small_bit ); + TT_Get_Glyph_Pixmap( glyph, &small_bit, -xmin, -ymin ); + Blit_Or( &bit, &small_bit, xmin/64 + x_off, -ymin/64 - y_off ); + } + } + + + static void Render_All_Glyphs( char* txt, int txtlen ) + { + int i; + TT_F26Dot6 x, y, adjx; + TT_Glyph_Metrics gmetrics; + + + x = pnm_x_shift; + y = pnm_y_shift; + + for ( i = 0; i < txtlen; i++ ) + { + unsigned char j = txt[i]; + + if ( !TT_VALID( glyphs[j] ) ) + continue; + + TT_Get_Glyph_Metrics( glyphs[j], &gmetrics ); + + adjx = x; /* ??? lsb */ + Render_Glyph( glyphs[j], adjx, y, &gmetrics ); + + x += gmetrics.advance / 64; + } + } + + + static void usage( void ) + { + printf( "\n" ); + printf( "%s: simple text to image converter -- part of the FreeType project\n", PROGNAME ); + printf( "\n" ); + printf( "Usage: %s [options below] filename [string]\n", PROGNAME ); + printf( "\n" ); + printf( " -g gray-level rendering (default: off)\n" ); + printf( " -h hinting off (default: on)\n" ); + printf( " -r X resolution X dpi (default: 96)\n" ); + printf( " -p X pointsize X pt (default: 12)\n" ); + printf( " -b X border X pixels wide (default: 0)\n" ); + printf( "\n" ); + + exit( EXIT_FAILURE ); + } + + + int main( int argc, char** argv ) + { + int option, txtlen; + char *txt, *filename; + TT_Error error; + + + /* Parse options */ + + while ( 1 ) + { + option = ft_getopt( argc, argv, "ghr:p:b:" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'g': + smooth = 1; + break; + case 'h': + hinted = 0; + break; + case 'r': + dpi = atoi( ft_optarg ); + break; + case 'p': + ptsize = atoi( ft_optarg ); + break; + case 'b': + border = atoi( ft_optarg ); + break; + + default: + usage(); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 0 || argc > 2 || dpi <= 0 || ptsize <= 0 || border < 0 ) + usage(); + + filename = argv[0]; + + if ( argc > 1 ) + txt = argv[1]; + else + txt = "The quick brown fox jumps over the lazy dog"; + + txtlen = strlen( txt ); + + /* Initialize engine and other stuff */ + + error = TT_Init_FreeType( &engine ); + if ( error ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + Init_Face( filename ); + Load_Glyphs( txt, txtlen ); + Init_Raster_Areas( txt, txtlen ); + + /* Do the real work now */ + + Render_All_Glyphs( txt, txtlen ); + Dump_Raster_Map( &bit, stdout ); + + /* Clean up */ + + Done_Raster_Areas(); + Done_Glyphs(); + Done_Face(); + + /* That's all, folks! */ + + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/ftstrtto.c b/test/ftstrtto.c new file mode 100644 index 0000000..f23ced3 --- /dev/null +++ b/test/ftstrtto.c @@ -0,0 +1,1158 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftstrtto: Making string text from individual glyph information, using */ +/* TrueType Open features. */ +/* */ +/* Keys: */ +/* */ +/* + : fast scale up */ +/* - : fast scale down */ +/* u : fine scale down */ +/* j : fine scale up */ +/* */ +/* h : toggle hinting */ +/* K : toggle kerning */ +/* B : toggle sbit */ +/* G : toggle GSUB */ +/* */ +/* q : */ +/* ESC : exit */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "arabic.h" +#include "blitter.h" +#include "common.h" /* for Panic() only */ +#include "display.h" + +#include "freetype.h" +#include "ftxkern.h" +#include "ftxopen.h" +#include "ftxsbit.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + + +#define MAXPTSIZE 500 /* dtp */ +#define Center_X ( Bit.width / 2 ) /* dtp */ +#define Center_Y ( Bit.rows / 2 ) /* dtp */ + +#define FEATURE_init MAKE_TT_TAG( 'i', 'n', 'i', 't' ) +#define FEATURE_medi MAKE_TT_TAG( 'm', 'e', 'd', 'i' ) +#define FEATURE_fina MAKE_TT_TAG( 'f', 'i', 'n', 'a' ) +#define FEATURE_isol MAKE_TT_TAG( 'i', 's', 'o', 'l' ) + + + char Header[128]; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_CharMap char_map; + TT_Kerning directory; + + TTO_GSUBHeader gsub_; + TTO_GSUBHeader* gsub; + TTO_GDEFHeader gdef_; + TTO_GDEFHeader* gdef; + + TT_Big_Glyph_Metrics metrics; + TT_Outline outline; + TT_Face_Properties face_properties; + TT_Instance_Metrics imetrics; + + TT_SBit_Image* sbit; + + int pt_size; + int ttc_index; + TT_Bool hinted; + TT_Bool gray_render; + TT_Bool r2l; + TT_Bool vertical; + + TT_Bool has_kern; + TT_Bool use_kern; + TT_Bool has_gdef; + TT_Bool has_gsub; + TT_Bool use_gsub; + TT_Bool has_sbit; + TT_Bool use_sbit; + TT_Bool glyph_has_sbit; + + TT_Bool default_language_system; + + int Fail; + + char* char_string; + + TT_UShort glyph_code_array[129]; + TT_UShort char_code[128]; + TT_UShort properties[128]; + + TT_UShort* glyph_code; + int num_glyphs; + + TT_ULong script_tag; + char* script_tag_string; + TT_UShort script_index; + + TT_ULong language_tag; + char* language_tag_string; + TT_UShort language_index; + TT_UShort req_feature_index = 0xFFFF; + + TT_ULong* feature_tags; + char** feature_tag_strings; + TT_UShort* feature_indices; + int num_features; + + + static void Select_CMap( void ) + { + TT_UShort i, n; + TT_UShort platform, encoding; + + + n = face_properties.num_CharMaps; + + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + if ( platform == 3 && encoding == 1 ) + { + TT_Get_CharMap( face, i, &char_map ); + break; + } + } + + /* we try only pid/eid (0,0) if no (3,1) map is found -- many Windows + fonts have only rudimentary (0,0) support. */ + + if ( i == n ) + { + for ( i = 0; i < n; i++ ) + { + TT_Get_CharMap_ID( face, i, &platform, &encoding ); + if ( platform == 0 && encoding == 0 ) + { + TT_Get_CharMap( face, i, &char_map ); + break; + } + } + + if ( i == n ) + Panic( "Sorry, but this font doesn't contain" + " any Unicode mapping table\n" ); + } + } + + + /* Convert a Latin 1 string to a string of glyph indexes. */ + /* */ + /* IMPORTANT NOTE: */ + /* */ + /* There is no portable way to convert from any system's char. code */ + /* to Unicode. This function simply takes a char. string as argument */ + /* and `interprets' each character as a Unicode char. index with no */ + /* further check. */ + /* */ + /* We interpret the command line string as Unicode with the high byte */ + /* set to zero. This is equivalent to Latin-1. */ + + static void Latin1Char_To_Glyph( char* source ) + { + TT_UShort n; + + + glyph_code = glyph_code_array + 1; /* we want to make glyph_code[-1] */ + glyph_code[-1] = 0; /* possible. */ + + for ( n = 0; n < 128 && source[n]; n++ ) + { + char_code[n] = (TT_UShort)( (unsigned char)source[n] ); + glyph_code[n] = TT_Char_Index( char_map, char_code[n] ); + } + + num_glyphs = n; + } + + + static void UTF8Char_To_Glyph( char* source ) + { + TT_UShort in, out, in_code, out_code; + TT_UShort count, limit; + + + glyph_code = glyph_code_array + 1; /* we want to make glyph_code[-1] */ + glyph_code[-1] = 0; /* possible. */ + + for ( in = out = 0, count = limit = 1, in_code = out_code = 0; + in < 128 && source[in]; in++ ) + { + in_code = (TT_UShort)( (unsigned char)source[in] ); + + if ( in_code >= 0xC0 ) + { + limit = 1; + count = 1; + + if ( in_code < 0xE0 ) /* U+0080 - U+07FF */ + { + limit = 2; + out_code = in_code & 0x1F; + } + else if ( in_code < 0xF0 ) /* U+0800 - U+FFFF */ + { + limit = 3; + out_code = in_code & 0x0F; + } + continue; + } + else if ( in_code >= 0x80 ) + { + count++; + + if ( count <= limit ) + { + out_code <<= 6; + out_code += in_code & 0x3F; + } + if ( count != limit ) + continue; + } + else + out_code = in_code; + + char_code[out] = out_code; + glyph_code[out++] = TT_Char_Index( char_map, out_code ); + } + + num_glyphs = out; + } + + + static TT_Error Reset_Scale( int pointSize ) + { + TT_Error error; + + + error = TT_Set_Instance_CharSize( instance, pointSize * 64L ); + if ( error ) + { + RestoreScreen(); + Panic( "Could not reset instance, code = 0x%x.\n", error ); + } + + TT_Get_Instance_Metrics( instance, &imetrics ); + + /* now re-allocate the small bitmap */ + if ( gray_render ) + { + Init_Small( imetrics.x_ppem, imetrics.y_ppem ); + Clear_Small(); + } + + return TT_Err_Ok; + } + + + static TT_Error Load_TrueType_Char( TT_UShort idx, + int hint ) + { + int flags; + TT_Error error; + + + glyph_has_sbit = 0; + + error = TT_Load_Glyph_Bitmap( face, instance, idx, sbit ); + if ( error == TT_Err_Ok ) + { + has_sbit = 1; + glyph_has_sbit = 1; + } + + if ( glyph_has_sbit && use_sbit ) + return TT_Err_Ok; + + flags = TTLOAD_SCALE_GLYPH; + if ( hint ) + flags |= TTLOAD_HINT_GLYPH; + + return TT_Load_Glyph( instance, glyph, idx, flags ); + } + + + static TT_Error Get_Kern_Values( TT_UShort idx, + TT_Pos* x, + TT_Pos* y ) + { + TT_UShort i; + TT_Kern_Subtable table; + TT_Kern_0_Pair* pairs_0; + + TT_UShort min, max, new_min, new_max, middle; + TT_Long target_idx, current_idx; + + + *x = 0; + *y = 0; + + for ( i = 0; i < directory.nTables; i++ ) + { + table = directory.tables[i]; + + /* handle only horizontal kerning tables */ + + if ( table.coverage & 0x0001 ) + { + switch ( table.format ) + { + case 0: + pairs_0 = table.t.kern0.pairs; + target_idx = ( glyph_code[idx - 1] << 16 ) + glyph_code[idx]; + + /* binary search */ + + new_min = 0; + new_max = table.t.kern0.nPairs - 1; + + do + { + min = new_min; + max = new_max; + middle = max - ( ( max - min ) >> 1 ); + + current_idx = ( pairs_0[middle].left << 16 ) + + pairs_0[middle].right; + + if ( target_idx == current_idx ) + { + *x += pairs_0[middle].value; + break; + } + else if ( target_idx < current_idx ) + { + if ( middle == min ) + break; + new_max = middle - 1; + } + else + { + if ( middle == max ) + break; + new_min = middle + 1; + } + } while ( min < max ); + + break; + + /* we currently ignore format 2 kerning tables */ + + case 2: + break; + } + } + } + + /* scaling and rounding */ + + *x = ( ( ( *x * imetrics.x_scale ) / 0x10000 ) + 32 ) & -64; + *y = ( ( ( *y * imetrics.y_scale ) / 0x10000 ) + 32 ) & -64; + + return TT_Err_Ok; + } + + + /* for testing purposes, we always select the last available alternate + glyph, not using the `data' field. */ + + static TT_UShort alternate_function( TT_ULong pos, + TT_UShort glyphID, + TT_UShort num_alternates, + TT_UShort* alternates, + void* data ) + { + return num_alternates - 1; + } + + + static TT_Error Render_All( void ) + { + TT_Pos x, y, z, min_x, min_y, max_x, max_y; + TT_Pos kern_x, kern_y; + int i, n; + TT_UShort* gc; + TT_UShort glyph_property = 0; + + TT_Error error; + + TTO_GSUB_String in, out; + + + /* On the first pass, we compute the compound bounding box */ + + x = y = 0; + kern_x = kern_y = 0; + min_x = min_y = max_x = max_y = 0; + + in.length = num_glyphs; + in.pos = 0; + in.string = glyph_code; + in.properties = properties; + + out.pos = 0; + out.allocated = 0; + out.string = NULL; + out.properties = NULL; + + if ( has_gsub && use_gsub ) + { + error = TT_GSUB_Apply_String( gsub, &in, &out ); + if ( error && error != TTO_Err_Not_Covered ) + return error; + + n = out.length; + gc = out.string; + } + else + { + n = in.length; + gc = in.string; + } + + has_sbit = 0; + + for ( i = 0; i < n; i++ ) + { + error = Load_TrueType_Char( gc[i], hinted ); + if ( error == TT_Err_Ok ) + { + if ( glyph_has_sbit && use_sbit ) + metrics = sbit->metrics; + else + TT_Get_Glyph_Big_Metrics( glyph, &metrics ); + if ( has_kern && use_kern ) + Get_Kern_Values( i, &kern_x, &kern_y ); + + z = x + metrics.bbox.xMin + kern_x; + if ( min_x > z ) + min_x = z; + + z = x + metrics.bbox.xMax + kern_x; + if ( max_x < z ) + max_x = z; + + z = y + metrics.bbox.yMin + kern_y; + if ( min_y > z ) + min_y = z; + + z = y + metrics.bbox.yMax + kern_y; + if ( max_y < z ) + max_y = z; + + if ( has_gdef ) + { + error = TT_GDEF_Get_Glyph_Property( gdef, gc[i], &glyph_property ); + if ( error ) + return error; + } + + /* advance only if it is not a mark glyph */ + + if ( !( glyph_property & TTO_MARK ) ) + { + if ( vertical ) + y += ( metrics.vertAdvance & -64 ) + kern_y; + else + x += ( metrics.horiAdvance & -64 ) + kern_x; + } + } + else + Fail++; + } + + /* We now center the bbox inside the target bitmap */ + + min_x = ( min_x & -64 ) >> 6; + min_y = ( min_y & -64 ) >> 6; + + max_x = ( (max_x + 63) & -64 ) >> 6; + max_y = ( (max_y + 63) & -64 ) >> 6; + + max_x -= min_x; + max_y -= min_y; + + min_x = ( Bit.width - max_x ) / 2; + min_y = ( Bit.rows - max_y ) / 2; + + max_x += min_x; + max_y += min_y; + + /* On the second pass, we render each glyph to its centered position. */ + /* This is slow, because we reload each glyph to render it! */ + + x = vertical ? min_x : ( r2l ? max_x : min_x ); + y = vertical ? ( r2l ? min_y : max_y ) : min_y; + + for ( i = 0; i < n; i++ ) + { + error = Load_TrueType_Char( gc[i], hinted ); + if ( error == TT_Err_Ok ) + { + if ( glyph_has_sbit && use_sbit ) + metrics = sbit->metrics; + else + TT_Get_Glyph_Big_Metrics( glyph, &metrics ); + if ( has_kern && use_kern ) + Get_Kern_Values( i, &kern_x, &kern_y ); + + if ( has_gdef ) + (void)TT_GDEF_Get_Glyph_Property( gdef, gc[i], &glyph_property ); + + if ( !( glyph_property & TTO_MARK ) ) + { + if ( r2l ) + { + if ( vertical ) + y += metrics.vertAdvance / 64; + else + x -= metrics.horiAdvance / 64; + } + else + { + if ( vertical ) + y -= kern_y / 64; + else + x += kern_x / 64; + } + } + + /* We must specify the upper left corner of the bitmap, but the + lower left corner for the outline. Another complication is that + Blit_Bitmap() assumes that increasing y values means moving + downwards. + + For vertical layout, the origin of the horizontal and vertical + bearings of embedded bitmaps is the top, thus we shift the + outline glyphs down. */ + + if ( glyph_has_sbit && use_sbit ) + Blit_Bitmap( &Bit, + &sbit->map, + gray_render ? 8 : 1, + x + + ( vertical ? metrics.vertBearingX : + metrics.horiBearingX ) / 64, + Bit.rows - y - + ( vertical ? metrics.vertBearingY : + metrics.horiBearingY ) / 64, + gray_palette[4] ); + else + Render_Single_Glyph( + gray_render, + glyph, + x, + y - + ( vertical ? metrics.vertBearingY + metrics.bbox.yMax : + 0 ) / 64 ); + + if ( !( glyph_property & TTO_MARK ) ) + { + if ( r2l ) + { + if ( vertical ) + y += kern_y / 64; + else + x -= kern_x / 64; + } + else + { + if ( vertical ) + y -= metrics.vertAdvance / 64; + else + x += metrics.horiAdvance / 64; + } + } + } + } + + if ( out.string ) + free( out.string ); + if ( out.properties ) + free( out.properties ); + + return TT_Err_Ok; + } + + + static int Process_Event( TEvent* event ) + { + switch ( event->what ) + { + case event_Quit: /* ESC or q */ + return 0; + + case event_Keyboard: + if ( event->info == 'h' ) /* Toggle hinting */ + hinted = !hinted; + else if ( event->info == 'K' ) /* Toggle kerning */ + use_kern = !use_kern; + else if ( event->info == 'B' ) /* Toggle sbit */ + use_sbit = !use_sbit; + else if ( event->info == 'G' ) /* Toggle gsub */ + use_gsub = !use_gsub; + break; + + case event_Rotate_Glyph: + break; + + case event_Scale_Glyph: + pt_size += event->info; + if ( pt_size < 1 ) pt_size = 1; + if ( pt_size > MAXPTSIZE ) pt_size = MAXPTSIZE; + break; + + case event_Change_Glyph: + break; + } + + return 1; + } + + + static void Usage( char* execname ) + { + fprintf( stderr, + "\n" + "ftstrtto: TrueType Open String Test Display -- part of the FreeType project\n" + "---------------------------------------------------------------------------\n" + "\n" + "Usage: %s [options below] ppem fontname[.ttf|.ttc] [string|-]\n" + "\n" + " -c C use font with index C in TrueType collection (default: 0)\n" + " -f F use feature F (can be specified more than once)\n" + " -g gray-level rendering\n" + " -l L use language L\n" + " -r R use resolution R dpi (default: 96)\n" + " -s S use script S\n" + " -u interpret input data as UTF8-encoded\n" + " -v display string vertically\n" + " -x display string from right to left\n" + "\n" + " F, L, and S must be specified as 4-character tags.\n" + " Specifying only F and S selects default language system of S.\n" + " Specifying only L and S selects the req. feature of L only (if any).\n" + "\n" + " If `-' is specified as input string, stdin is read instead.\n" + "\n", execname ); + + exit( EXIT_FAILURE ); + } + + + static TT_ULong Make_Tag( char* tag_string ) + { + char t1 = ' ', t2 = ' ', t3 = ' ', t4 = ' '; + + + if ( !tag_string ) + return 0; + + t1 = tag_string[0]; + if ( tag_string[1] ) + t2 = tag_string[1]; + if ( tag_string[2] ) + t3 = tag_string[2]; + if ( tag_string[3] ) + t4 = tag_string[3]; + + return MAKE_TT_TAG( t1, t2, t3, t4 ); + } + + + int main( int argc, + char** argv ) + { + int i, old_pt_size, orig_pt_size, file; + + int graphics_initialized = 0; + + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + + int option; + int res = 96; + int utf8 = 0; + + TT_Error error; + TEvent event; + + + execname = argv[0]; + + while ( 1 ) + { + option = ft_getopt( argc, argv, "c:f:gl:r:s:uvx" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'c': + ttc_index = atoi( ft_optarg ); + if ( ttc_index < 0 ) + Usage( execname ); + break; + + case 'f': + num_features++; + feature_tag_strings = (char**) + realloc( feature_tag_strings, + num_features * sizeof ( char* ) ); + feature_tags = (TT_ULong*) + realloc( feature_tags, + num_features * sizeof ( TT_ULong ) ); + feature_tag_strings[num_features - 1] = ft_optarg; + if ( !(feature_tags[num_features - 1] = Make_Tag( ft_optarg ) ) ) + Usage( execname ); + break; + + case 'g': + gray_render = 1; + break; + + case 'l': + language_tag_string = ft_optarg; + if ( !(language_tag = Make_Tag( ft_optarg ) ) ) + Usage( execname ); + break; + + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + Usage( execname ); + break; + + case 's': + script_tag_string = ft_optarg; + if ( !(script_tag = Make_Tag( ft_optarg ) ) ) + Usage( execname ); + break; + + case 'u': + utf8 = 1; + break; + + case 'v': + vertical = 1; + break; + + case 'x': + r2l = 1; + break; + + default: + Usage( execname ); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 1 ) + Usage( execname ); + + if ( sscanf( argv[0], "%d", &orig_pt_size ) != 1 ) + orig_pt_size = 64; + + file = 1; + + /* Initialize engine */ + + error = TT_Init_FreeType( &engine ); + if ( error ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + error = TT_Init_Kerning_Extension( engine ); + if ( error ) + Panic( "Error while initializing kerning extension, code = 0x%x.\n", + error ); + + error = TT_Init_SBit_Extension( engine ); + if ( error ) + Panic( "Error while initializing sbit extension, code = 0x%x.\n", + error ); + + error = TT_Init_GDEF_Extension( engine ); + if ( error ) + Panic( "Error while initializing GDEF extension, code = 0x%x.\n", + error ); + + error = TT_Init_GSUB_Extension( engine ); + if ( error ) + Panic( "Error while initializing GSUB extension, code = 0x%x.\n", + error ); + + pt_size = orig_pt_size; + hinted = 1; + use_gsub = 1; + use_kern = 1; + use_sbit = 1; + + i = strlen( argv[file] ); + while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) + { + if ( argv[file][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[file], 128 ); + strncpy( alt_filename, argv[file], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open `%s'.\n", filename ); + else if ( error ) + Panic( "Error while opening `%s', code = 0x%x.\n", + filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &face_properties ); + + /* open font in collection */ + + if ( ttc_index >= face_properties.num_Faces ) + Panic( "There is no collection with index %d in this font file.\n", + ttc_index ); + + TT_Close_Face( face ); + + error = TT_Open_Collection( engine, filename, ttc_index, &face ); + if ( error ) + Panic( "Error while opening collection %d in `%s', code = 0x%x.\n", + ttc_index, filename, error ); + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container, code = 0x%x.\n", error ); + + /* create sbit slot */ + + error = TT_New_SBit_Image( &sbit ); + if ( error ) + Panic( "Could not create sbit slot, code = 0x%x.\n" , error); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for `%s', code = 0x%x.\n", + filename, error ); + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + Panic( "Could not set device resolutions, code = 0x%x.\n", error ); + + error = TT_Get_Kerning_Directory( face, &directory ); + if ( error ) + Panic( "Could not get kerning directory, code = 0x%x.\n", error ); + + /* load all kerning tables */ + + for ( i = 0; i < directory.nTables; i++ ) + { + error = TT_Load_Kerning_Table( face, i ); + if ( error ) + Panic( "Could not load kerning table, code = 0x%x.\n", error ); + } + + if ( directory.nTables ) + has_kern = 1; + + Select_CMap(); + + /* GDEF support */ + + gdef = &gdef_; + + error = TT_Load_GDEF_Table( face, gdef ); + if ( !error ) + has_gdef = 1; + else if ( error != TT_Err_Table_Missing ) + Panic( "Error while loading GDEF table, code = 0x%x.\n", error ); + + /* we must assign glyph properties in case no GDEF table is available */ + + if ( !has_gdef ) + { + Build_Arabic_Glyph_Properties( char_map, face_properties.num_Glyphs, + &gdef ); + if ( gdef ) + has_gdef = 1; + } + + /* GSUB support */ + + gsub = &gsub_; + + error = TT_Load_GSUB_Table( face, gsub, gdef ); + if ( !error ) + { + if ( script_tag && feature_tags ) + has_gsub = 1; + if ( script_tag && language_tag ) + has_gsub = 1; + } + else if ( error != TT_Err_Table_Missing ) + Panic( "Error while loading GSUB table, code = 0x%x.\n", error ); + + TT_GSUB_Clear_Features( gsub ); + + if ( has_gsub && !language_tag ) + default_language_system = 1; + + feature_indices = (TT_UShort*) + malloc( num_features * sizeof ( TT_UShort ) ); + + if ( has_gsub ) + { + error = TT_GSUB_Select_Script( gsub, + script_tag, + &script_index ); + if ( error ) + Panic( "Requested script `%-4.4s' not found.\n", + script_tag_string ); + + if ( default_language_system ) + { + for ( i = 0; i < num_features; i++ ) + { + error = TT_GSUB_Select_Feature( gsub, + feature_tags[i], + script_index, 0xFFFF, + &feature_indices[i] ); + if ( error ) + Panic( "Requested feature `%-4.4s'\n" + "for default language system of script `%-4.4s' not found.\n", + feature_tag_strings[i], script_tag_string ); + } + } + else + { + error = TT_GSUB_Select_Language( gsub, + language_tag, + script_index, + &language_index, + &req_feature_index ); + if ( error ) + Panic( "Requested language `%-4.4s'\n" + "for script `%-4.4s' not found.\n", + language_tag_string, script_tag_string ); + + for ( i = 0; i < num_features; i++ ) + { + error = TT_GSUB_Select_Feature( gsub, + feature_tags[i], + script_index, language_index, + &feature_indices[i] ); + if ( error ) + Panic( "Requested feature `%-4.4s'\n" + "for script `%-4.4s', language `%-4.4s' not found.\n", + feature_tag_strings[i], script_tag_string, + language_tag_string ); + } + } + + if ( req_feature_index != 0xFFFF ) + TT_GSUB_Add_Feature( gsub, req_feature_index, ALL_GLYPHS ); + else if ( !num_features ) + has_gsub = 0; + + for ( i = 0; i < num_features; i++ ) + { + if ( feature_tags[i] == FEATURE_init ) + TT_GSUB_Add_Feature( gsub, feature_indices[i], initial ); + else if ( feature_tags[i] == FEATURE_medi ) + TT_GSUB_Add_Feature( gsub, feature_indices[i], medial ); + else if ( feature_tags[i] == FEATURE_fina ) + TT_GSUB_Add_Feature( gsub, feature_indices[i], final ); + else if ( feature_tags[i] == FEATURE_isol ) + TT_GSUB_Add_Feature( gsub, feature_indices[i], isolated ); + else + TT_GSUB_Add_Feature( gsub, feature_indices[i], ALL_GLYPHS ); + } + + TT_GSUB_Register_Alternate_Function( gsub, alternate_function, NULL ); + } + + + if ( !graphics_initialized ) + { + graphics_initialized = 1; + + if ( gray_render ) + { + if ( !SetGraphScreen( Graphics_Mode_Gray ) ) + Panic( "Could not set up grayscale graphics mode.\n" ); + + TT_Set_Raster_Gray_Palette( engine, virtual_palette ); + } + else + { + if ( !SetGraphScreen( Graphics_Mode_Mono ) ) + Panic( "Could not set up mono graphics mode.\n" ); + } + } + + Init_Display( gray_render ); + + Reset_Scale( pt_size ); + + old_pt_size = pt_size; + + Fail = 0; + + /* get string to display, if any */ + + if ( argv[2] ) + { + if ( argv[2][0] == '-' ) + { + int ch; + char* p; + + + char_string = (char*)malloc( 128 * sizeof ( char ) ); + p = char_string; + + for ( i = 0; i < 128; i++ ) + { + ch = getchar(); + if ( ch == '\n' || ch == EOF ) + { + *p = '\0'; + break; + } + + *p++ = (char)ch; + } + + *p = '\0'; + } + else + char_string = argv[2]; + } + else + char_string = "The quick brown fox jumps over the lazy dog"; + + if ( utf8 ) + UTF8Char_To_Glyph( char_string ); + else + Latin1Char_To_Glyph( char_string ); + + /* we assign Arabic script features (e.g. `initial' or `final') */ + + Assign_Arabic_Properties( char_code, properties, num_glyphs ); + + for ( ;; ) + { + int key; + + + Clear_Display(); + + error = Render_All(); + if ( error ) + Panic( "Error while rendering string, code = 0x%x.\n", error ); + + if ( gray_render ) + Convert_To_Display_Palette(); + + sprintf( Header, + "%s: ptsize: %d hinting: %s%s%s%s%s%s%s", + ft_basename( filename ), + pt_size, + hinted ? "on" : "off", + has_kern ? " kerning: " : "", + has_kern ? ( use_kern ? "on" : "off" ) : "", + has_sbit ? " sbit: " : "", + has_sbit ? ( use_sbit ? "on" : "off" ) : "", + has_gsub ? " GSUB: " : "", + has_gsub ? ( use_gsub ? "on" : "off" ) : "" ); + + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + +#ifndef X11 +#ifndef OS2 + Print_XY( 0, 0, Header ); +#endif +#endif + + Get_Event( &event ); + if ( !( key = Process_Event( &event ) ) ) + goto Fin; + + if ( pt_size != old_pt_size ) + { + if ( Reset_Scale( pt_size ) ) + Panic( "Could not resize font.\n" ); + + old_pt_size = pt_size; + } + } + + Fin: + RestoreScreen(); + + TT_Done_FreeType( engine ); + + printf( "Execution completed successfully.\n" ); + printf( "Fails = %d.\n", Fail ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/fttimer.c b/test/fttimer.c new file mode 100644 index 0000000..2372afd --- /dev/null +++ b/test/fttimer.c @@ -0,0 +1,455 @@ +/****************************************************************************/ +/* */ +/* The FreeType project - a Free and Portable Quality TrueType Renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* fttimer: A simple performance benchmark. Now with graylevel rendering */ +/* with the '-g' option. */ +/* */ +/* Be aware that the timer program benchmarks different things */ +/* in each release of the FreeType library. Thus, performance */ +/* should only be compared between similar release numbers. */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. In no way does it shows the final */ +/* high-level interface that client applications will use. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "common.h" /* for Panic() */ +#include "freetype.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + +#ifndef __USE_MISC +#define __USE_MISC /* MkLinux needs this to get a definition of + CLOCKS_PER_SEC */ +#endif + +#include /* for clock() */ + +/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include */ +/* to get the HZ macro which is the equivalent. */ +#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4) +#include +#define CLOCKS_PER_SEC HZ +#endif + +#define MAX_GLYPHS 512 /* Maximum number of glyphs rendered at one time */ + + char Header[128]; + + TT_Error error; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + + TT_Outline outline; + TT_Glyph_Metrics metrics; + + TT_Face_Properties properties; + + TT_F26Dot6* cur_x; + TT_F26Dot6* cur_y; + + unsigned short* cur_endContour; + unsigned char* cur_touch; + + TT_Outline outlines[MAX_GLYPHS]; + + int num_glyphs; + int tab_glyphs; + int cur_glyph; + int cur_point; + unsigned short cur_contour; + + TT_Raster_Map Bit; + + int Fail; + int Num; + + short visual; /* display glyphs while rendering */ + short gray_render; /* smooth fonts with gray levels */ + + + static void Clear_Buffer( void ); + + +/*******************************************************************/ +/* */ +/* Get_Time: */ +/* */ +/* Returns the current time in milliseconds. */ +/* */ +/*******************************************************************/ + + long Get_Time( void ) + { + return clock() * 1000 / CLOCKS_PER_SEC; + } + + +/*******************************************************************/ +/* */ +/* Init_Engine: */ +/* */ +/* Allocates bitmap, render pool and other structs... */ +/* */ +/*******************************************************************/ + + void Init_Engine( void ) + { + Bit.rows = vio_Height; /* The whole window */ + Bit.width = vio_Width; + + if ( gray_render ) + { + Bit.cols = Bit.width; + Bit.flow = TT_Flow_Up; + Bit.size = Bit.rows * Bit.width; + } + else + { + Bit.cols = (Bit.width + 7) / 8; /* convert to # of bytes */ + Bit.flow = TT_Flow_Up; + Bit.size = Bit.rows * Bit.cols; /* number of bytes in buffer */ + } + + Bit.bitmap = (void*)malloc( Bit.size ); + if ( !Bit.bitmap ) + Panic( "ERROR: not enough memory to allocate bitmap!\n" ); + + Clear_Buffer(); + } + + +/*******************************************************************/ +/* */ +/* Clear_Buffer: */ +/* */ +/* Clears current bitmap. */ +/* */ +/*******************************************************************/ + + static void Clear_Buffer( void ) + { + if ( gray_render ) + memset( Bit.bitmap, gray_palette[0], Bit.size ); + else + memset( Bit.bitmap, 0, Bit.size ); + } + + +/*******************************************************************/ +/* */ +/* LoadTrueTypeChar: */ +/* */ +/* Loads a glyph into memory. */ +/* */ +/*******************************************************************/ + + TT_Error LoadTrueTypeChar( int idx ) + { + error = TT_Load_Glyph( instance, glyph, idx, TTLOAD_DEFAULT ); + if ( error ) + return error; + + TT_Get_Glyph_Outline( glyph, &outline ); + + outline.second_pass = 0; + outline.high_precision = 0; + outline.dropout_mode = 0; + + /* debugging */ +#if 0 + if ( idx == 0 && !visual ) + { + printf( "points = %d\n", outline.points ); + for ( j = 0; j < outline.points; j++ ) + printf( "%02x (%01hx,%01hx)\n", + j, outline.xCoord[j], outline.yCoord[j] ); + printf( "\n" ); + } +#endif + + /* create a new outline */ + TT_New_Outline( outline.n_points, + outline.n_contours, + &outlines[cur_glyph] ); + + /* copy the glyph outline into it */ + outline.high_precision = 0; + outline.second_pass = 0; + TT_Copy_Outline( &outline, &outlines[cur_glyph] ); + + /* translate it */ + TT_Translate_Outline( &outlines[cur_glyph], + vio_Width * 16, + vio_Height * 16 ); + cur_glyph++; + + return TT_Err_Ok; + } + + +/*******************************************************************/ +/* */ +/* ConvertRaster: */ +/* */ +/* Performs scan conversion. */ +/* */ +/*******************************************************************/ + + TT_Error ConvertRaster( int index ) + { + outlines[index].second_pass = 0; + outlines[index].high_precision = 0; + + if ( gray_render ) + return TT_Get_Outline_Pixmap( engine, &outlines[index], &Bit ); + else + return TT_Get_Outline_Bitmap( engine, &outlines[index], &Bit ); + } + + + int main( int argc, char** argv ) + { + int i, total, mode, base, rendered_glyphs; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + + long t, t0, tz0; + + + execname = argv[0]; + + gray_render = 0; + visual = 0; + + while ( argc > 1 && argv[1][0] == '-' ) + { + switch ( argv[1][1] ) + { + case 'g': + gray_render = 1; + break; + + case 'v': + visual = 1; + break; + + default: + Panic( "Unknown argument '%s'!\n", argv[1] ); + } + argc--; + argv++; + } + + if ( argc != 2 ) + { + fprintf( stderr, "fttimer: simple performance timer -- part of the FreeType project\n" ); + fprintf( stderr,"-----------------------------------------------------------------\n\n" ); + fprintf( stderr,"Usage: %s [-g] [-v] fontname[.ttf|.ttc]\n\n", execname ); + fprintf( stderr," where '-g' asks for gray-levels rendering\n" ); + fprintf( stderr," '-v' displays while rendering (slower)\n" ); + + exit( EXIT_FAILURE ); + } + + i = strlen( argv[1] ); + while ( i > 0 && argv[1][i] != '\\' ) + { + if ( argv[1][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[1], 128 ); + strncpy( alt_filename, argv[1], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Initialize engine */ + + if ( (error = TT_Init_FreeType( &engine )) ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else if ( error ) + Panic( "Error while opening %s, error code = 0x%x.\n", + filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + + num_glyphs = properties.num_Glyphs; + + tab_glyphs = MAX_GLYPHS; + if ( tab_glyphs > num_glyphs ) + tab_glyphs = num_glyphs; + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container.\n" ); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for %s.\n", filename ); + + error = TT_Set_Instance_CharSize( instance, 400*64 ); + if ( error ) + Panic( "Could not reset instance for %s.\n", filename ); + + if ( gray_render ) + mode = Graphics_Mode_Gray; + else + mode = Graphics_Mode_Mono; + + if ( visual ) + { + if ( !SetGraphScreen( mode ) ) + Panic( "Could not set graphics mode.\n" ); + TT_Set_Raster_Gray_Palette( engine, gray_palette ); + } + else + { + /* This is the default bitmap size used */ + vio_Width = 640; + vio_Height = 450; + } + + Init_Engine(); + + Num = 0; + Fail = 0; + + total = num_glyphs; + base = 0; + + rendered_glyphs = 0; + + t0 = 0; /* Initial time */ + + tz0 = Get_Time(); + + while ( total > 0 ) + { + /* First, preload 'tab_glyphs' in memory */ + + cur_glyph = 0; + cur_point = 0; + cur_contour = 0; + + printf( "loading %d glyphs", tab_glyphs ); + + for ( Num = 0; Num < tab_glyphs; Num++ ) + { + error = LoadTrueTypeChar( base + Num ); + if ( error ) + Fail++; + + total--; + } + + base += tab_glyphs; + + if ( tab_glyphs > total ) + tab_glyphs = total; + + printf( ", rendering... " ); + + /* Now, render the loaded glyphs */ + + t = Get_Time(); + + for ( Num = 0; Num < cur_glyph; Num++ ) + { + if ( (error = ConvertRaster( Num )) ) + Fail++; + else + { + rendered_glyphs ++; + + if ( visual ) + { + sprintf( Header, "Glyph: %5d", Num ); + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + + Clear_Buffer(); + } + } + } + + t = Get_Time() - t; + if ( t < 0 ) + t += 100L * 60 * 60; + + printf( " = %f s\n", (double)t / 1000 ); + t0 += t; + + /* Now free all loaded outlines */ + for ( Num = 0; Num < cur_glyph; Num++ ) + TT_Done_Outline( &outlines[Num] ); + } + + tz0 = Get_Time() - tz0; + + if ( visual ) + RestoreScreen(); + + TT_Close_Face( face ); + + printf( "\n" ); + printf( "rendered glyphs = %d\n", rendered_glyphs ); + printf( "render time = %f s\n", (double)t0 / 1000 ); + printf( "fails = %d\n", Fail ); + printf( "average glyphs/s = %f\n", + (double)rendered_glyphs / t0 * 1000 ); + + printf( "total timing = %f s\n", (double)tz0 / 1000 ); + printf( "Fails = %d\n", Fail ); + + TT_Done_FreeType( engine ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/ftview.c b/test/ftview.c new file mode 100644 index 0000000..7e753d1 --- /dev/null +++ b/test/ftview.c @@ -0,0 +1,540 @@ +/****************************************************************************/ +/* */ +/* The FreeType project -- a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftview: A simple font viewer. Now supports hinting and grayscaling */ +/* with the '-g' option. */ +/* */ +/* */ +/* Keys: */ +/* */ +/* x : fine counter-clockwise rotation */ +/* c : fine clockwise rotation */ +/* */ +/* v : fast counter-clockwise rotation */ +/* b : fast clockwise rotation */ +/* */ +/* + : fast scale up */ +/* - : fast scale down */ +/* u : fine scale down */ +/* j : fine scale up */ +/* */ +/* l : go to next glyph */ +/* k : go to previous glyph */ +/* */ +/* o : go to tenth next glyph */ +/* i : go to tenth previous glyph */ +/* */ +/* 0 : go to hundredth next glyph */ +/* 9 : go to hundredth previous glyph */ +/* */ +/* ) : go to 1000th next glyph */ +/* ( : go to 1000th previous glyph */ +/* */ +/* } : go to 10000th next glyph */ +/* { : go to 10000th previous glyph */ +/* */ +/* n : go to next (or last) .ttf file */ +/* p : go to previous (or first) .ttf file */ +/* */ +/* h : toggle hinting */ +/* */ +/* B : toggle sbit */ +/* */ +/* ESC : exit */ +/* */ +/* */ +/* NOTE: This is just a test program that is used to show off and */ +/* debug the current engine. */ +/* */ +/****************************************************************************/ + +#include +#include +#include + +#include "blitter.h" +#include "common.h" /* for Panic() only */ +#include "display.h" +#include "freetype.h" +#include "ftxsbit.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + +#define Pi 3.1415926535 + +#define MAXPTSIZE 500 /* dtp */ +#define Center_X ( Bit.width / 2 ) /* dtp */ +#define Center_Y ( Bit.rows / 2 ) /* dtp */ + +/* + * If Ignore_Err_Not_SBit is not defined, + * "Fail" increase when the glyph does not have sbit and + * sbit_flag is 1. + */ +#define Ignore_Err_Not_SBit 1 + + char Header[128]; + + TT_Engine engine; + + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_CharMap char_map; + + TT_Big_Glyph_Metrics metrics; + TT_Outline outline; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + + TT_SBit_Image* sbit; + + int num_glyphs; + + int ptsize; + int hinted; + + int Rotation; + int Fail; + int Num; + unsigned char autorun; + + int gray_render; + unsigned int sbit_flag; /* 0 if to display outlines + * 1 if to use embedded bitmaps + * 2 if to show sbit and outline glyphs + */ + + int glyph_has_sbit; + + + + static TT_Error Reset_Scale( int pointSize ) + { + TT_Error error; + TT_SBit_Strike strike; + + if ( (error = TT_Set_Instance_PointSize( instance, pointSize )) ) + { + RestoreScreen(); + fprintf( stderr, "Error = 0x%x.\n", (int)error ); + Panic( "Could not reset instance.\n" ); + } + TT_Get_Instance_Metrics( instance, &imetrics ); + + /* now re-allocates the small bitmap */ + if ( gray_render ) + { + Init_Small( imetrics.x_ppem, imetrics.y_ppem ); + Clear_Small(); + } + + if ( TT_Get_SBit_Strike( face, instance, &strike ) ) + glyph_has_sbit = 0; + else + glyph_has_sbit = 1; + + return TT_Err_Ok; + } + + + static TT_Error LoadTrueTypeChar( int idx, + int hint ) + { + int flags; + + + flags = TTLOAD_SCALE_GLYPH; + if ( hint ) + flags |= TTLOAD_HINT_GLYPH; + + return TT_Load_Glyph( instance, glyph, idx, flags ); + } + + + static TT_Error Render_All( int first_glyph, + int ptsize ) + { + TT_F26Dot6 start_x, start_y, step_x, step_y, x, y; + int i; + + TT_Error error = 0; + + + start_x = 4; + start_y = vio_Height - ( ( ptsize * 96 + 36 ) / 72 + 10 ); + + step_x = imetrics.x_ppem + 4; + step_y = imetrics.y_ppem + 10; + + x = start_x; + y = start_y; + + i = first_glyph; + + while ( i < num_glyphs ) + { + if ( ( glyph_has_sbit ) && + ( ( sbit_flag + 1 ) & 2 ) && + !(error = TT_Load_Glyph_Bitmap( face, instance, i, sbit )) ) + { + Blit_Bitmap( &Bit, + &sbit->map, + gray_render ? 8 : 1, + x + (sbit->metrics.horiBearingX/64), + Bit.rows - y - (sbit->metrics.horiBearingY/64), + gray_palette[4] ); + metrics = sbit->metrics; + goto Step; + } + + if ( ( ( !glyph_has_sbit ) || + ( ( sbit_flag + 1 ) & 1 ) ) && + !(error = LoadTrueTypeChar( i, hinted )) ) + { + TT_Get_Glyph_Outline( glyph, &outline ); + TT_Get_Glyph_Big_Metrics( glyph, &metrics ); + + Render_Single_Glyph( gray_render, glyph, x, y ); + } + else + { +#ifdef Ignore_Err_Not_SBit + if (!(( glyph_has_sbit ) && + ( sbit_flag == 1 ) && + ( error == TT_Err_Invalid_Glyph_Index ))) +#endif + Fail++; + } + Step: + x += ( metrics.horiAdvance / 64 ) + 1; + + if ( x + imetrics.x_ppem > vio_Width ) + { + x = start_x; + y -= step_y; + + if ( y < 10 ) + return TT_Err_Ok; + } + i++; + } + return TT_Err_Ok; + } + + + static int Process_Event( TEvent* event ) + { + switch ( event->what ) + { + case event_Quit: /* ESC or q */ + return 0; + + case event_Keyboard: + if ( event->info == 'n' ) /* Next file */ + return 'n'; + if ( event->info == 'p' ) /* Previous file */ + return 'p'; + if ( event->info == 'h' ) /* Toggle hinting */ + hinted = !hinted; + if ( ( event->info == 'B' ) && ( glyph_has_sbit ) ) /* Toggle sbit */ + sbit_flag = ( sbit_flag + 1 ) % 3; + break; + + case event_Rotate_Glyph: + Rotation = ( Rotation + event->info ) & 1023; + break; + + case event_Scale_Glyph: + ptsize += event->info; + if ( ptsize < 1 ) ptsize = 1; + if ( ptsize > MAXPTSIZE ) ptsize = MAXPTSIZE; + break; + + case event_Change_Glyph: + Num += event->info; + if ( Num < 0 ) Num = 0; + if ( Num >= num_glyphs ) Num = num_glyphs - 1; + break; + } + + return 1; + } + + + static void usage( char* execname ) + { + fprintf( stderr, "\n" ); + fprintf( stderr, "ftview: simple TrueType interpreter tester -- part of the FreeType project\n" ); + fprintf( stderr, "--------------------------------------------------------------------------\n" ); + fprintf( stderr, "\n" ); + fprintf( stderr, "Usage: %s [options below] ppem fontname[.ttf|.ttc] ...\n", + execname ); + fprintf( stderr, "\n" ); + fprintf( stderr, " -g gray-level rendering (default: none)\n" ); + fprintf( stderr, " -r R use resolution R dpi (default: 96)\n" ); + fprintf( stderr, " -B use embedded bitmaps (default: none)\n" ); + fprintf( stderr, "\n" ); + + exit( EXIT_FAILURE ); + } + + + int main( int argc, + char** argv ) + { + int i, old_ptsize, orig_ptsize, file; + int XisSetup = 0; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + int option; + int res = 96; + + TT_Error error; + TEvent event; + + TT_EBLC eblc_table; + + + execname = ft_basename( argv[0] ); + + while ( 1 ) + { + option = ft_getopt( argc, argv, "gr:B" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'g': + gray_render = 1; + sbit_flag = 0; + break; + + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + usage( execname ); + break; + + case 'B': + if (!gray_render) +#if 0 + sbit_flag = 1; +#else + sbit_flag = 2; +#endif + break; + + default: + usage( execname ); + break; + } + } + + argc -= ft_optind; + argv += ft_optind; + + if ( argc <= 1 ) + usage( execname ); + + if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 ) + orig_ptsize = 64; + + file = 1; + + /* Initialize engine */ + + if ( (error = TT_Init_FreeType( &engine )) ) + Panic( "Error while initializing engine, code = 0x%x.\n", error ); + + if ( (error = TT_Init_SBit_Extension( engine )) ) + Panic( "Error while initializing sbit extention, code = 0x%x.\n", error ); + + NewFile: + ptsize = orig_ptsize; + hinted = 1; + + i = strlen( argv[file] ); + while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) + { + if ( argv[file][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[file], 128 ); + strncpy( alt_filename, argv[file], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else if ( error ) + Panic( "Error while opening %s, code = 0x%x.\n", filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + + num_glyphs = properties.num_Glyphs; + + glyph_has_sbit = 0; + + error = TT_Get_Face_Bitmaps( face, &eblc_table ); + if ( error == TT_Err_Ok ) + glyph_has_sbit = 1; + if ( sbit_flag && !glyph_has_sbit ) + Panic( "%s does not have embedded bitmap glyphs.\n", filename ); + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container.\n" ); + + error = TT_New_SBit_Image( &sbit ); + if ( error ) + Panic( "Could not create sbit slot.\n" ); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for %s.\n", filename ); + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + Panic( "Could not set device resolutions." ); + + if ( !XisSetup ) + { + XisSetup = 1; + + if ( gray_render ) + { + if ( !SetGraphScreen( Graphics_Mode_Gray ) ) + Panic( "Could not set up grayscale graphics mode.\n" ); + + TT_Set_Raster_Gray_Palette( engine, virtual_palette ); + } + else + { + if ( !SetGraphScreen( Graphics_Mode_Mono ) ) + Panic( "Could not set up mono graphics mode.\n" ); + } + } + + Init_Display( gray_render ); + + Reset_Scale( ptsize ); + + old_ptsize = ptsize; + + Fail = 0; + Num = 0; + + for ( ;; ) + { + int key; + char* sbit_string; + static char* sbit_messages[4] = + { "off", "on", " if available", "NONE" }; + + sbit_string = sbit_messages[3]; + if ( glyph_has_sbit ) + { + if (sbit_flag >= 0 && sbit_flag < 3) + sbit_string = sbit_messages[sbit_flag]; + } + + Clear_Display(); + Render_All( Num, ptsize ); + if ( gray_render ) + Convert_To_Display_Palette(); + + sprintf( Header, "%s: Glyph: %4d ptsize: %4d hinting: %s sbit: %s", + ft_basename( filename ), Num, ptsize, + hinted ? "on" : "off", + sbit_string ); + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + +#ifndef X11 +#ifndef OS2 + Print_XY( 0, 0, Header ); +#endif +#endif + + Get_Event( &event ); + if ( !( key = Process_Event( &event ) ) ) + goto End; + + if ( key == 'n' ) + { + TT_Close_Face( face ); + + if ( file < argc - 1 ) + file++; + + goto NewFile; + } + + if ( key == 'p' ) + { + TT_Close_Face( face ); + + if ( file > 1 ) + file--; + + goto NewFile; + } + + if ( ptsize != old_ptsize ) + { + if ( Reset_Scale( ptsize ) ) + Panic( "Could not resize font.\n" ); + + old_ptsize = ptsize; + } + } + + End: + RestoreScreen(); + + TT_Done_FreeType( engine ); + + printf( "Execution completed successfully.\n" ); + printf( "Fails = %d\n", Fail ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ +} + + +/* End */ diff --git a/test/ftzoom.c b/test/ftzoom.c new file mode 100644 index 0000000..98e4db2 --- /dev/null +++ b/test/ftzoom.c @@ -0,0 +1,681 @@ +/****************************************************************************/ +/* */ +/* The FreeType project - a free and portable quality TrueType renderer. */ +/* */ +/* Copyright 1996-1999 by */ +/* D. Turner, R.Wilhelm, and W. Lemberg */ +/* */ +/* ftzoom : A simple glyph viewer. Now supports graylevel rendering */ +/* with the '-g' option. */ +/* */ +/* Use `-p ' together with `-e ' to */ +/* select a cmap. */ +/* */ +/* Keys: */ +/* */ +/* x : fine counter_clockwise rotation */ +/* c : fine clockwise rotation */ +/* */ +/* v : fast counter_clockwise rotation */ +/* b : fast clockwise rotation */ +/* */ +/* + : fast scale up */ +/* - : fast scale down */ +/* u : fine scale down */ +/* j : fine scale up */ +/* */ +/* l : go to next glyph */ +/* k : go to previous glyph */ +/* */ +/* o : go to tenth next glyph */ +/* i : go to tenth previous glyph */ +/* */ +/* 0 : go to hundredth next glyph */ +/* 9 : go to hundredth previous glyph */ +/* */ +/* ) : go to 1000th next glyph */ +/* ( : go to 1000th previous glyph */ +/* */ +/* } : go to 10000th next glyph */ +/* { : go to 10000th previous glyph */ +/* */ +/* q : */ +/* ESC : exit */ +/* */ +/* */ +/* NOTE 1: This is just a test program that is used to show off and */ +/* debug the current engine. In no way does it show the final */ +/* high-level interface that client applications will use. */ +/* */ +/* NOTE 2: The `post' engine is used to display the PS glyph names. */ +/* Use the `-n' switch if you don't want that. */ +/* */ +/****************************************************************************/ + +#include +#include +#include +#include + +#include "common.h" /* for Panic() only */ +#include "freetype.h" +#include "ftxpost.h" + +#include "gdriver.h" +#include "gevents.h" +#include "gmain.h" + +#ifdef DEBUG_LEVEL_TRACE +#include "ttdebug.h" +#endif + + +#define Pi 3.1415926535 + +#define MAXPTSIZE 5000 /* dtp */ + + char Header[128]; + + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Glyph glyph; + TT_CharMap char_map; + + TT_Glyph_Metrics metrics; + TT_Outline outline; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + + int num_glyphs; + int xcenter_upem; + int ycenter_upem; + int units_per_em; + + int ptsize; + int old_ptsize; + int rotation; + int old_rotation; + + TT_Matrix matrix; + TT_Matrix zoom_matrix; + int apply_matrix; + int xcenter; + int ycenter; + int xoffset; + int yoffset; + + TT_Raster_Map Bit; + + int Fail; + int Num; + int Code; + + int gray_render = 0; + int hinted = 1; + int use_cmap = 0; + int zoom_factor = 1; + int grid = 0; + int use_post = 1; + + char palette[5] = { 0, 1, 2, 3, 4 }; + + + static void ClearData( void ) + { + if ( gray_render ) + memset( Bit.bitmap, gray_palette[0], Bit.size ); + else + memset( Bit.bitmap, 0, Bit.size ); + } + + + void Init_Raster_Area( void ) + { + Bit.rows = vio_Height; /* The whole window */ + Bit.width = vio_Width; + Bit.flow = TT_Flow_Up; + + if ( gray_render ) + { + Bit.cols = Bit.width; + Bit.size = Bit.rows * Bit.width; + } + else + { + Bit.cols = ( Bit.width + 7 ) / 8; /* convert to # of bytes */ + Bit.size = Bit.rows * Bit.cols; /* number of bytes in buffer */ + } + + Bit.bitmap = (void*)malloc( (int)Bit.size ); + if ( !Bit.bitmap ) + Panic( "Not enough memory to allocate bitmap!\n" ); + + ClearData(); + } + + + static TT_Error Reset_PtSize( int pointSize ) + { + TT_Error error; + + + if ( (error = TT_Set_Instance_PointSize( instance, pointSize )) ) + { + RestoreScreen(); + printf( "Error = 0x%x.\n", (int)error ); + Panic( "Could not reset instance.\n" ); + } + + TT_Get_Instance_Metrics( instance, &imetrics ); + + xcenter = imetrics.x_ppem * xcenter_upem / units_per_em / 4; + ycenter = imetrics.y_ppem * ycenter_upem / units_per_em / 4; + + xoffset = vio_Width/2 - xcenter; + yoffset = vio_Height/2 - ycenter; + + return TT_Err_Ok; + } + + + static TT_Error Reset_Rotation( int rotation ) + { + if ( rotation ) + { + float angle; + + + TT_Set_Instance_Transform_Flags( instance, 1, 0 ); + + angle = rotation * Pi / 512; + + matrix.xx = (TT_Fixed)(cos( angle ) * (1L<<16)); + matrix.xy = (TT_Fixed)(sin( angle ) * (1L<<16)); + matrix.yx = -matrix.xy; + matrix.yy = matrix.xx; + + apply_matrix = 1; + } + else + apply_matrix = 0; + + if ( zoom_factor != 1 ) + { + zoom_matrix.xx = zoom_matrix.yy = zoom_factor * (1L<<16); + zoom_matrix.xy = zoom_matrix.yx = 0; + } + + return TT_Err_Ok; + } + + + static TT_Error LoadTrueTypeChar( int idx, int hint ) + { + TT_Error error; + int flags; + + + flags = TTLOAD_SCALE_GLYPH; + if ( hint ) + flags |= TTLOAD_HINT_GLYPH; + + error = TT_Load_Glyph( instance, glyph, idx, flags ); + if ( error ) + return error; + + if ( apply_matrix || zoom_factor != 1 ) + { + TT_Get_Glyph_Outline( glyph, &outline ); + TT_Translate_Outline( &outline, -xcenter*64L, -ycenter*64L ); + if ( apply_matrix ) + TT_Transform_Outline( &outline, &matrix ); + if ( zoom_factor != 1 ) + TT_Transform_Outline( &outline, &zoom_matrix ); + TT_Translate_Outline( &outline, xcenter*64L, ycenter*64L ); + } + + return error; + } + + + static TT_Error ConvertRaster( void ) + { + if ( gray_render ) + return TT_Get_Glyph_Pixmap( glyph, &Bit, xoffset*64L, yoffset*64L ); + else + return TT_Get_Glyph_Bitmap( glyph, &Bit, xoffset*64L, yoffset*64L ); + } + + + static void DrawGrid( void ) + { + char *bmap, mask; + int x, y, shift, toggle; + + + bmap = (char *)Bit.bitmap; + + for ( y = 0; y < Bit.rows; ++y ) + { + if ( ( y - xoffset ) % zoom_factor == 0 ) + { + if ( gray_render ) + for ( x = y & 1; x < Bit.cols; x += 2 ) + bmap[x] = 4 - bmap[x]; + else { + mask = y & 1 ? 0x55 : 0xAA; + for ( x = 0; x < Bit.cols; ++x ) + bmap[x] ^= mask; + } + } + else + { + toggle = y & 1; + + if ( gray_render ) + { + for ( x = xoffset % zoom_factor; x < Bit.cols; x += zoom_factor ) + if ( ( x & 1 ) == toggle ) + bmap[x] = 4 - bmap[x]; + } + else + { + /* tricky business */ + shift = xoffset % zoom_factor; + for ( x = 0; x < Bit.cols; ++x ) + { + for ( mask = 0; shift < 8; shift += zoom_factor ) + if ( ( shift & 1 ) == toggle ) + mask |= 0x80 >> shift; + bmap[x] ^= mask; + shift -= 8; + } + } + } + bmap += Bit.cols; + } + } + + + static int Process_Event( TEvent* event ) + { + switch ( event->what ) + { + case event_Quit: /* ESC or q */ + return 0; + + case event_Keyboard: + if ( event->info == 'h' ) /* Toggle hinting */ + hinted = !hinted; + break; + + case event_Rotate_Glyph: + rotation = ( rotation + event->info ) & 1023; + break; + + case event_Scale_Glyph: + ptsize += event->info; + if ( ptsize < 1 ) + ptsize = 1; + if ( ptsize > MAXPTSIZE / zoom_factor ) + ptsize = MAXPTSIZE / zoom_factor; + break; + + case event_Change_Glyph: + if ( use_cmap ) + { + if ( event->info < 0 ) + { + if ( Code > -event->info ) + Code += event->info; + else + Code = 0; + + for ( ; Code >= 0; Code-- ) + { + Num = TT_Char_Index( char_map, Code ); + if ( Num > 0 ) + break; + } + } + else + { + if ( Code < 65536 - event->info - 1 ) + Code += event->info; + else + Code = 65536 - 1; + + for ( ; Code < 65536; Code++ ) + { + Num = TT_Char_Index( char_map, Code ); + if ( Num > 0 ) + break; + } + } + } + else + { + if ( event->info < 0 ) + { + if ( Num > -event->info ) + Num += event->info; + else + Num = 0; + } + else + { + if ( Num < num_glyphs - event->info - 1 ) + Num += event->info; + else + Num = num_glyphs - 1; + } + } + break; + } + + return 1; + } + + + void usage( char* execname ) + { + printf( "\n" ); + printf( "ftzoom: simple TrueType glyph viewer -- part of the FreeType project\n" ); + printf( "--------------------------------------------------------------------\n" ); + printf( "\n" ); + printf( "Usage: %s [options below] fontname[.ttf|.ttc]\n", execname ); + printf( "\n" ); + printf( " -g gray-level rendering (default: none)\n" ); + printf( " -r R use resolution R dpi (default: 96)\n" ); + printf( " -z Z Z:1 magnification (default: 1:1)\n" ); + printf( " -p id platform id (default: none)\n" ); + printf( " -e id encoding id (default: none)\n" ); + printf( " -n don't use the `post' table\n" ); + printf( " If either -p or -e is not set, no cmap will be used.\n" ); + printf( "\n" ); + + exit( EXIT_FAILURE ); + } + + + /* stack check dtp */ + + int main( int argc, char** argv ) + { + int i; + int platform = -1, encoding = -1; + char filename[128 + 4]; + char alt_filename[128 + 4]; + char* execname; + int option; + int res = 96; + TT_Error error; + TT_Post post; + + TEvent event; + + + execname = argv[0]; + gray_render = 0; + + +#ifdef DEBUG_LEVEL_TRACE + + set_tt_trace_levels( trace_raster, 7 ); + set_tt_trace_levels( trace_gload, 7 ); + +#endif + + + while ( 1 ) + { + option = ft_getopt( argc, argv, "e:gnp:r:z:" ); + + if ( option == -1 ) + break; + + switch ( option ) + { + case 'e': + encoding = atoi( ft_optarg ); + break; + + case 'g': + gray_render = 1; + break; + + case 'n': + use_post = 0; + break; + + case 'p': + platform = atoi( ft_optarg ); + break; + + case 'r': + res = atoi( ft_optarg ); + if ( res < 1 ) + usage( execname ); + break; + + case 'z': + zoom_factor = atoi( ft_optarg ); + if ( zoom_factor < 1 || zoom_factor > 16 ) + usage( execname ); + if ( zoom_factor > 4 ) + grid = 1; + break; + + default: + usage( execname ); + break; + } + } + + if ( ft_optind == argc ) + usage( execname ); + + i = strlen( argv[ft_optind] ); + while ( i > 0 && argv[ft_optind][i] != '\\' && argv[ft_optind][i] != '/' ) + { + if ( argv[ft_optind][i] == '.' ) + i = 0; + i--; + } + + filename[128] = '\0'; + alt_filename[128] = '\0'; + + strncpy( filename, argv[ft_optind], 128 ); + strncpy( alt_filename, argv[ft_optind], 128 ); + + if ( i >= 0 ) + { + strncpy( filename + strlen( filename ), ".ttf", 4 ); + strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); + } + + if ( platform >= 0 || encoding >= 0 ) + use_cmap = 1; + + /* Initialization */ + TT_Init_FreeType( &engine ); + + /* Initialization of the post extension */ + if ( use_post ) + TT_Init_Post_Extension( engine ); + + /* Load face */ + + error = TT_Open_Face( engine, filename, &face ); + + if ( error == TT_Err_Could_Not_Open_File ) + { + strcpy( filename, alt_filename ); + error = TT_Open_Face( engine, alt_filename, &face ); + } + + if ( error == TT_Err_Could_Not_Open_File ) + Panic( "Could not find/open %s.\n", filename ); + else if ( error ) + Panic( "Error while opening %s, error code = 0x%x.\n", + filename, error ); + + /* get face properties and allocate preload arrays */ + + TT_Get_Face_Properties( face, &properties ); + + num_glyphs = properties.num_Glyphs; + xcenter_upem = (properties.header->xMax - properties.header->xMin) / 2; + ycenter_upem = (properties.header->yMax - properties.header->yMin) / 2; + units_per_em = properties.header->Units_Per_EM; + + /* load full post table */ + if ( use_post ) + { + error = TT_Load_PS_Names( face, &post ); + if ( error ) + Panic( "Could not load PS names.\n" ); + } + + /* create glyph */ + + error = TT_New_Glyph( face, &glyph ); + if ( error ) + Panic( "Could not create glyph container.\n" ); + + /* create instance */ + + error = TT_New_Instance( face, &instance ); + if ( error ) + Panic( "Could not create instance for %s.\n", filename ); + + error = TT_Set_Instance_Resolutions( instance, res, res ); + if ( error ) + Panic( "Could not set device resolutions." ); + + if ( gray_render ) + { + if ( !SetGraphScreen( Graphics_Mode_Gray ) ) + Panic( "Could not set up grayscale graphics mode.\n" ); + + TT_Set_Raster_Gray_Palette( engine, gray_palette ); + } + else + { + if ( !SetGraphScreen( Graphics_Mode_Mono ) ) + Panic( "Could not set up mono graphics mode.\n" ); + } + + Init_Raster_Area(); + + old_ptsize = ptsize = 150 / zoom_factor; + old_rotation = rotation = 0; + + Reset_PtSize ( ptsize ); + Reset_Rotation( rotation ); + + if ( use_cmap ) + { + unsigned short num_cmap; + unsigned short cmap_plat; + unsigned short cmap_enc; + + + num_cmap = properties.num_CharMaps; + for ( i = 0; i < num_cmap; i++ ) + { + error = TT_Get_CharMap_ID( face, i, &cmap_plat, &cmap_enc ); + if ( error ) + Panic( "Cannot query cmap, error = 0x%x.\n", error ); + if ( cmap_plat == platform && cmap_enc == encoding ) + break; + } + + if ( i == num_cmap ) + Panic( "Invalid platform and/or encoding ID.\n" ); + + error = TT_Get_CharMap( face, i, &char_map ); + if ( error ) + Panic( "Cannot load cmap, error = 0x%x.\n", error ); + + num_glyphs = (1L << 16) - 1; + } + + Code = 0; + Num = 0; + Fail = 0; + + for ( ;; ) + { + char *glyphname; + + + glyphname = NULL; + + ClearData(); + + if ( ptsize != old_ptsize ) + { + Reset_PtSize( ptsize ); + old_ptsize = ptsize; + } + + if ( rotation != old_rotation ) + { + Reset_Rotation( rotation ); + old_rotation = rotation; + } + + if ( (error = LoadTrueTypeChar( Num, hinted )) == TT_Err_Ok ) + { + ConvertRaster(); + if ( grid ) + DrawGrid(); + + if ( use_post ) + (void)TT_Get_PS_Name(face, Num, &glyphname); + + if ( use_cmap ) + sprintf( Header, "\"%s\": index = %3d, code = 0x%x, hinting = %s", + use_post ? glyphname : "", Num, Code, + hinted ? "ON" : "OFF" ); + else + sprintf( Header, "\"%s\": index = %3d, hinting = %s", + use_post ? glyphname : "", Num, hinted ? "ON" : "OFF" ); + } + else { + Fail++; + sprintf( Header, "\"%s\": index = %3d, hinting = %s (ERROR 0x%lx)", + glyphname ? glyphname : "", Num, + hinted ? "ON" : "OFF", error ); + } + + Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); + +#ifndef X11 +#ifndef OS2 + Print_XY( 0, 0, Header ); +#endif +#endif + + Get_Event( &event ); + if ( !Process_Event( &event ) ) goto End; + } + + End: + + RestoreScreen(); + + TT_Done_FreeType( engine ); + + printf( "Fails = %d.\n", Fail ); + + exit( EXIT_SUCCESS ); /* for safety reasons */ + + return 0; /* never reached */ + } + + +/* End */ diff --git a/test/gdriver.h b/test/gdriver.h new file mode 100644 index 0000000..0caf42f --- /dev/null +++ b/test/gdriver.h @@ -0,0 +1,55 @@ +/******************************************************************* + * + * gdriver.h : Graphics utility driver generic interface 1.1 + * + * Generic interface for all drivers of the graphics utility used + * by the FreeType test programs. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef GDRIVER_H +#define GDRIVER_H + + /* Note that we now support an event based model, even with */ + /* full-screen modes. It is the responsability of the driver */ + /* to map its events to the TEvent structure when called */ + /* through Get_Event. */ + + /* The event classes are defined in the file 'gevents.h' included */ + /* by the test programs, not by the graphics utility. */ + + typedef struct _TEvent + { + int what; /* event class */ + int info; /* event parameter */ + } TEvent; + + + /* Get last event. In full-screen modes, a keystroke must be */ + /* translated to an event class with a parameter. */ + void Get_Event( TEvent* event ); + + /* A call to this function must set the graphics mode, the Vio */ + /* variable, as well as the values vio_ScanLineWidth, vio_Width */ + /* and vio_Height. */ + int Driver_Set_Graphics( int mode ); + + /* Restore previous mode or release display buffer/window */ + int Driver_Restore_Mode( void ); + + /* display bitmap on screen */ + int Driver_Display_Bitmap( char* buffer, int line, int col ); + +#endif /* GDRIVER_H */ + + +/* End */ diff --git a/test/gevents.h b/test/gevents.h new file mode 100644 index 0000000..5b2f73f --- /dev/null +++ b/test/gevents.h @@ -0,0 +1,43 @@ +/******************************************************************* + * + * gevents.h test programs events definition 1.1 + * + * This file defines the events used by the FreeType test programs + * It is _not_ included by 'gmain.c'. This file is also used by the + * drivers to translate their own events in GEvents. + * + * Not a very good design, but we're not rewriting X... + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef GEVENTS_H +#define GEVENTS_H + + typedef enum _GEvent + { + event_None, + event_Quit, /* Quit program */ + + event_Keyboard, /* unknown keystroke */ + + event_Change_Glyph, + event_Rotate_Glyph, + event_Scale_Glyph, + + event_Change_ScanType, + event_Change_Instructions + } GEvent; + +#endif /* GEVENTS_H */ + + +/* End */ diff --git a/test/gmain.c b/test/gmain.c new file mode 100644 index 0000000..e5b1e7e --- /dev/null +++ b/test/gmain.c @@ -0,0 +1,475 @@ +/******************************************************************* + * + * gmain.c graphics utility main body 1.1 + * + * This file defines a common implementation of the graphics + * utility used by the FreeType test programs. It relies on + * system-specific drivers, like 'gfs_os.c', which interface is + * described in the file 'gdriver.h'. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#include "gdriver.h" +#include "gmain.h" + +#ifndef FAILURE +#define FAILURE 0 +#endif + +#ifndef SUCCESS +#define SUCCESS 1 +#endif + + char* Vio; /* pointer to VRAM or display buffer */ + + int vio_ScanLineWidth; /* scan line width in bytes */ + + int vio_Width; + int vio_Height; + + int gcursor_x = 0; + int gcursor_y = 0; + + int gwindow_width = 0; + int gwindow_height = 0; + + unsigned char gray_palette[5]; + + + typedef void TFunction_Print_8x8_Char( int x, + int y, + unsigned char c ); + + TFunction_Print_8x8_Char* Print_8x8_Char; + + /* font characters */ + + unsigned char font_8x8[2048] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, + 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, + 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, + 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C, + 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, + 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, + 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, + 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, + 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, + 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78, + 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, + 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0, + 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, + 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, + 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, + 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, + 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, + 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, + 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, + 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, + 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, + 0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00, + 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, + 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, + 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, + 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, + 0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00, + 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, + 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, + 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, + 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, + 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, + 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, + 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30, + 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, + 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, + 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, + 0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, + 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, + 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, + 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, + 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, + 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, + 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00, + 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, + 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, + 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, + 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, + 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, + 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, + 0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, + 0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00, + 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, + 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + 0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, + 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, + 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, + 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00, + 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, + 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00, + 0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, + 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, + 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00, + 0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00, + 0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, + 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00, + 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, + 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, + 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, + 0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00, + 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38, + 0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, + 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, + 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, + 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, + 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, + 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, + 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, + 0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, + 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, + 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, + 0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30, + 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3, + 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, + 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, + 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00, + 0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00, + 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, + 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, + 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, + 0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F, + 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03, + 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, + 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0xDB, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, + 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, + 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, + 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, + 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, + 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, + 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, + 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, + 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, + 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, + 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, + 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, + 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, + 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, + 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, + 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, + 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, + 0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, + 0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + + void Print_8x8_Mono( int x, int y, unsigned char c ) + { + int offset, i; + unsigned char* bitm; + + if ( !Vio ) + return; + + offset = x + y * vio_ScanLineWidth * 8; + bitm = font_8x8 + (int)c * 8; + + for ( i = 0; i < 8; i++ ) + { + Vio[offset] = *bitm; + bitm++; + offset += vio_ScanLineWidth; + } + } + + + void Print_8x8_Gray( int x, int y, unsigned char c ) + { + int offset, i, bit; + unsigned char* bitm; + + if ( !Vio ) + return; + + offset = x * 8 + y * vio_ScanLineWidth * 8; + bitm = font_8x8 + (int)c * 8; + + for ( i = 0; i < 8; i++ ) + { + bit = 0x80; + while ( bit > 0 ) + { + if ( bit & *bitm ) + Vio[offset] = (char)0x0f; + else + Vio[offset] = 0x00; + + bit >>= 1; + offset++; + } + offset += vio_ScanLineWidth - 8; + bitm++; + } + } + + + int SetGraphScreen( int mode ) + { + gcursor_x = 0; + gcursor_y = 0; + + switch( mode ) + { + case Graphics_Mode_Mono: + if ( !Driver_Set_Graphics( mode ) ) + return FAILURE; + + gwindow_width = vio_ScanLineWidth; + gwindow_height = vio_Height / 8; + + Print_8x8_Char = Print_8x8_Mono; + break; + + case Graphics_Mode_Gray: + if ( !Driver_Set_Graphics( mode ) ) + return FAILURE; + + gwindow_width = vio_ScanLineWidth / 8; + gwindow_height = vio_Height / 8; + + Print_8x8_Char = Print_8x8_Gray; + break; + + default: + /* Invalid function call */ + return FAILURE; + } + + return SUCCESS; + } + + + /* restore previous (or text) video mode */ + + int RestoreScreen( void ) + { + gcursor_x = 0; + gcursor_y = 0; + gwindow_height = 0; + gwindow_height = 0; + + return Driver_Restore_Mode(); + } + + + void Display_Bitmap_On_Screen( char* buffer, int line, int col ) + { + Driver_Display_Bitmap( buffer, line, col ); + } + + + void Goto_XY( int x, int y ) + { + gcursor_x = x; + gcursor_y = y; + } + + + void Print_Str( char* string ) + { + if ( !string ) return; + + while ( *string ) + { + switch ( *string ) + { + case '\n': + gcursor_x = 0; + gcursor_y++; + if ( gcursor_y > gwindow_height ) gcursor_y = 0; + break; + + default: + (*Print_8x8_Char)( gcursor_x, gcursor_y, *string ); + + gcursor_x++; + + if ( gcursor_x >= gwindow_width ) + { + gcursor_x = 0; + gcursor_y++; + + if ( gcursor_y >= gwindow_height ) gcursor_y = 0; + } + } + string++; + } + } + + + void Print_XY( int x, int y, char* string ) + { + Goto_XY( x, y ); + Print_Str( string ); + } + + + + + + + + + +/* End */ diff --git a/test/gmain.h b/test/gmain.h new file mode 100644 index 0000000..3cf16f4 --- /dev/null +++ b/test/gmain.h @@ -0,0 +1,71 @@ +/******************************************************************* + * + * gmain.h graphics utility main interface 1.1 + * + * This file defines a common interface, implemented in the body + * file 'gmain.c'. It relies on system dependent driver files, + * like 'gfs_os.c', whose interface is described in 'gdriver.h'. + * + * Copyright 1996-1999 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used + * modified and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + ******************************************************************/ + +#ifndef GMAIN_H +#define GMAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Graphics mode definitions */ + +#define Graphics_Mode_Mono 1 /* monochrome graphics mode */ +#define Graphics_Mode_Gray 2 /* 8-bit palette graphics mode */ + + extern char* Vio; /* Pointer to VRAM or display buffer */ + + extern int vio_ScanLineWidth; /* Scan Line width in bytes */ + + extern int vio_Width; + extern int vio_Height; + + extern unsigned char gray_palette[5]; /* standard gray_palette */ + + + /* set a graphics mode, chosen from the FS_Graphics_xxx list */ + int SetGraphScreen( int mode ); + + /* restore previous (or text) video mode */ + int RestoreScreen( void ); + + /* display a bitmap of 'line' lines, and 'col' columns (each */ + /* column made of 8 bits) */ + void Display_Bitmap_On_Screen( char* buffer, int line, int col ); + + void Goto_XY( int x, int y ); + + + extern int gcursor_x; + extern int gcursor_y; + + extern int gwindow_width; + extern int gwindow_height; + + void Print_Str( char* string ); + void Print_XY ( int x, int y, char* string ); + +#ifdef __cplusplus +} +#endif + +#endif /* GMAIN_H */ + + +/* End */